Merge "Turn on ENABLE_VIRTUAL_DISPLAY_REFRESH_RATE flag" into udc-dev
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index 4bddbd6..4caaa09 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -4589,6 +4589,22 @@
                     Binder.restoreCallingIdentity(token);
                 }
             }
+        } else if ("force-active".equals(cmd)) {
+            getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
+                    null);
+            synchronized (this) {
+                final long token = Binder.clearCallingIdentity();
+                try {
+                    mForceIdle = true;
+                    becomeActiveLocked("force-active", Process.myUid());
+                    pw.print("Light state: ");
+                    pw.print(lightStateToString(mLightState));
+                    pw.print(", deep state: ");
+                    pw.println(stateToString(mState));
+                } finally {
+                    Binder.restoreCallingIdentity(token);
+                }
+            }
         } else if ("force-idle".equals(cmd)) {
             getContext().enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER,
                     null);
diff --git a/core/api/current.txt b/core/api/current.txt
index 2968b59..eef16be 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -15782,9 +15782,9 @@
     method @NonNull public static android.graphics.MeshSpecification make(@NonNull @Size(max=8) android.graphics.MeshSpecification.Attribute[], @IntRange(from=1, to=1024) int, @NonNull @Size(max=6) android.graphics.MeshSpecification.Varying[], @NonNull String, @NonNull String, @NonNull android.graphics.ColorSpace);
     method @NonNull public static android.graphics.MeshSpecification make(@NonNull @Size(max=8) android.graphics.MeshSpecification.Attribute[], @IntRange(from=1, to=1024) int, @NonNull @Size(max=6) android.graphics.MeshSpecification.Varying[], @NonNull String, @NonNull String, @NonNull android.graphics.ColorSpace, int);
     field public static final int ALPHA_TYPE_OPAQUE = 1; // 0x1
-    field public static final int ALPHA_TYPE_PREMUL = 2; // 0x2
-    field public static final int ALPHA_TYPE_PREMULT = 3; // 0x3
+    field public static final int ALPHA_TYPE_PREMULTIPLIED = 2; // 0x2
     field public static final int ALPHA_TYPE_UNKNOWN = 0; // 0x0
