Merge "Add mount@ to view OWNERS" into main
diff --git a/core/api/current.txt b/core/api/current.txt
index 7cf7e19..af58174 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -18291,11 +18291,13 @@
   public class BiometricManager {
     method @Deprecated @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate();
     method @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public int canAuthenticate(int);
+    method @FlaggedApi("android.hardware.biometrics.last_authentication_time") @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public long getLastAuthenticationTime(int);
     method @NonNull @RequiresPermission(android.Manifest.permission.USE_BIOMETRIC) public android.hardware.biometrics.BiometricManager.Strings getStrings(int);
     field public static final int BIOMETRIC_ERROR_HW_UNAVAILABLE = 1; // 0x1
     field public static final int BIOMETRIC_ERROR_NONE_ENROLLED = 11; // 0xb
     field public static final int BIOMETRIC_ERROR_NO_HARDWARE = 12; // 0xc
     field public static final int BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED = 15; // 0xf
+    field @FlaggedApi("android.hardware.biometrics.last_authentication_time") public static final long BIOMETRIC_NO_AUTHENTICATION = -1L; // 0xffffffffffffffffL
     field public static final int BIOMETRIC_SUCCESS = 0; // 0x0
   }
 
@@ -18341,6 +18343,7 @@
     field public static final int BIOMETRIC_ERROR_UNABLE_TO_PROCESS = 2; // 0x2
     field public static final int BIOMETRIC_ERROR_USER_CANCELED = 10; // 0xa
     field public static final int BIOMETRIC_ERROR_VENDOR = 8; // 0x8
