Merge "Make Display.Mode.isSynthetic TestApi" into aosp-main-future
diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp
index d991da5..b3a674f 100644
--- a/api/StubLibraries.bp
+++ b/api/StubLibraries.bp
@@ -890,7 +890,7 @@
     cmd: "rm -f $(genDir)/framework.aidl.merged && " +
         "for i in $(in); do " +
         "  rm -f $(genDir)/framework.aidl.tmp && " +
-        "  $(location sdkparcelables) $$i $(genDir)/framework.aidl.tmp && " +
+        "  $(location sdkparcelables) $$i $(genDir)/framework.aidl.tmp --guarantee_stable && " +
         "  cat $(genDir)/framework.aidl.tmp >> $(genDir)/framework.aidl.merged; " +
         "done && " +
         "sort -u $(genDir)/framework.aidl.merged > $(out)",
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index a539ff1..fdd8b04 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -399,7 +399,7 @@
     @RequiresPermission(TEST_BIOMETRIC)
     public BiometricTestSession createTestSession(int sensorId) {
         try {
-            return new BiometricTestSession(mContext, getSensorProperties(), sensorId,
+            return new BiometricTestSession(mContext, sensorId,
                     (context, sensorId1, callback) -> mService
                             .createTestSession(sensorId1, callback, context.getOpPackageName()));
         } catch (RemoteException e) {
diff --git a/core/java/android/hardware/biometrics/BiometricTestSession.java b/core/java/android/hardware/biometrics/BiometricTestSession.java
index 8bd3528..027d101 100644
--- a/core/java/android/hardware/biometrics/BiometricTestSession.java
+++ b/core/java/android/hardware/biometrics/BiometricTestSession.java
@@ -27,15 +27,12 @@
 import android.util.ArraySet;
 import android.util.Log;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 /**
  * Common set of interfaces to test biometric-related APIs, including {@link BiometricPrompt} and
  * {@link android.hardware.fingerprint.FingerprintManager}.
- *
  * @hide
  */
 @TestApi
@@ -51,29 +48,21 @@
                 @NonNull ITestSessionCallback callback) throws RemoteException;
     }
 
+    private final Context mContext;
     private final int mSensorId;
-    private final List<ITestSession> mTestSessionsForAllSensors = new ArrayList<>();
-    private ITestSession mTestSession;
+    private final ITestSession mTestSession;
 
     // Keep track of users that were tested, which need to be cleaned up when finishing.
-    @NonNull
-    private final ArraySet<Integer> mTestedUsers;
+    @NonNull private final ArraySet<Integer> mTestedUsers;
 
     // Track the users currently cleaning up, and provide a latch that gets notified when all
     // users have finished cleaning up. This is an imperfect system, as there can technically be
     // multiple cleanups per user. Theoretically we should track the cleanup's BaseClientMonitor's
     // unique ID, but it's complicated to plumb it through. This should be fine for now.
-    @Nullable
-    private CountDownLatch mCloseLatch;
-    @NonNull
-    private final ArraySet<Integer> mUsersCleaningUp;
+    @Nullable private CountDownLatch mCloseLatch;
+    @NonNull private final ArraySet<Integer> mUsersCleaningUp;
 
-    private class TestSessionCallbackIml extends ITestSessionCallback.Stub {
-        private final int mSensorId;
-        private TestSessionCallbackIml(int sensorId) {
-            mSensorId = sensorId;
-        }
-
+    private final ITestSessionCallback mCallback = new ITestSessionCallback.Stub() {
         @Override
         public void onCleanupStarted(int userId) {
             Log.d(getTag(), "onCleanupStarted, sensor: " + mSensorId + ", userId: " + userId);
@@ -87,30 +76,19 @@
             mUsersCleaningUp.remove(userId);
 
             if (mUsersCleaningUp.isEmpty() && mCloseLatch != null) {
-                Log.d(getTag(), "counting down");
                 mCloseLatch.countDown();
             }
         }
-    }
+    };
 
     /**
      * @hide
      */
-    public BiometricTestSession(@NonNull Context context, List<SensorProperties> sensors,
-            int sensorId, @NonNull TestSessionProvider testSessionProvider) throws RemoteException {
+    public BiometricTestSession(@NonNull Context context, int sensorId,
+            @NonNull TestSessionProvider testSessionProvider) throws RemoteException {
+        mContext = context;
         mSensorId = sensorId;
-        // When any of the sensors should create the test session, all the other sensors should
-        // set test hal enabled too.
-        for (SensorProperties sensor : sensors) {
-            final int id = sensor.getSensorId();
-            final ITestSession session = testSessionProvider.createTestSession(context, id,
-                    new TestSessionCallbackIml(id));
-            mTestSessionsForAllSensors.add(session);
-            if (id == sensorId) {
-                mTestSession = session;
-            }
-        }
-
+        mTestSession = testSessionProvider.createTestSession(context, sensorId, mCallback);
         mTestedUsers = new ArraySet<>();
         mUsersCleaningUp = new ArraySet<>();
         setTestHalEnabled(true);
@@ -129,11 +107,8 @@
     @RequiresPermission(TEST_BIOMETRIC)
     private void setTestHalEnabled(boolean enabled) {
         try {
-            for (ITestSession session : mTestSessionsForAllSensors) {
-                Log.w(getTag(), "setTestHalEnabled, sensor: " + session.getSensorId() + " enabled: "
-                        + enabled);
-                session.setTestHalEnabled(enabled);
-            }
+            Log.w(getTag(), "setTestHalEnabled, sensor: " + mSensorId + " enabled: " + enabled);
+            mTestSession.setTestHalEnabled(enabled);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -200,12 +175,10 @@
     /**
      * Simulates an acquired message from the HAL.
      *
-     * @param userId      User that this command applies to.
+     * @param userId User that this command applies to.
      * @param acquireInfo See
-     *                    {@link
-     *                    BiometricPrompt.AuthenticationCallback#onAuthenticationAcquired(int)} and
-     *                    {@link
-     *                    FingerprintManager.AuthenticationCallback#onAuthenticationAcquired(int)}
+     * {@link BiometricPrompt.AuthenticationCallback#onAuthenticationAcquired(int)} and
+     * {@link FingerprintManager.AuthenticationCallback#onAuthenticationAcquired(int)}
      */
     @RequiresPermission(TEST_BIOMETRIC)
     public void notifyAcquired(int userId, int acquireInfo) {
@@ -219,12 +192,10 @@
     /**
      * Simulates an error message from the HAL.
      *
-     * @param userId    User that this command applies to.
+     * @param userId User that this command applies to.
      * @param errorCode See
-     *                  {@link BiometricPrompt.AuthenticationCallback#onAuthenticationError(int,
-     *                  CharSequence)} and
-     *                  {@link FingerprintManager.AuthenticationCallback#onAuthenticationError(int,
-     *                  CharSequence)}
+     * {@link BiometricPrompt.AuthenticationCallback#onAuthenticationError(int, CharSequence)} and
+     * {@link FingerprintManager.AuthenticationCallback#onAuthenticationError(int, CharSequence)}
      */
     @RequiresPermission(TEST_BIOMETRIC)
     public void notifyError(int userId, int errorCode) {
@@ -249,20 +220,8 @@
                 Log.w(getTag(), "Cleanup already in progress for user: " + userId);
             }
 
-            for (ITestSession session : mTestSessionsForAllSensors) {
-                mUsersCleaningUp.add(userId);
-                Log.d(getTag(), "cleanupInternalState for sensor: " + session.getSensorId());
-                mCloseLatch = new CountDownLatch(1);
-                session.cleanupInternalState(userId);
-
-                try {
-                    Log.d(getTag(), "Awaiting latch...");
-                    mCloseLatch.await(3, TimeUnit.SECONDS);
-                    Log.d(getTag(), "Finished awaiting");
-                } catch (InterruptedException e) {
-                    Log.e(getTag(), "Latch interrupted", e);
-                }
-            }
+            mUsersCleaningUp.add(userId);
+            mTestSession.cleanupInternalState(userId);
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
@@ -275,9 +234,18 @@
         // Cleanup can be performed using the test HAL, since it always responds to enumerate with
         // zero enrollments.
         if (!mTestedUsers.isEmpty()) {
+            mCloseLatch = new CountDownLatch(1);
             for (int user : mTestedUsers) {
                 cleanupInternalState(user);
             }
+
+            try {
+                Log.d(getTag(), "Awaiting latch...");
+                mCloseLatch.await(3, TimeUnit.SECONDS);
+                Log.d(getTag(), "Finished awaiting");
+            } catch (InterruptedException e) {
+                Log.e(getTag(), "Latch interrupted", e);
+            }
         }
 
         if (!mUsersCleaningUp.isEmpty()) {
diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl
index bd99606..df9f504 100644
--- a/core/java/android/hardware/biometrics/ITestSession.aidl
+++ b/core/java/android/hardware/biometrics/ITestSession.aidl
@@ -59,8 +59,4 @@
     // HAL is disabled (e.g. to clean up after a test).
     @EnforcePermission("TEST_BIOMETRIC")
     void cleanupInternalState(int userId);
-
-    // Get the sensor id of the current test session.
-    @EnforcePermission("TEST_BIOMETRIC")
-    int getSensorId();
 }
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 7f1cac0..903e916 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -172,7 +172,7 @@
     @RequiresPermission(TEST_BIOMETRIC)
     public BiometricTestSession createTestSession(int sensorId) {
         try {
-            return new BiometricTestSession(mContext, getSensorProperties(), sensorId,
+            return new BiometricTestSession(mContext, sensorId,
                     (context, sensorId1, callback) -> mService
                             .createTestSession(sensorId1, callback, context.getOpPackageName()));
         } catch (RemoteException e) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/OWNERS b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/OWNERS
new file mode 100644
index 0000000..134a56e
--- /dev/null
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/OWNERS
@@ -0,0 +1 @@
+include /packages/SettingsLib/src/com/android/settingslib/bluetooth/OWNERS
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/OWNERS b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/OWNERS
new file mode 100644
index 0000000..f6f98e9
--- /dev/null
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/OWNERS
@@ -0,0 +1 @@
+include /packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
index 443e9876..208a17c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/OWNERS
@@ -9,3 +9,4 @@
 jglazier@google.com
 mpietal@google.com
 tsuji@google.com
+yuandizhou@google.com
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 857d0a6..f706183 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12508,7 +12508,7 @@
                 opts.dumpProto = true;
             } else if ("--logstats".equals(opt)) {
                 opts.mDumpAllocatorStats = true;
-            } else if ("-h".equals(opt)) {
+            } else if ("-h".equals(opt) || "--help".equals(opt)) {
                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
                 pw.println("  -a: include all available information for each process.");
                 pw.println("  -d: include dalvik details.");
@@ -12522,6 +12522,8 @@
                 pw.println("             processes that have loaded that package.");
                 pw.println("  --checkin: dump data for a checkin");
                 pw.println("  --proto: dump data to proto");
+                pw.println("  --logstats: log native allocator statistics.");
+                pw.println("  --unreachable: dump unreachable native memory with libmemunreachable.");
                 pw.println("If [process] is specified it can be the name or ");
                 pw.println("pid of a specific process to dump.");
                 return;
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index 8e29de7..550d878 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1657,6 +1657,10 @@
         sendIILMsg(MSG_IIL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, codec, address, delayMs);
     }
 
+    /*package*/ void setHearingAidTimeout(String address, int delayMs) {
+        sendLMsg(MSG_IL_BT_HEARING_AID_TIMEOUT, SENDMSG_QUEUE, address, delayMs);
+    }
+
     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) {
         synchronized (mDeviceStateLock) {
             mBtHelper.setAvrcpAbsoluteVolumeSupported(supported);
@@ -1899,6 +1903,13 @@
                                 (String) msg.obj, msg.arg1, msg.arg2);
                     }
                     break;
+                case MSG_IL_BT_HEARING_AID_TIMEOUT:
+                    // msg.obj  == address of Hearing Aid device
+                    synchronized (mDeviceStateLock) {
+                        mDeviceInventory.onMakeHearingAidDeviceUnavailableNow(
+                                (String) msg.obj);
+                    }
+                    break;
                 case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: {
                     final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
                     final Pair<Integer, Boolean> codecAndChanged = mBtHelper.getCodecWithFallback(
@@ -2174,6 +2185,7 @@
     private static final int MSG_L_SYNCHRONIZE_ADI_DEVICES_IN_INVENTORY = 58;
     private static final int MSG_IL_UPDATED_ADI_DEVICE_STATE = 59;
     private static final int MSG_L_SET_FORCE_BT_A2DP_USE_NO_MUTE = 60;
+    private static final int MSG_IL_BT_HEARING_AID_TIMEOUT = 61;
 
     private static boolean isMessageHandledUnderWakelock(int msgId) {
         switch(msgId) {
@@ -2186,6 +2198,7 @@
             case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT:
             case MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT:
             case MSG_CHECK_MUTE_MUSIC:
+            case MSG_IL_BT_HEARING_AID_TIMEOUT:
                 return true;
             default:
                 return false;
@@ -2270,6 +2283,7 @@
                 case MSG_IL_BTA2DP_TIMEOUT:
                 case MSG_IIL_BTLEAUDIO_TIMEOUT:
                 case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE:
+                case MSG_IL_BT_HEARING_AID_TIMEOUT:
                     if (sLastDeviceConnectMsgTime >= time) {
                         // add a little delay to make sure messages are ordered as expected
                         time = sLastDeviceConnectMsgTime + 30;
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index 6ff4a61..ea3d821 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -1023,6 +1023,11 @@
         }
     }
 
+    /*package*/ void onMakeHearingAidDeviceUnavailableNow(String address) {
+        synchronized (mDevicesLock) {
+            makeHearingAidDeviceUnavailable(address);
+        }
+    }
 
     /**
      * Goes over all connected LE Audio devices in the provided group ID and
@@ -1866,12 +1871,10 @@
                     .set(MediaMetrics.Property.EVENT, "disconnectHearingAid")
                     .record();
             if (toRemove.size() > 0) {
-                /*final int delay = */
-                checkSendBecomingNoisyIntentInt(DEVICE_OUT_HEARING_AID,
+                final int delay = checkSendBecomingNoisyIntentInt(DEVICE_OUT_HEARING_AID,
                         AudioService.CONNECTION_STATE_DISCONNECTED, AudioSystem.DEVICE_NONE);
                 toRemove.stream().forEach(deviceAddress ->
-                        // TODO delay not used?
-                        makeHearingAidDeviceUnavailable(deviceAddress /*, delay*/)
+                        makeHearingAidDeviceUnavailableLater(deviceAddress, delay)
                 );
             }
         }
@@ -2450,6 +2453,15 @@
         mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
     }
 
+    @GuardedBy("mDevicesLock")
+    private void makeHearingAidDeviceUnavailableLater(
+            String address, int delayMs) {
+        // the device will be made unavailable later, so consider it disconnected right away
+        mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(DEVICE_OUT_HEARING_AID, address));
+        // send the delayed message to make the device unavailable later
+        mDeviceBroker.setHearingAidTimeout(address, delayMs);
+    }
+
     /**
      * Returns whether a device of type DEVICE_OUT_HEARING_AID is connected.
      * Visibility by APM plays no role
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
index dca1491..0fdd57d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java
@@ -264,11 +264,4 @@
             }
         });
     }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public int getSensorId() {
-        super.getSensorId_enforcePermission();
-        return mSensorId;
-    }
 }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
index caa2c1c..8dc560b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java
@@ -293,11 +293,4 @@
             }
         });
     }
-
-    @android.annotation.EnforcePermission(android.Manifest.permission.TEST_BIOMETRIC)
-    @Override
-    public int getSensorId() {
-        super.getSensorId_enforcePermission();
-        return mSensorId;
-    }
 }
\ No newline at end of file
diff --git a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
index 0b61948..9c44332 100644
--- a/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
+++ b/tools/sdkparcelables/src/com/android/sdkparcelables/Main.kt
@@ -23,13 +23,21 @@
 import java.util.zip.ZipFile
 
 fun main(args: Array<String>) {
-    if (args.size != 2) {
+    if (args.size < 2 || args.size > 3) {
         usage()
     }
 
     val zipFileName = args[0]
     val aidlFileName = args[1]
 
+    var stable = false
+    if (args.size == 3) {
+        if (args[2] != "--guarantee_stable") {
+            usage()
+        }
+        stable = true
+    }
+
     val zipFile: ZipFile
 
     try {
@@ -55,6 +63,9 @@
         val outFile = File(aidlFileName)
         val outWriter = outFile.bufferedWriter()
         for (parcelable in parcelables) {
+            if (stable) {
+                outWriter.write("@JavaOnlyStableParcelable ")
+            }
             outWriter.write("parcelable ")
             outWriter.write(parcelable.replace('/', '.').replace('$', '.'))
             outWriter.write(";\n")