diff --git a/tools/lint/Android.bp b/tools/lint/Android.bp
new file mode 100644
index 0000000..dcbc32b
--- /dev/null
+++ b/tools/lint/Android.bp
@@ -0,0 +1,46 @@
+// Copyright (C) 2021 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 {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_base_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["frameworks_base_license"],
+}
+
+java_library_host {
+    name: "AndroidFrameworkLintChecker",
+    srcs: ["checks/src/main/java/**/*.kt"],
+    plugins: ["auto_service_plugin"],
+    libs: [
+        "auto_service_annotations",
+        "lint_api",
+    ],
+}
+
+// TODO: (b/162368644) Implement these (working in gradle) Kotlin Tests to run on Soong
+//java_test_host {
+//    name: "AndroidFrameworkLintCheckerTest",
+//    srcs: [
+//     "checks/src/test/java/**/*.kt",
+//     "checks/src/main/java/**/*.kt",
+//    ],
+//    plugins: ["auto_service_plugin"],
+//    static_libs: [
+//        "auto_service_annotations",
+//        "lint_api",
+//    ],
+//}
diff --git a/tools/lint/checks/src/main/java/com/android/lint/CallingIdentityTokenDetector.kt b/tools/lint/checks/src/main/java/com/android/lint/CallingIdentityTokenDetector.kt
new file mode 100644
index 0000000..4e30834
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/android/lint/CallingIdentityTokenDetector.kt
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2021 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.lint
+
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.ISSUE_NESTED_CLEAR_IDENTITY_CALLS
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.ISSUE_NON_FINAL_TOKEN
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.ISSUE_RESTORE_IDENTITY_CALL_NOT_IN_FINALLY_BLOCK
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.ISSUE_UNUSED_TOKEN
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.ISSUE_USE_OF_CALLER_AWARE_METHODS_WITH_CLEARED_IDENTITY
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.getIncidentMessageNestedClearIdentityCallsPrimary
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.getIncidentMessageNestedClearIdentityCallsSecondary
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.getIncidentMessageNonFinalToken
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.getIncidentMessageRestoreIdentityCallNotInFinallyBlock
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.getIncidentMessageUnusedToken
+import com.android.lint.CallingIdentityTokenIssueRegistry.Companion.getIncidentMessageUseOfCallerAwareMethodsWithClearedIdentity
+import com.android.tools.lint.client.api.UElementHandler
+import com.android.tools.lint.detector.api.Context
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.search.PsiSearchScopeUtil
+import com.intellij.psi.search.SearchScope
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UElement
+import org.jetbrains.uast.UExpression
+import org.jetbrains.uast.ULocalVariable
+import org.jetbrains.uast.UQualifiedReferenceExpression
+import org.jetbrains.uast.USimpleNameReferenceExpression
+import org.jetbrains.uast.UTryExpression
+import org.jetbrains.uast.getParentOfType
+import org.jetbrains.uast.isUastChildOf
+
+/**
+ * Lint Detector that finds issues with improper usages of the token returned by
+ * Binder.clearCallingIdentity()
+ */
+@Suppress("UnstableApiUsage")
+class CallingIdentityTokenDetector : Detector(), SourceCodeScanner {
+    private companion object {
+        const val CLASS_BINDER = "android.os.Binder"
+        const val CLASS_USER_HANDLE = "android.os.UserHandle"
+
+        @JvmField
+        val callerAwareMethods = listOf(
+                Method.BINDER_GET_CALLING_PID,
+                Method.BINDER_GET_CALLING_UID,
+                Method.BINDER_GET_CALLING_UID_OR_THROW,
+                Method.BINDER_GET_CALLING_USER_HANDLE,
+                Method.USER_HANDLE_GET_CALLING_APP_ID,
+                Method.USER_HANDLE_GET_CALLING_USER_ID
+        )
+    }
+
+    /** Map of <Token variable name, Token object> */
+    private val tokensMap = mutableMapOf<String, Token>()
+
+    override fun getApplicableUastTypes(): List<Class<out UElement?>> =
+            listOf(ULocalVariable::class.java, UQualifiedReferenceExpression::class.java)
+
+    override fun createUastHandler(context: JavaContext): UElementHandler =
+            TokenUastHandler(context)
+
+    /** File analysis starts with a clear map */
+    override fun beforeCheckFile(context: Context) {
+        tokensMap.clear()
+    }
+
+    /**
+     * - If tokensMap has tokens after checking the file -> reports all locations as unused token
+     * issue incidents
+     * - File analysis ends with a clear map
+     */
+    override fun afterCheckFile(context: Context) {
+        for (token in tokensMap.values) {
+            context.report(
+                    ISSUE_UNUSED_TOKEN,
+                    token.location,
+                    getIncidentMessageUnusedToken(token.variableName)
+            )
+        }
+        tokensMap.clear()
+    }
+
+    /** UAST handler that analyses elements and reports incidents */
+    private inner class TokenUastHandler(val context: JavaContext) : UElementHandler() {
+        /**
+         * For every variable initialization with Binder.clearCallingIdentity():
+         * - Checks for non-final token issue
+         * - Checks for unused token issue within different scopes
+         * - Checks for nested calls of clearCallingIdentity() issue
+         * - Stores token variable name, scope in the file and its location in tokensMap
+         */
+        override fun visitLocalVariable(node: ULocalVariable) {
+            val rhsExpression = node.uastInitializer as? UQualifiedReferenceExpression ?: return
+            if (!isMethodCall(rhsExpression, Method.BINDER_CLEAR_CALLING_IDENTITY)) return
+            val location = context.getLocation(node as UElement)
+            val variableName = node.getName()
+            if (!node.isFinal) {
+                context.report(
+                        ISSUE_NON_FINAL_TOKEN,
+                        location,
+                        getIncidentMessageNonFinalToken(variableName)
+                )
+            }
+            // If there exists an unused variable with the same name in the map, we can imply that
+            // we left the scope of the previous declaration, so we need to report the unused token
+            val oldToken = tokensMap[variableName]
+            if (oldToken != null) {
+                context.report(
+                        ISSUE_UNUSED_TOKEN,
+                        oldToken.location,
+                        getIncidentMessageUnusedToken(oldToken.variableName)
+                )
+            }
+            // If there exists a token in the same scope as the current new token, it means that
+            // clearCallingIdentity() has been called at least twice without immediate restoration
+            // of identity, so we need to report the nested call of clearCallingIdentity()
+            val firstCallToken = findFirstTokenInScope(node)
+            if (firstCallToken != null) {
+                context.report(
+                        ISSUE_NESTED_CLEAR_IDENTITY_CALLS,
+                        createNestedLocation(firstCallToken, location),
+                        getIncidentMessageNestedClearIdentityCallsPrimary(
+                                firstCallToken.variableName,
+                                variableName
+                        )
+                )
+            }
+            tokensMap[variableName] = Token(variableName, node.sourcePsi?.getUseScope(), location)
+        }
+
+        /**
+         * For every class.method():
+         * - Checks use of caller-aware methods issue
+         * For every call of Binder.restoreCallingIdentity(token):
+         * - Checks for restoreCallingIdentity() not in the finally block issue
+         * - Removes token from tokensMap if token is within the scope of the method
+         */
+        override fun visitQualifiedReferenceExpression(node: UQualifiedReferenceExpression) {
+            val token = findFirstTokenInScope(node)
+            if (isCallerAwareMethod(node) && token != null) {
+                context.report(
+                        ISSUE_USE_OF_CALLER_AWARE_METHODS_WITH_CLEARED_IDENTITY,
+                        context.getLocation(node),
+                        getIncidentMessageUseOfCallerAwareMethodsWithClearedIdentity(
+                                token.variableName,
+                                node.asRenderString()
+                        )
+                )
+                return
+            }
+            if (!isMethodCall(node, Method.BINDER_RESTORE_CALLING_IDENTITY)) return
+            val selector = node.selector as UCallExpression
+            val arg = selector.valueArguments[0] as? USimpleNameReferenceExpression ?: return
+            val variableName = arg.identifier
+            if (!isInFinallyBlock(node)) {
+                context.report(
+                        ISSUE_RESTORE_IDENTITY_CALL_NOT_IN_FINALLY_BLOCK,
+                        context.getLocation(node),
+                        getIncidentMessageRestoreIdentityCallNotInFinallyBlock(variableName)
+                )
+            }
+            val originalScope = tokensMap[variableName]?.scope ?: return
+            val psi = arg.sourcePsi ?: return
+            if (PsiSearchScopeUtil.isInScope(originalScope, psi)) {
+                tokensMap.remove(variableName)
+            }
+        }
+
+        private fun isCallerAwareMethod(expression: UQualifiedReferenceExpression): Boolean =
+                callerAwareMethods.any { method -> isMethodCall(expression, method) }
+
+        private fun isMethodCall(
+            expression: UQualifiedReferenceExpression,
+            method: Method
+        ): Boolean {
+            val psiMethod = expression.resolve() as? PsiMethod ?: return false
+            return psiMethod.getName() == method.methodName &&
+                    context.evaluator.methodMatches(
+                            psiMethod,
+                            method.className,
+                            /* allowInherit */ true,
+                            *method.args
+                    )
+        }
+    }
+
+    private fun isInFinallyBlock(expression: UExpression): Boolean {
+        val tryExpression = expression.getParentOfType<UTryExpression>(strict = true)
+                ?: return false
+        return expression.isUastChildOf(tryExpression.finallyClause)
+    }
+
+    private fun findFirstTokenInScope(node: UElement): Token? {
+        val psi = node.sourcePsi ?: return null
+        for (token in tokensMap.values) {
+            if (token.scope != null && PsiSearchScopeUtil.isInScope(token.scope, psi)) {
+                return token
+            }
+        }
+        return null
+    }
+
+    /**
+     * Creates a new instance of the primary location with the secondary location
+     *
+     * Here, secondary location is the helper location that shows where the issue originated
+     *
+     * The detector reports locations as objects, so when we add a secondary location to a location
+     * that has multiple issues, the secondary location gets displayed every time a location is
+     * referenced.
+     *
+     * Example:
+     * 1: final long token1 = Binder.clearCallingIdentity();
+     * 2: long token2 = Binder.clearCallingIdentity();
+     * 3: Binder.restoreCallingIdentity(token1);
+     * 4: Binder.restoreCallingIdentity(token2);
+     *
+     * Explanation:
+     * token2 has 2 issues: NonFinal and NestedCalls
+     *
+     *     Lint report without cloning                        Lint report with cloning
+     * line 2: [NonFinalIssue]                            line 2: [NonFinalIssue]
+     *     line 1: [NestedCallsIssue]
+     * line 2: [NestedCallsIssue]                            line 2: [NestedCallsIssue]
+     *     line 1: [NestedCallsIssue]                           line 1: [NestedCallsIssue]
+     */
+    private fun createNestedLocation(
+        firstCallToken: Token,
+        secondCallTokenLocation: Location
+    ): Location {
+        return cloneLocation(secondCallTokenLocation)
+                .withSecondary(
+                        cloneLocation(firstCallToken.location),
+                        getIncidentMessageNestedClearIdentityCallsSecondary(
+                                firstCallToken.variableName
+                        )
+                )
+    }
+
+    private fun cloneLocation(location: Location): Location {
+        // smart cast of location.start to 'Position' is impossible, because 'location.start' is a
+        // public API property declared in different module
+        val locationStart = location.start
+        return if (locationStart == null) {
+            Location.create(location.file)
+        } else {
+            Location.create(location.file, locationStart, location.end)
+        }
+    }
+
+    private enum class Method(
+        val className: String,
+        val methodName: String,
+        val args: Array<String>
+    ) {
+        BINDER_CLEAR_CALLING_IDENTITY(CLASS_BINDER, "clearCallingIdentity", emptyArray()),
+        BINDER_RESTORE_CALLING_IDENTITY(CLASS_BINDER, "restoreCallingIdentity", arrayOf("long")),
+        BINDER_GET_CALLING_PID(CLASS_BINDER, "getCallingPid", emptyArray()),
+        BINDER_GET_CALLING_UID(CLASS_BINDER, "getCallingUid", emptyArray()),
+        BINDER_GET_CALLING_UID_OR_THROW(CLASS_BINDER, "getCallingUidOrThrow", emptyArray()),
+        BINDER_GET_CALLING_USER_HANDLE(CLASS_BINDER, "getCallingUserHandle", emptyArray()),
+        USER_HANDLE_GET_CALLING_APP_ID(CLASS_USER_HANDLE, "getCallingAppId", emptyArray()),
+        USER_HANDLE_GET_CALLING_USER_ID(CLASS_USER_HANDLE, "getCallingUserId", emptyArray())
+    }
+
+    private data class Token(
+        val variableName: String,
+        val scope: SearchScope?,
+        val location: Location
+    )
+}
diff --git a/tools/lint/checks/src/main/java/com/android/lint/CallingIdentityTokenIssueRegistry.kt b/tools/lint/checks/src/main/java/com/android/lint/CallingIdentityTokenIssueRegistry.kt
new file mode 100644
index 0000000..a0e9249
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/android/lint/CallingIdentityTokenIssueRegistry.kt
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2021 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.lint
+
+import com.android.tools.lint.client.api.IssueRegistry
+// TODO: uncomment when lint API in Soong becomes 30.0+
+// import com.android.tools.lint.client.api.Vendor
+import com.android.tools.lint.detector.api.CURRENT_API
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.google.auto.service.AutoService
+
+@AutoService(IssueRegistry::class)
+@Suppress("UnstableApiUsage")
+class CallingIdentityTokenIssueRegistry : IssueRegistry() {
+    override val issues = listOf(
+            ISSUE_UNUSED_TOKEN,
+            ISSUE_NON_FINAL_TOKEN,
+            ISSUE_NESTED_CLEAR_IDENTITY_CALLS,
+            ISSUE_RESTORE_IDENTITY_CALL_NOT_IN_FINALLY_BLOCK,
+            ISSUE_USE_OF_CALLER_AWARE_METHODS_WITH_CLEARED_IDENTITY
+    )
+
+    override val api: Int
+        get() = CURRENT_API
+
+    override val minApi: Int
+        get() = 8
+
+//    TODO: uncomment when lint API in Soong becomes 30.0+
+//    override val vendor: Vendor = Vendor(
+//            vendorName = "Android Open Source Project",
+//            feedbackUrl = "http://b/issues/new?component=315013",
+//            contact = "brufino@google.com"
+//    )
+
+    companion object {
+        /** Issue: unused token from Binder.clearCallingIdentity() */
+        @JvmField
+        val ISSUE_UNUSED_TOKEN: Issue = Issue.create(
+                id = "UnusedTokenOfOriginalCallingIdentity",
+                briefDescription = "Unused token of Binder.clearCallingIdentity()",
+                explanation = """
+                    You cleared the original calling identity with \
+                    `Binder.clearCallingIdentity()`, but have not used the returned token to \
+                    restore the identity.
+
+                    Call `Binder.restoreCallingIdentity(token)` in the `finally` block, at the end \
+                    of the method or when you need to restore the identity.
+
+                    `token` is the result of `Binder.clearCallingIdentity()`
+                    """,
+                category = Category.SECURITY,
+                priority = 6,
+                severity = Severity.WARNING,
+                implementation = Implementation(
+                        CallingIdentityTokenDetector::class.java,
+                        Scope.JAVA_FILE_SCOPE
+                )
+        )
+
+        fun getIncidentMessageUnusedToken(variableName: String) = "`$variableName` has not been " +
+                "used to restore the calling identity. Call " +
+                "`Binder.restoreCallingIdentity($variableName)` or remove `$variableName`."
+
+        /** Issue: non-final token from Binder.clearCallingIdentity() */
+        @JvmField
+        val ISSUE_NON_FINAL_TOKEN: Issue = Issue.create(
+                id = "NonFinalTokenOfOriginalCallingIdentity",
+                briefDescription = "Non-final token of Binder.clearCallingIdentity()",
+                explanation = """
+                    You cleared the original calling identity with \
+                    `Binder.clearCallingIdentity()`, but have not made the returned token `final`.
+
+                    The token should be `final` in order to prevent it from being overwritten, \
+                    which can cause problems when restoring the identity with \
+                    `Binder.restoreCallingIdentity(token)`.
+                    """,
+                category = Category.SECURITY,
+                priority = 6,
+                severity = Severity.WARNING,
+                implementation = Implementation(
+                        CallingIdentityTokenDetector::class.java,
+                        Scope.JAVA_FILE_SCOPE
+                )
+        )
+
+        fun getIncidentMessageNonFinalToken(variableName: String) = "`$variableName` is a " +
+                "non-final token from `Binder.clearCallingIdentity()`. Add `final` keyword to " +
+                "`$variableName`."
+
+        /** Issue: nested calls of Binder.clearCallingIdentity() */
+        @JvmField
+        val ISSUE_NESTED_CLEAR_IDENTITY_CALLS: Issue = Issue.create(
+                id = "NestedClearCallingIdentityCalls",
+                briefDescription = "Nested calls of Binder.clearCallingIdentity()",
+                explanation = """
+                    You cleared the original calling identity with \
+                    `Binder.clearCallingIdentity()` twice without restoring identity with the \
+                    result of the first call.
+
+                    Make sure to restore the identity after each clear identity call.
+                    """,
+                category = Category.SECURITY,
+                priority = 6,
+                severity = Severity.WARNING,
+                implementation = Implementation(
+                        CallingIdentityTokenDetector::class.java,
+                        Scope.JAVA_FILE_SCOPE
+                )
+        )
+
+        fun getIncidentMessageNestedClearIdentityCallsPrimary(
+            firstCallVariableName: String,
+            secondCallVariableName: String
+        ): String = "The calling identity has already been cleared and returned into " +
+                "`$firstCallVariableName`. Move `$secondCallVariableName` declaration after " +
+                "restoring the calling identity with " +
+                "`Binder.restoreCallingIdentity($firstCallVariableName)`."
+
+        fun getIncidentMessageNestedClearIdentityCallsSecondary(
+            firstCallVariableName: String
+        ): String = "Location of the `$firstCallVariableName` declaration."
+
+        /** Issue: Binder.restoreCallingIdentity() is not in finally block */
+        @JvmField
+        val ISSUE_RESTORE_IDENTITY_CALL_NOT_IN_FINALLY_BLOCK: Issue = Issue.create(
+                id = "RestoreIdentityCallNotInFinallyBlock",
+                briefDescription = "Binder.restoreCallingIdentity() is not in finally block",
+                explanation = """
+                    You are restoring the original calling identity with \
+                    `Binder.restoreCallingIdentity()`, but the call is not in the `finally` block \
+                    of the `try` statement.
+
+                    Use the following pattern for running operations with your own identity:
+
+                    ```
+                    final long token = Binder.clearCallingIdentity();
+                    try {
+                        // Code using your own identity
+                    } finally {
+                        Binder.restoreCallingIdentity();
+                    }
+                    ```
+
+                    If you do not surround the code using your identity with the `try` statement \
+                    and call `Binder.restoreCallingIdentity()` in the `finally` block, you may run \
+                    code with your identity that was originally intended to run with the calling \
+                    application's identity.
+                    """,
+                category = Category.SECURITY,
+                priority = 6,
+                severity = Severity.WARNING,
+                implementation = Implementation(
+                        CallingIdentityTokenDetector::class.java,
+                        Scope.JAVA_FILE_SCOPE
+                )
+        )
+
+        fun getIncidentMessageRestoreIdentityCallNotInFinallyBlock(variableName: String): String =
+                "`Binder.restoreCallingIdentity($variableName)` is not in the `finally` block. " +
+                        "Surround the call with `finally` block."
+
+        /** Issue: Use of caller-aware methods after Binder.clearCallingIdentity() */
+        @JvmField
+        val ISSUE_USE_OF_CALLER_AWARE_METHODS_WITH_CLEARED_IDENTITY: Issue = Issue.create(
+                id = "UseOfCallerAwareMethodsWithClearedIdentity",
+                briefDescription = "Use of caller-aware methods after " +
+                        "Binder.clearCallingIdentity()",
+                explanation = """
+                    You cleared the original calling identity with \
+                    `Binder.clearCallingIdentity()`, but used one of the methods below before \
+                    restoring the identity. These methods will use your own identity instead of \
+                    the caller's identity, so if this is expected replace them with methods that \
+                    explicitly query your own identity such as `Process.myUid()`, \
+                    `Process.myPid()` and `UserHandle.myUserId()`, otherwise move those methods \
+                    out of the `Binder.clearCallingIdentity()` / `Binder.restoreCallingIdentity()` \
+                    section.
+
+                    ```
+                    Binder.getCallingPid()
+                    Binder.getCallingUid()
+                    Binder.getCallingUidOrThrow()
+                    Binder.getCallingUserHandle()
+                    UserHandle.getCallingAppId()
+                    UserHandle.getCallingUserId()
+                    ```
+                    """,
+                category = Category.SECURITY,
+                priority = 6,
+                severity = Severity.WARNING,
+                implementation = Implementation(
+                        CallingIdentityTokenDetector::class.java,
+                        Scope.JAVA_FILE_SCOPE
+                )
+        )
+
+        fun getIncidentMessageUseOfCallerAwareMethodsWithClearedIdentity(
+            variableName: String,
+            methodName: String
+        ): String = "You cleared the original identity with `Binder.clearCallingIdentity()` " +
+                "and returned into `$variableName`, so `$methodName` will be using your own " +
+                "identity instead of the caller's. Either explicitly query your own identity or " +
+                "move it after restoring the identity with " +
+                "`Binder.restoreCallingIdentity($variableName)`."
+    }
+}
diff --git a/tools/lint/checks/src/test/java/com/android/lint/CallingIdentityTokenDetectorTest.kt b/tools/lint/checks/src/test/java/com/android/lint/CallingIdentityTokenDetectorTest.kt
new file mode 100644
index 0000000..8a81609
--- /dev/null
+++ b/tools/lint/checks/src/test/java/com/android/lint/CallingIdentityTokenDetectorTest.kt
@@ -0,0 +1,747 @@
+/*
+ * Copyright (C) 2021 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.lint
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class CallingIdentityTokenDetectorTest : LintDetectorTest() {
+    override fun getDetector(): Detector = CallingIdentityTokenDetector()
+
+    override fun getIssues(): List<Issue> = listOf(
+            CallingIdentityTokenIssueRegistry.ISSUE_UNUSED_TOKEN,
+            CallingIdentityTokenIssueRegistry.ISSUE_NON_FINAL_TOKEN,
+            CallingIdentityTokenIssueRegistry.ISSUE_NESTED_CLEAR_IDENTITY_CALLS,
+            CallingIdentityTokenIssueRegistry.ISSUE_RESTORE_IDENTITY_CALL_NOT_IN_FINALLY_BLOCK,
+            CallingIdentityTokenIssueRegistry
+                    .ISSUE_USE_OF_CALLER_AWARE_METHODS_WITH_CLEARED_IDENTITY
+    )
+
+    /** No issue scenario */
+
+    fun testDoesNotDetectIssuesInCorrectScenario() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod() {
+                            final long token1 = Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                Binder.restoreCallingIdentity(token1);
+                            }
+                            final long token2 = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token2);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expectClean()
+    }
+
+    /** Unused token issue tests */
+
+    fun testDetectsUnusedTokens() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod1() {
+                            final long token1 = Binder.clearCallingIdentity();
+                        }
+                        private void testMethod2() {
+                            final long token2 = android.os.Binder.clearCallingIdentity();
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:5: Warning: token1 has not been used to \
+                        restore the calling identity. Call Binder.restoreCallingIdentity(token1) \
+                        or remove token1. [UnusedTokenOfOriginalCallingIdentity]
+                                final long token1 = Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:8: Warning: token2 has not been used to \
+                        restore the calling identity. Call Binder.restoreCallingIdentity(token2) \
+                        or remove token2. [UnusedTokenOfOriginalCallingIdentity]
+                                final long token2 = android.os.Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 2 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDetectsUnusedTokensInScopes() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod1() {
+                            final long token = Binder.clearCallingIdentity();
+                        }
+                        private void testMethod2() {
+                            long token = 0;
+                            try {
+                            } finally {
+                                Binder.restoreCallingIdentity(token);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:5: Warning: token has not been used to \
+                        restore the calling identity. Call Binder.restoreCallingIdentity(token) \
+                        or remove token. [UnusedTokenOfOriginalCallingIdentity]
+                                final long token = Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectUsedTokensInScopes() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod1() {
+                            final long token = Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                Binder.restoreCallingIdentity(token);
+                            }
+                        }
+                        private void testMethod2() {
+                            long token = 0;
+                            try {
+                            } finally {
+                                Binder.restoreCallingIdentity(token);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expectClean()
+    }
+
+    fun testDetectsUnusedTokensWithSimilarNamesInScopes() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod1() {
+                            final long token = Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                            }
+                        }
+                        private void testMethod2() {
+                            final long token = Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:5: Warning: token has not been used to \
+                        restore the calling identity. Call Binder.restoreCallingIdentity(token) \
+                        or remove token. [UnusedTokenOfOriginalCallingIdentity]
+                                final long token = Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:11: Warning: token has not been used to \
+                        restore the calling identity. Call Binder.restoreCallingIdentity(token) \
+                        or remove token. [UnusedTokenOfOriginalCallingIdentity]
+                                final long token = Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 2 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    /** Non-final token issue tests */
+
+    fun testDetectsNonFinalTokens() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod() {
+                            long token1 = Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                Binder.restoreCallingIdentity(token1);
+                            }
+                            long token2 = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token2);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:5: Warning: token1 is a non-final token from \
+                        Binder.clearCallingIdentity(). Add final keyword to token1. \
+                        [NonFinalTokenOfOriginalCallingIdentity]
+                                long token1 = Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:10: Warning: token2 is a non-final token from \
+                        Binder.clearCallingIdentity(). Add final keyword to token2. \
+                        [NonFinalTokenOfOriginalCallingIdentity]
+                                long token2 = android.os.Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 2 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    /** Nested clearCallingIdentity() calls issue tests */
+
+    fun testDetectsNestedClearCallingIdentityCallsPattern1() {
+        // Pattern: clear - clear - restore - clear - restore - restore
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod() {
+                            final long token1 = Binder.clearCallingIdentity();
+                            final long token2 = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token1);
+                            }
+                            final long token3 = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token2);
+                            }
+                            try {
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token3);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:6: Warning: The calling identity has already \
+                        been cleared and returned into token1. Move token2 declaration after \
+                        restoring the calling identity with Binder.restoreCallingIdentity(token1). \
+                        [NestedClearCallingIdentityCalls]
+                                final long token2 = android.os.Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                            src/test/pkg/TestClass1.java:5: Location of the token1 declaration.
+                        src/test/pkg/TestClass1.java:11: Warning: The calling identity has already \
+                        been cleared and returned into token2. Move token3 declaration after \
+                        restoring the calling identity with Binder.restoreCallingIdentity(token2). \
+                        [NestedClearCallingIdentityCalls]
+                                final long token3 = android.os.Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                            src/test/pkg/TestClass1.java:6: Location of the token2 declaration.
+                        0 errors, 2 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDetectsNestedClearCallingIdentityCallsPattern2() {
+        // Pattern: clear - clear - clear - restore - restore - restore
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod() {
+                            final long token1 = Binder.clearCallingIdentity();
+                            final long token2 = android.os.Binder.clearCallingIdentity();
+                            final long token3 = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                Binder.restoreCallingIdentity(token1);
+                            }
+                            try {
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token2);
+                            }
+                            try {
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token3);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:6: Warning: The calling identity has already \
+                        been cleared and returned into token1. Move token2 declaration after \
+                        restoring the calling identity with Binder.restoreCallingIdentity(token1). \
+                        [NestedClearCallingIdentityCalls]
+                                final long token2 = android.os.Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                            src/test/pkg/TestClass1.java:5: Location of the token1 declaration.
+                        src/test/pkg/TestClass1.java:7: Warning: The calling identity has already \
+                        been cleared and returned into token1. Move token3 declaration after \
+                        restoring the calling identity with Binder.restoreCallingIdentity(token1). \
+                        [NestedClearCallingIdentityCalls]
+                                final long token3 = android.os.Binder.clearCallingIdentity();
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                            src/test/pkg/TestClass1.java:5: Location of the token1 declaration.
+                        0 errors, 2 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDetectsNestedClearCallingIdentityCallsInScopes() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod() {
+                            final long token1 = Binder.clearCallingIdentity();
+                            try {
+                                final long token2 = android.os.Binder.clearCallingIdentity();
+                                try {
+                                } finally {
+                                    Binder.restoreCallingIdentity(token2);
+                                }
+                            } finally {
+                                android.os.Binder.restoreCallingIdentity(token1);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:7: Warning: The calling identity has already \
+                        been cleared and returned into token1. Move token2 declaration after \
+                        restoring the calling identity with Binder.restoreCallingIdentity(token1). \
+                        [NestedClearCallingIdentityCalls]
+                                    final long token2 = android.os.Binder.clearCallingIdentity();
+                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                            src/test/pkg/TestClass1.java:5: Location of the token1 declaration.
+                        0 errors, 1 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    /** restoreCallingIdentity() call not in finally block issue tests */
+
+    fun testDetectsRestoreCallingIdentityCallNotInFinally() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod1() {
+                            final long token = Binder.clearCallingIdentity();
+                            try {
+                            } catch (Exception e) {
+                            }
+                            Binder.restoreCallingIdentity(token);
+                            }
+                            private void testMethod2() {
+                            final long token = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                            }
+                            android.os.Binder.restoreCallingIdentity(token);
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:9: Warning: \
+                        Binder.restoreCallingIdentity(token) is not in the finally block. Surround \
+                        the call with finally block. [RestoreIdentityCallNotInFinallyBlock]
+                                Binder.restoreCallingIdentity(token);
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:16: Warning: \
+                        Binder.restoreCallingIdentity(token) is not in the finally block. Surround \
+                        the call with finally block. [RestoreIdentityCallNotInFinallyBlock]
+                                android.os.Binder.restoreCallingIdentity(token);
+                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 2 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDetectsRestoreCallingIdentityCallNotInFinallyInScopes() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod1() {
+                            final long token = Binder.clearCallingIdentity();
+                            try {
+                            } catch (Exception e) {
+                            }
+                            {
+                                Binder.restoreCallingIdentity(token);
+                            }
+                        }
+                        private void testMethod2() {
+                            final long token = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                            }
+                            {
+                                {
+                                    {
+                                        android.os.Binder.restoreCallingIdentity(token);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:10: Warning: \
+                        Binder.restoreCallingIdentity(token) is not in the finally block. Surround \
+                        the call with finally block. [RestoreIdentityCallNotInFinallyBlock]
+                                    Binder.restoreCallingIdentity(token);
+                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:21: Warning: \
+                        Binder.restoreCallingIdentity(token) is not in the finally block. Surround \
+                        the call with finally block. [RestoreIdentityCallNotInFinallyBlock]
+                                            android.os.Binder.restoreCallingIdentity(token);
+                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 2 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    fun testDoesNotDetectRestoreCallingIdentityCallInFinallyInScopes() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    public class TestClass1 {
+                        private void testMethod() {
+                            final long token1 = Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                {
+                                    {
+                                        Binder.restoreCallingIdentity(token1);
+                                    }
+                                }
+                            }
+                            final long token2 = android.os.Binder.clearCallingIdentity();
+                            try {
+                            } finally {
+                                {
+                                    {
+                                        android.os.Binder.restoreCallingIdentity(token2);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expectClean()
+    }
+
+    /** Use of caller-aware methods after clearCallingIdentity() issue tests */
+
+    fun testDetectsUseOfCallerAwareMethodsWithClearedIdentityIssuesInScopes() {
+        lint().files(
+                java(
+                    """
+                    package test.pkg;
+                    import android.os.Binder;
+                    import android.os.UserHandle;
+                    public class TestClass1 {
+                        private void testMethod() {
+                            final long token = Binder.clearCallingIdentity();
+                            int pid1 = Binder.getCallingPid();
+                            int pid2 = android.os.Binder.getCallingPid();
+                            int uid1 = Binder.getCallingUid();
+                            int uid2 = android.os.Binder.getCallingUid();
+                            try {
+                                int uid3 = Binder.getCallingUidOrThrow();
+                                int uid4 = android.os.Binder.getCallingUidOrThrow();
+                                UserHandle uh1 = Binder.getCallingUserHandle();
+                                UserHandle uh2 = android.os.Binder.getCallingUserHandle();
+                                {
+                                    int appId1 = UserHandle.getCallingAppId();
+                                    int appId2 = android.os.UserHandle.getCallingAppId();
+                                    int userId1 = UserHandle.getCallingUserId();
+                                    int userId2 = android.os.UserHandle.getCallingUserId();
+                                }
+                            } finally {
+                            Binder.restoreCallingIdentity(token);
+                            }
+                        }
+                    }
+                    """
+                ).indented(),
+                *stubs
+        )
+                .run()
+                .expect(
+                        """
+                        src/test/pkg/TestClass1.java:7: Warning: You cleared the original identity \
+                        with Binder.clearCallingIdentity() and returned into token, so \
+                        Binder.getCallingPid() will be using your own identity instead of the \
+                        caller's. Either explicitly query your own identity or move it after \
+                        restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                int pid1 = Binder.getCallingPid();
+                                           ~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:8: Warning: You cleared the original identity \
+                        with Binder.clearCallingIdentity() and returned into token, so \
+                        android.os.Binder.getCallingPid() will be using your own identity instead \
+                        of the caller's. Either explicitly query your own identity or move it \
+                        after restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                int pid2 = android.os.Binder.getCallingPid();
+                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:9: Warning: You cleared the original identity \
+                        with Binder.clearCallingIdentity() and returned into token, so \
+                        Binder.getCallingUid() will be using your own identity instead of the \
+                        caller's. Either explicitly query your own identity or move it after \
+                        restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                int uid1 = Binder.getCallingUid();
+                                           ~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:10: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        android.os.Binder.getCallingUid() will be using your own identity instead \
+                        of the caller's. Either explicitly query your own identity or move it \
+                        after restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                int uid2 = android.os.Binder.getCallingUid();
+                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:12: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        Binder.getCallingUidOrThrow() will be using your own identity instead of \
+                        the caller's. Either explicitly query your own identity or move it after \
+                        restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                    int uid3 = Binder.getCallingUidOrThrow();
+                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:13: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        android.os.Binder.getCallingUidOrThrow() will be using your own identity \
+                        instead of the caller's. Either explicitly query your own identity or move \
+                        it after restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                    int uid4 = android.os.Binder.getCallingUidOrThrow();
+                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:14: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        Binder.getCallingUserHandle() will be using your own identity instead of \
+                        the caller's. Either explicitly query your own identity or move it after \
+                        restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                    UserHandle uh1 = Binder.getCallingUserHandle();
+                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:15: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        android.os.Binder.getCallingUserHandle() will be using your own identity \
+                        instead of the caller's. Either explicitly query your own identity or move \
+                        it after restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                    UserHandle uh2 = android.os.Binder.getCallingUserHandle();
+                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:17: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        UserHandle.getCallingAppId() will be using your own identity instead of \
+                        the caller's. Either explicitly query your own identity or move it after \
+                        restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                        int appId1 = UserHandle.getCallingAppId();
+                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:18: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        android.os.UserHandle.getCallingAppId() will be using your own identity \
+                        instead of the caller's. Either explicitly query your own identity or move \
+                        it after restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                        int appId2 = android.os.UserHandle.getCallingAppId();
+                                                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:19: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        UserHandle.getCallingUserId() will be using your own identity instead of \
+                        the caller's. Either explicitly query your own identity or move it after \
+                        restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                        int userId1 = UserHandle.getCallingUserId();
+                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        src/test/pkg/TestClass1.java:20: Warning: You cleared the original \
+                        identity with Binder.clearCallingIdentity() and returned into token, so \
+                        android.os.UserHandle.getCallingUserId() will be using your own identity \
+                        instead of the caller's. Either explicitly query your own identity or move \
+                        it after restoring the identity with Binder.restoreCallingIdentity(token). \
+                        [UseOfCallerAwareMethodsWithClearedIdentity]
+                                        int userId2 = android.os.UserHandle.getCallingUserId();
+                                                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+                        0 errors, 12 warnings
+                        """.addLineContinuation()
+                )
+    }
+
+    /** Stubs for classes used for testing */
+
+    private val binderStub: TestFile = java(
+            """
+            package android.os;
+            public class Binder {
+                public static final native long clearCallingIdentity() {
+                    return 0;
+                }
+                public static final native void restoreCallingIdentity(long token) {
+                }
+                public static final native int getCallingPid() {
+                    return 0;
+                }
+                public static final native int getCallingUid() {
+                    return 0;
+                }
+                public static final int getCallingUidOrThrow() {
+                    return 0;
+                }
+                public static final @NonNull UserHandle getCallingUserHandle() {
+                    return UserHandle.of(UserHandle.getUserId(getCallingUid()));
+                }
+            }
+            """
+    ).indented()
+
+    private val userHandleStub: TestFile = java(
+            """
+            package android.os;
+            import android.annotation.AppIdInt;
+            import android.annotation.UserIdInt;
+            public class UserHandle {
+                public static @AppIdInt int getCallingAppId() {
+                    return getAppId(Binder.getCallingUid());
+                }
+                public static @UserIdInt int getCallingUserId() {
+                    return getUserId(Binder.getCallingUid());
+                }
+                public static @UserIdInt int getUserId(int uid) {
+                    return 0;
+                }
+                public static @AppIdInt int getAppId(int uid) {
+                    return 0;
+                }
+                public static UserHandle of(@UserIdInt int userId) {
+                    return new UserHandle();
+                }
+            }
+            """
+    ).indented()
+
+    private val userIdIntStub: TestFile = java(
+            """
+            package android.annotation;
+            public @interface UserIdInt {
+            }
+            """
+    ).indented()
+
+    private val appIdIntStub: TestFile = java(
+            """
+            package android.annotation;
+            public @interface AppIdInt {
+            }
+            """
+    ).indented()
+
+    private val stubs = arrayOf(binderStub, userHandleStub, userIdIntStub, appIdIntStub)
+
+    // Substitutes "backslash + new line" with an empty string to imitate line continuation
+    private fun String.addLineContinuation(): String = this.trimIndent().replace("\\\n", "")
+}