+    field @FlaggedApi("android.hardware.biometrics.last_authentication_time") public static final long BIOMETRIC_NO_AUTHENTICATION = -1L; // 0xffffffffffffffffL
   }
 
   public abstract static class BiometricPrompt.AuthenticationCallback {
@@ -28960,12 +28963,12 @@
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addExposedCapability(int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder addGatewayOption(int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig build();
-    method @FlaggedApi("android.net.vcn.safe_mode_config") @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder enableSafeMode(boolean);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeExposedCapability(int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder removeGatewayOption(int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMaxMtu(@IntRange(from=0x500) int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setMinUdpPort4500NatTimeoutSeconds(@IntRange(from=0x78) int);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setRetryIntervalsMillis(@NonNull long[]);
+    method @FlaggedApi("android.net.vcn.safe_mode_config") @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setSafeModeEnabled(boolean);
     method @NonNull public android.net.vcn.VcnGatewayConnectionConfig.Builder setVcnUnderlyingNetworkPriorities(@NonNull java.util.List<android.net.vcn.VcnUnderlyingNetworkTemplate>);
   }
 
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 943eee4..61d8702 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -18,6 +18,7 @@
 
 import static android.hardware.biometrics.BiometricManager.Authenticators;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.os.Build;
@@ -296,4 +297,15 @@
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({BIOMETRIC_LOCKOUT_NONE, BIOMETRIC_LOCKOUT_TIMED, BIOMETRIC_LOCKOUT_PERMANENT})
     @interface LockoutMode {}
+
+    //
+    // Other miscellaneous constants
+    //
+
+    /**
+     * Returned from {@link BiometricManager#getLastAuthenticationTime(int)} when there has
+     * been no successful authentication for the given authenticator since boot.
+     */
+    @FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME)
+    long BIOMETRIC_NO_AUTHENTICATION = -1;
 }
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 82694ee..90bbca8 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -23,6 +23,8 @@
 
 import static com.android.internal.util.FrameworkStatsLog.AUTH_DEPRECATED_APIUSED__DEPRECATED_API__API_BIOMETRIC_MANAGER_CAN_AUTHENTICATE;
 
+import android.annotation.ElapsedRealtimeLong;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -30,6 +32,7 @@
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
+import android.app.KeyguardManager;
 import android.content.Context;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -86,6 +89,17 @@
             BiometricConstants.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED;
 
     /**
+     * Returned from {@link BiometricManager#getLastAuthenticationTime(int)} when no matching
+     * successful authentication has been performed since boot.
+     */
+    @FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME)
+    public static final long BIOMETRIC_NO_AUTHENTICATION =
+            BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
+
+    private static final int GET_LAST_AUTH_TIME_ALLOWED_AUTHENTICATORS =
+            Authenticators.DEVICE_CREDENTIAL | Authenticators.BIOMETRIC_STRONG;
+
+    /**
      * @hide
      */
     @IntDef({BIOMETRIC_SUCCESS,
@@ -637,5 +651,58 @@
         }
 
     }
+
+    /**
+     * Gets the last time the user successfully authenticated using one of the given authenticators.
+     * The returned value is time in
+     * {@link android.os.SystemClock#elapsedRealtime SystemClock.elapsedRealtime()} (time since
+     * boot, including sleep).
+     * <p>
+     * {@link BiometricManager#BIOMETRIC_NO_AUTHENTICATION} is returned in the case where there
+     * has been no successful authentication using any of the given authenticators since boot.
+     * <p>
+     * Currently, only {@link Authenticators#DEVICE_CREDENTIAL} and
+     * {@link Authenticators#BIOMETRIC_STRONG} are accepted. {@link IllegalArgumentException} will
+     * be thrown if {@code authenticators} contains other authenticator types.
+     * <p>
+     * Note that this may return successful authentication times even if the device is currently
+     * locked. You may use {@link KeyguardManager#isDeviceLocked()} to determine if the device
+     * is unlocked or not. Additionally, this method may return valid times for an authentication
+     * method that is no longer available. For instance, if the user unlocked the device with a
+     * {@link Authenticators#BIOMETRIC_STRONG} authenticator but then deleted that authenticator
+     * (e.g., fingerprint data), this method will still return the time of that unlock for
+     * {@link Authenticators#BIOMETRIC_STRONG} if it is the most recent successful event. The caveat
+     * is that {@link BiometricManager#BIOMETRIC_NO_AUTHENTICATION} will be returned if the device
+     * no longer has a secure lock screen at all, even if there were successful authentications
+     * performed before the lock screen was made insecure.
+     *
+     * @param authenticators bit field consisting of constants defined in {@link Authenticators}.
+     * @return the time of last authentication or
+     * {@link BiometricManager#BIOMETRIC_NO_AUTHENTICATION}
+     * @throws IllegalArgumentException if {@code authenticators} contains values other than
+     * {@link Authenticators#DEVICE_CREDENTIAL} and {@link Authenticators#BIOMETRIC_STRONG} or is
+     * 0.
+     */
+    @RequiresPermission(USE_BIOMETRIC)
+    @ElapsedRealtimeLong
+    @FlaggedApi(Flags.FLAG_LAST_AUTHENTICATION_TIME)
+    public long getLastAuthenticationTime(
+            @BiometricManager.Authenticators.Types int authenticators) {
+        if (authenticators == 0
+                || (GET_LAST_AUTH_TIME_ALLOWED_AUTHENTICATORS & authenticators) != authenticators) {
+            throw new IllegalArgumentException(
+                    "Only BIOMETRIC_STRONG and DEVICE_CREDENTIAL authenticators may be used.");
+        }
+
+        if (mService != null) {
+            try {
+                return mService.getLastAuthenticationTime(UserHandle.myUserId(), authenticators);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        } else {
+            return BIOMETRIC_NO_AUTHENTICATION;
+        }
+    }
 }
 
diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl
index c2e5c0b..5bdbe2b5 100644
--- a/core/java/android/hardware/biometrics/IAuthService.aidl
+++ b/core/java/android/hardware/biometrics/IAuthService.aidl
@@ -57,6 +57,9 @@
     // Checks if biometrics can be used.
     int canAuthenticate(String opPackageName, int userId, int authenticators);
 
+    // Gets the time of last authentication for the given user and authenticators.
+    long getLastAuthenticationTime(int userId, int authenticators);
+
     // Checks if any biometrics are enrolled.
     boolean hasEnrolledBiometrics(int userId, String opPackageName);
 
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 18c8d1b..058f302 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -53,6 +53,10 @@
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     int canAuthenticate(String opPackageName, int userId, int callingUserId, int authenticators);
 
+    // Gets the time of last authentication for the given user and authenticators.
+    @EnforcePermission("USE_BIOMETRIC_INTERNAL")
+    long getLastAuthenticationTime(int userId, int authenticators);
+
     // Checks if any biometrics are enrolled.
     @EnforcePermission("USE_BIOMETRIC_INTERNAL")
     boolean hasEnrolledBiometrics(int userId, String opPackageName);
diff --git a/core/java/android/hardware/biometrics/flags.aconfig b/core/java/android/hardware/biometrics/flags.aconfig
index 0924e0d1..c370ad6 100644
--- a/core/java/android/hardware/biometrics/flags.aconfig
+++ b/core/java/android/hardware/biometrics/flags.aconfig
@@ -1,6 +1,13 @@
 package: "android.hardware.biometrics"
 
 flag {
+    name: "last_authentication_time"
+    namespace: "wallet_integration"
+    description: "Feature flag for adding getLastAuthenticationTime API to BiometricManager"
+    bug: "301979982"
+}
+
+flag {
   name: "add_key_agreement_crypto_object"
   namespace: "biometrics"
   description: "Feature flag for adding KeyAgreement api to CryptoObject."
diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
index 779a8db..6f11d3a 100644
--- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
+++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java
@@ -493,7 +493,7 @@
     /**
      * Check whether safe mode is enabled
      *
-     * @see Builder#enableSafeMode(boolean)
+     * @see Builder#setSafeModeEnabled(boolean)
      */
     @FlaggedApi(FLAG_SAFE_MODE_CONFIG)
     public boolean isSafeModeEnabled() {
@@ -815,8 +815,8 @@
          *
          * <p>If a VCN fails to provide connectivity within a system-provided timeout, it will enter
          * safe mode. In safe mode, the VCN Network will be torn down and the system will restore
-         * connectivity by allowing underlying cellular networks to be used as default. At the same
-         * time, VCN will continue to retry until it succeeds.
+         * connectivity by allowing underlying cellular or WiFi networks to be used as default. At
+         * the same time, VCN will continue to retry until it succeeds.
          *
          * <p>When safe mode is disabled and VCN connection fails to provide connectivity, end users
          * might not have connectivity, and may not have access to carrier-owned underlying
@@ -826,7 +826,7 @@
          */
         @FlaggedApi(FLAG_SAFE_MODE_CONFIG)
         @NonNull
-        public Builder enableSafeMode(boolean enabled) {
+        public Builder setSafeModeEnabled(boolean enabled) {
             mIsSafeModeDisabled = !enabled;
             return this;
         }
diff --git a/keystore/java/android/security/Authorization.java b/keystore/java/android/security/Authorization.java
index 2d2dd24..b4b3e92 100644
--- a/keystore/java/android/security/Authorization.java
+++ b/keystore/java/android/security/Authorization.java
@@ -18,7 +18,9 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.hardware.biometrics.BiometricConstants;
 import android.hardware.security.keymint.HardwareAuthToken;
+import android.hardware.security.keymint.HardwareAuthenticatorType;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.ServiceSpecificException;
@@ -37,7 +39,10 @@
 
     public static final int SYSTEM_ERROR = ResponseCode.SYSTEM_ERROR;
 
-    private static IKeystoreAuthorization getService() {
+    /**
+     * @return an instance of IKeystoreAuthorization
+     */
+    public static IKeystoreAuthorization getService() {
         return IKeystoreAuthorization.Stub.asInterface(
                     ServiceManager.checkService("android.security.authorization"));
     }
@@ -100,4 +105,24 @@
         }
     }
 
+    /**
+     * Gets the last authentication time of the given user and authenticators.
+     *
+     * @param userId user id
+     * @param authenticatorTypes an array of {@link HardwareAuthenticatorType}.
+     * @return the last authentication time or
+     * {@link BiometricConstants#BIOMETRIC_NO_AUTHENTICATION}.
+     */
+    public static long getLastAuthenticationTime(
+            long userId, @HardwareAuthenticatorType int[] authenticatorTypes) {
+        try {
+            return getService().getLastAuthTime(userId, authenticatorTypes);
+        } catch (RemoteException | NullPointerException e) {
+            Log.w(TAG, "Can not connect to keystore", e);
+            return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
+        } catch (ServiceSpecificException e) {
+            return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
+        }
+    }
+
 }
diff --git a/keystore/java/android/security/GateKeeper.java b/keystore/java/android/security/GateKeeper.java
index af188a9..464714f 100644
--- a/keystore/java/android/security/GateKeeper.java
+++ b/keystore/java/android/security/GateKeeper.java
@@ -45,8 +45,19 @@
 
     @UnsupportedAppUsage
     public static long getSecureUserId() throws IllegalStateException {
+        return getSecureUserId(UserHandle.myUserId());
+    }
+
+    /**
+     * Return the secure user id for a given user id
+     * @param userId the user id, e.g. 0
+     * @return the secure user id or {@link GateKeeper#INVALID_SECURE_USER_ID} if no such mapping
+     * for the given user id is found.
+     * @throws IllegalStateException if there is an error retrieving the secure user id
+     */
+    public static long getSecureUserId(int userId) throws IllegalStateException {
         try {
-            return getService().getSecureUserId(UserHandle.myUserId());
+            return getService().getSecureUserId(userId);
         } catch (RemoteException e) {
             throw new IllegalStateException(
                     "Failed to obtain secure user ID from gatekeeper", e);
diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags
index b67e627..a71966b 100644
--- a/services/core/java/com/android/server/EventLogTags.logtags
+++ b/services/core/java/com/android/server/EventLogTags.logtags
@@ -179,6 +179,15 @@
 3130 pm_snapshot_stats (build_count|1|1),(reuse_count|1|1),(big_builds|1|1),(short_lived|1|1),(max_build_time|1|3),(cumm_build_time|2|3)
 # Snapshot rebuild instance
 3131 pm_snapshot_rebuild (build_time|1|3),(lifetime|1|3)
+# Caller information to clear application data
+1003160 pm_clear_app_data_caller (pid|1),(uid|1),(package|3)
+# ---------------------------
+# Installer.java
+# ---------------------------
+# Caller Information to clear application data
+1003200 installer_clear_app_data_caller (pid|1),(uid|1),(package|3),(flags|1)
+# Call stack to clear application data
+1003201 installer_clear_app_data_call_stack (method|3),(class|3),(file|3),(line|1)
 
 # ---------------------------
 # InputMethodManagerService.java
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e74371e..c0da30d 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3468,6 +3468,7 @@
         enforceNotIsolatedCaller("clearApplicationUserData");
         int uid = Binder.getCallingUid();
         int pid = Binder.getCallingPid();
+        EventLog.writeEvent(EventLogTags.AM_CLEAR_APP_DATA_CALLER, pid, uid, packageName);
         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
 
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index 9e9db6a..931914f 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -129,3 +129,6 @@
 
 # Intent Sender redirect for UserHandle.USER_CURRENT
 30110 am_intent_sender_redirect_user (userId|1|5)
+
+# Caller information to clear application data
+1030002 am_clear_app_data_caller (pid|1),(uid|1),(package|3)
diff --git a/services/core/java/com/android/server/am/LmkdStatsReporter.java b/services/core/java/com/android/server/am/LmkdStatsReporter.java
index 1e4dd64..507fd9e 100644
--- a/services/core/java/com/android/server/am/LmkdStatsReporter.java
+++ b/services/core/java/com/android/server/am/LmkdStatsReporter.java
@@ -107,6 +107,8 @@
                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM_AND_SWAP_UTIL;
             case LOW_FILECACHE_AFTER_THRASHING:
                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_FILECACHE_AFTER_THRASHING;
+            case LOW_MEM:
+                return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__LOW_MEM;
             default:
                 return FrameworkStatsLog.LMK_KILL_OCCURRED__REASON__UNKNOWN;
         }
diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java
index 4538cad..0629e637 100644
--- a/services/core/java/com/android/server/biometrics/AuthService.java
+++ b/services/core/java/com/android/server/biometrics/AuthService.java
@@ -39,6 +39,7 @@
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.ComponentInfoInternal;
+import android.hardware.biometrics.Flags;
 import android.hardware.biometrics.IAuthService;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.biometrics.IBiometricService;
@@ -333,6 +334,33 @@
         }
 
         @Override
+        public long getLastAuthenticationTime(int userId,
+                @Authenticators.Types int authenticators) throws RemoteException {
+            // Only allow internal clients to call getLastAuthenticationTime with a different
+            // userId.
+            final int callingUserId = UserHandle.getCallingUserId();
+
+            if (userId != callingUserId) {
+                checkInternalPermission();
+            } else {
+                checkPermission();
+            }
+
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                // We can't do this above because we need the READ_DEVICE_CONFIG permission, which
+                // the calling user may not possess.
+                if (!Flags.lastAuthenticationTime()) {
+                    throw new UnsupportedOperationException();
+                }
+
+                return mBiometricService.getLastAuthenticationTime(userId, authenticators);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+
+        @Override
         public boolean hasEnrolledBiometrics(int userId, String opPackageName)
                 throws RemoteException {
             checkInternalPermission();
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index e8ffe4f..9c454ae 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -18,6 +18,7 @@
 
 import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
+import static android.hardware.biometrics.BiometricManager.BIOMETRIC_NO_AUTHENTICATION;
 
 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_IDLE;
 
@@ -37,6 +38,7 @@
 import android.hardware.biometrics.BiometricAuthenticator;
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.Flags;
 import android.hardware.biometrics.IBiometricAuthenticator;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.biometrics.IBiometricSensorReceiver;
@@ -51,6 +53,7 @@
 import android.hardware.camera2.CameraManager;
 import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
+import android.hardware.security.keymint.HardwareAuthenticatorType;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -60,10 +63,16 @@
 import android.os.Looper;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.security.Authorization;
+import android.security.GateKeeper;
 import android.security.KeyStore;
+import android.security.authorization.IKeystoreAuthorization;
+import android.security.authorization.ResponseCode;
+import android.service.gatekeeper.IGateKeeperService;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Pair;
@@ -77,6 +86,7 @@
 import com.android.internal.util.DumpUtils;
 import com.android.server.SystemService;
 import com.android.server.biometrics.log.BiometricContext;
+import com.android.server.utils.Slogf;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -114,6 +124,10 @@
     KeyStore mKeyStore;
     @VisibleForTesting
     ITrustManager mTrustManager;
+    @VisibleForTesting
+    IKeystoreAuthorization mKeystoreAuthorization;
+    @VisibleForTesting
+    IGateKeeperService mGateKeeper;
 
     // Get and cache the available biometric authenticators and their associated info.
     final ArrayList<BiometricSensor> mSensors = new ArrayList<>();
@@ -630,6 +644,64 @@
         }
 
         @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
+        @Override // Binder call
+        public long getLastAuthenticationTime(
+                int userId, @Authenticators.Types int authenticators) {
+            super.getLastAuthenticationTime_enforcePermission();
+
+            if (!Flags.lastAuthenticationTime()) {
+                throw new UnsupportedOperationException();
+            }
+
+            Slogf.d(TAG, "getLastAuthenticationTime(userId=%d, authenticators=0x%x)",
+                    userId, authenticators);
+
+            final long secureUserId;
+            try {
+                secureUserId = mGateKeeper.getSecureUserId(userId);
+            } catch (RemoteException e) {
+                Slogf.w(TAG, "Failed to get secure user id for " + userId, e);
+                return BIOMETRIC_NO_AUTHENTICATION;
+            }
+
+            if (secureUserId == GateKeeper.INVALID_SECURE_USER_ID) {
+                Slogf.w(TAG, "No secure user id for " + userId);
+                return BIOMETRIC_NO_AUTHENTICATION;
+            }
+
+            ArrayList<Integer> hardwareAuthenticators = new ArrayList<>(2);
+
+            if ((authenticators & Authenticators.DEVICE_CREDENTIAL) != 0) {
+                hardwareAuthenticators.add(HardwareAuthenticatorType.PASSWORD);
+            }
+
+            if ((authenticators & Authenticators.BIOMETRIC_STRONG) != 0) {
+                hardwareAuthenticators.add(HardwareAuthenticatorType.FINGERPRINT);
+            }
+
+            if (hardwareAuthenticators.isEmpty()) {
+                throw new IllegalArgumentException("authenticators must not be empty");
+            }
+
+            int[] authTypesArray = hardwareAuthenticators.stream()
+                    .mapToInt(Integer::intValue)
+                    .toArray();
+            try {
+                return mKeystoreAuthorization.getLastAuthTime(secureUserId, authTypesArray);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "Error getting last auth time: " + e);
+                return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
+            } catch (ServiceSpecificException e) {
+                // This is returned when the feature flag test fails in keystore2
+                if (e.errorCode == ResponseCode.PERMISSION_DENIED) {
+                    throw new UnsupportedOperationException();
+                }
+
+                return BiometricConstants.BIOMETRIC_NO_AUTHENTICATION;
+            }
+        }
+
+        @android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
         @Override
         public boolean hasEnrolledBiometrics(int userId, String opPackageName) {
 
@@ -951,6 +1023,14 @@
             return ActivityManager.getService();
         }
 
+        public IKeystoreAuthorization getKeystoreAuthorizationService() {
+            return Authorization.getService();
+        }
+
+        public IGateKeeperService getGateKeeperService() {
+            return GateKeeper.getService();
+        }
+
         public ITrustManager getTrustManager() {
             return ITrustManager.Stub.asInterface(ServiceManager.getService(Context.TRUST_SERVICE));
         }
@@ -1064,6 +1144,8 @@
         mBiometricContext = injector.getBiometricContext(context);
         mUserManager = injector.getUserManager(context);
         mBiometricCameraManager = injector.getBiometricCameraManager(context);
+        mKeystoreAuthorization = injector.getKeystoreAuthorizationService();
+        mGateKeeper = injector.getGateKeeperService();
 
         try {
             injector.getActivityManagerService().registerUserSwitchObserver(
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 9ac983d..c401dab 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -24,6 +24,7 @@
 import android.annotation.UserIdInt;
 import android.content.Context;
 import android.content.pm.PackageStats;
+import android.os.Binder;
 import android.os.Build;
 import android.os.CreateAppDataArgs;
 import android.os.CreateAppDataResult;
@@ -34,9 +35,11 @@
 import android.os.ServiceManager;
 import android.os.storage.CrateMetadata;
 import android.text.format.DateUtils;
+import android.util.EventLog;
 import android.util.Slog;
 
 import com.android.internal.os.BackgroundThread;
+import com.android.server.EventLogTags;
 import com.android.server.SystemService;
 
 import dalvik.system.BlockGuard;
@@ -438,6 +441,26 @@
         if (!checkBeforeRemote()) return;
         try {
             mInstalld.clearAppData(uuid, packageName, userId, flags, ceDataInode);
+
+            final StackTraceElement[] elements = Thread.currentThread().getStackTrace();
+            String className;
+            String methodName;
+            String fileName;
+            int lineNumber;
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            EventLog.writeEvent(EventLogTags.INSTALLER_CLEAR_APP_DATA_CALLER, pid, uid, packageName,
+                    flags);
+            // Skip the first two elements since they are always the same, ie
+            // Thread#getStackTrace() and VMStack#getThreadStackTrace()
+            for (int i = 2; i < elements.length; i++) {
+                className = elements[i].getClassName();
+                methodName = elements[i].getMethodName();
+                fileName = elements[i].getFileName();
+                lineNumber = elements[i].getLineNumber();
+                EventLog.writeEvent(EventLogTags.INSTALLER_CLEAR_APP_DATA_CALL_STACK, methodName,
+                        className, fileName, lineNumber);
+            }
         } catch (Exception e) {
             throw InstallerException.from(e);
         }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index daf3617..a1c435a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4729,6 +4729,9 @@
                 throw new SecurityException("Cannot clear data for a protected package: "
                         + packageName);
             }
+            final int callingPid = Binder.getCallingPid();
+            EventLog.writeEvent(EventLogTags.PM_CLEAR_APP_DATA_CALLER, callingPid, callingUid,
+                    packageName);
 
             // Queue up an async operation since the package deletion may take a little while.
             mHandler.post(new Runnable() {
@@ -4861,6 +4864,9 @@
                     /* checkShell= */ false, "delete application cache files");
             final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.ACCESS_INSTANT_APPS);
+            final int callingPid = Binder.getCallingPid();
+            EventLog.writeEvent(EventLogTags.PM_CLEAR_APP_DATA_CALLER, callingPid, callingUid,
+                    packageName);
 
             // Queue up an async operation since the package deletion may take a little while.
             mHandler.post(() -> {
diff --git a/services/midi/OWNERS b/services/midi/OWNERS
index f4d51f9..683cae1 100644
--- a/services/midi/OWNERS
+++ b/services/midi/OWNERS
@@ -1 +1,3 @@
 philburk@google.com
+robertwu@google.com
+elaurent@google.com #{LAST_RESORT_SUGGESTION}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index f770f8c..e656cf3 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -65,6 +65,7 @@
         "ActivityContext",
         "coretests-aidl",
         "securebox",
+        "flag-junit",
     ],
 
     libs: [
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
index f88afe7..a78f2dc 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthServiceTest.java
@@ -41,6 +41,8 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
+import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.Flags;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.biometrics.IBiometricService;
 import android.hardware.biometrics.IBiometricServiceReceiver;
@@ -53,6 +55,7 @@
 import android.os.Binder;
 import android.os.UserHandle;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -84,6 +87,8 @@
     @Rule
     public MockitoRule mockitorule = MockitoJUnit.rule();
 
+    @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     @Mock
     private Context mContext;
     @Mock
@@ -418,6 +423,37 @@
                 eq(callback));
     }
 
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetLastAuthenticationTime_flaggedOff_throwsUnsupportedOperationException()
+            throws Exception {
+        mSetFlagsRule.disableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
+        setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
+
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        mAuthService.mImpl.getLastAuthenticationTime(0,
+                BiometricManager.Authenticators.BIOMETRIC_STRONG);
+    }
+
+    @Test
+    public void testGetLastAuthenticationTime_flaggedOn_callsBiometricService()
+            throws Exception {
+        mSetFlagsRule.enableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
+        setInternalAndTestBiometricPermissions(mContext, true /* hasPermission */);
+
+        mAuthService = new AuthService(mContext, mInjector);
+        mAuthService.onStart();
+
+        final int userId = 0;
+        final int authenticators = BiometricManager.Authenticators.BIOMETRIC_STRONG;
+
+        mAuthService.mImpl.getLastAuthenticationTime(userId, authenticators);
+
+        waitForIdle();
+        verify(mBiometricService).getLastAuthenticationTime(eq(userId), eq(authenticators));
+    }
+
     private static void setInternalAndTestBiometricPermissions(
             Context context, boolean hasPermission) {
         for (String p : List.of(TEST_BIOMETRIC, MANAGE_BIOMETRIC, USE_BIOMETRIC_INTERNAL)) {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
index 6f4791a..14a567a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/BiometricServiceTest.java
@@ -18,7 +18,6 @@
 
 import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
 import static android.hardware.biometrics.BiometricManager.Authenticators;
-import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
 import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
 
 import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTHENTICATED_PENDING_SYSUI;
@@ -61,6 +60,7 @@
 import android.hardware.biometrics.BiometricConstants;
 import android.hardware.biometrics.BiometricManager;
 import android.hardware.biometrics.BiometricPrompt;
+import android.hardware.biometrics.Flags;
 import android.hardware.biometrics.IBiometricAuthenticator;
 import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
 import android.hardware.biometrics.IBiometricSensorReceiver;
@@ -70,12 +70,17 @@
 import android.hardware.biometrics.PromptInfo;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.keymaster.HardwareAuthenticatorType;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.os.UserManager;
 import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.SetFlagsRule;
+import android.security.GateKeeper;
 import android.security.KeyStore;
+import android.security.authorization.IKeystoreAuthorization;
+import android.service.gatekeeper.IGateKeeperService;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.WindowManager;
@@ -91,6 +96,7 @@
 import com.android.server.biometrics.sensors.LockoutTracker;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.AdditionalMatchers;
 import org.mockito.ArgumentCaptor;
@@ -104,6 +110,9 @@
 @SmallTest
 public class BiometricServiceTest {
 
+    @Rule
+    public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
     private static final String TEST_PACKAGE_NAME = "test_package";
     private static final long TEST_REQUEST_ID = 44;
 
@@ -155,10 +164,16 @@
     @Mock
     private BiometricCameraManager mBiometricCameraManager;
 
+    @Mock
+    private IKeystoreAuthorization mKeystoreAuthService;
+
+    @Mock
+    private IGateKeeperService mGateKeeperService;
+
     BiometricContextProvider mBiometricContextProvider;
 
     @Before
-    public void setUp() {
+    public void setUp() throws RemoteException {
         MockitoAnnotations.initMocks(this);
 
         resetReceivers();
@@ -196,6 +211,9 @@
                 mStatusBarService, null /* handler */,
                 mAuthSessionCoordinator);
         when(mInjector.getBiometricContext(any())).thenReturn(mBiometricContextProvider);
+        when(mInjector.getKeystoreAuthorizationService()).thenReturn(mKeystoreAuthService);
+        when(mInjector.getGateKeeperService()).thenReturn(mGateKeeperService);
+        when(mGateKeeperService.getSecureUserId(anyInt())).thenReturn(42L);
 
         final String[] config = {
                 "0:2:15",  // ID0:Fingerprint:Strong
@@ -1612,6 +1630,44 @@
         verifyNoMoreInteractions(callback);
     }
 
+    @Test(expected = UnsupportedOperationException.class)
+    public void testGetLastAuthenticationTime_flagOff_throwsUnsupportedOperationException()
+            throws RemoteException {
+        mSetFlagsRule.disableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
+
+        mBiometricService = new BiometricService(mContext, mInjector);
+        mBiometricService.mImpl.getLastAuthenticationTime(0, Authenticators.BIOMETRIC_STRONG);
+    }
+
+    @Test
+    public void testGetLastAuthenticationTime_flagOn_callsKeystoreAuthorization()
+            throws RemoteException {
+        mSetFlagsRule.enableFlags(Flags.FLAG_LAST_AUTHENTICATION_TIME);
+
+        final int[] hardwareAuthenticators = new int[] {
+                HardwareAuthenticatorType.PASSWORD,
+                HardwareAuthenticatorType.FINGERPRINT
+        };
+
+        final int userId = 0;
+        final long secureUserId = mGateKeeperService.getSecureUserId(userId);
+
+        assertNotEquals(GateKeeper.INVALID_SECURE_USER_ID, secureUserId);
+
+        final long expectedResult = 31337L;
+
+        when(mKeystoreAuthService.getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators)))
+                .thenReturn(expectedResult);
+
+        mBiometricService = new BiometricService(mContext, mInjector);
+
+        final long result = mBiometricService.mImpl.getLastAuthenticationTime(userId,
+                Authenticators.BIOMETRIC_STRONG | Authenticators.DEVICE_CREDENTIAL);
+
+        assertEquals(expectedResult, result);
+        verify(mKeystoreAuthService).getLastAuthTime(eq(secureUserId), eq(hardwareAuthenticators));
+    }
+
     // Helper methods
 
     private int invokeCanAuthenticate(BiometricService service, int authenticators)
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index cb37821..59dc689 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -313,7 +313,8 @@
 
     @Test
     public void testBuilderAndGettersSafeModeDisabled() {
-        final VcnGatewayConnectionConfig config = newBuilderMinimal().enableSafeMode(false).build();
+        final VcnGatewayConnectionConfig config =
+                newBuilderMinimal().setSafeModeEnabled(false).build();
 
         assertFalse(config.isSafeModeEnabled());
     }
@@ -335,7 +336,8 @@
 
     @Test
     public void testPersistableBundleSafeModeDisabled() {
-        final VcnGatewayConnectionConfig config = newBuilderMinimal().enableSafeMode(false).build();
+        final VcnGatewayConnectionConfig config =
+                newBuilderMinimal().setSafeModeEnabled(false).build();
 
         assertEquals(config, new VcnGatewayConnectionConfig(config.toPersistableBundle()));
     }
@@ -456,7 +458,7 @@
         assertEquals(config.isSafeModeEnabled(), configEqual.isSafeModeEnabled());
 
         final VcnGatewayConnectionConfig configNotEqual =
-                newBuilderMinimal().enableSafeMode(false).build();
+                newBuilderMinimal().setSafeModeEnabled(false).build();
 
         assertEquals(config, configEqual);
         assertNotEquals(config, configNotEqual);
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index bf73198..f846164 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -661,7 +661,7 @@
             throws Exception {
         final VcnGatewayConnectionConfig config =
                 VcnGatewayConnectionConfigTest.newTestBuilderMinimal()
-                        .enableSafeMode(safeModeEnabledByCaller)
+                        .setSafeModeEnabled(safeModeEnabledByCaller)
                         .build();
         final VcnGatewayConnection.Dependencies deps =
                 mock(VcnGatewayConnection.Dependencies.class);
diff --git a/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
index e03d92ab..f1727b7 100644
--- a/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
+++ b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
@@ -30,6 +30,7 @@
 const val IINTERFACE_INTERFACE = "android.os.IInterface"
 
 const val AIDL_PERMISSION_HELPER_SUFFIX = "_enforcePermission"
+const val PERMISSION_PREFIX_LITERAL = "android.permission."
 
 /**
  * If a non java (e.g. c++) backend is enabled, the @EnforcePermission
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
index a74400d..83b8f16 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/EnforcePermissionDetector.kt
@@ -97,7 +97,7 @@
             val v1 = ConstantEvaluator.evaluate(context, value1)
             val v2 = ConstantEvaluator.evaluate(context, value2)
             if (v1 != null && v2 != null) {
-                if (v1 != v2) {
+                if (v1 != v2 && !isOneShortPermissionOfOther(v1, v2)) {
                     return false
                 }
             } else {
@@ -109,7 +109,7 @@
                 for (j in children1.indices) {
                     val c1 = ConstantEvaluator.evaluate(context, children1[j])
                     val c2 = ConstantEvaluator.evaluate(context, children2[j])
-                    if (c1 != c2) {
+                    if (c1 != c2 && !isOneShortPermissionOfOther(c1, c2)) {
                         return false
                     }
                 }
@@ -118,6 +118,12 @@
         return true
     }
 
+    private fun isOneShortPermissionOfOther(
+        permission1: Any?,
+        permission2: Any?
+    ): Boolean = permission1 == (permission2 as? String)?.removePrefix(PERMISSION_PREFIX_LITERAL) ||
+            permission2 == (permission1 as? String)?.removePrefix(PERMISSION_PREFIX_LITERAL)
+
     private fun compareMethods(
         context: JavaContext,
         element: UElement,
@@ -191,6 +197,15 @@
             /* Check that we are connected to the super class */
             val overridingMethod = node as PsiMethod
             val parents = overridingMethod.findSuperMethods()
+            if (parents.isEmpty()) {
+                context.report(
+                    ISSUE_MISUSING_ENFORCE_PERMISSION,
+                    node,
+                    context.getLocation(node),
+                    "The method ${node.name} does not override an AIDL generated method"
+                )
+                return
+            }
             for (overriddenMethod in parents) {
                 // The equivalence check can be skipped, if both methods are
                 // annotated, it will be verified by visitAnnotationUsage.
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
index 75b0073..d8afcb9 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionDetectorTest.kt
@@ -28,7 +28,9 @@
 
     override fun getIssues(): List<Issue> = listOf(
             EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION,
-            EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION
+            EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION,
+            EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
+            EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION
     )
 
     override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
@@ -41,7 +43,9 @@
             public class TestClass2 extends IFooMethod.Stub {
                 @Override
                 @EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
-                public void testMethod() {}
+                public void testMethod() {
+                    testMethod_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -58,7 +62,9 @@
             public class TestClass11 extends IFooMethod.Stub {
                 @Override
                 @EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE})
-                public void testMethodAll() {}
+                public void testMethodAll() {
+                    testMethodAll_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -75,7 +81,10 @@
             public class TestClass111 extends IFooMethod.Stub {
                 @Override
                 @EnforcePermission(allOf={"android.permission.INTERNET", android.Manifest.permission.READ_PHONE_STATE})
-                public void testMethodAllLiteral() {}
+                public void testMethodAllLiteral() {
+                    testMethodAllLiteral_enforcePermission();
+
+                }
             }
             """).indented(),
                 *stubs
@@ -92,7 +101,9 @@
             public class TestClass12 extends IFooMethod.Stub {
                 @Override
                 @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE})
-                public void testMethodAny() {}
+                public void testMethodAny() {
+                    testMethodAny_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -109,7 +120,9 @@
             public class TestClass121 extends IFooMethod.Stub {
                 @Override
                 @EnforcePermission(anyOf={"android.permission.INTERNET", android.Manifest.permission.READ_PHONE_STATE})
-                public void testMethodAnyLiteral() {}
+                public void testMethodAnyLiteral() {
+                    testMethodAnyLiteral_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -124,7 +137,9 @@
             package test.pkg;
             public class TestClass4 extends IFooMethod.Stub {
                 @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET)
-                public void testMethod() {}
+                public void testMethod() {
+                    testMethod_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -132,21 +147,44 @@
         .run()
         .expect("""
                 src/test/pkg/TestClass4.java:4: Error: The method TestClass4.testMethod is annotated with @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET) \
-                which differs from the overridden method Stub.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \
+                which differs from the overridden method IFooMethod.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \
                 The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
-                    public void testMethod() {}
+                    public void testMethod() {
                                 ~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
     }
 
+    fun testDetectIssuesAnnotationOnNonStubMethod() {
+        lint().files(java(
+            """
+            package test.pkg;
+            public class TestClass42 extends IFooMethod.Stub {
+                @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET)
+                public void aRegularMethodNotPartOfStub() {
+                }
+            }
+            """).indented(),
+                *stubs
+        )
+        .run()
+        .expect("""
+                src/test/pkg/TestClass42.java:3: Error: The method aRegularMethodNotPartOfStub does not override an AIDL generated method [MisusingEnforcePermissionAnnotation]
+                    @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET)
+                    ^
+                1 errors, 0 warnings
+                """.addLineContinuation())
+    }
+
     fun testDetectIssuesEmptyAnnotationOnMethod() {
         lint().files(java(
             """
             package test.pkg;
             public class TestClass41 extends IFooMethod.Stub {
                 @android.annotation.EnforcePermission
-                public void testMethod() {}
+                public void testMethod() {
+                  testMethod_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -154,9 +192,9 @@
         .run()
         .expect("""
                 src/test/pkg/TestClass41.java:4: Error: The method TestClass41.testMethod is annotated with @android.annotation.EnforcePermission \
-                which differs from the overridden method Stub.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \
+                which differs from the overridden method IFooMethod.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). \
                 The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
-                    public void testMethod() {}
+                    public void testMethod() {
                                 ~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
@@ -168,7 +206,9 @@
             package test.pkg;
             public class TestClass9 extends IFooMethod.Stub {
                 @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC})
-                public void testMethodAny() {}
+                public void testMethodAny() {
+                    testMethodAny_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -177,10 +217,10 @@
         .expect("""
                 src/test/pkg/TestClass9.java:4: Error: The method TestClass9.testMethodAny is annotated with \
                 @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC}) \
-                which differs from the overridden method Stub.testMethodAny: \
+                which differs from the overridden method IFooMethod.testMethodAny: \
                 @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}). \
                 The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
-                    public void testMethodAny() {}
+                    public void testMethodAny() {
                                 ~~~~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
@@ -192,7 +232,9 @@
             package test.pkg;
             public class TestClass91 extends IFooMethod.Stub {
                 @android.annotation.EnforcePermission(anyOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"})
-                public void testMethodAnyLiteral() {}
+                public void testMethodAnyLiteral() {
+                    testMethodAnyLiteral_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -201,10 +243,10 @@
         .expect("""
                 src/test/pkg/TestClass91.java:4: Error: The method TestClass91.testMethodAnyLiteral is annotated with \
                 @android.annotation.EnforcePermission(anyOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"}) \
-                which differs from the overridden method Stub.testMethodAnyLiteral: \
+                which differs from the overridden method IFooMethod.testMethodAnyLiteral: \
                 @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \
                 The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
-                    public void testMethodAnyLiteral() {}
+                    public void testMethodAnyLiteral() {
                                 ~~~~~~~~~~~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
@@ -216,7 +258,9 @@
             package test.pkg;
             public class TestClass10 extends IFooMethod.Stub {
                 @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC})
-                public void testMethodAll() {}
+                public void testMethodAll() {
+                    testMethodAll_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -225,10 +269,10 @@
         .expect("""
                 src/test/pkg/TestClass10.java:4: Error: The method TestClass10.testMethodAll is annotated with \
                 @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.NFC}) \
-                which differs from the overridden method Stub.testMethodAll: \
+                which differs from the overridden method IFooMethod.testMethodAll: \
                 @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE}). \
                 The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
-                    public void testMethodAll() {}
+                    public void testMethodAll() {
                                 ~~~~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
@@ -240,7 +284,9 @@
             package test.pkg;
             public class TestClass101 extends IFooMethod.Stub {
                 @android.annotation.EnforcePermission(allOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"})
-                public void testMethodAllLiteral() {}
+                public void testMethodAllLiteral() {
+                    testMethodAllLiteral_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
@@ -249,10 +295,10 @@
         .expect("""
                 src/test/pkg/TestClass101.java:4: Error: The method TestClass101.testMethodAllLiteral is annotated with \
                 @android.annotation.EnforcePermission(allOf={"android.permission.INTERNET", "android.permissionoopsthisisatypo.READ_PHONE_STATE"}) \
-                which differs from the overridden method Stub.testMethodAllLiteral: \
+                which differs from the overridden method IFooMethod.testMethodAllLiteral: \
                 @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \
                 The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
-                    public void testMethodAllLiteral() {}
+                    public void testMethodAllLiteral() {
                                 ~~~~~~~~~~~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
@@ -263,16 +309,18 @@
             """
             package test.pkg;
             public class TestClass6 extends IFooMethod.Stub {
-                public void testMethod() {}
+                public void testMethod() {
+                    testMethod_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
         )
         .run()
         .expect("""
-                src/test/pkg/TestClass6.java:3: Error: The method TestClass6.testMethod overrides the method Stub.testMethod which is annotated with @EnforcePermission. \
+                src/test/pkg/TestClass6.java:3: Error: The method TestClass6.testMethod overrides the method IFooMethod.testMethod which is annotated with @EnforcePermission. \
                 The same annotation must be used on TestClass6.testMethod [MissingEnforcePermissionAnnotation]
-                    public void testMethod() {}
+                    public void testMethod() {
                                 ~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
@@ -284,16 +332,18 @@
             package test.pkg;
             public class TestClass7 extends IBar.Stub {
                 @android.annotation.EnforcePermission(android.Manifest.permission.INTERNET)
-                public void testMethod() {}
+                public void testMethod() {
+                    testMethod_enforcePermission();
+                }
             }
             """).indented(),
                 *stubs
         )
         .run()
         .expect("""
-                src/test/pkg/TestClass7.java:4: Error: The method TestClass7.testMethod overrides the method Stub.testMethod which is not annotated with @EnforcePermission. \
-                The same annotation must be used on Stub.testMethod. Did you forget to annotate the AIDL definition? [MissingEnforcePermissionAnnotation]
-                    public void testMethod() {}
+                src/test/pkg/TestClass7.java:4: Error: The method TestClass7.testMethod overrides the method IBar.testMethod which is not annotated with @EnforcePermission. \
+                The same annotation must be used on IBar.testMethod. Did you forget to annotate the AIDL definition? [MissingEnforcePermissionAnnotation]
+                    public void testMethod() {
                                 ~~~~~~~~~~
                 1 errors, 0 warnings
                 """.addLineContinuation())
@@ -304,7 +354,9 @@
             """
             package test.pkg;
             public class Default extends IFooMethod.Stub {
-                public void testMethod() {}
+                public void testMethod() {
+                    testMethod_enforcePermission();
+                }
             }
             """).indented(),
             *stubs
@@ -313,23 +365,74 @@
             .expect(
                 """
                 src/test/pkg/Default.java:3: Error: The method Default.testMethod \
-                overrides the method Stub.testMethod which is annotated with @EnforcePermission. The same annotation must be used on Default.testMethod [MissingEnforcePermissionAnnotation]
-                    public void testMethod() {}
+                overrides the method IFooMethod.testMethod which is annotated with @EnforcePermission. The same annotation must be used on Default.testMethod [MissingEnforcePermissionAnnotation]
+                    public void testMethod() {
                                 ~~~~~~~~~~
-                1 errors, 0 warnings 
+                1 errors, 0 warnings
                 """.addLineContinuation()
             )
     }
 
-    fun testDoesDetectIssuesShortStringsNotAllowed() {
+    fun testDoesNotDetectIssuesShortStringsAllowedInChildAndParent() {
         lint().files(java(
             """
             package test.pkg;
             import android.annotation.EnforcePermission;
             public class TestClass121 extends IFooMethod.Stub {
                 @Override
+                @EnforcePermission("READ_PHONE_STATE")
+                public void testMethod() {
+                    testMethod_enforcePermission();
+                }
+                @Override
+                @EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
+                public void testMethodParentShortPermission() {
+                    testMethodParentShortPermission_enforcePermission();
+                }
+                @Override
                 @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"})
-                public void testMethodAnyLiteral() {}
+                public void testMethodAnyLiteral() {
+                    testMethodAnyLiteral_enforcePermission();
+                }
+                @Override
+                @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE})
+                public void testMethodAnyLiteralParentsShortPermission() {
+                    testMethodAnyLiteralParentsShortPermission_enforcePermission();
+                }
+            }
+            """).indented(),
+            *stubs
+        )
+            .run()
+            .expectClean()
+    }
+
+    fun testDoesDetectIssuesWrongShortStringsInChildAndParent() {
+        lint().files(java(
+            """
+            package test.pkg;
+            import android.annotation.EnforcePermission;
+            public class TestClass121 extends IFooMethod.Stub {
+                @Override
+                @EnforcePermission("READ_WRONG_PHONE_STATE")
+                public void testMethod() {
+                    testMethod_enforcePermission();
+                }
+                @Override
+                @EnforcePermission(android.Manifest.permission.READ_WRONG_PHONE_STATE)
+                public void testMethodParentShortPermission() {
+                    testMethodParentShortPermission_enforcePermission();
+                }
+                @Override
+                @EnforcePermission(anyOf={"WRONG_INTERNET", "READ_PHONE_STATE"})
+                public void testMethodAnyLiteral() {
+                    testMethodAnyLiteral_enforcePermission();
+                }
+                @Override
+                @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_WRONG_PHONE_STATE})
+                public void testMethodAnyLiteralParentsShortPermission() {
+                    testMethodAnyLiteralParentsShortPermission_enforcePermission();
+                }
             }
             """).indented(),
             *stubs
@@ -337,14 +440,19 @@
             .run()
             .expect(
                 """
-                src/test/pkg/TestClass121.java:6: Error: The method \
-                TestClass121.testMethodAnyLiteral is annotated with @EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}) \
-                which differs from the overridden method Stub.testMethodAnyLiteral: \
-                @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). \
-                The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
-                    public void testMethodAnyLiteral() {}
-                                ~~~~~~~~~~~~~~~~~~~~
-                1 errors, 0 warnings
+            src/test/pkg/TestClass121.java:6: Error: The method TestClass121.testMethod is annotated with @EnforcePermission("READ_WRONG_PHONE_STATE") which differs from the overridden method IFooMethod.testMethod: @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
+                public void testMethod() {
+                            ~~~~~~~~~~
+            src/test/pkg/TestClass121.java:11: Error: The method TestClass121.testMethodParentShortPermission is annotated with @EnforcePermission(android.Manifest.permission.READ_WRONG_PHONE_STATE) which differs from the overridden method IFooMethod.testMethodParentShortPermission: @android.annotation.EnforcePermission("READ_PHONE_STATE"). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
+                public void testMethodParentShortPermission() {
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+            src/test/pkg/TestClass121.java:16: Error: The method TestClass121.testMethodAnyLiteral is annotated with @EnforcePermission(anyOf={"WRONG_INTERNET", "READ_PHONE_STATE"}) which differs from the overridden method IFooMethod.testMethodAnyLiteral: @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"}). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
+                public void testMethodAnyLiteral() {
+                            ~~~~~~~~~~~~~~~~~~~~
+            src/test/pkg/TestClass121.java:21: Error: The method TestClass121.testMethodAnyLiteralParentsShortPermission is annotated with @EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_WRONG_PHONE_STATE}) which differs from the overridden method IFooMethod.testMethodAnyLiteralParentsShortPermission: @android.annotation.EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"}). The same annotation must be used for both methods. [MismatchingEnforcePermissionAnnotation]
+                public void testMethodAnyLiteralParentsShortPermission() {
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+            4 errors, 0 warnings
                 """.addLineContinuation()
             )
     }
@@ -356,28 +464,17 @@
         """
         public interface IFooMethod extends android.os.IInterface {
          public static abstract class Stub extends android.os.Binder implements IFooMethod {
-            @Override
-            @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
-            public void testMethod() {}
-            @Override
-            @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE})
-            public void testMethodAny() {}
-            @Override
-            @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"})
-            public void testMethodAnyLiteral() {}
-            @Override
-            @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE})
-            public void testMethodAll() {}
-            @Override
-            @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"})
-            public void testMethodAllLiteral() {}
           }
           @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE)
           public void testMethod();
+          @android.annotation.EnforcePermission("READ_PHONE_STATE")
+          public void testMethodParentShortPermission();
           @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE})
           public void testMethodAny() {}
           @android.annotation.EnforcePermission(anyOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"})
           public void testMethodAnyLiteral() {}
+          @android.annotation.EnforcePermission(anyOf={"INTERNET", "READ_PHONE_STATE"})
+          public void testMethodAnyLiteralParentsShortPermission() {}
           @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, android.Manifest.permission.READ_PHONE_STATE})
           public void testMethodAll() {}
           @android.annotation.EnforcePermission(allOf={android.Manifest.permission.INTERNET, "android.permission.READ_PHONE_STATE"})
@@ -391,8 +488,6 @@
         """
         public interface IBar extends android.os.IInterface {
          public static abstract class Stub extends android.os.Binder implements IBar {
-            @Override
-            public void testMethod() {}
           }
           public void testMethod();
         }
@@ -404,6 +499,7 @@
         package android.Manifest;
         class permission {
           public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
+          public static final String READ_WRONG_PHONE_STATE = "android.permission.READ_WRONG_PHONE_STATE";
           public static final String NFC = "android.permission.NFC";
           public static final String INTERNET = "android.permission.INTERNET";
         }
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt
index 3ef02f8..a4b0bc3 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/EnforcePermissionHelperDetectorCodegenTest.kt
@@ -28,7 +28,8 @@
     override fun getDetector(): Detector = EnforcePermissionDetector()
 
     override fun getIssues(): List<Issue> = listOf(
-            EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER
+            EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER,
+            EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION
     )
 
     override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)