Merge "Make a11y node info parceling more robust" into oc-dev
diff --git a/api/current.txt b/api/current.txt
index cea9c4f..53b1c1e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -21480,40 +21480,6 @@
     method public default void onRoutingChanged(android.media.AudioRouting);
   }
 
-  public final class BufferingParams implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getInitialBufferingMode();
-    method public int getInitialBufferingWatermarkKB();
-    method public int getInitialBufferingWatermarkMs();
-    method public int getRebufferingMode();
-    method public int getRebufferingWatermarkHighKB();
-    method public int getRebufferingWatermarkHighMs();
-    method public int getRebufferingWatermarkLowKB();
-    method public int getRebufferingWatermarkLowMs();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int BUFFERING_MODE_NONE = 0; // 0x0
-    field public static final int BUFFERING_MODE_SIZE_ONLY = 2; // 0x2
-    field public static final int BUFFERING_MODE_TIME_ONLY = 1; // 0x1
-    field public static final int BUFFERING_MODE_TIME_THEN_SIZE = 3; // 0x3
-    field public static final android.os.Parcelable.Creator<android.media.BufferingParams> CREATOR;
-  }
-
-  public static class BufferingParams.Builder {
-    ctor public BufferingParams.Builder();
-    ctor public BufferingParams.Builder(android.media.BufferingParams);
-    method public android.media.BufferingParams build();
-    method public android.media.BufferingParams.Builder setInitialBufferingMode(int);
-    method public android.media.BufferingParams.Builder setInitialBufferingWatermarkKB(int);
-    method public android.media.BufferingParams.Builder setInitialBufferingWatermarkMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingMode(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkHighKB(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkHighMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkLowKB(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkLowMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarksKB(int, int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarksMs(int, int);
-  }
-
   public class CamcorderProfile {
     method public static android.media.CamcorderProfile get(int);
     method public static android.media.CamcorderProfile get(int, int);
@@ -22818,9 +22784,7 @@
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
     method public int getAudioSessionId();
-    method public android.media.BufferingParams getBufferingParams();
     method public int getCurrentPosition();
-    method public android.media.BufferingParams getDefaultBufferingParams();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
     method public java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer.NoDrmSchemeException;
     method public int getDuration();
@@ -22851,7 +22815,6 @@
     method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public deprecated void setAudioStreamType(int);
     method public void setAuxEffectSendLevel(float);
-    method public void setBufferingParams(android.media.BufferingParams);
     method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -22894,6 +22857,7 @@
     field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
     field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
     field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
+    field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
     field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
     field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
     field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
@@ -22902,6 +22866,7 @@
     field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
     field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
     field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
+    field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
     field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
     field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
     field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -37075,11 +37040,11 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
-    field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3; // 0x3
-    field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5; // 0x5
+    field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
+    field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
     field public static final int SAVE_DATA_TYPE_GENERIC = 0; // 0x0
     field public static final int SAVE_DATA_TYPE_PASSWORD = 1; // 0x1
-    field public static final int SAVE_DATA_TYPE_USERNAME = 4; // 0x4
+    field public static final int SAVE_DATA_TYPE_USERNAME = 8; // 0x8
   }
 
   public static final class SaveInfo.Builder {
@@ -39530,6 +39495,7 @@
     field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
     field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
     field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
diff --git a/api/system-current.txt b/api/system-current.txt
index b587e1d..f10fd9b 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -23305,40 +23305,6 @@
     method public default void onRoutingChanged(android.media.AudioRouting);
   }
 
-  public final class BufferingParams implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getInitialBufferingMode();
-    method public int getInitialBufferingWatermarkKB();
-    method public int getInitialBufferingWatermarkMs();
-    method public int getRebufferingMode();
-    method public int getRebufferingWatermarkHighKB();
-    method public int getRebufferingWatermarkHighMs();
-    method public int getRebufferingWatermarkLowKB();
-    method public int getRebufferingWatermarkLowMs();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int BUFFERING_MODE_NONE = 0; // 0x0
-    field public static final int BUFFERING_MODE_SIZE_ONLY = 2; // 0x2
-    field public static final int BUFFERING_MODE_TIME_ONLY = 1; // 0x1
-    field public static final int BUFFERING_MODE_TIME_THEN_SIZE = 3; // 0x3
-    field public static final android.os.Parcelable.Creator<android.media.BufferingParams> CREATOR;
-  }
-
-  public static class BufferingParams.Builder {
-    ctor public BufferingParams.Builder();
-    ctor public BufferingParams.Builder(android.media.BufferingParams);
-    method public android.media.BufferingParams build();
-    method public android.media.BufferingParams.Builder setInitialBufferingMode(int);
-    method public android.media.BufferingParams.Builder setInitialBufferingWatermarkKB(int);
-    method public android.media.BufferingParams.Builder setInitialBufferingWatermarkMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingMode(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkHighKB(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkHighMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkLowKB(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkLowMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarksKB(int, int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarksMs(int, int);
-  }
-
   public class CamcorderProfile {
     method public static android.media.CamcorderProfile get(int);
     method public static android.media.CamcorderProfile get(int, int);
@@ -24643,9 +24609,7 @@
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
     method public int getAudioSessionId();
-    method public android.media.BufferingParams getBufferingParams();
     method public int getCurrentPosition();
-    method public android.media.BufferingParams getDefaultBufferingParams();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
     method public java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer.NoDrmSchemeException;
     method public int getDuration();
@@ -24676,7 +24640,6 @@
     method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public deprecated void setAudioStreamType(int);
     method public void setAuxEffectSendLevel(float);
-    method public void setBufferingParams(android.media.BufferingParams);
     method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -24719,6 +24682,7 @@
     field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
     field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
     field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
+    field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
     field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
     field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
     field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
@@ -24727,6 +24691,7 @@
     field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
     field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
     field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
+    field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
     field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
     field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
     field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -40171,11 +40136,11 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
-    field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3; // 0x3
-    field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5; // 0x5
+    field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
+    field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
     field public static final int SAVE_DATA_TYPE_GENERIC = 0; // 0x0
     field public static final int SAVE_DATA_TYPE_PASSWORD = 1; // 0x1
-    field public static final int SAVE_DATA_TYPE_USERNAME = 4; // 0x4
+    field public static final int SAVE_DATA_TYPE_USERNAME = 8; // 0x8
   }
 
   public static final class SaveInfo.Builder {
@@ -42977,6 +42942,7 @@
     field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
     field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
     field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
diff --git a/api/test-current.txt b/api/test-current.txt
index 50b3234..b1d55c8 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -21593,40 +21593,6 @@
     method public default void onRoutingChanged(android.media.AudioRouting);
   }
 
-  public final class BufferingParams implements android.os.Parcelable {
-    method public int describeContents();
-    method public int getInitialBufferingMode();
-    method public int getInitialBufferingWatermarkKB();
-    method public int getInitialBufferingWatermarkMs();
-    method public int getRebufferingMode();
-    method public int getRebufferingWatermarkHighKB();
-    method public int getRebufferingWatermarkHighMs();
-    method public int getRebufferingWatermarkLowKB();
-    method public int getRebufferingWatermarkLowMs();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final int BUFFERING_MODE_NONE = 0; // 0x0
-    field public static final int BUFFERING_MODE_SIZE_ONLY = 2; // 0x2
-    field public static final int BUFFERING_MODE_TIME_ONLY = 1; // 0x1
-    field public static final int BUFFERING_MODE_TIME_THEN_SIZE = 3; // 0x3
-    field public static final android.os.Parcelable.Creator<android.media.BufferingParams> CREATOR;
-  }
-
-  public static class BufferingParams.Builder {
-    ctor public BufferingParams.Builder();
-    ctor public BufferingParams.Builder(android.media.BufferingParams);
-    method public android.media.BufferingParams build();
-    method public android.media.BufferingParams.Builder setInitialBufferingMode(int);
-    method public android.media.BufferingParams.Builder setInitialBufferingWatermarkKB(int);
-    method public android.media.BufferingParams.Builder setInitialBufferingWatermarkMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingMode(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkHighKB(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkHighMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkLowKB(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarkLowMs(int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarksKB(int, int);
-    method public android.media.BufferingParams.Builder setRebufferingWatermarksMs(int, int);
-  }
-
   public class CamcorderProfile {
     method public static android.media.CamcorderProfile get(int);
     method public static android.media.CamcorderProfile get(int, int);
@@ -22931,9 +22897,7 @@
     method public android.media.VolumeShaper createVolumeShaper(android.media.VolumeShaper.Configuration);
     method public void deselectTrack(int) throws java.lang.IllegalStateException;
     method public int getAudioSessionId();
-    method public android.media.BufferingParams getBufferingParams();
     method public int getCurrentPosition();
-    method public android.media.BufferingParams getDefaultBufferingParams();
     method public android.media.MediaPlayer.DrmInfo getDrmInfo();
     method public java.lang.String getDrmPropertyString(java.lang.String) throws android.media.MediaPlayer.NoDrmSchemeException;
     method public int getDuration();
@@ -22964,7 +22928,6 @@
     method public void setAudioSessionId(int) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
     method public deprecated void setAudioStreamType(int);
     method public void setAuxEffectSendLevel(float);
-    method public void setBufferingParams(android.media.BufferingParams);
     method public void setDataSource(android.content.Context, android.net.Uri) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>, java.util.List<java.net.HttpCookie>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
     method public void setDataSource(android.content.Context, android.net.Uri, java.util.Map<java.lang.String, java.lang.String>) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException, java.lang.SecurityException;
@@ -23007,6 +22970,7 @@
     field public static final int MEDIA_ERROR_TIMED_OUT = -110; // 0xffffff92
     field public static final int MEDIA_ERROR_UNKNOWN = 1; // 0x1
     field public static final int MEDIA_ERROR_UNSUPPORTED = -1010; // 0xfffffc0e
+    field public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804; // 0x324
     field public static final int MEDIA_INFO_BAD_INTERLEAVING = 800; // 0x320
     field public static final int MEDIA_INFO_BUFFERING_END = 702; // 0x2be
     field public static final int MEDIA_INFO_BUFFERING_START = 701; // 0x2bd
@@ -23015,6 +22979,7 @@
     field public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902; // 0x386
     field public static final int MEDIA_INFO_UNKNOWN = 1; // 0x1
     field public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901; // 0x385
+    field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
     field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
     field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
     field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
@@ -37233,11 +37198,11 @@
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.service.autofill.SaveInfo> CREATOR;
     field public static final int SAVE_DATA_TYPE_ADDRESS = 2; // 0x2
-    field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3; // 0x3
-    field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5; // 0x5
+    field public static final int SAVE_DATA_TYPE_CREDIT_CARD = 4; // 0x4
+    field public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 16; // 0x10
     field public static final int SAVE_DATA_TYPE_GENERIC = 0; // 0x0
     field public static final int SAVE_DATA_TYPE_PASSWORD = 1; // 0x1
-    field public static final int SAVE_DATA_TYPE_USERNAME = 4; // 0x4
+    field public static final int SAVE_DATA_TYPE_USERNAME = 8; // 0x8
   }
 
   public static final class SaveInfo.Builder {
@@ -39729,6 +39694,7 @@
     field public static final java.lang.String KEY_GSM_ROAMING_NETWORKS_STRING_ARRAY = "gsm_roaming_networks_string_array";
     field public static final java.lang.String KEY_HAS_IN_CALL_NOISE_SUPPRESSION_BOOL = "has_in_call_noise_suppression_bool";
     field public static final java.lang.String KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL = "hide_carrier_network_settings_bool";
+    field public static final java.lang.String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
     field public static final java.lang.String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
     field public static final java.lang.String KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL = "hide_preferred_network_type_bool";
     field public static final java.lang.String KEY_HIDE_SIM_LOCK_SETTINGS_BOOL = "hide_sim_lock_settings_bool";
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 4004bd6..e288387 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1118,6 +1118,16 @@
     }
 
     /**
+     * Returns true if the system supports running activities on secondary displays.
+     * @hide
+     */
+    static public boolean supportsMultiDisplay() {
+        return !isLowRamDeviceStatic()
+                && Resources.getSystem().getBoolean(
+                    com.android.internal.R.bool.config_supportsMultiDisplay);
+    }
+
+    /**
      * Return the maximum number of actions that will be displayed in the picture-in-picture UI when
      * the user interacts with the activity currently in picture-in-picture mode.
      */
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 93204d1..23e54ba 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -284,8 +284,8 @@
 
     private int mVerifyState;
 
-    /** Whether or not the intent filter is visible to ephemeral apps. */
-    private boolean mVisibleToEphemeral;
+    /** Whether or not the intent filter is visible to instant apps. */
+    private boolean mVisibleToInstantApp;
     // These functions are the start of more optimized code for managing
     // the string sets...  not yet implemented.
 
@@ -452,6 +452,7 @@
         }
         mHasPartialTypes = o.mHasPartialTypes;
         mVerifyState = o.mVerifyState;
+        mVisibleToInstantApp = o.mVisibleToInstantApp;
     }
 
     /**
@@ -654,12 +655,12 @@
     }
 
     /** @hide */
-    public void setVisibleToEphemeral(boolean visibleToEmphemeral) {
-        mVisibleToEphemeral = visibleToEmphemeral;
+    public void setVisibleToInstantApp(boolean visibleToInstantApp) {
+        mVisibleToInstantApp = visibleToInstantApp;
     }
     /** @hide */
     public boolean isVisibleToInstantApp() {
-        return mVisibleToEphemeral;
+        return mVisibleToInstantApp;
     }
 
     /**
@@ -1858,6 +1859,7 @@
         dest.writeInt(mPriority);
         dest.writeInt(mHasPartialTypes ? 1 : 0);
         dest.writeInt(getAutoVerify() ? 1 : 0);
+        dest.writeInt(isVisibleToInstantApp() ? 1 : 0);
     }
 
     /**
@@ -1926,6 +1928,7 @@
         mPriority = source.readInt();
         mHasPartialTypes = source.readInt() > 0;
         setAutoVerify(source.readInt() > 0);
+        setVisibleToInstantApp(source.readInt() > 0);
     }
 
     private final boolean findMimeType(String type) {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 940447c..d44d0dc 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -4258,7 +4258,7 @@
                     a.intents.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -4291,7 +4291,7 @@
                     owner.preferredActivityFilters.add(intent);
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -4307,12 +4307,12 @@
                     owner.visibleToInstantApps = true;
                     // cycle through any filters already seen
                     for (int i = a.intents.size() - 1; i >= 0; --i) {
-                        a.intents.get(i).setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+                        a.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
                     }
                     if (owner.preferredActivityFilters != null) {
                         for (int i = owner.preferredActivityFilters.size() - 1; i >= 0; --i) {
                             owner.preferredActivityFilters.get(i)
-                                    .setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+                                    .setVisibleToInstantApp(true /*visibleToInstantApp*/);
                         }
                     }
                 }
@@ -4618,7 +4618,7 @@
                             + mArchiveSourcePath + " "
                             + parser.getPositionDescription());
                 } else {
-                    intent.setVisibleToEphemeral(
+                    intent.setVisibleToInstantApp(
                             visibleToEphemeral || isWebBrowsableIntent(intent));
                     a.intents.add(intent);
                 }
@@ -4821,7 +4821,7 @@
                 }
                 outInfo.intents.add(intent);
                 // adjust provider flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -4838,7 +4838,7 @@
                     owner.visibleToInstantApps = true;
                     // cycle through any filters already seen
                     for (int i = outInfo.intents.size() - 1; i >= 0; --i) {
-                        outInfo.intents.get(i).setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+                        outInfo.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
                     }
                 }
 
@@ -5126,7 +5126,7 @@
                     return null;
                 }
                 // adjust activity flags when we implicitly expose it via a browsable filter
-                intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+                intent.setVisibleToInstantApp(visibleToEphemeral || isWebBrowsableIntent(intent));
                 if (intent.isVisibleToInstantApp()) {
                     s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
                 }
@@ -5143,7 +5143,7 @@
                     owner.visibleToInstantApps = true;
                     // cycle through any filters already seen
                     for (int i = s.intents.size() - 1; i >= 0; --i) {
-                        s.intents.get(i).setVisibleToEphemeral(true /*visibleToEmphemeral*/);
+                        s.intents.get(i).setVisibleToInstantApp(true /*visibleToInstantApp*/);
                     }
                 }
             } else {
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index f75b7af..4ad0f08 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -25,6 +25,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.util.DebugUtils;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
@@ -111,52 +112,41 @@
      * Type used on when the service can save the contents of an activity, but cannot describe what
      * the content is for.
      */
-    public static final int SAVE_DATA_TYPE_GENERIC = 0;
+    public static final int SAVE_DATA_TYPE_GENERIC = 0x0;
 
     /**
      * Type used when the {@link FillResponse} represents user credentials that have a password.
      */
-    public static final int SAVE_DATA_TYPE_PASSWORD = 1;
+    public static final int SAVE_DATA_TYPE_PASSWORD = 0x01;
 
     /**
      * Type used on when the {@link FillResponse} represents a physical address (such as street,
      * city, state, etc).
      */
-    public static final int SAVE_DATA_TYPE_ADDRESS = 2;
+    public static final int SAVE_DATA_TYPE_ADDRESS = 0x02;
 
     /**
      * Type used when the {@link FillResponse} represents a credit card.
      */
-    public static final int SAVE_DATA_TYPE_CREDIT_CARD = 3;
+    public static final int SAVE_DATA_TYPE_CREDIT_CARD = 0x04;
 
     /**
      * Type used when the {@link FillResponse} represents just an username, without a password.
      */
-    public static final int SAVE_DATA_TYPE_USERNAME = 4;
+    public static final int SAVE_DATA_TYPE_USERNAME = 0x08;
 
     /**
      * Type used when the {@link FillResponse} represents just an email address, without a password.
      */
-    public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 5;
+    public static final int SAVE_DATA_TYPE_EMAIL_ADDRESS = 0x10;
 
-    private final @SaveDataType int mType;
+    private final int mType;
     private final CharSequence mNegativeActionTitle;
     private final IntentSender mNegativeActionListener;
     private final AutofillId[] mRequiredIds;
     private final AutofillId[] mOptionalIds;
     private final CharSequence mDescription;
 
-    /** @hide */
-    @IntDef({
-        SAVE_DATA_TYPE_GENERIC,
-        SAVE_DATA_TYPE_PASSWORD,
-        SAVE_DATA_TYPE_ADDRESS,
-        SAVE_DATA_TYPE_CREDIT_CARD
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SaveDataType {
-    }
-
     private SaveInfo(Builder builder) {
         mType = builder.mType;
         mNegativeActionTitle = builder.mNegativeActionTitle;
@@ -201,7 +191,7 @@
      */
     public static final class Builder {
 
-        private final @SaveDataType int mType;
+        private final int mType;
         private CharSequence mNegativeActionTitle;
         private IntentSender mNegativeActionListener;
         // TODO(b/33197203): make mRequiredIds final once addSavableIds() is gone
@@ -213,32 +203,24 @@
         /**
          * Creates a new builder.
          *
-         * @param type the type of information the associated {@link FillResponse} represents. Must
-         * be {@link SaveInfo#SAVE_DATA_TYPE_GENERIC}, {@link SaveInfo#SAVE_DATA_TYPE_PASSWORD},
-         * {@link SaveInfo#SAVE_DATA_TYPE_ADDRESS}, or {@link SaveInfo#SAVE_DATA_TYPE_CREDIT_CARD};
-         * otherwise it will assume {@link SaveInfo#SAVE_DATA_TYPE_GENERIC}.
+         * @param type the type of information the associated {@link FillResponse} represents, can
+         * be any combination of {@link SaveInfo#SAVE_DATA_TYPE_GENERIC},
+         * {@link SaveInfo#SAVE_DATA_TYPE_PASSWORD},
+         * {@link SaveInfo#SAVE_DATA_TYPE_ADDRESS}, {@link SaveInfo#SAVE_DATA_TYPE_CREDIT_CARD},
+         * {@link SaveInfo#SAVE_DATA_TYPE_USERNAME}, or
+         * {@link SaveInfo#SAVE_DATA_TYPE_EMAIL_ADDRESS}.
          * @param requiredIds ids of all required views that will trigger a save request.
          *
          * <p>See {@link SaveInfo} for more info.
          *
          * @throws IllegalArgumentException if {@code requiredIds} is {@code null} or empty.
          */
-        public Builder(@SaveDataType int type, @NonNull AutofillId[] requiredIds) {
+        public Builder(int type, @NonNull AutofillId[] requiredIds) {
             if (false) {// TODO(b/33197203): re-move when clients use it
             Preconditions.checkArgument(requiredIds != null && requiredIds.length > 0,
                     "must have at least one required id: " + Arrays.toString(requiredIds));
             }
-            switch (type) {
-                case SAVE_DATA_TYPE_PASSWORD:
-                case SAVE_DATA_TYPE_ADDRESS:
-                case SAVE_DATA_TYPE_CREDIT_CARD:
-                case SAVE_DATA_TYPE_USERNAME:
-                case SAVE_DATA_TYPE_EMAIL_ADDRESS:
-                    mType = type;
-                    break;
-                default:
-                    mType = SAVE_DATA_TYPE_GENERIC;
-            }
+            mType = type;
             mRequiredIds = requiredIds;
         }
 
@@ -248,7 +230,7 @@
          * // TODO(b/33197203): make sure is removed when clients migrated
          */
         @Deprecated
-        public Builder(@SaveDataType int type) {
+        public Builder(int type) {
             this(type, null);
         }
 
@@ -355,7 +337,8 @@
     public String toString() {
         if (!DEBUG) return super.toString();
 
-        return new StringBuilder("SaveInfo: [type=").append(mType)
+        return new StringBuilder("SaveInfo: [type=")
+                .append(DebugUtils.flagsToString(SaveInfo.class, "SAVE_DATA_TYPE_", mType))
                 .append(", requiredIds=").append(Arrays.toString(mRequiredIds))
                 .append(", optionalIds=").append(Arrays.toString(mOptionalIds))
                 .append(", description=").append(mDescription)
diff --git a/core/java/android/text/method/DateTimeKeyListener.java b/core/java/android/text/method/DateTimeKeyListener.java
index 551db55..1593db5 100644
--- a/core/java/android/text/method/DateTimeKeyListener.java
+++ b/core/java/android/text/method/DateTimeKeyListener.java
@@ -68,7 +68,7 @@
         final LinkedHashSet<Character> chars = new LinkedHashSet<>();
         // First add the digits. Then, add all the character in AM and PM markers. Finally, add all
         // the non-pattern characters seen in the patterns for "yMdhms" and "yMdHms".
-        boolean success = NumberKeyListener.addDigits(chars, locale)
+        final boolean success = NumberKeyListener.addDigits(chars, locale)
                           && NumberKeyListener.addAmPmChars(chars, locale)
                           && NumberKeyListener.addFormatCharsFromSkeleton(
                               chars, locale, SKELETON_12HOUR, SYMBOLS_TO_IGNORE)
@@ -76,7 +76,14 @@
                               chars, locale, SKELETON_24HOUR, SYMBOLS_TO_IGNORE);
         if (success) {
             mCharacters = NumberKeyListener.collectionToArray(chars);
-            mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+            if (locale != null && "en".equals(locale.getLanguage())) {
+                // For backward compatibility reasons, assume we don't need advanced input for
+                // English locales, although English locales literally also need a comma and perhaps
+                // uppercase letters for AM and PM.
+                mNeedsAdvancedInput = false;
+            } else {
+                mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+            }
         } else {
             mCharacters = CHARACTERS;
             mNeedsAdvancedInput = false;
diff --git a/core/java/android/text/method/TimeKeyListener.java b/core/java/android/text/method/TimeKeyListener.java
index 5b1db11..f11f400 100644
--- a/core/java/android/text/method/TimeKeyListener.java
+++ b/core/java/android/text/method/TimeKeyListener.java
@@ -68,7 +68,7 @@
         final LinkedHashSet<Character> chars = new LinkedHashSet<>();
         // First add the digits. Then, add all the character in AM and PM markers. Finally, add all
         // the non-pattern characters seen in the patterns for "hms" and "Hms".
-        boolean success = NumberKeyListener.addDigits(chars, locale)
+        final boolean success = NumberKeyListener.addDigits(chars, locale)
                           && NumberKeyListener.addAmPmChars(chars, locale)
                           && NumberKeyListener.addFormatCharsFromSkeleton(
                               chars, locale, SKELETON_12HOUR, SYMBOLS_TO_IGNORE)
@@ -76,7 +76,14 @@
                               chars, locale, SKELETON_24HOUR, SYMBOLS_TO_IGNORE);
         if (success) {
             mCharacters = NumberKeyListener.collectionToArray(chars);
-            mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+            if (locale != null && "en".equals(locale.getLanguage())) {
+                // For backward compatibility reasons, assume we don't need advanced input for
+                // English locales, although English locales may need uppercase letters for
+                // AM and PM.
+                mNeedsAdvancedInput = false;
+            } else {
+                mNeedsAdvancedInput = !ArrayUtils.containsAll(CHARACTERS, mCharacters);
+            }
         } else {
             mCharacters = CHARACTERS;
             mNeedsAdvancedInput = false;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 076b33c..31911cb 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -683,7 +683,8 @@
                     mTranslator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
-                if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
+                if (mSurfaceControl != null
+                        && (!isHardwareAccelerated() || !mRtHandlingPositionUpdates)) {
                     try {
                         if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
                                 "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 58ef0af..4a7b16e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1249,6 +1249,13 @@
         mIsAmbientMode = ambient;
     }
 
+    void setWindowVisibility(int visibility) {
+        if (visibility != mAttachInfo.mWindowVisibility) {
+            mAttachInfo.mWindowVisibility = visibility;
+            mView.dispatchWindowVisibilityChanged(visibility);
+        }
+    }
+
     void setWindowStopped(boolean stopped) {
         if (mStopped != stopped) {
             mStopped = stopped;
@@ -1263,6 +1270,7 @@
                 if (renderer != null) {
                     renderer.destroyHardwareResources(mView);
                 }
+                mView.dispatchWindowVisibilityChanged(View.GONE);
             }
         }
     }
@@ -1297,7 +1305,8 @@
     }
 
     int getHostVisibility() {
-        return (mAppVisible || mForceDecorViewVisibility) ? mView.getVisibility() : View.GONE;
+        return (mAppVisible || mForceDecorViewVisibility) && !mStopped
+            ? mView.getVisibility() : View.GONE;
     }
 
     /**
@@ -1654,8 +1663,8 @@
         }
 
         if (viewVisibilityChanged) {
-            mAttachInfo.mWindowVisibility = viewVisibility;
-            host.dispatchWindowVisibilityChanged(viewVisibility);
+            setWindowVisibility(viewVisibility);
+
             if (viewUserVisibilityChanged) {
                 host.dispatchVisibilityAggregated(viewVisibility == View.VISIBLE);
             }
diff --git a/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java b/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java
index e40090f..924b3f7 100644
--- a/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java
+++ b/core/java/com/android/internal/view/SurfaceFlingerVsyncChoreographer.java
@@ -31,7 +31,7 @@
     private static final long ONE_S_IN_NS = ONE_MS_IN_NS * 1000;
 
     private final Handler mHandler;
-    private final Choreographer mChoreographer = Choreographer.getInstance();
+    private final Choreographer mChoreographer;
 
     /**
      * The offset between vsync-app and vsync-surfaceflinger. See
@@ -39,8 +39,10 @@
      */
     private long mSurfaceFlingerOffsetMs;
 
-    public SurfaceFlingerVsyncChoreographer(Handler handler, Display display) {
+    public SurfaceFlingerVsyncChoreographer(Handler handler, Display display,
+            Choreographer choreographer) {
         mHandler = handler;
+        mChoreographer = choreographer;
         mSurfaceFlingerOffsetMs = calculateAppSurfaceFlingerVsyncOffsetMs(display);
     }
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ae28797..75de4da 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4594,6 +4594,14 @@
     <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
          by an autofill service, and the service does knows what the activity represents (for example, credit card info) [CHAR LIMIT=NONE] -->
     <string name="autofill_save_title_with_type">Save <xliff:g id="type" example="Credit Card">%1$s</xliff:g> to <xliff:g id="label" example="MyPass">%2$s</xliff:g>?</string>
+    <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
+         by an autofill service, and the service does knows what the activity represents, and it represents 2 types of
+         data (for example, password and credit card info) [CHAR LIMIT=NONE] -->
+    <string name="autofill_save_title_with_2types">Save <xliff:g id="type" example="Password">%1$s</xliff:g>, <xliff:g id="type" example="Credit Card">%2$s</xliff:g> to <xliff:g id="label" example="MyPass">%3$s</xliff:g>?</string>
+    <!-- Title for the autofill save dialog shown when the the contents of the activity can be saved
+         by an autofill service, and the service does knows what the activity represents, and it represents 3 types of
+         data (for example, username, password and credit card info) [CHAR LIMIT=NONE] -->
+    <string name="autofill_save_title_with_3types">Save <xliff:g id="type" example="Username">%1$s</xliff:g>, <xliff:g id="type" example="Password">%2$s</xliff:g>, <xliff:g id="type" example="Credit Card">%3$s</xliff:g> to <xliff:g id="label" example="MyPass">%4$s</xliff:g>?</string>
     <!-- Label for the autofill save button [CHAR LIMIT=NONE] -->
     <string name="autofill_save_yes">Save</string>
     <!-- Label for the autofill cancel button [CHAR LIMIT=NONE] -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 89c3943..7cb9ba8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2881,6 +2881,8 @@
   <java-symbol type="string" name="autofill_picker_accessibility_title " />
   <java-symbol type="string" name="autofill_save_title" />
   <java-symbol type="string" name="autofill_save_title_with_type" />
+  <java-symbol type="string" name="autofill_save_title_with_2types" />
+  <java-symbol type="string" name="autofill_save_title_with_3types" />
   <java-symbol type="string" name="autofill_save_yes" />
   <java-symbol type="string" name="autofill_save_no" />
   <java-symbol type="string" name="autofill_save_type_password" />
diff --git a/media/java/android/media/BufferingParams.java b/media/java/android/media/BufferingParams.java
index fdcd6ba..681271b 100644
--- a/media/java/android/media/BufferingParams.java
+++ b/media/java/android/media/BufferingParams.java
@@ -63,6 +63,7 @@
  * </ul>
  * </ul>
  * <p>Users should use {@link Builder} to change {@link BufferingParams}.
+ * @hide
  */
 public final class BufferingParams implements Parcelable {
     /**
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 1ee05b8..71a968b 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -46,7 +46,6 @@
 import android.widget.VideoView;
 import android.graphics.SurfaceTexture;
 import android.media.AudioManager;
-import android.media.BufferingParams;
 import android.media.MediaDrm;
 import android.media.MediaFormat;
 import android.media.MediaMetricsSet;
@@ -493,11 +492,6 @@
  *     <td>{} </p></td>
  *     <td>This method can be called in any state and calling it does not change
  *         the object state. </p></td></tr>
- * <tr><td>setBufferingParams</p></td>
- *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}</p></td>
- *     <td>{Idle} </p></td>
- *     <td>This method does not change the object state.
- *         </p></td></tr>
  * <tr><td>setPlaybackParams</p></td>
  *     <td>{Initialized, Prepared, Started, Paused, PlaybackCompleted, Error}</p></td>
  *     <td>{Idle, Stopped} </p></td>
@@ -1529,6 +1523,7 @@
      * @return the default buffering management params supported by the source component.
      * @throws IllegalStateException if the internal player engine has not been
      * initialized, or {@code setDataSource} has not been called.
+     * @hide
      */
     @NonNull
     public native BufferingParams getDefaultBufferingParams();
@@ -1540,6 +1535,7 @@
      * @return the current buffering management params used by the source component.
      * @throws IllegalStateException if the internal player engine has not been
      * initialized, or {@code setDataSource} has not been called.
+     * @hide
      */
     @NonNull
     public native BufferingParams getBufferingParams();
@@ -1557,6 +1553,7 @@
      * @throws IllegalStateException if the internal player engine has not been
      * initialized or has been released, or {@code setDataSource} has not been called.
      * @throws IllegalArgumentException if params is invalid or not supported.
+     * @hide
      */
     public native void setBufferingParams(@NonNull BufferingParams params);
 
@@ -3825,6 +3822,18 @@
      */
     public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
 
+    /** Informs that audio is not playing. Note that playback of the video
+     * is not interrupted.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804;
+
+    /** Informs that video is not playing. Note that playback of the audio
+     * is not interrupted.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805;
+
     /** Failed to handle timed text track properly.
      * @see android.media.MediaPlayer.OnInfoListener
      *
diff --git a/packages/PrintRecommendationService/res/values/strings.xml b/packages/PrintRecommendationService/res/values/strings.xml
index b6c45b7..2bab1b6 100644
--- a/packages/PrintRecommendationService/res/values/strings.xml
+++ b/packages/PrintRecommendationService/res/values/strings.xml
@@ -18,6 +18,7 @@
 -->
 
 <resources>
+    <string name="plugin_vendor_google_cloud_print">Cloud Print</string>
     <string name="plugin_vendor_hp">HP</string>
     <string name="plugin_vendor_lexmark">Lexmark</string>
     <string name="plugin_vendor_brother">Brother</string>
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
index e18ee90..128ed50 100644
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
@@ -22,6 +22,7 @@
 import android.printservice.recommendation.RecommendationService;
 import android.util.Log;
 
+import com.android.printservice.recommendation.plugin.google.CloudPrintPlugin;
 import com.android.printservice.recommendation.plugin.hp.HPRecommendationPlugin;
 import com.android.printservice.recommendation.plugin.mdnsFilter.MDNSFilterPlugin;
 import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
@@ -65,6 +66,14 @@
         }
 
         try {
+            mPlugins.add(new RemotePrintServicePlugin(new CloudPrintPlugin(this), this,
+                    true));
+        } catch (Exception e) {
+            Log.e(LOG_TAG, "Could not initiate "
+                            + getString(R.string.plugin_vendor_google_cloud_print) + " plugin", e);
+        }
+
+        try {
             mPlugins.add(new RemotePrintServicePlugin(new HPRecommendationPlugin(this), this,
                     false));
         } catch (Exception e) {
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/google/CloudPrintPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/google/CloudPrintPlugin.java
new file mode 100644
index 0000000..05b0c86
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/google/CloudPrintPlugin.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.printservice.recommendation.plugin.google;
+
+import static com.android.printservice.recommendation.util.MDNSUtils.ATTRIBUTE_TY;
+
+import android.annotation.NonNull;
+import android.annotation.StringRes;
+import android.content.Context;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.printservice.recommendation.PrintServicePlugin;
+import com.android.printservice.recommendation.R;
+import com.android.printservice.recommendation.util.MDNSFilteredDiscovery;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Plugin detecting <a href="https://developers.google.com/cloud-print/docs/privet">Google Cloud
+ * Print</a> printers.
+ */
+public class CloudPrintPlugin implements PrintServicePlugin {
+    private static final String LOG_TAG = CloudPrintPlugin.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private static final String ATTRIBUTE_TXTVERS = "txtvers";
+    private static final String ATTRIBUTE_URL = "url";
+    private static final String ATTRIBUTE_TYPE = "type";
+    private static final String ATTRIBUTE_ID = "id";
+    private static final String ATTRIBUTE_CS = "cs";
+
+    private static final String TYPE = "printer";
+
+    private static final String PRIVET_SERVICE = "_privet._tcp";
+
+    /** The required mDNS service types */
+    private static final Set<String> PRINTER_SERVICE_TYPE = new HashSet<String>() {{
+        // Not checking _printer_._sub
+        add(PRIVET_SERVICE);
+    }};
+
+    /** All possible connection states */
+    private static final Set<String> POSSIBLE_CONNECTION_STATES = new HashSet<String>() {{
+        add("online");
+        add("offline");
+        add("connecting");
+        add("not-configured");
+    }};
+
+    private static final byte SUPPORTED_TXTVERS = '1';
+
+    /** The mDNS filtered discovery */
+    private final MDNSFilteredDiscovery mMDNSFilteredDiscovery;
+
+    /**
+     * Create a plugin detecting Google Cloud Print printers.
+     *
+     * @param context The context the plugin runs in
+     */
+    public CloudPrintPlugin(@NonNull Context context) {
+        mMDNSFilteredDiscovery = new MDNSFilteredDiscovery(context, PRINTER_SERVICE_TYPE,
+                nsdServiceInfo -> {
+                    // The attributes are case insensitive. For faster searching create a clone of
+                    // the map with the attribute-keys all in lower case.
+                    ArrayMap<String, byte[]> caseInsensitiveAttributes =
+                            new ArrayMap<>(nsdServiceInfo.getAttributes().size());
+                    for (Map.Entry<String, byte[]> entry : nsdServiceInfo.getAttributes()
+                            .entrySet()) {
+                        caseInsensitiveAttributes.put(entry.getKey().toLowerCase(),
+                                entry.getValue());
+                    }
+
+                    if (DEBUG) {
+                        Log.i(LOG_TAG, nsdServiceInfo.getServiceName() + ":");
+                        Log.i(LOG_TAG, "type:  " + nsdServiceInfo.getServiceType());
+                        Log.i(LOG_TAG, "host:  " + nsdServiceInfo.getHost());
+                        for (Map.Entry<String, byte[]> entry : caseInsensitiveAttributes.entrySet()) {
+                            if (entry.getValue() == null) {
+                                Log.i(LOG_TAG, entry.getKey() + "= null");
+                            } else {
+                                Log.i(LOG_TAG, entry.getKey() + "=" + new String(entry.getValue(),
+                                        StandardCharsets.UTF_8));
+                            }
+                        }
+                    }
+
+                    byte[] txtvers = caseInsensitiveAttributes.get(ATTRIBUTE_TXTVERS);
+                    if (txtvers == null || txtvers.length != 1 || txtvers[0] != SUPPORTED_TXTVERS) {
+                        // The spec requires this to be the first attribute, but at this time we
+                        // lost the order of the attributes
+                        return false;
+                    }
+
+                    if (caseInsensitiveAttributes.get(ATTRIBUTE_TY) == null) {
+                        return false;
+                    }
+
+                    byte[] url = caseInsensitiveAttributes.get(ATTRIBUTE_URL);
+                    if (url == null || url.length == 0) {
+                        return false;
+                    }
+
+                    byte[] type = caseInsensitiveAttributes.get(ATTRIBUTE_TYPE);
+                    if (type == null || !TYPE.equals(
+                            new String(type, StandardCharsets.UTF_8).toLowerCase())) {
+                        return false;
+                    }
+
+                    if (caseInsensitiveAttributes.get(ATTRIBUTE_ID) == null) {
+                        return false;
+                    }
+
+                    byte[] cs = caseInsensitiveAttributes.get(ATTRIBUTE_CS);
+                    if (cs == null || !POSSIBLE_CONNECTION_STATES.contains(
+                            new String(cs, StandardCharsets.UTF_8).toLowerCase())) {
+                        return false;
+                    }
+
+                    InetAddress address = nsdServiceInfo.getHost();
+                    if (!(address instanceof Inet4Address)) {
+                        // Not checking for link local address
+                        return false;
+                    }
+
+                    return true;
+                });
+    }
+
+    @Override
+    @NonNull public CharSequence getPackageName() {
+        return "com.google.android.apps.cloudprint";
+    }
+
+    @Override
+    public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception {
+        mMDNSFilteredDiscovery.start(callback);
+    }
+
+    @Override
+    @StringRes public int getName() {
+        return R.string.plugin_vendor_google_cloud_print;
+    }
+
+    @Override
+    public void stop() throws Exception {
+        mMDNSFilteredDiscovery.stop();
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
index 0ee3e19..c48ecdb 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java
@@ -33,6 +33,7 @@
 import android.os.Handler;
 import android.os.Message;
 import android.util.AttributeSet;
+import android.view.Choreographer;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.GestureDetector;
@@ -312,7 +313,8 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         EventBus.getDefault().register(this);
-        mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, getDisplay());
+        mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, getDisplay(),
+                Choreographer.getInstance());
     }
 
     @Override
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index b59e00d..579c54c 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3901,6 +3901,11 @@
     // FIELD: Action for a nav button event
     FIELD_NAV_ACTION = 933;
 
+    // OPEN: Settings > Security > Nexus Imprint > [Fingerprint] > Delete
+    // CATEGORY: SETTINGS
+    // OS: O
+    FINGERPRINT_REMOVE_SIDECAR = 934;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 9092bdb..c3cbf18 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -398,8 +398,7 @@
             return true;
         }
 
-        // TODO(b/33197203 , b/35707731): must iterate over all responses
-        final FillResponse response = mResponses.get(0);
+        final FillResponse response = mResponses.get(mResponses.size() - 1);
 
         final SaveInfo saveInfo = response.getSaveInfo();
         if (DEBUG) {
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index d35cc95..f94d456 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -24,7 +24,7 @@
 import android.content.IntentSender;
 import android.os.Handler;
 import android.service.autofill.SaveInfo;
-import android.text.format.DateUtils;
+import android.util.ArraySet;
 import android.util.Slog;
 import android.view.Gravity;
 import android.view.Window;
@@ -105,31 +105,44 @@
         final View view = inflater.inflate(R.layout.autofill_save, null);
 
         final TextView titleView = (TextView) view.findViewById(R.id.autofill_save_title);
-        final String type;
 
-        switch(info.getType()) {
-            case SaveInfo.SAVE_DATA_TYPE_PASSWORD:
-                type = context.getString(R.string.autofill_save_type_password);
-                break;
-            case SaveInfo.SAVE_DATA_TYPE_ADDRESS:
-                type = context.getString(R.string.autofill_save_type_address);
-                break;
-            case SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD:
-                type = context.getString(R.string.autofill_save_type_credit_card);
-                break;
-            case SaveInfo.SAVE_DATA_TYPE_USERNAME:
-                type = context.getString(R.string.autofill_save_type_username);
-                break;
-            case SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS:
-                type = context.getString(R.string.autofill_save_type_email_address);
-                break;
-            default:
-                type = null;
+        final ArraySet<String> types = new ArraySet<>(3);
+        final int type = info.getType();
+
+        if ((type & SaveInfo.SAVE_DATA_TYPE_PASSWORD) != 0) {
+            types.add(context.getString(R.string.autofill_save_type_password));
+        }
+        if ((type & SaveInfo.SAVE_DATA_TYPE_ADDRESS) != 0) {
+            types.add(context.getString(R.string.autofill_save_type_address));
+        }
+        if ((type & SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD) != 0) {
+            types.add(context.getString(R.string.autofill_save_type_credit_card));
+        }
+        if ((type & SaveInfo.SAVE_DATA_TYPE_USERNAME) != 0) {
+            types.add(context.getString(R.string.autofill_save_type_username));
+        }
+        if ((type & SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS) != 0) {
+            types.add(context.getString(R.string.autofill_save_type_email_address));
         }
 
-        final String title = (type == null)
-                ? context.getString(R.string.autofill_save_title, providerLabel)
-                : context.getString(R.string.autofill_save_title_with_type, type, providerLabel);
+        final String title;
+        switch (types.size()) {
+            case 1:
+                title = context.getString(R.string.autofill_save_title_with_type,
+                        types.valueAt(0), providerLabel);
+                break;
+            case 2:
+                title = context.getString(R.string.autofill_save_title_with_2types,
+                        types.valueAt(0), types.valueAt(1), providerLabel);
+                break;
+            case 3:
+                title = context.getString(R.string.autofill_save_title_with_3types,
+                        types.valueAt(0), types.valueAt(1), types.valueAt(2), providerLabel);
+                break;
+            default:
+                // Use generic if more than 3 or invalid type (size 0).
+                title = context.getString(R.string.autofill_save_title, providerLabel);
+        }
 
         titleView.setText(title);
         final CharSequence subTitle = info.getDescription();
@@ -139,6 +152,10 @@
             subTitleView.setVisibility(View.VISIBLE);
         }
 
+        if (DEBUG) {
+            Slog.d(TAG, "Title: " + title + " SubTitle: " + subTitle);
+        }
+
         final TextView noButton = view.findViewById(R.id.autofill_save_no);
         if (info.getNegativeActionTitle() != null) {
             noButton.setText(info.getNegativeActionTitle());
diff --git a/services/core/java/com/android/server/AnimationThread.java b/services/core/java/com/android/server/AnimationThread.java
new file mode 100644
index 0000000..08392b0
--- /dev/null
+++ b/services/core/java/com/android/server/AnimationThread.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server;
+
+import static android.os.Process.THREAD_PRIORITY_DISPLAY;
+
+import android.os.Handler;
+import android.os.Trace;
+
+/**
+ * Thread for handling all window animations, or anything that's directly impacting animations like
+ * starting windows or traversals.
+ */
+public final class AnimationThread extends ServiceThread {
+    private static AnimationThread sInstance;
+    private static Handler sHandler;
+
+    private AnimationThread() {
+        super("android.anim", THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new AnimationThread();
+            sInstance.start();
+            sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_WINDOW_MANAGER);
+            sHandler = new Handler(sInstance.getLooper());
+        }
+    }
+
+    public static AnimationThread get() {
+        synchronized (AnimationThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+
+    public static Handler getHandler() {
+        synchronized (AnimationThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/DisplayThread.java b/services/core/java/com/android/server/DisplayThread.java
index 9ef0259..cad2a61 100644
--- a/services/core/java/com/android/server/DisplayThread.java
+++ b/services/core/java/com/android/server/DisplayThread.java
@@ -17,6 +17,7 @@
 package com.android.server;
 
 import android.os.Handler;
+import android.os.Process;
 import android.os.Trace;
 
 /**
@@ -30,7 +31,9 @@
     private static Handler sHandler;
 
     private DisplayThread() {
-        super("android.display", android.os.Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
+        // DisplayThread runs important stuff, but these are not as important as things running in
+        // AnimationThread. Thus, set the priority to one lower.
+        super("android.display", Process.THREAD_PRIORITY_DISPLAY + 1, false /*allowIo*/);
     }
 
     private static void ensureThreadLocked() {
diff --git a/services/core/java/com/android/server/ThreadPriorityBooster.java b/services/core/java/com/android/server/ThreadPriorityBooster.java
index 17965d0..31726ad 100644
--- a/services/core/java/com/android/server/ThreadPriorityBooster.java
+++ b/services/core/java/com/android/server/ThreadPriorityBooster.java
@@ -41,8 +41,8 @@
         final int tid = Process.myTid();
         final int prevPriority = Process.getThreadPriority(tid);
         PriorityState state = mThreadState.get();
+        state.prevPriority = prevPriority;
         if (state.regionCounter == 0 && prevPriority > mBoostToPriority) {
-            state.prevPriority = prevPriority;
             Process.setThreadPriority(tid, mBoostToPriority);
         }
         state.regionCounter++;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index be5ff80..f4e3b31 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2385,16 +2385,19 @@
                 idleUids();
             } break;
             case VR_MODE_CHANGE_MSG: {
-                if (mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
-                    synchronized (ActivityManagerService.this) {
-                        if (mVrController.shouldDisableNonVrUiLocked()) {
-                            // If we are in a VR mode where Picture-in-Picture mode is unsupported,
-                            // then remove the pinned stack.
-                            final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
-                                    PINNED_STACK_ID);
-                            if (pinnedStack != null) {
-                                mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
-                            }
+                if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
+                    return;
+                }
+                synchronized (ActivityManagerService.this) {
+                    final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
+                    mWindowManager.disableNonVrUi(disableNonVrUi);
+                    if (disableNonVrUi) {
+                        // If we are in a VR mode where Picture-in-Picture mode is unsupported,
+                        // then remove the pinned stack.
+                        final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
+                                PINNED_STACK_ID);
+                        if (pinnedStack != null) {
+                            mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
                         }
                     }
                 }
@@ -13763,6 +13766,7 @@
         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
         final boolean supportsSplitScreenMultiWindow =
                 ActivityManager.supportsSplitScreenMultiWindow();
+        final boolean supportsMultiDisplay = ActivityManager.supportsMultiDisplay();
         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
         final boolean alwaysFinishActivities =
@@ -13800,6 +13804,7 @@
             }
             mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
             mSupportsPictureInPicture = supportsPictureInPicture;
+            mSupportsMultiDisplay = supportsMultiDisplay;
             mWindowManager.setForceResizableTasks(mForceResizableActivities);
             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
             // This happens before any activities are started, so we can change global configuration
@@ -13828,8 +13833,6 @@
                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
             }
             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
-            mSupportsMultiDisplay = res.getBoolean(
-                    com.android.internal.R.bool.config_supportsMultiDisplay);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 6011418..2b3a19a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -2386,7 +2386,7 @@
         if (res == null) {
             return -1;
         }
-        pw.println(res.getBoolean(com.android.internal.R.bool.config_supportsMultiWindow));
+        pw.println(ActivityManager.supportsMultiWindow());
         return 0;
     }
 
@@ -2395,8 +2395,7 @@
         if (res == null) {
             return -1;
         }
-        pw.println(
-                res.getBoolean(com.android.internal.R.bool.config_supportsSplitScreenMultiWindow));
+        pw.println(ActivityManager.supportsSplitScreenMultiWindow());
         return 0;
     }
 
@@ -2405,7 +2404,7 @@
         if (res == null) {
             return -1;
         }
-        pw.println(res.getBoolean(com.android.internal.R.bool.config_supportsMultiDisplay));
+        pw.println(ActivityManager.supportsMultiDisplay());
         return 0;
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 5edfb06..2881787 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -102,7 +102,7 @@
         mLastLogTimeSecs = now;
 
         ActivityStack stack = mSupervisor.getStack(DOCKED_STACK_ID);
-        if (stack != null && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) {
+        if (stack != null && stack.shouldBeVisible(null) != STACK_INVISIBLE) {
             mWindowState = WINDOW_STATE_SIDE_BY_SIDE;
             return;
         }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ceddcac..51011b5 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -312,6 +312,11 @@
      */
     boolean mConfigWillChange;
 
+    /**
+     * When set, will force the stack to report as invisible.
+     */
+    boolean mForceHidden = false;
+
     // Whether or not this stack covers the entire screen; by default stacks are fullscreen
     boolean mFullscreen = true;
     // Current bounds of the stack or null if fullscreen.
@@ -1559,13 +1564,20 @@
         return true;
     }
 
+    /** Returns true if the stack is currently considered visible. */
+    boolean isVisible() {
+        return mWindowContainerController != null && mWindowContainerController.isVisible()
+                && !mForceHidden;
+    }
+
     /**
-     * Returns stack's visibility: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE} or
-     * {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
+     * Returns what the stack visibility should be: {@link #STACK_INVISIBLE}, {@link #STACK_VISIBLE}
+     * or {@link #STACK_VISIBLE_ACTIVITY_BEHIND}.
+     *
      * @param starting The currently starting activity or null if there is none.
      */
-    int getStackVisibilityLocked(ActivityRecord starting) {
-        if (!isAttached()) {
+    int shouldBeVisible(ActivityRecord starting) {
+        if (!isAttached() || mForceHidden) {
             return STACK_INVISIBLE;
         }
 
@@ -1714,7 +1726,7 @@
             // If the top activity is not fullscreen, then we need to
             // make sure any activities under it are now visible.
             boolean aboveTop = top != null;
-            final int stackVisibility = getStackVisibilityLocked(starting);
+            final int stackVisibility = shouldBeVisible(starting);
             final boolean stackInvisible = stackVisibility != STACK_VISIBLE;
             final boolean stackVisibleBehind = stackVisibility == STACK_VISIBLE_ACTIVITY_BEHIND;
             boolean behindFullscreenActivity = stackInvisible;
@@ -2096,7 +2108,7 @@
         // activities as we need to display their starting window until they are done initializing.
         boolean behindFullscreenActivity = false;
 
-        if (getStackVisibilityLocked(null) == STACK_INVISIBLE) {
+        if (shouldBeVisible(null) == STACK_INVISIBLE) {
             // The stack is not visible, so no activity in it should be displaying a starting
             // window. Mark all activities below top and behind fullscreen.
             aboveTop = false;
@@ -3214,8 +3226,25 @@
         r.addResultLocked(null, resultWho, requestCode, resultCode, data);
     }
 
+    /** Returns true if the task is one of the task finishing on-top of the top running task. */
+    boolean isATopFinishingTask(TaskRecord task) {
+        for (int i = mTaskHistory.size() - 1; i >= 0; --i) {
+            final TaskRecord current = mTaskHistory.get(i);
+            final ActivityRecord r = current.topRunningActivityLocked();
+            if (r != null) {
+                // We got a top running activity, so there isn't a top finishing task...
+                return false;
+            }
+            if (current == task) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void adjustFocusedActivityStackLocked(ActivityRecord r, String reason) {
-        if (!mStackSupervisor.isFocusedStack(this) || mResumedActivity != r) {
+        if (!mStackSupervisor.isFocusedStack(this) ||
+                ((mResumedActivity != r) && (mResumedActivity != null))) {
             return;
         }
 
@@ -3230,8 +3259,8 @@
                 final TaskRecord task = r.getTask();
                 final boolean isAssistantOrOverAssistant = task.getStack().isAssistantStack() ||
                         task.isOverAssistantStack();
-                if (r.frontOfTask && task == topTask() &&
-                        (task.isOverHomeStack() || isAssistantOrOverAssistant)) {
+                if (r.frontOfTask && isATopFinishingTask(task)
+                        && (task.isOverHomeStack() || isAssistantOrOverAssistant)) {
                     // For non-fullscreen or assistant stack, we want to move the focus to the next
                     // visible stack to prevent the home screen from moving to the top and obscuring
                     // other visible stacks.
@@ -4181,7 +4210,7 @@
         if (hasVisibleBehindActivity() &&
                 !mHandler.hasMessages(RELEASE_BACKGROUND_RESOURCES_TIMEOUT_MSG)) {
             if (r == topRunningActivityLocked()
-                    && getStackVisibilityLocked(null) == STACK_VISIBLE) {
+                    && shouldBeVisible(null) == STACK_VISIBLE) {
                 // Don't release the top activity if it has requested to run behind the next
                 // activity and the stack is currently visible.
                 return;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index baa7cf4..c9bb9e5 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -42,6 +42,7 @@
 import static android.view.Display.INVALID_DISPLAY;
 import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
 
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONTAINERS;
 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
@@ -167,7 +168,6 @@
 
 import com.android.internal.content.ReferrerIntent;
 import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.os.TransferPipe;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.ArrayUtils;
@@ -2204,7 +2204,7 @@
             for (int j = stacks.size() - 1; j >= 0; --j) {
                 final ActivityStack stack = stacks.get(j);
                 if (stack != currentFocus && stack.isFocusable()
-                        && stack.getStackVisibilityLocked(null) != STACK_INVISIBLE) {
+                        && stack.shouldBeVisible(null) != STACK_INVISIBLE) {
                     return stack;
                 }
             }
@@ -2343,7 +2343,6 @@
         mWindowManager.deferSurfaceLayout();
         try {
             if (fromStackId == DOCKED_STACK_ID) {
-
                 // We are moving all tasks from the docked stack to the fullscreen stack,
                 // which is dismissing the docked stack, so resize all other stacks to
                 // fullscreen here already so we don't end up with resize trashing.
@@ -2362,13 +2361,19 @@
                 // resize when we remove task from it below and it is detached from the
                 // display because it no longer contains any tasks.
                 mAllowDockedStackResize = false;
+            } else if (fromStackId == PINNED_STACK_ID) {
+                if (onTop) {
+                    // Log if we are expanding the PiP to fullscreen
+                    MetricsLogger.action(mService.mContext,
+                            ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN);
+                }
             }
             ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
             final boolean isFullscreenStackVisible = fullscreenStack != null &&
-                    fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
+                    fullscreenStack.shouldBeVisible(null) == STACK_VISIBLE;
             // If we are moving from the pinned stack, then the animation takes care of updating
             // the picture-in-picture mode.
-            final boolean schedulePictureInPictureModeChange = (fromStackId != PINNED_STACK_ID);
+            final boolean schedulePictureInPictureModeChange = (fromStackId == PINNED_STACK_ID);
             final ArrayList<TaskRecord> tasks = stack.getAllTasks();
             final int size = tasks.size();
             if (onTop) {
@@ -2381,8 +2386,6 @@
                         // pinned stack is recreated. See moveActivityToPinnedStackLocked().
                         task.setTaskToReturnTo(isFullscreenStackVisible && onTop ?
                                 APPLICATION_ACTIVITY_TYPE : HOME_ACTIVITY_TYPE);
-                        MetricsLogger.action(mService.mContext,
-                                MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN);
                     }
                     // Defer resume until all the tasks have been moved to the fullscreen stack
                     task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
@@ -2537,27 +2540,24 @@
 
         final ArrayList<TaskRecord> tasks = stack.getAllTasks();
         if (stack.getStackId() == PINNED_STACK_ID) {
-            final ActivityStack fullscreenStack = getStack(FULLSCREEN_WORKSPACE_STACK_ID);
-            if (fullscreenStack != null) {
-                final boolean isFullscreenStackVisible =
-                        fullscreenStack.getStackVisibilityLocked(null) == STACK_VISIBLE;
-                for (int i = 0; i < tasks.size(); i++) {
-                    // Insert the task either at the top of the fullscreen stack if it is hidden,
-                    // or to the bottom if it is currently visible
-                    final int insertPosition = isFullscreenStackVisible ? 0
-                            : fullscreenStack.getChildCount();
-                    final TaskRecord task = tasks.get(i);
-                    // Defer resume until we remove all the tasks
-                    task.reparent(FULLSCREEN_WORKSPACE_STACK_ID, insertPosition,
-                            REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME, "removeStack");
-                }
-                ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
-                resumeFocusedStackTopActivityLocked();
-            } else {
-                // If there is no fullscreen stack, then create the stack and move all the tasks
-                // onto the stack
-                moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);
-            }
+            /**
+             * Workaround: Force-stop all the activities in the pinned stack before we reparent them
+             * to the fullscreen stack.  This is to guarantee that when we are removing a stack,
+             * that the client receives onStop() before it is reparented.  We do this by detaching
+             * the stack from the display so that it will be considered invisible when
+             * ensureActivitiesVisibleLocked() is called, and all of its activitys will be marked
+             * invisible as well and added to the stopping list.  After which we process the
+             * stopping list by handling the idle.
+             */
+            final PinnedActivityStack pinnedStack = (PinnedActivityStack) stack;
+            pinnedStack.mForceHidden = true;
+            pinnedStack.ensureActivitiesVisibleLocked(null, 0, PRESERVE_WINDOWS);
+            pinnedStack.mForceHidden = false;
+            activityIdleInternalLocked(null, false /* fromTimeout */,
+                    true /* processPausingActivites */, null /* configuration */);
+
+            // Move all the tasks to the bottom of the fullscreen stack
+            moveTasksToFullscreenStackLocked(PINNED_STACK_ID, !ON_TOP);
         } else {
             for (int i = tasks.size() - 1; i >= 0; i--) {
                 removeTaskByIdLocked(tasks.get(i).taskId, true /* killProcess */,
@@ -2935,6 +2935,10 @@
         ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
         resumeFocusedStackTopActivityLocked();
 
+        // TODO(b/36099777): Schedule the PiP mode change here immediately until we can defer all
+        // callbacks until after the bounds animation
+        scheduleUpdatePictureInPictureModeIfNeeded(r.getTask(), destBounds, true /* immediate */);
+
         stack.animateResizePinnedStack(sourceBounds, destBounds, -1 /* animationDuration */);
         mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName);
     }
@@ -3579,7 +3583,7 @@
                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                     ActivityStack stack = stacks.get(stackNdx);
                     if (!dumpVisibleStacksOnly ||
-                            stack.getStackVisibilityLocked(null) == STACK_VISIBLE) {
+                            stack.shouldBeVisible(null) == STACK_VISIBLE) {
                         activities.addAll(stack.getDumpActivitiesLocked(name));
                     }
                 }
@@ -3886,7 +3890,7 @@
         info.displayId = DEFAULT_DISPLAY;
         info.stackId = stack.mStackId;
         info.userId = stack.mCurrentUser;
-        info.visible = stack.getStackVisibilityLocked(null) == STACK_VISIBLE;
+        info.visible = stack.shouldBeVisible(null) == STACK_VISIBLE;
         info.position = display != null
                 ? display.mStacks.indexOf(stack)
                 : 0;
@@ -5005,7 +5009,7 @@
             for (int j = display.mStacks.size() - 1; j >= 0; j--) {
                 final ActivityStack stack = display.mStacks.get(j);
                 // Get top activity from a visible stack and add it to the list.
-                if (stack.getStackVisibilityLocked(null /* starting */)
+                if (stack.shouldBeVisible(null /* starting */)
                         == ActivityStack.STACK_VISIBLE) {
                     final ActivityRecord top = stack.topActivity();
                     if (top != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index dcd293a..59f6098 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -74,7 +74,6 @@
 import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.ASSISTANT_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
 import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
 import static com.android.server.am.ActivityStack.STACK_INVISIBLE;
 import static com.android.server.am.ActivityStackSupervisor.CREATE_IF_NEEDED;
@@ -558,31 +557,17 @@
             startedActivityStackId = targetStack.mStackId;
         }
 
-        // If we launched the activity from a no display activity that was launched from the home
-        // screen, we also need to start recents to un-minimize the docked stack, since the
-        // noDisplay activity will be finished shortly after.
-        // Note that some apps have trampoline activities without noDisplay being set. In that case,
-        // we have another heuristic in DockedStackDividerController.notifyAppTransitionStarting
-        // that tries to detect that case.
-        // TODO: We should prevent noDisplay activities from affecting task/stack ordering and
-        // visibility instead of using this flag.
-        final boolean noDisplayActivityOverHome = sourceRecord != null
-                && sourceRecord.noDisplay
-                && sourceRecord.getTask().getTaskToReturnTo() == HOME_ACTIVITY_TYPE;
-        if (startedActivityStackId == DOCKED_STACK_ID
-                && (prevFocusedStackId == HOME_STACK_ID || noDisplayActivityOverHome)) {
+        if (startedActivityStackId == DOCKED_STACK_ID) {
             final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID);
-            final ActivityRecord topActivityHomeStack = homeStack != null
-                    ? homeStack.topRunningActivityLocked() : null;
-            if (topActivityHomeStack == null
-                    || topActivityHomeStack.mActivityType != RECENTS_ACTIVITY_TYPE) {
+            final boolean homeStackVisible = homeStack != null && homeStack.isVisible();
+            if (homeStackVisible) {
                 // We launch an activity while being in home stack, which means either launcher or
                 // recents into docked stack. We don't want the launched activity to be alone in a
                 // docked stack, so we want to immediately launch recents too.
                 if (DEBUG_RECENTS) Slog.d(TAG, "Scheduling recents launch.");
                 mWindowManager.showRecentApps(true /* fromHome */);
-                return;
             }
+            return;
         }
 
         if (startedActivityStackId == PINNED_STACK_ID
@@ -1472,17 +1457,11 @@
     }
 
     /**
-     * Returns the ID of the display to use for a new activity. If the source activity has
-     * a explicit display ID set, use that to launch the activity. If not and the device is in VR
-     * mode, then return the Vr mode's virtual display ID.
+     * Returns the ID of the display to use for a new activity. If the device is in VR mode,
+     * then return the Vr mode's virtual display ID. If not, if the source activity has
+     * a explicit display ID set, use that to launch the activity.
      */
     private int getSourceDisplayId(ActivityRecord sourceRecord, ActivityRecord startingActivity) {
-        int displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
-        // If the activity has a displayId set explicitly, launch it on the same displayId.
-        if (displayId != INVALID_DISPLAY) {
-            return displayId;
-        }
-
         // Check if the Activity is a VR activity. If so, the activity should be launched in
         // main display.
         if (startingActivity != null && startingActivity.requestedVrComponent != null) {
@@ -1490,7 +1469,7 @@
         }
 
         // Get the virtual display id from ActivityManagerService.
-        displayId = mService.mVrCompatibilityDisplayId;
+        int displayId = mService.mVrCompatibilityDisplayId;
         if (displayId != INVALID_DISPLAY) {
             if (DEBUG_STACK) {
                 Slog.d(TAG, "getSourceDisplayId :" + displayId);
@@ -1498,6 +1477,12 @@
             mUsingVrCompatibilityDisplay = true;
             return displayId;
         }
+
+        displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
+        // If the activity has a displayId set explicitly, launch it on the same displayId.
+        if (displayId != INVALID_DISPLAY) {
+            return displayId;
+        }
         return DEFAULT_DISPLAY;
     }
 
@@ -2153,7 +2138,7 @@
                 // activity into parent's stack, because we can't find a better place.
                 final ActivityStack dockedStack = mSupervisor.getStack(DOCKED_STACK_ID);
                 if (dockedStack != null
-                        && dockedStack.getStackVisibilityLocked(r) == STACK_INVISIBLE) {
+                        && dockedStack.shouldBeVisible(r) == STACK_INVISIBLE) {
                     // There is a docked stack, but it isn't visible, so we can't launch into that.
                     return null;
                 } else {
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index d83676b..2082958 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -63,6 +63,7 @@
 import android.view.Surface;
 import android.view.WindowManagerInternal;
 
+import com.android.server.AnimationThread;
 import com.android.server.DisplayThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -257,13 +258,13 @@
     }
 
     public void setupSchedulerPolicies() {
-	/*
-	 * android.display is critical to user experience and we should
-	 * make sure it is not in the default foregroup groups, add it to
-	 * top-app to make sure it uses all the cores and scheduling
-	 * settings for top-app when it runs.
-	 */
-	Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(), Process.THREAD_GROUP_TOP_APP);
+        // android.display and android.anim is critical to user experience and we should make sure
+        // it is not in the default foregroup groups, add it to top-app to make sure it uses all the
+        // cores and scheduling settings for top-app when it runs.
+        Process.setThreadGroupAndCpuset(DisplayThread.get().getThreadId(),
+                Process.THREAD_GROUP_TOP_APP);
+        Process.setThreadGroupAndCpuset(AnimationThread.get().getThreadId(),
+                Process.THREAD_GROUP_TOP_APP);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 2b85570..656e01a 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (C) 2014 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +16,12 @@
 
 package com.android.server.fingerprint;
 
+import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+import static android.Manifest.permission.INTERACT_ACROSS_USERS;
+import static android.Manifest.permission.MANAGE_FINGERPRINT;
+import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
+import static android.Manifest.permission.USE_FINGERPRINT;
+
 import android.Manifest;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RunningAppProcessInfo;
@@ -30,8 +36,14 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
+import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.FingerprintManager;
 import android.hardware.fingerprint.IFingerprintClientActiveCallback;
+import android.hardware.fingerprint.IFingerprintService;
 import android.hardware.fingerprint.IFingerprintServiceLockoutResetCallback;
+import android.hardware.fingerprint.IFingerprintServiceReceiver;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.DeadObjectException;
@@ -42,12 +54,12 @@
 import android.os.IRemoteCallback;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
-import android.security.KeyStore;
 import android.os.RemoteException;
 import android.os.SELinux;
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.security.KeyStore;
 import android.service.fingerprint.FingerprintActionStatsProto;
 import android.service.fingerprint.FingerprintServiceDumpProto;
 import android.service.fingerprint.FingerprintUserStatsProto;
@@ -64,19 +76,6 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
-import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprintClientCallback;
-import android.hardware.fingerprint.Fingerprint;
-import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.IFingerprintService;
-import android.hardware.fingerprint.IFingerprintServiceReceiver;
-
-import static android.Manifest.permission.INTERACT_ACROSS_USERS;
-import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
-import static android.Manifest.permission.MANAGE_FINGERPRINT;
-import static android.Manifest.permission.RESET_FINGERPRINT_LOCKOUT;
-import static android.Manifest.permission.USE_FINGERPRINT;
-
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -121,7 +120,7 @@
     private static final int MAX_FAILED_ATTEMPTS = 5;
     private static final long CANCEL_TIMEOUT_LIMIT = 3000; // max wait for onCancel() from HAL,in ms
     private final String mKeyguardPackage;
-    private int mCurrentUserId = UserHandle.USER_CURRENT;
+    private int mCurrentUserId = UserHandle.USER_NULL;
     private final FingerprintUtils mFingerprintUtils = FingerprintUtils.getInstance();
     private Context mContext;
     private long mHalDeviceId;
@@ -208,10 +207,6 @@
     public void serviceDied(long cookie) {
         Slog.v(TAG, "fingerprint HAL died");
         MetricsLogger.count(mContext, "fingerprintd_died", 1);
-        synchronized (this) {
-            mDaemon = null;
-        }
-        mCurrentUserId = UserHandle.USER_CURRENT;
         handleError(mHalDeviceId, FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
                 0 /*vendorCode */);
     }
@@ -300,6 +295,7 @@
             synchronized (this) {
                 mDaemon = null;
                 mHalDeviceId = 0;
+                mCurrentUserId = UserHandle.USER_NULL;
             }
         }
     }
@@ -538,15 +534,16 @@
         final long token = Binder.clearCallingIdentity();
         try {
             // Allow current user or profiles of the current user...
-            for (int profileId : um.getEnabledProfileIds(mCurrentUserId)) {
+            for (int profileId : um.getEnabledProfileIds(ActivityManager.getCurrentUser())) {
                 if (profileId == userId) {
                     return true;
                 }
             }
-            return false;
         } finally {
             Binder.restoreCallingIdentity(token);
         }
+
+        return false;
     }
 
     private boolean isForegroundActivity(int uid, int pid) {
@@ -635,7 +632,7 @@
             } catch (RemoteException re) {
                 // If the remote is dead, stop notifying it
                 mClientActiveCallbacks.remove(callbacks.get(i));
-           }
+            }
         }
     }
 
@@ -982,7 +979,6 @@
                     startRemove(token, fingerId, groupId, userId, receiver, restricted);
                 }
             });
-
         }
 
         public void enumerate(final IBinder token, final int userId,
@@ -995,7 +991,6 @@
                     startEnumerate(token, userId, receiver, restricted);
                 }
             });
-
         }
 
         @Override // Binder call
@@ -1004,8 +999,14 @@
                     Binder.getCallingUid(), Binder.getCallingPid())) {
                 return false;
             }
-            IBiometricsFingerprint daemon = getFingerprintDaemon();
-            return daemon != null && mHalDeviceId != 0;
+
+            final long token = Binder.clearCallingIdentity();
+            try {
+                IBiometricsFingerprint daemon = getFingerprintDaemon();
+                return daemon != null && mHalDeviceId != 0;
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
         }
 
         @Override // Binder call
@@ -1029,9 +1030,6 @@
                     Binder.getCallingUid(), Binder.getCallingPid())) {
                 return Collections.emptyList();
             }
-            if (!isCurrentUserOrProfile(userId)) {
-                return Collections.emptyList();
-            }
 
             return FingerprintService.this.getEnrolledFingerprints(userId);
         }
@@ -1043,9 +1041,6 @@
                 return false;
             }
 
-            if (!isCurrentUserOrProfile(userId)) {
-                return false;
-            }
             return FingerprintService.this.hasEnrolledFingerprints(userId);
         }
 
@@ -1085,6 +1080,7 @@
                 Binder.restoreCallingIdentity(ident);
             }
         }
+
         @Override // Binder call
         public void resetTimeout(byte [] token) {
             checkPermission(RESET_FINGERPRINT_LOCKOUT);
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index efc92cf..7ed3eac 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -50,7 +50,7 @@
     private String mNotificationTag;
     private final NotificationManager mNotificationManager;
     private final String mPackageName;
-    private boolean mCancelled;
+    private boolean mPosted;
     private IconUtilities mIconUtilities;
 
     AlertWindowNotification(WindowManagerService service, String packageName) {
@@ -61,7 +61,9 @@
         mNotificationTag = CHANNEL_PREFIX + mPackageName;
         mRequestCode = sNextRequestCode++;
         mIconUtilities = new IconUtilities(mService.mContext);
+    }
 
+    void post() {
         // We can't create/post the notification while the window manager lock is held since it will
         // end up calling into activity manager. So, we post a message to do it later.
         mService.mH.post(this::onPostNotification);
@@ -76,16 +78,21 @@
 
     /** Don't call with the window manager lock held! */
     private void onCancelNotification() {
+        if (!mPosted) {
+            // Notification isn't currently posted...
+            return;
+        }
+        mPosted = false;
         mNotificationManager.cancel(mNotificationTag, NOTIFICATION_ID);
-        mCancelled = true;
     }
 
     /** Don't call with the window manager lock held! */
     private void onPostNotification() {
-        if (mCancelled) {
-            // Notification was cancelled, so nothing more to do...
+        if (mPosted) {
+            // Notification already posted...
             return;
         }
+        mPosted = true;
 
         final Context context = mService.mContext;
         final PackageManager pm = context.getPackageManager();
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 4b4be40..a39131c 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -554,7 +554,7 @@
         // want to process the message ASAP, before any other queued
         // messages.
         if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
-        mHandler.postAtFrontOfQueue(mAddStartingWindow);
+        mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
     }
 
     private boolean createSnapshot() {
diff --git a/services/core/java/com/android/server/wm/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java
index 7b8057ca..2811145 100644
--- a/services/core/java/com/android/server/wm/BoundsAnimationController.java
+++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java
@@ -170,8 +170,8 @@
 
             // If we are animating to a new fullscreen state (either to/from fullscreen), then
             // notify the target of the change with the new frozen task bounds
-            if (mAnimatingToNewFullscreenState) {
-                mTarget.updatePictureInPictureMode(mMoveToFullScreen ? null : mTo);
+            if (mAnimatingToNewFullscreenState && mMoveToFullScreen) {
+                mTarget.updatePictureInPictureMode(null);
             }
 
             // Immediately update the task bounds if they have to become larger, but preserve
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 30e0ded..6a7123c 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -81,6 +81,7 @@
     private final Set<WindowSurfaceController> mAlertWindowSurfaces = new HashSet<>();
     final boolean mCanAddInternalSystemWindow;
     private AlertWindowNotification mAlertWindowNotification;
+    private boolean mShowingAlertWindowNotificationAllowed;
     private boolean mClientDead = false;
     private float mLastReportedAnimatorScale;
     private String mPackageName;
@@ -95,6 +96,7 @@
         mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
         mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission(
                 INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
+        mShowingAlertWindowNotificationAllowed = mService.mShowAlertWindowNotifications;
         StringBuilder sb = new StringBuilder();
         sb.append("Session{");
         sb.append(Integer.toHexString(System.identityHashCode(this)));
@@ -591,6 +593,9 @@
                     cancelAlertWindowNotification();
                 } else if (mAlertWindowNotification == null){
                     mAlertWindowNotification = new AlertWindowNotification(mService, mPackageName);
+                    if (mShowingAlertWindowNotificationAllowed) {
+                        mAlertWindowNotification.post();
+                    }
                 }
             }
         }
@@ -612,6 +617,17 @@
         }
     }
 
+    void setShowingAlertWindowNotificationAllowed(boolean allowed) {
+        mShowingAlertWindowNotificationAllowed = allowed;
+        if (mAlertWindowNotification != null) {
+            if (allowed) {
+                mAlertWindowNotification.post();
+            } else {
+                mAlertWindowNotification.cancel();
+            }
+        }
+    }
+
     private void killSessionLocked() {
         if (mNumWindow > 0 || !mClientDead) {
             return;
diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java
index 635527e..5d0384e 100644
--- a/services/core/java/com/android/server/wm/StackWindowController.java
+++ b/services/core/java/com/android/server/wm/StackWindowController.java
@@ -94,6 +94,12 @@
         }
     }
 
+    public boolean isVisible() {
+        synchronized (mWindowMap) {
+            return mContainer != null && mContainer.isVisible();
+        }
+    }
+
     public void reparent(int displayId, Rect outStackBounds) {
         synchronized (mWindowMap) {
             if (mContainer == null) {
@@ -363,7 +369,7 @@
     }
 
     /** Calls directly into activity manager so window manager lock shouldn't held. */
-    public void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
+    void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds) {
         if (mListener != null) {
             mListener.updatePictureInPictureModeForPinnedStackAnimation(targetStackBounds);
         }
diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java
index 53c24e1..0c68e2c 100644
--- a/services/core/java/com/android/server/wm/TaskPositioner.java
+++ b/services/core/java/com/android/server/wm/TaskPositioner.java
@@ -262,7 +262,8 @@
         mService.mInputManager.registerInputChannel(mServerChannel, null);
 
         mInputEventReceiver = new WindowPositionerEventReceiver(
-                mClientChannel, mService.mH.getLooper(), mService.mChoreographer);
+                mClientChannel, mService.mAnimationHandler.getLooper(),
+                mService.mAnimator.getChoreographer());
 
         mDragApplicationHandle = new InputApplicationHandle(null);
         mDragApplicationHandle.name = TAG;
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 57eaa2b..1367a06 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -25,7 +25,6 @@
 import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
 
 import android.content.Context;
-import android.os.Handler;
 import android.os.Trace;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -35,7 +34,7 @@
 import android.view.WindowManagerPolicy;
 
 import com.android.internal.view.SurfaceFlingerVsyncChoreographer;
-import com.android.server.DisplayThread;
+import com.android.server.AnimationThread;
 
 import java.io.PrintWriter;
 
@@ -87,20 +86,25 @@
     private final Runnable mAnimationTick;
     private final SurfaceFlingerVsyncChoreographer mSfChoreographer;
 
+    private Choreographer mChoreographer;
+    private boolean mAnimationScheduled;
+
+
     WindowAnimator(final WindowManagerService service) {
         mService = service;
         mContext = service.mContext;
         mPolicy = service.mPolicy;
         mWindowPlacerLocked = service.mWindowPlacerLocked;
-        final Handler handler = DisplayThread.getHandler();
+        AnimationThread.getHandler().runWithScissors(
+                () -> mChoreographer = Choreographer.getInstance(), 0 /* timeout */);
 
         // TODO: Multi-display: If displays have different vsync tick, have a separate tick per
         // display.
-        mSfChoreographer = new SurfaceFlingerVsyncChoreographer(handler,
-                mService.getDefaultDisplayContentLocked().getDisplay());
+        mSfChoreographer = new SurfaceFlingerVsyncChoreographer(AnimationThread.getHandler(),
+                mService.getDefaultDisplayContentLocked().getDisplay(), mChoreographer);
         mAnimationTick = () -> {
             synchronized (mService.mWindowMap) {
-                mService.mAnimationScheduled = false;
+                mAnimationScheduled = false;
                 animateLocked(mCurrentFrameTime);
             }
         };
@@ -366,6 +370,13 @@
         mRemoveReplacedWindows = true;
     }
 
+    void scheduleAnimation() {
+        if (!mAnimationScheduled) {
+            mAnimationScheduled = true;
+            mChoreographer.postFrameCallback(mAnimationFrameCallback);
+        }
+    }
+
     private class DisplayContentsAnimator {
         ScreenRotationAnimation mScreenRotationAnimation = null;
     }
@@ -374,6 +385,14 @@
         return mAnimating;
     }
 
+    boolean isAnimationScheduled() {
+        return mAnimationScheduled;
+    }
+
+    Choreographer getChoreographer() {
+        return mChoreographer;
+    }
+
     void setAnimating(boolean animating) {
         mAnimating = animating;
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 1be0512..0f4707e 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -31,6 +31,7 @@
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Process.THREAD_PRIORITY_DISPLAY;
 import static android.os.Process.myPid;
+import static android.os.Process.myTid;
 import static android.os.UserHandle.USER_NULL;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_INVALID;
@@ -147,6 +148,7 @@
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.PowerSaveState;
+import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.StrictMode;
@@ -169,7 +171,6 @@
 import android.util.TimeUtils;
 import android.util.TypedValue;
 import android.view.AppTransitionAnimationSpec;
-import android.view.Choreographer;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Gravity;
@@ -218,6 +219,7 @@
 import com.android.internal.view.IInputMethodClient;
 import com.android.internal.view.IInputMethodManager;
 import com.android.internal.view.WindowManagerPolicyThread;
+import com.android.server.AnimationThread;
 import com.android.server.DisplayThread;
 import com.android.server.EventLogTags;
 import com.android.server.FgThread;
@@ -402,6 +404,9 @@
 
     final DisplaySettings mDisplaySettings;
 
+    /** If the system should display notifications for apps displaying an alert window. */
+    boolean mShowAlertWindowNotifications = true;
+
     /**
      * All currently active sessions with clients.
      */
@@ -601,7 +606,12 @@
 
     final H mH = new H();
 
-    final Choreographer mChoreographer = Choreographer.getInstance();
+    /**
+     * Handler for things to run that have direct impact on an animation, i.e. animation tick,
+     * layout, starting window creation, whereas {@link H} runs things that are still important, but
+     * not as critical.
+     */
+    final Handler mAnimationHandler = new Handler(AnimationThread.getHandler().getLooper());
 
     WindowState mCurrentFocus = null;
     WindowState mLastFocus = null;
@@ -708,8 +718,6 @@
     // For frozen screen animations.
     private int mExitAnimId, mEnterAnimId;
 
-    boolean mAnimationScheduled;
-
     /** Skip repeated AppWindowTokens initialization. Note that AppWindowsToken's version of this
      * is a long initialized to Long.MIN_VALUE so that it doesn't match this value on startup. */
     int mTransactionSequence;
@@ -4645,7 +4653,6 @@
     final class H extends android.os.Handler {
         public static final int REPORT_FOCUS_CHANGE = 2;
         public static final int REPORT_LOSING_FOCUS = 3;
-        public static final int DO_TRAVERSAL = 4;
         public static final int WINDOW_FREEZE_TIMEOUT = 11;
 
         public static final int APP_TRANSITION_TIMEOUT = 13;
@@ -4775,12 +4782,6 @@
                     }
                 } break;
 
-                case DO_TRAVERSAL: {
-                    synchronized(mWindowMap) {
-                        mWindowPlacerLocked.performSurfacePlacement();
-                    }
-                } break;
-
                 case WINDOW_FREEZE_TIMEOUT: {
                     // TODO(multidisplay): Can non-default displays rotate?
                     synchronized (mWindowMap) {
@@ -4849,7 +4850,7 @@
                     synchronized (mWindowMap) {
                         // Since we're holding both mWindowMap and mAnimator we don't need to
                         // hold mAnimator.mLayoutToAnim.
-                        if (mAnimator.isAnimating() || mAnimationScheduled) {
+                        if (mAnimator.isAnimating() || mAnimator.isAnimationScheduled()) {
                             // If we are animating, don't do the gc now but
                             // delay a bit so we don't interrupt the animation.
                             sendEmptyMessageDelayed(H.FORCE_GC, 2000);
@@ -5744,10 +5745,7 @@
 
     /** Note that Locked in this case is on mLayoutToAnim */
     void scheduleAnimationLocked() {
-        if (!mAnimationScheduled) {
-            mAnimationScheduled = true;
-            mChoreographer.postFrameCallback(mAnimator.mAnimationFrameCallback);
-        }
+        mAnimator.scheduleAnimation();
     }
 
     // TODO: Move to DisplayContent
@@ -7370,4 +7368,21 @@
             }
         }
     }
+
+    /** Called to inform window manager if non-Vr UI shoul be disabled or not. */
+    public void disableNonVrUi(boolean disable) {
+        synchronized (mWindowMap) {
+            // Allow alert window notifications to be shown if non-vr UI is enabled.
+            final boolean showAlertWindowNotifications = !disable;
+            if (showAlertWindowNotifications == mShowAlertWindowNotifications) {
+                return;
+            }
+            mShowAlertWindowNotifications = showAlertWindowNotifications;
+
+            for (int i = mSessions.size() - 1; i >= 0; --i) {
+                final Session s = mSessions.valueAt(i);
+                s.setShowingAlertWindowNotificationAllowed(mShowAlertWindowNotifications);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index ee2d5de..ddd1ca5 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -30,7 +30,6 @@
 import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL;
 import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING;
 import static com.android.server.wm.WindowManagerService.H.REPORT_WINDOWS_CHANGE;
 import static com.android.server.wm.WindowManagerService.LAYOUT_REPEAT_THRESHOLD;
@@ -97,9 +96,16 @@
     private final ArrayList<SurfaceControl> mPendingDestroyingSurfaces = new ArrayList<>();
     private final SparseIntArray mTempTransitionReasons = new SparseIntArray();
 
+    private final Runnable mPerformSurfacePlacement;
+
     public WindowSurfacePlacer(WindowManagerService service) {
         mService = service;
         mWallpaperControllerLocked = mService.mRoot.mWallpaperController;
+        mPerformSurfacePlacement = () -> {
+            synchronized (mService.mWindowMap) {
+                performSurfacePlacement();
+            }
+        };
     }
 
     /**
@@ -131,7 +137,7 @@
         do {
             mTraversalScheduled = false;
             performSurfacePlacementLoop();
-            mService.mH.removeMessages(DO_TRAVERSAL);
+            mService.mAnimationHandler.removeCallbacks(mPerformSurfacePlacement);
             loopCount--;
         } while (mTraversalScheduled && loopCount > 0);
         mService.mRoot.mWallpaperActionPending = false;
@@ -735,7 +741,7 @@
     void requestTraversal() {
         if (!mTraversalScheduled) {
             mTraversalScheduled = true;
-            mService.mH.sendEmptyMessage(DO_TRAVERSAL);
+            mService.mAnimationHandler.post(mPerformSurfacePlacement);
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index 25004de..3c8bf20 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -98,11 +98,11 @@
                 createAppWindowController();
         controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
-        waitUntilHandlerIdle();
+        waitUntilHandlersIdle();
         final AppWindowToken atoken = controller.getAppWindowToken();
         assertHasStartingWindow(atoken);
         controller.removeStartingWindow();
-        waitUntilHandlerIdle();
+        waitUntilHandlersIdle();
         assertNoStartingWindow(atoken);
     }
 
@@ -114,11 +114,11 @@
                 createAppWindowController();
         controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
-        waitUntilHandlerIdle();
+        waitUntilHandlersIdle();
         controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
                 true, true, false);
-        waitUntilHandlerIdle();
+        waitUntilHandlersIdle();
         assertNoStartingWindow(controller1.getAppWindowToken());
         assertHasStartingWindow(controller2.getAppWindowToken());
     }
@@ -138,7 +138,7 @@
         });
         controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
                 android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false);
-        waitUntilHandlerIdle();
+        waitUntilHandlersIdle();
         assertNoStartingWindow(controller1.getAppWindowToken());
         assertHasStartingWindow(controller2.getAppWindowToken());
     }
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index eaf4ac4..218af73 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -167,8 +167,9 @@
     /**
      * Waits until the main handler for WM has processed all messages.
      */
-    void waitUntilHandlerIdle() {
+    void waitUntilHandlersIdle() {
         sWm.mH.runWithScissors(() -> { }, 0);
+        sWm.mAnimationHandler.runWithScissors(() -> { }, 0);
     }
 
     private static WindowToken createWindowToken(DisplayContent dc, int stackId, int type) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index bb83633..0b4a3e8 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -771,6 +771,13 @@
     public static final String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
 
     /**
+     * Determines whether the Enhanced 4G LTE toggle will be shown in the settings. When this
+     * option is {@code true}, the toggle will be hidden regardless of whether the device and
+     * carrier supports 4G LTE or not.
+     */
+    public static final String KEY_HIDE_ENHANCED_4G_LTE_BOOL = "hide_enhanced_4g_lte_bool";
+
+    /**
      * Determine whether IMS apn can be shown.
      */
     public static final String KEY_HIDE_IMS_APN_BOOL = "hide_ims_apn_bool";
@@ -1529,6 +1536,7 @@
         sDefaults.putInt(KEY_IMS_CONFERENCE_SIZE_LIMIT_INT, 5);
         sDefaults.putBoolean(KEY_DISPLAY_HD_AUDIO_PROPERTY_BOOL, true);
         sDefaults.putBoolean(KEY_EDITABLE_ENHANCED_4G_LTE_BOOL, true);
+        sDefaults.putBoolean(KEY_HIDE_ENHANCED_4G_LTE_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_IMS_APN_BOOL, false);
         sDefaults.putBoolean(KEY_HIDE_PREFERRED_NETWORK_TYPE_BOOL, false);
         sDefaults.putBoolean(KEY_ALLOW_EMERGENCY_VIDEO_CALLS_BOOL, false);
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index a33fd06..407eb52 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -2151,7 +2151,7 @@
   }
 
   AxisConfigFilter filter;
-  if (configs.empty()) {
+  if (!configs.empty()) {
     for (const std::string& config_arg : configs) {
       for (const StringPiece& config_str : util::Tokenize(config_arg, ',')) {
         ConfigDescription config;