+    field public static final int ALPHA_TYPE_UNPREMULTIPLIED = 3; // 0x3
     field public static final int TYPE_FLOAT = 0; // 0x0
     field public static final int TYPE_FLOAT2 = 1; // 0x1
     field public static final int TYPE_FLOAT3 = 2; // 0x2
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 6581c42..95e331e 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -10152,7 +10152,6 @@
 
   public abstract class SharedConnectivityService extends android.app.Service {
     ctor public SharedConnectivityService();
-    ctor public SharedConnectivityService(@NonNull android.os.Handler);
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
     method public abstract void onConnectKnownNetwork(@NonNull android.net.wifi.sharedconnectivity.app.KnownNetwork);
     method public abstract void onConnectTetherNetwork(@NonNull android.net.wifi.sharedconnectivity.app.TetherNetwork);
diff --git a/graphics/java/android/graphics/MeshSpecification.java b/graphics/java/android/graphics/MeshSpecification.java
index 0201525..70311fd 100644
--- a/graphics/java/android/graphics/MeshSpecification.java
+++ b/graphics/java/android/graphics/MeshSpecification.java
@@ -54,7 +54,8 @@
      */
     @IntDef(
         prefix = {"ALPHA_TYPE_"},
-        value = {ALPHA_TYPE_UNKNOWN, ALPHA_TYPE_OPAQUE, ALPHA_TYPE_PREMUL, ALPHA_TYPE_PREMULT}
+        value = {ALPHA_TYPE_UNKNOWN, ALPHA_TYPE_OPAQUE, ALPHA_TYPE_PREMULTIPLIED,
+                ALPHA_TYPE_UNPREMULTIPLIED}
     )
     @Retention(RetentionPolicy.SOURCE)
     private @interface AlphaType {}
@@ -72,12 +73,12 @@
     /**
      * Pixel components are premultiplied by alpha.
      */
-    public static final int ALPHA_TYPE_PREMUL = 2;
+    public static final int ALPHA_TYPE_PREMULTIPLIED = 2;
 
     /**
      * Pixel components are independent of alpha.
      */
-    public static final int ALPHA_TYPE_PREMULT = 3;
+    public static final int ALPHA_TYPE_UNPREMULTIPLIED = 3;
 
     /**
      * Constants for {@link Attribute} and {@link Varying} for determining the data type.
@@ -220,7 +221,7 @@
     /**
      * Creates a {@link MeshSpecification} object for use within {@link Mesh}. This uses a default
      * color space of {@link ColorSpace.Named#SRGB} and {@link AlphaType} of
-     * {@link #ALPHA_TYPE_PREMUL}.
+     * {@link #ALPHA_TYPE_PREMULTIPLIED}.
      *
      * @param attributes     list of attributes represented by {@link Attribute}. Can hold a max of
      *                       8.
@@ -253,7 +254,7 @@
 
     /**
      * Creates a {@link MeshSpecification} object.  This uses a default {@link AlphaType} of
-     * {@link #ALPHA_TYPE_PREMUL}.
+     * {@link #ALPHA_TYPE_PREMULTIPLIED}.
      *
      * @param attributes     list of attributes represented by {@link Attribute}. Can hold a max of
      *                       8.
@@ -306,8 +307,8 @@
      *                       one of
      *                       {@link MeshSpecification#ALPHA_TYPE_UNKNOWN},
      *                       {@link MeshSpecification#ALPHA_TYPE_OPAQUE},
-     *                       {@link MeshSpecification#ALPHA_TYPE_PREMUL}, or
-     *                       {@link MeshSpecification#ALPHA_TYPE_PREMULT}
+     *                       {@link MeshSpecification#ALPHA_TYPE_PREMULTIPLIED}, or
+     *                       {@link MeshSpecification#ALPHA_TYPE_UNPREMULTIPLIED}
      * @return {@link MeshSpecification} object for use when creating {@link Mesh}
      */
     @NonNull
diff --git a/media/java/android/media/tv/tuner/filter/MediaEvent.java b/media/java/android/media/tv/tuner/filter/MediaEvent.java
index 8f2e7b5..4676dff 100644
--- a/media/java/android/media/tv/tuner/filter/MediaEvent.java
+++ b/media/java/android/media/tv/tuner/filter/MediaEvent.java
@@ -224,6 +224,10 @@
 
     /**
      * Gets audio presentations.
+     *
+     * <p>The audio presentation order matters. As specified in ETSI EN 300 468 V1.17.1, all the
+     * audio programme components corresponding to the first audio preselection in the loop are
+     * contained in the main NGA stream.
      */
     @NonNull
     public List<AudioPresentation> getAudioPresentations() {
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index b001f3d..3304fb0 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -1263,6 +1263,10 @@
         sendILMsg(MSG_IL_BTA2DP_TIMEOUT, SENDMSG_QUEUE, a2dpCodec, address, delayMs);
     }
 
+    /*package*/ void setLeAudioTimeout(String address, int device, int delayMs) {
+        sendILMsg(MSG_IL_BTLEAUDIO_TIMEOUT, SENDMSG_QUEUE, device, address, delayMs);
+    }
+
     /*package*/ void setAvrcpAbsoluteVolumeSupported(boolean supported) {
         synchronized (mDeviceStateLock) {
             mBtHelper.setAvrcpAbsoluteVolumeSupported(supported);
@@ -1467,6 +1471,13 @@
                         mDeviceInventory.onMakeA2dpDeviceUnavailableNow((String) msg.obj, msg.arg1);
                     }
                     break;
+                case MSG_IL_BTLEAUDIO_TIMEOUT:
+                    // msg.obj  == address of LE Audio device
+                    synchronized (mDeviceStateLock) {
+                        mDeviceInventory.onMakeLeAudioDeviceUnavailableNow(
+                                (String) msg.obj, msg.arg1);
+                    }
+                    break;
                 case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
                     final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
                     synchronized (mDeviceStateLock) {
@@ -1703,12 +1714,14 @@
 
     private static final int MSG_IL_SAVE_NDEF_DEVICE_FOR_STRATEGY = 47;
     private static final int MSG_IL_SAVE_REMOVE_NDEF_DEVICE_FOR_STRATEGY = 48;
+    private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49;
 
     private static boolean isMessageHandledUnderWakelock(int msgId) {
         switch(msgId) {
             case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
             case MSG_L_SET_BT_ACTIVE_DEVICE:
             case MSG_IL_BTA2DP_TIMEOUT:
+            case MSG_IL_BTLEAUDIO_TIMEOUT:
             case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
             case MSG_TOGGLE_HDMI:
             case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT:
@@ -1800,6 +1813,7 @@
                 case MSG_L_SET_BT_ACTIVE_DEVICE:
                 case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
                 case MSG_IL_BTA2DP_TIMEOUT:
+                case MSG_IL_BTLEAUDIO_TIMEOUT:
                 case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
                     if (sLastDeviceConnectMsgTime >= time) {
                         // add a little delay to make sure messages are ordered as expected
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index f9270c9..aae1d38 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -395,7 +395,7 @@
                 case BluetoothProfile.LE_AUDIO:
                 case BluetoothProfile.LE_AUDIO_BROADCAST:
                     if (switchToUnavailable) {
-                        makeLeAudioDeviceUnavailable(address, btInfo.mAudioSystemDevice);
+                        makeLeAudioDeviceUnavailableNow(address, btInfo.mAudioSystemDevice);
                     } else if (switchToAvailable) {
                         makeLeAudioDeviceAvailable(address, BtHelper.getName(btInfo.mDevice),
                                 streamType, btInfo.mVolume == -1 ? -1 : btInfo.mVolume * 10,
@@ -507,6 +507,12 @@
         }
     }
 
+    /*package*/ void onMakeLeAudioDeviceUnavailableNow(String address, int device) {
+        synchronized (mDevicesLock) {
+            makeLeAudioDeviceUnavailableNow(address, device);
+        }
+    }
+
     /*package*/ void onReportNewRoutes() {
         int n = mRoutesObservers.beginBroadcast();
         if (n > 0) {
@@ -1027,10 +1033,11 @@
             new MediaMetrics.Item(mMetricsId + "disconnectLeAudio")
                     .record();
             if (toRemove.size() > 0) {
-                final int delay = checkSendBecomingNoisyIntentInt(device, 0,
+                final int delay = checkSendBecomingNoisyIntentInt(device,
+                        AudioService.CONNECTION_STATE_DISCONNECTED,
                         AudioSystem.DEVICE_NONE);
                 toRemove.stream().forEach(deviceAddress ->
-                        makeLeAudioDeviceUnavailable(deviceAddress, device)
+                        makeLeAudioDeviceUnavailableLater(deviceAddress, device, delay)
                 );
             }
         }
@@ -1331,9 +1338,21 @@
              */
             mDeviceBroker.setBluetoothA2dpOnInt(true, false /*fromA2dp*/, eventSource);
 
-            AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address, name),
+            final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+                    device, address, name),
                     AudioSystem.DEVICE_STATE_AVAILABLE,
                     AudioSystem.AUDIO_FORMAT_DEFAULT);
+            if (res != AudioSystem.AUDIO_STATUS_OK) {
+                AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
+                        "APM failed to make available LE Audio device addr=" + address
+                                + " error=" + res).printLog(TAG));
+                // TODO: connection failed, stop here
+                // TODO: return;
+            } else {
+                AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
+                        "LE Audio device addr=" + address + " now available").printLog(TAG));
+            }
+
             mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
                     new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
             mDeviceBroker.postAccessoryPlugMediaUnmute(device);
@@ -1354,11 +1373,23 @@
     }
 
     @GuardedBy("mDevicesLock")
