Framework: Lock inversion checker

Add an agent-based lock inversion checker. The agent will dynamically
rewrite bytecode to inject calls to LockHook, which runs a checker
on these.

Implement a simple on-thread checker that keeps a per-thread stack
of locks and a global map of lock ordering. As-is, transitivity of
checks is not guaranteed, but should be captured in most practical
cases.

To run a process with the lock checker, start the process with the
agent. The helper script start_with_lockagent.sh can be used for this:

  adb shell setprop wrap.pkg-name script start_with_lockagent

(cherry picked from commit aeb6fce5b33680bc538dbd66979a28bcba1329b4)

Bug: 124744938
Test: manual
Merged-In: Idd9a7066a5b8cb8c0de2e995f08759c98d9473e1
Change-Id: Idd9a7066a5b8cb8c0de2e995f08759c98d9473e1
diff --git a/tools/lock_agent/Android.bp b/tools/lock_agent/Android.bp
new file mode 100644
index 0000000..c54e5b5
--- /dev/null
+++ b/tools/lock_agent/Android.bp
@@ -0,0 +1,61 @@
+cc_library {
+    name: "liblockagent",
+    host_supported: false,
+    srcs: ["agent.cpp"],
+    static_libs: [
+        "libbase_ndk",
+        "slicer_ndk_no_rtti",
+    ],
+    shared_libs: [
+        "libz",  // for slicer (using adler32).
+        "liblog",
+    ],
+    sdk_version: "current",
+    stl: "c++_static",
+    include_dirs: [
+        // NDK headers aren't available in platform NDK builds.
+        "libnativehelper/include_jni",
+    ],
+    header_libs: [
+        "libopenjdkjvmti_headers",
+    ],
+    compile_multilib: "both",
+}
+
+cc_binary_host {
+    name: "lockagenttest",
+    srcs: ["agent.cpp"],
+    static_libs: [
+        "libbase",
+        "libz",
+        "slicer",
+    ],
+    include_dirs: [
+        // NDK headers aren't available in platform NDK builds.
+        "libnativehelper/include_jni",
+    ],
+    header_libs: [
+        "libopenjdkjvmti_headers",
+    ],
+}
+
+java_library {
+    name: "lockagent",
+    srcs: ["java/**/*.java"],
+    dex_preopt: {
+        enabled: false,
+    },
+    optimize: {
+        enabled: false,
+    },
+    installable: true,
+}
+
+sh_binary {
+    name: "start_with_lockagent",
+    src: "start_with_lockagent.sh",
+    required: [
+        "liblockagent",
+        "lockagent",
+    ],
+}