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",
+    ],
+}
diff --git a/tools/lock_agent/agent.cpp b/tools/lock_agent/agent.cpp
new file mode 100644
index 0000000..59bfa2b
--- /dev/null
+++ b/tools/lock_agent/agent.cpp
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstring>
+#include <iostream>
+#include <memory>
+#include <sstream>
+
+#include <jni.h>
+
+#include <jvmti.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h>
+#include <android-base/unique_fd.h>
+
+#include <fcntl.h>
+#include <sys/stat.h>
+
+// We need dladdr.
+#if !defined(__APPLE__) && !defined(_WIN32)
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#define DEFINED_GNU_SOURCE
+#endif
+#include <dlfcn.h>
+#ifdef DEFINED_GNU_SOURCE
+#undef _GNU_SOURCE
+#undef DEFINED_GNU_SOURCE
+#endif
+#endif
+
+// Slicer's headers have code that triggers these warnings. b/65298177
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#pragma clang diagnostic ignored "-Wsign-compare"
+
+#include <slicer/dex_ir.h>
+#include <slicer/code_ir.h>
+#include <slicer/dex_bytecode.h>
+#include <slicer/dex_ir_builder.h>
+#include <slicer/writer.h>
+#include <slicer/reader.h>
+
+#pragma clang diagnostic pop
+
+namespace {
+
+JavaVM* gJavaVM = nullptr;
+
+// Converts a class name to a type descriptor
+// (ex. "java.lang.String" to "Ljava/lang/String;")
+std::string classNameToDescriptor(const char* className) {
+    std::stringstream ss;
+    ss << "L";
+    for (auto p = className; *p != '\0'; ++p) {
+        ss << (*p == '.' ? '/' : *p);
+    }
+    ss << ";";
+    return ss.str();
+}
+
+using namespace dex;
+using namespace lir;
+
+bool transform(std::shared_ptr<ir::DexFile> dexIr) {
+    bool modified = false;
+
+    std::unique_ptr<ir::Builder> builder;
+
+    for (auto& method : dexIr->encoded_methods) {
+        // Do not look into abstract/bridge/native/synthetic methods.
+        if ((method->access_flags & (kAccAbstract | kAccBridge | kAccNative | kAccSynthetic))
+                != 0) {
+            continue;
+        }
+
+        struct HookVisitor: public Visitor {
+            HookVisitor(std::unique_ptr<ir::Builder>* b, std::shared_ptr<ir::DexFile> d_ir,
+                    CodeIr* c_ir) :
+                    b(b), dIr(d_ir), cIr(c_ir) {
+            }
+
+            bool Visit(Bytecode* bytecode) override {
+                if (bytecode->opcode == OP_MONITOR_ENTER) {
+                    prepare();
+                    addCall(bytecode, OP_INVOKE_STATIC_RANGE, hookType, "preLock", voidType,
+                            objectType, reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
+                    myModified = true;
+                    return true;
+                }
+                if (bytecode->opcode == OP_MONITOR_EXIT) {
+                    prepare();
+                    addCall(bytecode, OP_INVOKE_STATIC_RANGE, hookType, "postLock", voidType,
+                            objectType, reinterpret_cast<VReg*>(bytecode->operands[0])->reg);
+                    myModified = true;
+                    return true;
+                }
+                return false;
+            }
+
+            void prepare() {
+                if (*b == nullptr) {
+                    *b = std::unique_ptr<ir::Builder>(new ir::Builder(dIr));
+                }
+                if (voidType == nullptr) {
+                    voidType = (*b)->GetType("V");
+                    hookType = (*b)->GetType("Lcom/android/lock_checker/LockHook;");
+                    objectType = (*b)->GetType("Ljava/lang/Object;");
+                }
+            }
+
+            void addInst(lir::Instruction* instructionAfter, Opcode opcode,
+                    const std::list<Operand*>& operands) {
+                auto instruction = cIr->Alloc<Bytecode>();
+
+                instruction->opcode = opcode;
+
+                for (auto it = operands.begin(); it != operands.end(); it++) {
+                    instruction->operands.push_back(*it);
+                }
+
+                cIr->instructions.InsertBefore(instructionAfter, instruction);
+            }
+
+            void addCall(lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
+                    const char* methodName, ir::Type* returnType,
+                    const std::vector<ir::Type*>& types, const std::list<int>& regs) {
+                auto proto = (*b)->GetProto(returnType, (*b)->GetTypeList(types));
+                auto method = (*b)->GetMethodDecl((*b)->GetAsciiString(methodName), proto, type);
+
+                VRegList* paramRegs = cIr->Alloc<VRegList>();
+                for (auto it = regs.begin(); it != regs.end(); it++) {
+                    paramRegs->registers.push_back(*it);
+                }
+
+                addInst(instructionAfter, opcode,
+                        { paramRegs, cIr->Alloc<Method>(method, method->orig_index) });
+            }
+
+            void addCall(lir::Instruction* instructionAfter, Opcode opcode, ir::Type* type,
+                    const char* methodName, ir::Type* returnType, ir::Type* paramType,
+                    u4 paramVReg) {
+                auto proto = (*b)->GetProto(returnType, (*b)->GetTypeList( { paramType }));
+                auto method = (*b)->GetMethodDecl((*b)->GetAsciiString(methodName), proto, type);
+
+                VRegRange* args = cIr->Alloc<VRegRange>(paramVReg, 1);
+
+                addInst(instructionAfter, opcode,
+                        { args, cIr->Alloc<Method>(method, method->orig_index) });
+            }
+
+            std::unique_ptr<ir::Builder>* b;
+            std::shared_ptr<ir::DexFile> dIr;
+            CodeIr* cIr;
+            ir::Type* voidType = nullptr;
+            ir::Type* hookType = nullptr;
+            ir::Type* objectType = nullptr;
+            bool myModified = false;
+        };
+
+        CodeIr c(method.get(), dexIr);
+        HookVisitor visitor(&builder, dexIr, &c);
+
+        for (auto it = c.instructions.begin(); it != c.instructions.end(); ++it) {
+            lir::Instruction* fi = *it;
+            fi->Accept(&visitor);
+        }
+
+        if (visitor.myModified) {
+            modified = true;
+            c.Assemble();
+        }
+    }
+
+    return modified;
+}
+
+std::pair<dex::u1*, size_t> maybeTransform(const char* name, size_t classDataLen,
+        const unsigned char* classData, dex::Writer::Allocator* allocator) {
+    // Isolate byte code of class class. This is needed as Android usually gives us more
+    // than the class we need.
+    dex::Reader reader(classData, classDataLen);
+
+    dex::u4 index = reader.FindClassIndex(classNameToDescriptor(name).c_str());
+    CHECK_NE(index, kNoIndex);
+    reader.CreateClassIr(index);
+    std::shared_ptr<ir::DexFile> ir = reader.GetIr();
+
+    if (!transform(ir)) {
+        return std::make_pair(nullptr, 0);
+    }
+
+    size_t new_size;
+    dex::Writer writer(ir);
+    dex::u1* newClassData = writer.CreateImage(allocator, &new_size);
+    return std::make_pair(newClassData, new_size);
+}
+
+void transformHook(jvmtiEnv* jvmtiEnv, JNIEnv* env ATTRIBUTE_UNUSED,
+        jclass classBeingRedefined ATTRIBUTE_UNUSED, jobject loader, const char* name,
+        jobject protectionDomain ATTRIBUTE_UNUSED, jint classDataLen,
+        const unsigned char* classData, jint* newClassDataLen, unsigned char** newClassData) {
+    // Even reading the classData array is expensive as the data is only generated when the
+    // memory is touched. Hence call JvmtiAgent#shouldTransform to check if we need to transform
+    // the class.
+
+    // Skip bootclasspath classes. TODO: Make this configurable.
+    if (loader == nullptr) {
+        return;
+    }
+
+    // Do not look into java.* classes. Should technically be filtered by above, but when that's
+    // configurable have this.
+    if (strncmp("java", name, 4) == 0) {
+        return;
+    }
+
+    // Do not look into our Java classes.
+    if (strncmp("com/android/lock_checker", name, 24) == 0) {
+        return;
+    }
+
+    class JvmtiAllocator: public dex::Writer::Allocator {
+    public:
+        explicit JvmtiAllocator(::jvmtiEnv* jvmti) :
+                jvmti_(jvmti) {
+        }
+
+        void* Allocate(size_t size) override {
+            unsigned char* res = nullptr;
+            jvmti_->Allocate(size, &res);
+            return res;
+        }
+
+        void Free(void* ptr) override {
+            jvmti_->Deallocate(reinterpret_cast<unsigned char*>(ptr));
+        }
+
+    private:
+        ::jvmtiEnv* jvmti_;
+    };
+    JvmtiAllocator allocator(jvmtiEnv);
+    std::pair<dex::u1*, size_t> result = maybeTransform(name, classDataLen, classData,
+            &allocator);
+
+    if (result.second > 0) {
+        *newClassData = result.first;
+        *newClassDataLen = static_cast<jint>(result.second);
+    }
+}
+
+void dataDumpRequestHook(jvmtiEnv* jvmtiEnv ATTRIBUTE_UNUSED) {
+    if (gJavaVM == nullptr) {
+        LOG(ERROR) << "No JavaVM for dump";
+        return;
+    }
+    JNIEnv* env;
+    if (gJavaVM->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
+        LOG(ERROR) << "Could not get env for dump";
+        return;
+    }
+    jclass lockHookClass = env->FindClass("com/android/lock_checker/LockHook");
+    if (lockHookClass == nullptr) {
+        env->ExceptionClear();
+        LOG(ERROR) << "Could not find LockHook class";
+        return;
+    }
+    jmethodID dumpId = env->GetStaticMethodID(lockHookClass, "dump", "()V");
+    if (dumpId == nullptr) {
+        env->ExceptionClear();
+        LOG(ERROR) << "Could not find LockHook.dump";
+        return;
+    }
+    env->CallStaticVoidMethod(lockHookClass, dumpId);
+    env->ExceptionClear();
+}
+
+// A function for dladdr to search.
+extern "C" __attribute__ ((visibility ("default"))) void lock_agent_tag_fn() {
+}
+
+bool fileExists(const std::string& path) {
+    struct stat statBuf;
+    int rc = stat(path.c_str(), &statBuf);
+    return rc == 0;
+}
+
+std::string findLockAgentJar() {
+    // Check whether the jar is located next to the agent's so.
+#ifndef __APPLE__
+    {
+        Dl_info info;
+        if (dladdr(reinterpret_cast<const void*>(&lock_agent_tag_fn), /* out */ &info) != 0) {
+            std::string lockAgentSoPath = info.dli_fname;
+            std::string dir = android::base::Dirname(lockAgentSoPath);
+            std::string lockAgentJarPath = dir + "/" + "lockagent.jar";
+            if (fileExists(lockAgentJarPath)) {
+                return lockAgentJarPath;
+            }
+        } else {
+            LOG(ERROR) << "dladdr failed";
+        }
+    }
+#endif
+
+    std::string sysFrameworkPath = "/system/framework/lockagent.jar";
+    if (fileExists(sysFrameworkPath)) {
+        return sysFrameworkPath;
+    }
+
+    std::string relPath = "lockagent.jar";
+    if (fileExists(relPath)) {
+        return relPath;
+    }
+
+    return "";
+}
+
+void prepareHook(jvmtiEnv* env) {
+    // Inject the agent Java code.
+    {
+        std::string path = findLockAgentJar();
+        if (path.empty()) {
+            LOG(FATAL) << "Could not find lockagent.jar";
+        }
+        LOG(INFO) << "Will load Java parts from " << path;
+        jvmtiError res = env->AddToBootstrapClassLoaderSearch(path.c_str());
+        if (res != JVMTI_ERROR_NONE) {
+            LOG(FATAL) << "Could not add lockagent from " << path << " to boot classpath: " << res;
+        }
+    }
+
+    jvmtiCapabilities caps;
+    memset(&caps, 0, sizeof(caps));
+    caps.can_retransform_classes = 1;
+
+    if (env->AddCapabilities(&caps) != JVMTI_ERROR_NONE) {
+        LOG(FATAL) << "Could not add caps";
+    }
+
+    jvmtiEventCallbacks cb;
+    memset(&cb, 0, sizeof(cb));
+    cb.ClassFileLoadHook = transformHook;
+    cb.DataDumpRequest = dataDumpRequestHook;
+
+    if (env->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
+        LOG(FATAL) << "Could not set cb";
+    }
+
+    if (env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, nullptr)
+            != JVMTI_ERROR_NONE) {
+        LOG(FATAL) << "Could not enable events";
+    }
+    if (env->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DATA_DUMP_REQUEST, nullptr)
+            != JVMTI_ERROR_NONE) {
+        LOG(FATAL) << "Could not enable events";
+    }
+}
+
+jint attach(JavaVM* vm, char* options ATTRIBUTE_UNUSED, void* reserved ATTRIBUTE_UNUSED) {
+    gJavaVM = vm;
+
+    jvmtiEnv* env;
+    jint jvmError = vm->GetEnv(reinterpret_cast<void**>(&env), JVMTI_VERSION_1_2);
+    if (jvmError != JNI_OK) {
+        return jvmError;
+    }
+
+    prepareHook(env);
+
+    return JVMTI_ERROR_NONE;
+}
+
+extern "C" JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved) {
+    return attach(vm, options, reserved);
+}
+
+extern "C" JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
+    return attach(vm, options, reserved);
+}
+
+int locktest_main(int argc, char *argv[]) {
+    if (argc != 3) {
+        LOG(FATAL) << "Need two arguments: dex-file class-name";
+    }
+    struct stat statBuf;
+    int rc = stat(argv[1], &statBuf);
+    if (rc != 0) {
+        PLOG(FATAL) << "Could not get file size for " << argv[1];
+    }
+    std::unique_ptr<char[]> data(new char[statBuf.st_size]);
+    {
+        android::base::unique_fd fd(open(argv[1], O_RDONLY));
+        if (fd.get() == -1) {
+            PLOG(FATAL) << "Could not open file " << argv[1];
+        }
+        if (!android::base::ReadFully(fd.get(), data.get(), statBuf.st_size)) {
+            PLOG(FATAL) << "Could not read file " << argv[1];
+        }
+    }
+
+    class NewDeleteAllocator: public dex::Writer::Allocator {
+    public:
+        explicit NewDeleteAllocator() {
+        }
+
+        void* Allocate(size_t size) override {
+            return new char[size];
+        }
+
+        void Free(void* ptr) override {
+            delete[] reinterpret_cast<char*>(ptr);
+        }
+    };
+    NewDeleteAllocator allocator;
+
+    std::pair<dex::u1*, size_t> result = maybeTransform(argv[2], statBuf.st_size,
+            reinterpret_cast<unsigned char*>(data.get()), &allocator);
+
+    if (result.second == 0) {
+        LOG(INFO) << "No transformation";
+        return 0;
+    }
+
+    std::string newName(argv[1]);
+    newName.append(".new");
+
+    {
+        android::base::unique_fd fd(
+                open(newName.c_str(), O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR));
+        if (fd.get() == -1) {
+            PLOG(FATAL) << "Could not open file " << newName;
+        }
+        if (!android::base::WriteFully(fd.get(), result.first, result.second)) {
+            PLOG(FATAL) << "Could not write file " << newName;
+        }
+    }
+    LOG(INFO) << "Transformed file written to " << newName;
+
+    return 0;
+}
+
+}  // namespace
+
+int main(int argc, char *argv[]) {
+    return locktest_main(argc, argv);
+}
diff --git a/tools/lock_agent/java/com/android/lock_checker/LockHook.java b/tools/lock_agent/java/com/android/lock_checker/LockHook.java
new file mode 100644
index 0000000..95b3181
--- /dev/null
+++ b/tools/lock_agent/java/com/android/lock_checker/LockHook.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.lock_checker;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.util.Log;
+import android.util.LogWriter;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.util.StatLogger;
+
+import dalvik.system.AnnotatedStackTraceElement;
+
+import libcore.util.HexEncoding;
+
+import java.io.PrintWriter;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Entry class for lock inversion infrastructure. The agent will inject calls to preLock
+ * and postLock, and the hook will call the checker, and store violations.
+ */
+public class LockHook {
+    private static final String TAG = "LockHook";
+
+    private static final Charset sFilenameCharset = Charset.forName("UTF-8");
+
+    private static final HandlerThread sHandlerThread;
+    private static final WtfHandler sHandler;
+
+    private static final AtomicInteger sTotalObtainCount = new AtomicInteger();
+    private static final AtomicInteger sTotalReleaseCount = new AtomicInteger();
+    private static final AtomicInteger sDeepestNest = new AtomicInteger();
+
+    /**
+     * Whether to do the lock check on this thread.
+     */
+    private static final ThreadLocal<Boolean> sDoCheck = ThreadLocal.withInitial(() -> true);
+
+    interface Stats {
+        int ON_THREAD = 0;
+    }
+
+    static final StatLogger sStats = new StatLogger(new String[] { "on-thread", });
+
+    private static final ConcurrentLinkedQueue<Object> sViolations = new ConcurrentLinkedQueue<>();
+    private static final int MAX_VIOLATIONS = 50;
+
+    private static final LockChecker[] sCheckers;
+
+    static {
+        sHandlerThread = new HandlerThread("LockHook:wtf", Process.THREAD_PRIORITY_BACKGROUND);
+        sHandlerThread.start();
+        sHandler = new WtfHandler(sHandlerThread.getLooper());
+
+        sCheckers = new LockChecker[] { new OnThreadLockChecker() };
+    }
+
+    static <T> boolean shouldDumpStacktrace(StacktraceHasher hasher, Map<String, T> dumpedSet,
+            T val, AnnotatedStackTraceElement[] st, int from, int to) {
+        final String stacktraceHash = hasher.stacktraceHash(st, from, to);
+        if (dumpedSet.containsKey(stacktraceHash)) {
+            return false;
+        }
+        dumpedSet.put(stacktraceHash, val);
+        return true;
+    }
+
+    static void updateDeepestNest(int nest) {
+        for (;;) {
+            final int knownDeepest = sDeepestNest.get();
+            if (knownDeepest >= nest) {
+                return;
+            }
+            if (sDeepestNest.compareAndSet(knownDeepest, nest)) {
+                return;
+            }
+        }
+    }
+
+    static void wtf(String message) {
+        sHandler.wtf(message);
+    }
+
+    static void doCheckOnThisThread(boolean check) {
+        sDoCheck.set(check);
+    }
+
+    /**
+     * This method is called when a lock is about to be held. (Except if it's a
+     * synchronized, the lock is already held.)
+     */
+    public static void preLock(Object lock) {
+        if (Thread.currentThread() != sHandlerThread && sDoCheck.get()) {
+            sDoCheck.set(false);
+            try {
+                sTotalObtainCount.incrementAndGet();
+                for (LockChecker checker : sCheckers) {
+                    checker.pre(lock);
+                }
+            } finally {
+                sDoCheck.set(true);
+            }
+        }
+    }
+
+    /**
+     * This method is called when a lock is about to be released.
+     */
+    public static void postLock(Object lock) {
+        if (Thread.currentThread() != sHandlerThread && sDoCheck.get()) {
+            sDoCheck.set(false);
+            try {
+                sTotalReleaseCount.incrementAndGet();
+                for (LockChecker checker : sCheckers) {
+                    checker.post(lock);
+                }
+            } finally {
+                sDoCheck.set(true);
+            }
+        }
+    }
+
+    private static class WtfHandler extends Handler {
+        private static final int MSG_WTF = 1;
+
+        WtfHandler(Looper looper) {
+            super(looper);
+        }
+
+        public void wtf(String msg) {
+            sDoCheck.set(false);
+            SomeArgs args = SomeArgs.obtain();
+            args.arg1 = msg;
+            obtainMessage(MSG_WTF, args).sendToTarget();
+            sDoCheck.set(true);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_WTF:
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Log.wtf(TAG, (String) args.arg1);
+                    args.recycle();
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Generates a hash for a given stacktrace of a {@link Throwable}.
+     */
+    static class StacktraceHasher {
+        private byte[] mLineNumberBuffer = new byte[4];
+        private final MessageDigest mHash;
+
+        StacktraceHasher() {
+            try {
+                mHash = MessageDigest.getInstance("MD5");
+            } catch (NoSuchAlgorithmException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public String stacktraceHash(Throwable t) {
+            mHash.reset();
+            for (StackTraceElement e : t.getStackTrace()) {
+                hashStackTraceElement(e);
+            }
+            return HexEncoding.encodeToString(mHash.digest());
+        }
+
+        public String stacktraceHash(AnnotatedStackTraceElement[] annotatedStack, int from,
+                int to) {
+            mHash.reset();
+            for (int i = from; i <= to; i++) {
+                hashStackTraceElement(annotatedStack[i].getStackTraceElement());
+            }
+            return HexEncoding.encodeToString(mHash.digest());
+        }
+
+        private void hashStackTraceElement(StackTraceElement e) {
+            if (e.getFileName() != null) {
+                mHash.update(sFilenameCharset.encode(e.getFileName()).array());
+            } else {
+                if (e.getClassName() != null) {
+                    mHash.update(sFilenameCharset.encode(e.getClassName()).array());
+                }
+                if (e.getMethodName() != null) {
+                    mHash.update(sFilenameCharset.encode(e.getMethodName()).array());
+                }
+            }
+
+            final int line = e.getLineNumber();
+            mLineNumberBuffer[0] = (byte) ((line >> 24) & 0xff);
+            mLineNumberBuffer[1] = (byte) ((line >> 16) & 0xff);
+            mLineNumberBuffer[2] = (byte) ((line >> 8) & 0xff);
+            mLineNumberBuffer[3] = (byte) ((line >> 0) & 0xff);
+            mHash.update(mLineNumberBuffer);
+        }
+    }
+
+    static void addViolation(Object o) {
+        sViolations.offer(o);
+        while (sViolations.size() > MAX_VIOLATIONS) {
+            sViolations.poll();
+        }
+    }
+
+    /**
+     * Dump stats to the given PrintWriter.
+     */
+    public static void dump(PrintWriter pw, String indent) {
+        final int oc = LockHook.sTotalObtainCount.get();
+        final int rc = LockHook.sTotalReleaseCount.get();
+        final int dn = LockHook.sDeepestNest.get();
+        pw.print("Lock stats: oc=");
+        pw.print(oc);
+        pw.print(" rc=");
+        pw.print(rc);
+        pw.print(" dn=");
+        pw.print(dn);
+        pw.println();
+
+        for (LockChecker checker : sCheckers) {
+            pw.print(indent);
+            pw.print("  ");
+            checker.dump(pw);
+            pw.println();
+        }
+
+        sStats.dump(pw, indent);
+
+        pw.print(indent);
+        pw.println("Violations:");
+        for (Object v : sViolations) {
+            pw.print(indent); // This won't really indent a multiline string,
+                              // though.
+            pw.println(v);
+        }
+    }
+
+    /**
+     * Dump stats to logcat.
+     */
+    public static void dump() {
+        // Dump to logcat.
+        PrintWriter out = new PrintWriter(new LogWriter(Log.WARN, TAG), true);
+        dump(out, "");
+        out.close();
+    }
+
+    interface LockChecker {
+        void pre(Object lock);
+
+        void post(Object lock);
+
+        int getNumDetected();
+
+        int getNumDetectedUnique();
+
+        String getCheckerName();
+
+        void dump(PrintWriter pw);
+    }
+}
diff --git a/tools/lock_agent/java/com/android/lock_checker/OnThreadLockChecker.java b/tools/lock_agent/java/com/android/lock_checker/OnThreadLockChecker.java
new file mode 100644
index 0000000..0f3a285
--- /dev/null
+++ b/tools/lock_agent/java/com/android/lock_checker/OnThreadLockChecker.java
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.lock_checker;
+
+import android.util.Log;
+
+import dalvik.system.AnnotatedStackTraceElement;
+import dalvik.system.VMStack;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+
+
+class OnThreadLockChecker implements LockHook.LockChecker {
+    private static final String TAG = "LockCheckOnThread";
+
+    private static final boolean SKIP_RECURSIVE = true;
+
+    private final Thread mChecker;
+
+    private final AtomicInteger mNumDetected = new AtomicInteger();
+
+    private final AtomicInteger mNumDetectedUnique = new AtomicInteger();
+
+    // Queue for possible violations, to handle them on the sChecker thread.
+    private final LinkedBlockingQueue<Violation> mQueue = new LinkedBlockingQueue<>();
+
+    // The stack of locks held on the current thread.
+    private final ThreadLocal<List<Object>> mHeldLocks = ThreadLocal
+            .withInitial(() -> new ArrayList<>(10));
+
+    // A cached stacktrace hasher for each thread. The hasher caches internal objects and is not
+    // thread-safe.
+    private final ThreadLocal<LockHook.StacktraceHasher> mStacktraceHasher = ThreadLocal
+            .withInitial(() -> new LockHook.StacktraceHasher());
+
+    // A map of stacktrace hashes we have seen.
+    private final ConcurrentMap<String, Boolean> mDumpedStacktraceHashes =
+            new ConcurrentHashMap<>();
+
+    OnThreadLockChecker() {
+        mChecker = new Thread(() -> checker());
+        mChecker.setName(TAG);
+        mChecker.setPriority(Thread.MIN_PRIORITY);
+        mChecker.start();
+    }
+
+    private static class LockPair {
+        // Consider WeakReference. It will require also caching the String
+        // description for later reporting, though.
+        Object mFirst;
+        Object mSecond;
+
+        private int mCachedHashCode;
+
+        LockPair(Object first, Object second) {
+            mFirst = first;
+            mSecond = second;
+            computeHashCode();
+        }
+
+        public void set(Object newFirst, Object newSecond) {
+            mFirst = newFirst;
+            mSecond = newSecond;
+            computeHashCode();
+        }
+
+        private void computeHashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + ((mFirst == null) ? 0 : System.identityHashCode(mFirst));
+            result = prime * result + ((mSecond == null) ? 0 : System.identityHashCode(mSecond));
+            mCachedHashCode = result;
+        }
+
+        @Override
+        public int hashCode() {
+            return mCachedHashCode;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            LockPair other = (LockPair) obj;
+            return mFirst == other.mFirst && mSecond == other.mSecond;
+        }
+    }
+
+    private static class OrderData {
+        final int mTid;
+        final String mThreadName;
+        final AnnotatedStackTraceElement[] mStack;
+
+        OrderData(int tid, String threadName, AnnotatedStackTraceElement[] stack) {
+            this.mTid = tid;
+            this.mThreadName = threadName;
+            this.mStack = stack;
+        }
+    }
+
+    private static ConcurrentMap<LockPair, OrderData> sLockOrderMap = new ConcurrentHashMap<>();
+
+    @Override
+    public void pre(Object lock) {
+        handlePre(Thread.currentThread(), lock);
+    }
+
+    @Override
+    public void post(Object lock) {
+        handlePost(Thread.currentThread(), lock);
+    }
+
+    private void handlePre(Thread self, Object lock) {
+        List<Object> heldLocks = mHeldLocks.get();
+
+        LockHook.updateDeepestNest(heldLocks.size() + 1);
+
+        heldLocks.add(lock);
+        if (heldLocks.size() == 1) {
+            return;
+        }
+
+        // Data about this location. Cached and lazily initialized.
+        AnnotatedStackTraceElement[] annotatedStack = null;
+        OrderData orderData = null;
+
+        // Reused tmp pair;
+        LockPair tmp = new LockPair(lock, lock);
+
+        int size = heldLocks.size() - 1;
+        for (int i = 0; i < size; i++) {
+            Object alreadyHeld = heldLocks.get(i);
+            if (SKIP_RECURSIVE && lock == alreadyHeld) {
+                return;
+            }
+
+            // Check if we've already seen alreadyHeld -> lock.
+            tmp.set(alreadyHeld, lock);
+            if (sLockOrderMap.containsKey(tmp)) {
+                continue; // Already seen.
+            }
+
+            // Note: could insert the OrderData now. This would mean we only
+            // report one instance for each order violation, but it avoids
+            // the expensive hashing in handleViolation for duplicate stacks.
+
+            // Locking alreadyHeld -> lock, check whether the inverse exists.
+            tmp.set(lock, alreadyHeld);
+
+            // We technically need a critical section here. Add synchronized and
+            // skip
+            // instrumenting this class. For now, a concurrent hash map is good
+            // enough.
+
+            OrderData oppositeData = sLockOrderMap.getOrDefault(tmp, null);
+            if (oppositeData != null) {
+                if (annotatedStack == null) {
+                    annotatedStack = VMStack.getAnnotatedThreadStackTrace(self);
+                }
+                postViolation(self, alreadyHeld, lock, annotatedStack, oppositeData);
+                continue;
+            }
+
+            // Enter our occurrence.
+            if (annotatedStack == null) {
+                annotatedStack = VMStack.getAnnotatedThreadStackTrace(self);
+            }
+            if (orderData == null) {
+                orderData = new OrderData((int) self.getId(), self.getName(), annotatedStack);
+            }
+            sLockOrderMap.putIfAbsent(new LockPair(alreadyHeld, lock), orderData);
+
+            // Check again whether we might have raced with the opposite.
+            oppositeData = sLockOrderMap.getOrDefault(tmp, null);
+            if (oppositeData != null) {
+                postViolation(self, alreadyHeld, lock, annotatedStack, oppositeData);
+            }
+        }
+    }
+
+    private void handlePost(Thread self, Object lock) {
+        List<Object> heldLocks = mHeldLocks.get();
+        if (heldLocks.isEmpty()) {
+            Log.wtf("LockCheckMine", "Empty thread list on post()");
+            return;
+        }
+        int index = heldLocks.size() - 1;
+        if (heldLocks.get(index) != lock) {
+            Log.wtf("LockCheckMine", "post(" + Violation.describeLock(lock) + ") vs [..., "
+                    + Violation.describeLock(heldLocks.get(index)) + "]");
+            return;
+        }
+        heldLocks.remove(index);
+    }
+
+    private static class Violation {
+        int mSelfTid;
+        String mSelfName;
+        Object mAlreadyHeld;
+        Object mLock;
+        AnnotatedStackTraceElement[] mStack;
+        OrderData mOppositeData;
+
+        Violation(Thread self, Object alreadyHeld, Object lock,
+                AnnotatedStackTraceElement[] stack, OrderData oppositeData) {
+            this.mSelfTid = (int) self.getId();
+            this.mSelfName = self.getName();
+            this.mAlreadyHeld = alreadyHeld;
+            this.mLock = lock;
+            this.mStack = stack;
+            this.mOppositeData = oppositeData;
+        }
+
+        private static String getAnnotatedStackString(AnnotatedStackTraceElement[] stackTrace,
+                int skip, String extra, int prefixAfter, String prefix) {
+            StringBuilder sb = new StringBuilder();
+            for (int i = skip; i < stackTrace.length; i++) {
+                AnnotatedStackTraceElement element = stackTrace[i];
+                sb.append("    ").append(i >= prefixAfter ? prefix : "").append("at ")
+                        .append(element.getStackTraceElement()).append('\n');
+                if (i == skip && extra != null) {
+                    sb.append("    ").append(extra).append('\n');
+                }
+                if (element.getHeldLocks() != null) {
+                    for (Object held : element.getHeldLocks()) {
+                        sb.append("    ").append(i >= prefixAfter ? prefix : "")
+                                .append(describeLocking(held, "locked")).append('\n');
+                    }
+                }
+            }
+            return sb.toString();
+        }
+
+        private static String describeLocking(Object lock, String action) {
+            return String.format("- %s %s", action, describeLock(lock));
+        }
+
+        private static int getTo(AnnotatedStackTraceElement[] stack, Object searchFor) {
+            // Extract the range of the annotated stack.
+            int to = stack.length - 1;
+            for (int i = 0; i < stack.length; i++) {
+                Object[] locks = stack[i].getHeldLocks();
+                if (locks != null) {
+                    for (Object heldLock : locks) {
+                        if (heldLock == searchFor) {
+                            to = i;
+                            break;
+                        }
+                    }
+                }
+            }
+            return to;
+        }
+
+        private static String describeLock(Object lock) {
+            return String.format("<0x%08x> (a %s)", System.identityHashCode(lock),
+                    lock.getClass().getName());
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("Lock inversion detected!\n");
+            sb.append("  Locked ");
+            sb.append(describeLock(mLock));
+            sb.append(" -> ");
+            sb.append(describeLock(mAlreadyHeld));
+            sb.append(" on thread ").append(mOppositeData.mTid).append(" (")
+                    .append(mOppositeData.mThreadName).append(")");
+            sb.append(" at:\n");
+            sb.append(getAnnotatedStackString(mOppositeData.mStack, 4,
+                    describeLocking(mAlreadyHeld, "will lock"), getTo(mOppositeData.mStack, mLock)
+                    + 1, "    | "));
+            sb.append("  Locking ");
+            sb.append(describeLock(mAlreadyHeld));
+            sb.append(" -> ");
+            sb.append(describeLock(mLock));
+            sb.append(" on thread ").append(mSelfTid).append(" (").append(mSelfName).append(")");
+            sb.append(" at:\n");
+            sb.append(getAnnotatedStackString(mStack, 4, describeLocking(mLock, "will lock"),
+                    getTo(mStack, mAlreadyHeld) + 1, "    | "));
+
+            return sb.toString();
+        }
+    }
+
+    private void postViolation(Thread self, Object alreadyHeld, Object lock,
+            AnnotatedStackTraceElement[] annotatedStack, OrderData oppositeData) {
+        mQueue.offer(new Violation(self, alreadyHeld, lock, annotatedStack, oppositeData));
+    }
+
+    private void handleViolation(Violation v) {
+        mNumDetected.incrementAndGet();
+        // Extract the range of the annotated stack.
+        int to = Violation.getTo(v.mStack, v.mAlreadyHeld);
+
+        if (LockHook.shouldDumpStacktrace(mStacktraceHasher.get(), mDumpedStacktraceHashes,
+                Boolean.TRUE, v.mStack, 0, to)) {
+            mNumDetectedUnique.incrementAndGet();
+            LockHook.wtf(v.toString());
+            LockHook.addViolation(v);
+        }
+    }
+
+    private void checker() {
+        LockHook.doCheckOnThisThread(false);
+
+        for (;;) {
+            try {
+                Violation v = mQueue.take();
+                handleViolation(v);
+            } catch (InterruptedException e) {
+                // TODO Auto-generated catch block
+                e.printStackTrace();
+            }
+        }
+    }
+
+    @Override
+    public int getNumDetected() {
+        return mNumDetected.get();
+    }
+
+    @Override
+    public int getNumDetectedUnique() {
+        return mNumDetectedUnique.get();
+    }
+
+    @Override
+    public String getCheckerName() {
+        return "Standard LockChecker";
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        pw.print(getCheckerName());
+        pw.print(": d=");
+        pw.print(getNumDetected());
+        pw.print(" du=");
+        pw.print(getNumDetectedUnique());
+    }
+}
diff --git a/tools/lock_agent/start_with_lockagent.sh b/tools/lock_agent/start_with_lockagent.sh
new file mode 100755
index 0000000..9539222
--- /dev/null
+++ b/tools/lock_agent/start_with_lockagent.sh
@@ -0,0 +1,5 @@
+#!/system/bin/sh
+APP=$1
+shift
+$APP -Xplugin:libopenjdkjvmti.so -agentpath:liblockagent.so $@
+