-    private void makeLeAudioDeviceUnavailable(String address, int device) {
+    private void makeLeAudioDeviceUnavailableNow(String address, int device) {
         if (device != AudioSystem.DEVICE_NONE) {
-            AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(device, address),
+            final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
+                    device, address),
                     AudioSystem.DEVICE_STATE_UNAVAILABLE,
                     AudioSystem.AUDIO_FORMAT_DEFAULT);
+
+            if (res != AudioSystem.AUDIO_STATUS_OK) {
+                AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
+                        "APM failed to make unavailable LE Audio device addr=" + address
+                                + " error=" + res).printLog(TAG));
+                // TODO:  failed to disconnect, stop here
+                // TODO: return;
+            } else {
+                AudioService.sDeviceLogger.enqueue(new EventLogger.StringEvent(
+                        "LE Audio device addr=" + address + " made unavailable").printLog(TAG));
+            }
             mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
         }
 
@@ -1366,6 +1397,14 @@
     }
 
     @GuardedBy("mDevicesLock")
+    private void makeLeAudioDeviceUnavailableLater(String address, int device, int delayMs) {
+        // the device will be made unavailable later, so consider it disconnected right away
+        mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
+        // send the delayed message to make the device unavailable later
+        mDeviceBroker.setLeAudioTimeout(address, device, delayMs);
+    }
+
+    @GuardedBy("mDevicesLock")
     private void setCurrentAudioRouteNameIfPossible(String name, boolean fromA2dp) {
         synchronized (mCurAudioRoutes) {
             if (TextUtils.equals(mCurAudioRoutes.bluetoothName, name)) {
diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java
index a9ebd5c..07f2916 100644
--- a/telephony/java/com/android/internal/telephony/PhoneConstants.java
+++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java
@@ -250,6 +250,9 @@
      */
     public static final int DOMAIN_NON_3GPP_PS = 4;
 
+    /** Key to enable comparison of domain selection results from legacy and new code. */
+    public static final String EXTRA_COMPARE_DOMAIN = "compare_domain";
+
     /** The key to specify the emergency service category */
     public static final String EXTRA_EMERGENCY_SERVICE_CATEGORY = "emergency_service_category";
 }
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
index 13084f4..f3af062 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
@@ -59,7 +59,7 @@
     private static final String TAG = SharedConnectivityService.class.getSimpleName();
     private static final boolean DEBUG = true;
 
-    private  final Handler mHandler;
+    private  Handler mHandler;
     private final List<ISharedConnectivityCallback> mCallbacks = new ArrayList<>();
     // Used to find DeathRecipient when unregistering a callback to call unlinkToDeath.
     private final Map<ISharedConnectivityCallback, DeathRecipient> mDeathRecipientMap =
@@ -71,14 +71,6 @@
     private TetherNetworkConnectionStatus mTetherNetworkConnectionStatus;
     private KnownNetworkConnectionStatus mKnownNetworkConnectionStatus;
 
-    public SharedConnectivityService() {
-        mHandler = new Handler(getMainLooper());
-    }
-
-    public SharedConnectivityService(@NonNull Handler handler) {
-        mHandler = handler;
-    }
-
     private final class DeathRecipient implements IBinder.DeathRecipient {
         ISharedConnectivityCallback mCallback;
 
@@ -97,6 +89,7 @@
     @Nullable
     public final IBinder onBind(@NonNull Intent intent) {
         if (DEBUG) Log.i(TAG, "onBind intent=" + intent);
+        mHandler = new Handler(getMainLooper());
         return new ISharedConnectivityService.Stub() {
             @Override
             public void registerCallback(ISharedConnectivityCallback callback) {
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
index fb8d7bf..d7f7fea 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
@@ -17,16 +17,21 @@
 package android.net.wifi.sharedconnectivity.service;
 
 import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
 
+import android.content.Context;
 import android.content.Intent;
 import android.net.wifi.sharedconnectivity.app.KnownNetwork;
 import android.net.wifi.sharedconnectivity.app.TetherNetwork;
-import android.os.Handler;
-import android.os.test.TestLooper;
+import android.os.Looper;
 
+import androidx.annotation.NonNull;
 import androidx.test.filters.SmallTest;
 
+import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Unit tests for {@link android.net.wifi.sharedconnectivity.service.SharedConnectivityService}.
@@ -34,6 +39,33 @@
 @SmallTest
 public class SharedConnectivityServiceTest {
 
+    @Mock
+    Context mContext;
+
+    static class FakeSharedConnectivityService extends SharedConnectivityService {
+        public void attachBaseContext(Context context) {
+            super.attachBaseContext(context);
+        }
+
+        @Override
+        public void onConnectTetherNetwork(@NonNull TetherNetwork network) {}
+
+        @Override
+        public void onDisconnectTetherNetwork(@NonNull TetherNetwork network) {}
+
+        @Override
+        public void onConnectKnownNetwork(@NonNull KnownNetwork network) {}
+
+        @Override
+        public void onForgetKnownNetwork(@NonNull KnownNetwork network) {}
+    }
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
+    }
+
     /**
      * Verifies service returns
      */
@@ -51,18 +83,8 @@
     }
 
     private SharedConnectivityService createService() {
-        return new SharedConnectivityService(new Handler(new TestLooper().getLooper())) {
-            @Override
-            public void onConnectTetherNetwork(TetherNetwork network) {}
-
-            @Override
-            public void onDisconnectTetherNetwork(TetherNetwork network) {}
-
-            @Override
-            public void onConnectKnownNetwork(KnownNetwork network) {}
-
-            @Override
-            public void onForgetKnownNetwork(KnownNetwork network) {}
-        };
+        FakeSharedConnectivityService service = new FakeSharedConnectivityService();
+        service.attachBaseContext(mContext);
+        return service;
     }
 }