Merge "Fix potential use-after-free in LayerUpdateQueue"
diff --git a/Android.mk b/Android.mk
index 109f610..f544620 100644
--- a/Android.mk
+++ b/Android.mk
@@ -408,10 +408,10 @@
 	location/java/android/location/INetInitiatedListener.aidl \
 	location/java/com/android/internal/location/ILocationProvider.aidl \
 	media/java/android/media/IAudioService.aidl \
-	media/java/android/media/ICas.aidl \
-	media/java/android/media/ICasListener.aidl \
-	media/java/android/media/IDescrambler.aidl \
-	media/java/android/media/IMediaCasService.aidl \
+	../av/drm/libmediadrm/aidl/android/media/ICas.aidl \
+	../av/drm/libmediadrm/aidl/android/media/ICasListener.aidl \
+	../av/drm/libmediadrm/aidl/android/media/IDescrambler.aidl \
+	../av/drm/libmediadrm/aidl/android/media/IMediaCasService.aidl \
 	media/java/android/media/IAudioFocusDispatcher.aidl \
 	media/java/android/media/IAudioRoutesObserver.aidl \
 	media/java/android/media/IMediaHTTPConnection.aidl \
@@ -441,6 +441,7 @@
 	media/java/android/media/projection/IMediaProjectionManager.aidl \
 	media/java/android/media/projection/IMediaProjectionWatcherCallback.aidl \
 	media/java/android/media/session/IActiveSessionsListener.aidl \
+	media/java/android/media/session/ICallback.aidl \
 	media/java/android/media/session/IOnMediaKeyListener.aidl \
 	media/java/android/media/session/IOnVolumeKeyLongPressListener.aidl \
 	media/java/android/media/session/ISession.aidl \
@@ -537,6 +538,7 @@
 
 LOCAL_AIDL_INCLUDES += \
 	frameworks/av/camera/aidl \
+	frameworks/av/drm/libmediadrm/aidl \
 	frameworks/native/aidl/gui \
 	system/netd/server/binder
 
diff --git a/apct-tests/perftests/core/jni/SystemPerfTest.cpp b/apct-tests/perftests/core/jni/SystemPerfTest.cpp
index eb55408..f102e3e 100644
--- a/apct-tests/perftests/core/jni/SystemPerfTest.cpp
+++ b/apct-tests/perftests/core/jni/SystemPerfTest.cpp
@@ -73,7 +73,7 @@
         return JNI_ERR;
     }
 
-    if (registerNativeMethods(env, "java/lang/perftests/SystemPerfTest",
+    if (registerNativeMethods(env, "android/perftests/SystemPerfTest",
             sMethods, NELEM(sMethods)) == -1) {
         return JNI_ERR;
     }
diff --git a/apct-tests/perftests/core/src/java/lang/perftests/SystemPerfTest.java b/apct-tests/perftests/core/src/android/perftests/SystemPerfTest.java
similarity index 98%
rename from apct-tests/perftests/core/src/java/lang/perftests/SystemPerfTest.java
rename to apct-tests/perftests/core/src/android/perftests/SystemPerfTest.java
index afc9d0c..95a7144 100644
--- a/apct-tests/perftests/core/src/java/lang/perftests/SystemPerfTest.java
+++ b/apct-tests/perftests/core/src/android/perftests/SystemPerfTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package java.lang.perftests;
+package android.perftests;
 
 import android.perftests.utils.BenchmarkState;
 import android.perftests.utils.PerfStatusReporter;
diff --git a/api/current.txt b/api/current.txt
index 22dbe7b..cf6c925 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -16,6 +16,7 @@
     field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
     field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
+    field public static final java.lang.String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
@@ -1004,7 +1005,7 @@
     field public static final int preferenceStyle = 16842894; // 0x101008e
     field public static final int presentationTheme = 16843712; // 0x10103c0
     field public static final int previewImage = 16843482; // 0x10102da
-    field public static final int primaryContentAlpha = 16843367; // 0x1010267
+    field public static final int primaryContentAlpha = 16844117; // 0x1010555
     field public static final int priority = 16842780; // 0x101001c
     field public static final int privateImeOptions = 16843299; // 0x1010223
     field public static final int process = 16842769; // 0x1010011
@@ -1060,7 +1061,9 @@
     field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
+    field public static final int requiredFeature = 16844119; // 0x1010557
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
+    field public static final int requiredNotFeature = 16844120; // 0x1010558
     field public static final int requiresFadingEdge = 16843685; // 0x10103a5
     field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
     field public static final int resizeClip = 16843983; // 0x10104cf
@@ -1129,7 +1132,7 @@
     field public static final int searchSuggestSelection = 16843224; // 0x10101d8
     field public static final int searchSuggestThreshold = 16843373; // 0x101026d
     field public static final int searchViewStyle = 16843904; // 0x1010480
-    field public static final int secondaryContentAlpha = 16843688; // 0x10103a8
+    field public static final int secondaryContentAlpha = 16844118; // 0x1010556
     field public static final int secondaryProgress = 16843064; // 0x1010138
     field public static final int secondaryProgressTint = 16843879; // 0x1010467
     field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
@@ -4143,6 +4146,7 @@
     field public static final int MODE_ERRORED = 2; // 0x2
     field public static final int MODE_IGNORED = 1; // 0x1
     field public static final java.lang.String OPSTR_ADD_VOICEMAIL = "android:add_voicemail";
+    field public static final java.lang.String OPSTR_ANSWER_PHONE_CALLS = "android:answer_phone_calls";
     field public static final java.lang.String OPSTR_BODY_SENSORS = "android:body_sensors";
     field public static final java.lang.String OPSTR_CALL_PHONE = "android:call_phone";
     field public static final java.lang.String OPSTR_CAMERA = "android:camera";
@@ -5480,6 +5484,7 @@
 
   public final class NotificationChannel implements android.os.Parcelable {
     ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
+    ctor public NotificationChannel(java.lang.String, int, int);
     ctor protected NotificationChannel(android.os.Parcel);
     method public boolean canBypassDnd();
     method public boolean canShowBadge();
@@ -5493,6 +5498,7 @@
     method public int getLightColor();
     method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
+    method public int getNameResId();
     method public android.net.Uri getSound();
     method public long[] getVibrationPattern();
     method public void setBypassDnd(boolean);
@@ -6563,6 +6569,7 @@
     method public java.lang.String getIdEntry();
     method public java.lang.String getIdPackage();
     method public java.lang.String getIdType();
+    method public int getInputType();
     method public int getLeft();
     method public int getScrollX();
     method public int getScrollY();
@@ -8674,6 +8681,7 @@
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -10166,9 +10174,11 @@
     method public void unregisterSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
     method public void updateSessionAppIcon(int, android.graphics.Bitmap);
     method public void updateSessionAppLabel(int, java.lang.CharSequence);
+    field public static final java.lang.String ACTION_SESSION_COMMITTED = "android.content.pm.action.SESSION_COMMITTED";
     field public static final java.lang.String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
     field public static final java.lang.String EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_SESSION = "android.content.pm.extra.SESSION";
     field public static final java.lang.String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
     field public static final java.lang.String EXTRA_STATUS = "android.content.pm.extra.STATUS";
     field public static final java.lang.String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
@@ -10211,6 +10221,7 @@
     method public android.graphics.Bitmap getAppIcon();
     method public java.lang.CharSequence getAppLabel();
     method public java.lang.String getAppPackageName();
+    method public int getInstallReason();
     method public java.lang.String getInstallerPackageName();
     method public float getProgress();
     method public int getSessionId();
@@ -10339,6 +10350,7 @@
     method public abstract boolean hasSystemFeature(java.lang.String);
     method public abstract boolean hasSystemFeature(java.lang.String, int);
     method public abstract boolean isInstantApp();
+    method public abstract boolean isInstantApp(java.lang.String);
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -10470,8 +10482,11 @@
     field public static final int GET_SIGNATURES = 64; // 0x40
     field public static final deprecated int GET_UNINSTALLED_PACKAGES = 8192; // 0x2000
     field public static final int GET_URI_PERMISSION_PATTERNS = 2048; // 0x800
+    field public static final int INSTALL_REASON_DEVICE_RESTORE = 2; // 0x2
+    field public static final int INSTALL_REASON_DEVICE_SETUP = 3; // 0x3
     field public static final int INSTALL_REASON_POLICY = 1; // 0x1
     field public static final int INSTALL_REASON_UNKNOWN = 0; // 0x0
+    field public static final int INSTALL_REASON_USER = 4; // 0x4
     field public static final int MATCH_ALL = 131072; // 0x20000
     field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
     field public static final int MATCH_DIRECT_BOOT_AWARE = 524288; // 0x80000
@@ -10600,6 +10615,7 @@
     field public android.content.pm.ActivityInfo activityInfo;
     field public android.content.IntentFilter filter;
     field public int icon;
+    field public boolean instantAppAvailable;
     field public boolean isDefault;
     field public int labelRes;
     field public int match;
@@ -13822,12 +13838,12 @@
   }
 
   public final class Icon implements android.os.Parcelable {
+    method public static android.graphics.drawable.Icon createWithAdaptiveBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithContentUri(java.lang.String);
     method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
     method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
     method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
-    method public static android.graphics.drawable.Icon createWithMaskableBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
     method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
     method public int describeContents();
@@ -20660,6 +20676,26 @@
     field public static final int TYPE_WIRED_HEADSET = 3; // 0x3
   }
 
+  public final class AudioFocusRequest {
+    method public boolean acceptsDelayedFocusGain();
+    method public android.media.AudioAttributes getAudioAttributes();
+    method public int getFocusGain();
+    method public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
+    method public android.os.Handler getOnAudioFocusChangeListenerHandler();
+    method public boolean willPauseWhenDucked();
+  }
+
+  public static final class AudioFocusRequest.Builder {
+    ctor public AudioFocusRequest.Builder(int);
+    ctor public AudioFocusRequest.Builder(android.media.AudioFocusRequest);
+    method public android.media.AudioFocusRequest build();
+    method public android.media.AudioFocusRequest.Builder setAcceptsDelayedFocusGain(boolean);
+    method public android.media.AudioFocusRequest.Builder setAudioAttributes(android.media.AudioAttributes);
+    method public android.media.AudioFocusRequest.Builder setFocusGain(int);
+    method public android.media.AudioFocusRequest.Builder setOnAudioFocusChangeListener(android.media.AudioManager.OnAudioFocusChangeListener, android.os.Handler);
+    method public android.media.AudioFocusRequest.Builder setWillPauseWhenDucked(boolean);
+  }
+
   public final class AudioFormat implements android.os.Parcelable {
     method public int describeContents();
     method public int getChannelCount();
@@ -20736,6 +20772,7 @@
 
   public class AudioManager {
     method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
+    method public int abandonAudioFocusRequest(android.media.AudioFocusRequest);
     method public void adjustStreamVolume(int, int, int);
     method public void adjustSuggestedStreamVolume(int, int, int);
     method public void adjustVolume(int, int);
@@ -20772,6 +20809,7 @@
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
     method public deprecated boolean registerRemoteController(android.media.RemoteController);
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
+    method public int requestAudioFocus(android.media.AudioFocusRequest);
     method public deprecated void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
     method public void setMicrophoneMute(boolean);
@@ -20815,6 +20853,7 @@
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT = -2; // 0xfffffffe
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3; // 0xfffffffd
     field public static final int AUDIOFOCUS_NONE = 0; // 0x0
+    field public static final int AUDIOFOCUS_REQUEST_DELAYED = 2; // 0x2
     field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
     field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
     field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
@@ -24109,17 +24148,79 @@
     method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
     method public static final android.net.Uri buildRecordedProgramUri(long);
+    method public static final android.net.Uri buildWatchNextProgramUri(long);
     method public static final boolean isChannelUri(android.net.Uri);
     method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
     method public static final boolean isChannelUriForTunerInput(android.net.Uri);
     method public static final boolean isProgramUri(android.net.Uri);
+    field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
+    field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
+    field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
+    field public static final java.lang.String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED";
     field public static final java.lang.String AUTHORITY = "android.media.tv";
+    field public static final java.lang.String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
+    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_PREVIEW_PROGRAM_ID = "android.media.tv.extra.PREVIEW_PROGRAM_ID";
+    field public static final java.lang.String EXTRA_WATCH_NEXT_PROGRAM_ID = "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID";
+  }
+
+  public static abstract interface TvContract.BasePreviewProgramColumns implements android.media.tv.TvContract.BaseProgramColumns {
+    field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+    field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+    field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+    field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+    field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+    field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+    field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+    field public static final java.lang.String COLUMN_AUTHOR = "author";
+    field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
+    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
+    field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
+    field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+    field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
+    field public static final java.lang.String COLUMN_LIVE = "live";
+    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
+    field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+    field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+    field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+    field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
+    field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+    field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+    field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
+    field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+    field public static final java.lang.String COLUMN_TYPE = "type";
+    field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+    field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+    field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+    field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+    field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
+    field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+    field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+    field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+    field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+    field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+    field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+    field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+    field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+    field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+    field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+    field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+    field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+    field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
   }
 
   public static abstract interface TvContract.BaseProgramColumns implements android.media.tv.TvContract.BaseTvColumns {
     field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
     field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
-    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
     field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
@@ -24152,6 +24253,7 @@
     field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
     field public static final java.lang.String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
     field public static final java.lang.String COLUMN_APP_LINK_TEXT = "app_link_text";
+    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
     field public static final java.lang.String COLUMN_DESCRIPTION = "description";
     field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
     field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
@@ -24224,69 +24326,17 @@
     field public static final java.lang.String CONTENT_DIRECTORY = "logo";
   }
 
-  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BaseProgramColumns {
-    field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
-    field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
-    field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
-    field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
-    field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
-    field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
-    field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
-    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
-    field public static final java.lang.String COLUMN_AUTHOR = "author";
-    field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
-    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
-    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
-    field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
-    field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
-    field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
-    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
-    field public static final java.lang.String COLUMN_LIVE = "live";
-    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
-    field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
-    field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
-    field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
-    field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
-    field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
-    field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
-    field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
-    field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
-    field public static final java.lang.String COLUMN_TYPE = "type";
-    field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_WEIGHT = "weight";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/preview_program";
     field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
-    field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
-    field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
-    field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
-    field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
-    field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
-    field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
-    field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
-    field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
-    field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
-    field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
-    field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
-    field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
-    field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
-    field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
-    field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
-    field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
-    field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
-    field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
-    field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
-    field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
-    field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
-    field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
-    field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
-    field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
   }
 
   public static final class TvContract.Programs implements android.media.tv.TvContract.BaseProgramColumns {
     field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
@@ -24322,6 +24372,7 @@
 
   public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseProgramColumns {
     field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
     field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
@@ -24334,6 +24385,19 @@
     field public static final android.net.Uri CONTENT_URI;
   }
 
+  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+    ctor public TvContract.WatchNextPrograms();
+    field public static final java.lang.String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS = "last_engagement_time_utc_millis";
+    field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+    field public static final java.lang.String WATCH_NEXT_TYPE_WATCHLIST = "WATCH_NEXT_TYPE_WATCHLIST";
+  }
+
   public final class TvInputInfo implements android.os.Parcelable {
     method public boolean canRecord();
     method public android.content.Intent createSettingsIntent();
@@ -24383,15 +24447,10 @@
     method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
     method public void updateTvInputInfo(android.media.tv.TvInputInfo);
     field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
-    field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
     field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
-    field public static final java.lang.String ACTION_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PROGRAM_BROWSABLE_DISABLED";
     field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
     field public static final java.lang.String ACTION_SETUP_INPUTS = "android.media.tv.action.SETUP_INPUTS";
     field public static final java.lang.String ACTION_VIEW_RECORDING_SCHEDULES = "android.media.tv.action.VIEW_RECORDING_SCHEDULES";
-    field public static final java.lang.String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
-    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
-    field public static final java.lang.String EXTRA_PROGRAM_ID = "android.media.tv.extra.PROGRAM_ID";
     field public static final int INPUT_STATE_CONNECTED = 0; // 0x0
     field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
     field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
@@ -24963,6 +25022,68 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
+  public final class IpSecAlgorithm implements android.os.Parcelable {
+    ctor public IpSecAlgorithm(java.lang.String, byte[]);
+    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
+    method public int describeContents();
+    method public byte[] getKey();
+    method public java.lang.String getName();
+    method public int getTruncationLengthBits();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";
+    field public static final java.lang.String ALGO_CRYPT_AES_CBC = "cbc(aes)";
+    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
+  }
+
+  public final class IpSecManager {
+    method public void applyTransportModeTransform(java.net.Socket, android.net.IpSecTransform) throws java.io.IOException;
+    method public void applyTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
+    method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
+  }
+
+  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
+  }
+
+  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getPort();
+    method public java.io.FileDescriptor getSocket();
+  }
+
+  public final class IpSecTransform implements java.lang.AutoCloseable {
+    method public void close();
+    field public static final int DIRECTION_IN = 0; // 0x0
+    field public static final int DIRECTION_OUT = 1; // 0x1
+  }
+
+  public static class IpSecTransform.Builder {
+    ctor public IpSecTransform.Builder(android.content.Context);
+    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
+    method public android.net.IpSecTransform.Builder setSpi(int, int);
+    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
+  }
+
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -30013,12 +30134,12 @@
     field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
     field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
     field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
-    field public static final int BATTERY_PROPERTY_BATTERY_STATUS = 6; // 0x6
     field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
     field public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; // 0x1
     field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
     field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
     field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
+    field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
     field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
     field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
     field public static final int BATTERY_STATUS_FULL = 5; // 0x5
@@ -36299,7 +36420,6 @@
     field public static final int PURPOSE_ENCRYPT = 1; // 0x1
     field public static final int PURPOSE_SIGN = 4; // 0x4
     field public static final int PURPOSE_VERIFY = 8; // 0x8
-    field public static final int PURPOSE_WRAP_KEY = 16; // 0x10
     field public static final java.lang.String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
     field public static final java.lang.String SIGNATURE_PADDING_RSA_PSS = "PSS";
   }
@@ -36810,6 +36930,7 @@
     method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
     field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
+    field public static final java.lang.String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
     field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE";
   }
 
@@ -38119,6 +38240,7 @@
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
+    field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100
     field public static final int PROPERTY_WIFI = 8; // 0x8
   }
 
@@ -38132,9 +38254,6 @@
     field public static final int RTT_MODE_VCO = 3; // 0x3
   }
 
-  public static abstract class Call.RttCall.RttAudioMode implements java.lang.annotation.Annotation {
-  }
-
   public final class CallAudioState implements android.os.Parcelable {
     ctor public CallAudioState(boolean, int, int);
     method public static java.lang.String audioRouteToString(int);
@@ -38675,6 +38794,8 @@
   }
 
   public class TelecomManager {
+    method public void acceptRingingCall();
+    method public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
     method public void cancelMissedCallsNotification();
     method public android.content.Intent createManageBlockedNumbersIntent();
@@ -38689,6 +38810,7 @@
     method public boolean handleMmi(java.lang.String);
     method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
     method public boolean isInCall();
+    method public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isOutgoingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
@@ -38725,6 +38847,7 @@
     field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
     field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
     field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
+    field public static final java.lang.String METADATA_INCLUDE_SELF_MANAGED_CALLS = "android.telecom.INCLUDE_SELF_MANAGED_CALLS";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
     field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -39412,6 +39535,7 @@
     method public java.lang.String getDeviceId();
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
+    method public java.lang.String[] getForbiddenPlmns();
     method public java.lang.String getGroupIdLevel1();
     method public java.lang.String getIccAuthentication(int, int, java.lang.String);
     method public java.lang.String getLine1Number();
@@ -40260,6 +40384,7 @@
     method public boolean hasSystemFeature(java.lang.String);
     method public boolean hasSystemFeature(java.lang.String, int);
     method public boolean isInstantApp();
+    method public boolean isInstantApp(java.lang.String);
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -45821,6 +45946,7 @@
     method public abstract void setFocused(boolean);
     method public abstract void setHint(java.lang.CharSequence);
     method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
+    method public abstract void setInputType(int);
     method public abstract void setLongClickable(boolean);
     method public abstract void setSanitized(boolean);
     method public abstract void setSelected(boolean);
@@ -47072,10 +47198,12 @@
 
   public final class AutoFillType implements android.os.Parcelable {
     method public int describeContents();
+    method public static android.view.autofill.AutoFillType forDate();
     method public static android.view.autofill.AutoFillType forList();
     method public static android.view.autofill.AutoFillType forText(int);
     method public static android.view.autofill.AutoFillType forToggle();
     method public int getSubType();
+    method public boolean isDate();
     method public boolean isList();
     method public boolean isText();
     method public boolean isToggle();
@@ -47085,9 +47213,11 @@
 
   public final class AutoFillValue implements android.os.Parcelable {
     method public int describeContents();
+    method public static android.view.autofill.AutoFillValue forDate(long);
     method public static android.view.autofill.AutoFillValue forList(int);
     method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence);
     method public static android.view.autofill.AutoFillValue forToggle(boolean);
+    method public long getDateValue();
     method public int getListValue();
     method public java.lang.CharSequence getTextValue();
     method public boolean getToggleValue();
diff --git a/api/system-current.txt b/api/system-current.txt
index daf8cef..7ef4db8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25,6 +25,7 @@
     field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
     field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
     field public static final java.lang.String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK";
+    field public static final java.lang.String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
     field public static final java.lang.String BACKUP = "android.permission.BACKUP";
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
@@ -206,7 +207,6 @@
     field public static final java.lang.String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
     field public static final java.lang.String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
     field public static final java.lang.String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
-    field public static final java.lang.String REQUEST_NETWORK_SCORES = "android.permission.REQUEST_NETWORK_SCORES";
     field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
     field public static final java.lang.String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
     field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
@@ -1117,7 +1117,7 @@
     field public static final int preferenceStyle = 16842894; // 0x101008e
     field public static final int presentationTheme = 16843712; // 0x10103c0
     field public static final int previewImage = 16843482; // 0x10102da
-    field public static final int primaryContentAlpha = 16843367; // 0x1010267
+    field public static final int primaryContentAlpha = 16844117; // 0x1010555
     field public static final int priority = 16842780; // 0x101001c
     field public static final int privateImeOptions = 16843299; // 0x1010223
     field public static final int process = 16842769; // 0x1010011
@@ -1173,7 +1173,9 @@
     field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
+    field public static final int requiredFeature = 16844119; // 0x1010557
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
+    field public static final int requiredNotFeature = 16844120; // 0x1010558
     field public static final int requiresFadingEdge = 16843685; // 0x10103a5
     field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
     field public static final int resizeClip = 16843983; // 0x10104cf
@@ -1246,7 +1248,7 @@
     field public static final int searchSuggestSelection = 16843224; // 0x10101d8
     field public static final int searchSuggestThreshold = 16843373; // 0x101026d
     field public static final int searchViewStyle = 16843904; // 0x1010480
-    field public static final int secondaryContentAlpha = 16843688; // 0x10103a8
+    field public static final int secondaryContentAlpha = 16844118; // 0x1010556
     field public static final int secondaryProgress = 16843064; // 0x1010138
     field public static final int secondaryProgressTint = 16843879; // 0x1010467
     field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
@@ -4286,6 +4288,7 @@
     field public static final int MODE_IGNORED = 1; // 0x1
     field public static final java.lang.String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
     field public static final java.lang.String OPSTR_ADD_VOICEMAIL = "android:add_voicemail";
+    field public static final java.lang.String OPSTR_ANSWER_PHONE_CALLS = "android:answer_phone_calls";
     field public static final java.lang.String OPSTR_BODY_SENSORS = "android:body_sensors";
     field public static final java.lang.String OPSTR_CALL_PHONE = "android:call_phone";
     field public static final java.lang.String OPSTR_CAMERA = "android:camera";
@@ -5657,6 +5660,7 @@
 
   public final class NotificationChannel implements android.os.Parcelable {
     ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
+    ctor public NotificationChannel(java.lang.String, int, int);
     ctor protected NotificationChannel(android.os.Parcel);
     method public boolean canBypassDnd();
     method public boolean canShowBadge();
@@ -5670,6 +5674,7 @@
     method public int getLightColor();
     method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
+    method public int getNameResId();
     method public android.net.Uri getSound();
     method public int getUserLockedFields();
     method public long[] getVibrationPattern();
@@ -6803,6 +6808,7 @@
     method public java.lang.String getIdEntry();
     method public java.lang.String getIdPackage();
     method public java.lang.String getIdType();
+    method public int getInputType();
     method public int getLeft();
     method public int getScrollX();
     method public int getScrollY();
@@ -9137,6 +9143,7 @@
     field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -10703,9 +10710,11 @@
     method public void unregisterSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
     method public void updateSessionAppIcon(int, android.graphics.Bitmap);
     method public void updateSessionAppLabel(int, java.lang.CharSequence);
+    field public static final java.lang.String ACTION_SESSION_COMMITTED = "android.content.pm.action.SESSION_COMMITTED";
     field public static final java.lang.String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
     field public static final java.lang.String EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_SESSION = "android.content.pm.extra.SESSION";
     field public static final java.lang.String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
     field public static final java.lang.String EXTRA_STATUS = "android.content.pm.extra.STATUS";
     field public static final java.lang.String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
@@ -10748,6 +10757,7 @@
     method public android.graphics.Bitmap getAppIcon();
     method public java.lang.CharSequence getAppLabel();
     method public java.lang.String getAppPackageName();
+    method public int getInstallReason();
     method public java.lang.String getInstallerPackageName();
     method public float getProgress();
     method public int getSessionId();
@@ -10889,6 +10899,7 @@
     method public abstract boolean hasSystemFeature(java.lang.String);
     method public abstract boolean hasSystemFeature(java.lang.String, int);
     method public abstract boolean isInstantApp();
+    method public abstract boolean isInstantApp(java.lang.String);
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
     method public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -11073,8 +11084,11 @@
     field public static final int INSTALL_PARSE_FAILED_NOT_APK = -100; // 0xffffff9c
     field public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103; // 0xffffff99
     field public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102; // 0xffffff9a
+    field public static final int INSTALL_REASON_DEVICE_RESTORE = 2; // 0x2
+    field public static final int INSTALL_REASON_DEVICE_SETUP = 3; // 0x3
     field public static final int INSTALL_REASON_POLICY = 1; // 0x1
     field public static final int INSTALL_REASON_UNKNOWN = 0; // 0x0
+    field public static final int INSTALL_REASON_USER = 4; // 0x4
     field public static final int INSTALL_SUCCEEDED = 1; // 0x1
     field public static final int INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS = 2; // 0x2
     field public static final int INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK = 4; // 0x4
@@ -11222,6 +11236,7 @@
     field public android.content.pm.ActivityInfo activityInfo;
     field public android.content.IntentFilter filter;
     field public int icon;
+    field public boolean instantAppAvailable;
     field public boolean isDefault;
     field public int labelRes;
     field public int match;
@@ -14458,12 +14473,12 @@
   }
 
   public final class Icon implements android.os.Parcelable {
+    method public static android.graphics.drawable.Icon createWithAdaptiveBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithContentUri(java.lang.String);
     method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
     method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
     method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
-    method public static android.graphics.drawable.Icon createWithMaskableBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
     method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
     method public int describeContents();
@@ -22318,6 +22333,26 @@
     field public static final android.os.Parcelable.Creator<android.media.AudioFocusInfo> CREATOR;
   }
 
+  public final class AudioFocusRequest {
+    method public boolean acceptsDelayedFocusGain();
+    method public android.media.AudioAttributes getAudioAttributes();
+    method public int getFocusGain();
+    method public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
+    method public android.os.Handler getOnAudioFocusChangeListenerHandler();
+    method public boolean willPauseWhenDucked();
+  }
+
+  public static final class AudioFocusRequest.Builder {
+    ctor public AudioFocusRequest.Builder(int);
+    ctor public AudioFocusRequest.Builder(android.media.AudioFocusRequest);
+    method public android.media.AudioFocusRequest build();
+    method public android.media.AudioFocusRequest.Builder setAcceptsDelayedFocusGain(boolean);
+    method public android.media.AudioFocusRequest.Builder setAudioAttributes(android.media.AudioAttributes);
+    method public android.media.AudioFocusRequest.Builder setFocusGain(int);
+    method public android.media.AudioFocusRequest.Builder setOnAudioFocusChangeListener(android.media.AudioManager.OnAudioFocusChangeListener, android.os.Handler);
+    method public android.media.AudioFocusRequest.Builder setWillPauseWhenDucked(boolean);
+  }
+
   public final class AudioFormat implements android.os.Parcelable {
     method public int describeContents();
     method public int getChannelCount();
@@ -22395,6 +22430,7 @@
   public class AudioManager {
     method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
     method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes);
+    method public int abandonAudioFocusRequest(android.media.AudioFocusRequest);
     method public void adjustStreamVolume(int, int, int);
     method public void adjustSuggestedStreamVolume(int, int, int);
     method public void adjustVolume(int, int);
@@ -22433,6 +22469,7 @@
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
     method public deprecated boolean registerRemoteController(android.media.RemoteController);
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
+    method public int requestAudioFocus(android.media.AudioFocusRequest);
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int) throws java.lang.IllegalArgumentException;
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, android.media.AudioAttributes, int, int, android.media.audiopolicy.AudioPolicy) throws java.lang.IllegalArgumentException;
     method public deprecated void setBluetoothA2dpOn(boolean);
@@ -22482,6 +22519,7 @@
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT = -2; // 0xfffffffe
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3; // 0xfffffffd
     field public static final int AUDIOFOCUS_NONE = 0; // 0x0
+    field public static final int AUDIOFOCUS_REQUEST_DELAYED = 2; // 0x2
     field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
     field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
     field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
@@ -25939,23 +25977,86 @@
     method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
     method public static final android.net.Uri buildRecordedProgramUri(long);
+    method public static final android.net.Uri buildWatchNextProgramUri(long);
     method public static final boolean isChannelUri(android.net.Uri);
     method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
     method public static final boolean isChannelUriForTunerInput(android.net.Uri);
     method public static final boolean isProgramUri(android.net.Uri);
+    field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
+    field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
+    field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
+    field public static final java.lang.String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED";
     field public static final java.lang.String AUTHORITY = "android.media.tv";
+    field public static final java.lang.String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
     field public static final java.lang.String EXTRA_COLUMN_NAME = "android.media.tv.extra.COLUMN_NAME";
     field public static final java.lang.String EXTRA_DATA_TYPE = "android.media.tv.extra.DATA_TYPE";
     field public static final java.lang.String EXTRA_DEFAULT_VALUE = "android.media.tv.extra.DEFAULT_VALUE";
     field public static final java.lang.String EXTRA_EXISTING_COLUMN_NAMES = "android.media.tv.extra.EXISTING_COLUMN_NAMES";
+    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_PREVIEW_PROGRAM_ID = "android.media.tv.extra.PREVIEW_PROGRAM_ID";
+    field public static final java.lang.String EXTRA_WATCH_NEXT_PROGRAM_ID = "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID";
     field public static final java.lang.String METHOD_ADD_COLUMN = "add_column";
     field public static final java.lang.String METHOD_GET_COLUMNS = "get_columns";
   }
 
+  public static abstract interface TvContract.BasePreviewProgramColumns implements android.media.tv.TvContract.BaseProgramColumns {
+    field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+    field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+    field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+    field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+    field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+    field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+    field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+    field public static final java.lang.String COLUMN_AUTHOR = "author";
+    field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
+    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
+    field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
+    field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+    field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
+    field public static final java.lang.String COLUMN_LIVE = "live";
+    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
+    field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+    field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+    field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+    field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
+    field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+    field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+    field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
+    field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+    field public static final java.lang.String COLUMN_TRANSIENT = "transient";
+    field public static final java.lang.String COLUMN_TYPE = "type";
+    field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+    field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+    field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+    field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+    field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
+    field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+    field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+    field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+    field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+    field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+    field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+    field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+    field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+    field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+    field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+    field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+    field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+    field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+  }
+
   public static abstract interface TvContract.BaseProgramColumns implements android.media.tv.TvContract.BaseTvColumns {
     field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
     field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
-    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
     field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
@@ -26064,70 +26165,17 @@
     field public static final java.lang.String CONTENT_DIRECTORY = "logo";
   }
 
-  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BaseProgramColumns {
-    field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
-    field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
-    field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
-    field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
-    field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
-    field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
-    field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
-    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
-    field public static final java.lang.String COLUMN_AUTHOR = "author";
-    field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
-    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
-    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
-    field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
-    field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
-    field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
-    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
-    field public static final java.lang.String COLUMN_LIVE = "live";
-    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
-    field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
-    field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
-    field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
-    field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
-    field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
-    field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
-    field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
-    field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
-    field public static final java.lang.String COLUMN_TRANSIENT = "transient";
-    field public static final java.lang.String COLUMN_TYPE = "type";
-    field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_WEIGHT = "weight";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/preview_program";
     field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
-    field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
-    field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
-    field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
-    field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
-    field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
-    field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
-    field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
-    field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
-    field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
-    field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
-    field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
-    field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
-    field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
-    field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
-    field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
-    field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
-    field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
-    field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
-    field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
-    field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
-    field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
-    field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
-    field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
-    field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
   }
 
   public static final class TvContract.Programs implements android.media.tv.TvContract.BaseProgramColumns {
     field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
@@ -26163,6 +26211,7 @@
 
   public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseProgramColumns {
     field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
     field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
@@ -26175,6 +26224,19 @@
     field public static final android.net.Uri CONTENT_URI;
   }
 
+  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+    ctor public TvContract.WatchNextPrograms();
+    field public static final java.lang.String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS = "last_engagement_time_utc_millis";
+    field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+    field public static final java.lang.String WATCH_NEXT_TYPE_WATCHLIST = "WATCH_NEXT_TYPE_WATCHLIST";
+  }
+
   public static final class TvContract.WatchedPrograms implements android.media.tv.TvContract.BaseTvColumns {
     field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_DESCRIPTION = "description";
@@ -26304,15 +26366,10 @@
     method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
     method public void updateTvInputInfo(android.media.tv.TvInputInfo);
     field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
-    field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
     field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
-    field public static final java.lang.String ACTION_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PROGRAM_BROWSABLE_DISABLED";
     field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
     field public static final java.lang.String ACTION_SETUP_INPUTS = "android.media.tv.action.SETUP_INPUTS";
     field public static final java.lang.String ACTION_VIEW_RECORDING_SCHEDULES = "android.media.tv.action.VIEW_RECORDING_SCHEDULES";
-    field public static final java.lang.String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
-    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
-    field public static final java.lang.String EXTRA_PROGRAM_ID = "android.media.tv.extra.PROGRAM_ID";
     field public static final int INPUT_STATE_CONNECTED = 0; // 0x0
     field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
     field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
@@ -26988,6 +27045,73 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
+  public final class IpSecAlgorithm implements android.os.Parcelable {
+    ctor public IpSecAlgorithm(java.lang.String, byte[]);
+    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
+    method public int describeContents();
+    method public byte[] getKey();
+    method public java.lang.String getName();
+    method public int getTruncationLengthBits();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";
+    field public static final java.lang.String ALGO_CRYPT_AES_CBC = "cbc(aes)";
+    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
+  }
+
+  public final class IpSecManager {
+    method public void applyTransportModeTransform(java.net.Socket, android.net.IpSecTransform) throws java.io.IOException;
+    method public void applyTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform) throws java.io.IOException;
+    method public void applyTunnelModeTransform(android.net.Network, android.net.IpSecTransform);
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
+    method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
+    method public void removeTunnelModeTransform(android.net.Network, android.net.IpSecTransform);
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
+  }
+
+  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
+  }
+
+  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getPort();
+    method public java.io.FileDescriptor getSocket();
+  }
+
+  public final class IpSecTransform implements java.lang.AutoCloseable {
+    method public void close();
+    field public static final int DIRECTION_IN = 0; // 0x0
+    field public static final int DIRECTION_OUT = 1; // 0x1
+  }
+
+  public static class IpSecTransform.Builder {
+    ctor public IpSecTransform.Builder(android.content.Context);
+    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    method public android.net.IpSecTransform buildTunnelModeTransform(java.net.InetAddress, java.net.InetAddress);
+    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
+    method public android.net.IpSecTransform.Builder setNattKeepalive(int);
+    method public android.net.IpSecTransform.Builder setSpi(int, int);
+    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
+    method public android.net.IpSecTransform.Builder setUnderlyingNetwork(android.net.Network);
+  }
+
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -32611,12 +32735,12 @@
     field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
     field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
     field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
-    field public static final int BATTERY_PROPERTY_BATTERY_STATUS = 6; // 0x6
     field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
     field public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; // 0x1
     field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
     field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
     field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
+    field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
     field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
     field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
     field public static final int BATTERY_STATUS_FULL = 5; // 0x5
@@ -39219,7 +39343,6 @@
     field public static final int PURPOSE_ENCRYPT = 1; // 0x1
     field public static final int PURPOSE_SIGN = 4; // 0x4
     field public static final int PURPOSE_VERIFY = 8; // 0x8
-    field public static final int PURPOSE_WRAP_KEY = 16; // 0x10
     field public static final java.lang.String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
     field public static final java.lang.String SIGNATURE_PADDING_RSA_PSS = "PSS";
   }
@@ -39804,6 +39927,7 @@
     method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
     field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
+    field public static final java.lang.String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
     field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE";
   }
 
@@ -41166,6 +41290,7 @@
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
+    field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100
     field public static final int PROPERTY_WIFI = 8; // 0x8
   }
 
@@ -41183,9 +41308,6 @@
     field public static final int RTT_MODE_VCO = 3; // 0x3
   }
 
-  public static abstract class Call.RttCall.RttAudioMode implements java.lang.annotation.Annotation {
-  }
-
   public final class CallAudioState implements android.os.Parcelable {
     ctor public CallAudioState(boolean, int, int);
     method public static java.lang.String audioRouteToString(int);
@@ -41928,6 +42050,7 @@
     method public boolean handleMmi(java.lang.String);
     method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
     method public boolean isInCall();
+    method public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isOutgoingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isRinging();
@@ -41971,6 +42094,7 @@
     field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
     field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
     field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
+    field public static final java.lang.String METADATA_INCLUDE_SELF_MANAGED_CALLS = "android.telecom.INCLUDE_SELF_MANAGED_CALLS";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
     field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -42491,7 +42615,9 @@
     method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
     method public void sendMultimediaMessage(android.content.Context, android.net.Uri, java.lang.String, android.os.Bundle, android.app.PendingIntent);
     method public void sendMultipartTextMessage(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
+    method public void sendMultipartTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>);
     method public void sendTextMessage(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
+    method public void sendTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
     field public static final java.lang.String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
     field public static final java.lang.String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
     field public static final java.lang.String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
@@ -42699,6 +42825,7 @@
     method public java.lang.String getDeviceId();
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
+    method public java.lang.String[] getForbiddenPlmns();
     method public java.lang.String getGroupIdLevel1();
     method public java.lang.String getIccAuthentication(int, int, java.lang.String);
     method public java.lang.String getImei();
@@ -43598,6 +43725,7 @@
     method public boolean hasSystemFeature(java.lang.String);
     method public boolean hasSystemFeature(java.lang.String, int);
     method public boolean isInstantApp();
+    method public boolean isInstantApp(java.lang.String);
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
     method public java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(android.content.Intent, int);
@@ -49166,6 +49294,7 @@
     method public abstract void setFocused(boolean);
     method public abstract void setHint(java.lang.CharSequence);
     method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
+    method public abstract void setInputType(int);
     method public abstract void setLongClickable(boolean);
     method public abstract void setSanitized(boolean);
     method public abstract void setSelected(boolean);
@@ -50420,10 +50549,12 @@
 
   public final class AutoFillType implements android.os.Parcelable {
     method public int describeContents();
+    method public static android.view.autofill.AutoFillType forDate();
     method public static android.view.autofill.AutoFillType forList();
     method public static android.view.autofill.AutoFillType forText(int);
     method public static android.view.autofill.AutoFillType forToggle();
     method public int getSubType();
+    method public boolean isDate();
     method public boolean isList();
     method public boolean isText();
     method public boolean isToggle();
@@ -50433,9 +50564,11 @@
 
   public final class AutoFillValue implements android.os.Parcelable {
     method public int describeContents();
+    method public static android.view.autofill.AutoFillValue forDate(long);
     method public static android.view.autofill.AutoFillValue forList(int);
     method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence);
     method public static android.view.autofill.AutoFillValue forToggle(boolean);
+    method public long getDateValue();
     method public int getListValue();
     method public java.lang.CharSequence getTextValue();
     method public boolean getToggleValue();
diff --git a/api/test-current.txt b/api/test-current.txt
index e9dddc3..5e4911c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -16,6 +16,7 @@
     field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
     field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
+    field public static final java.lang.String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
     field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
@@ -1004,7 +1005,7 @@
     field public static final int preferenceStyle = 16842894; // 0x101008e
     field public static final int presentationTheme = 16843712; // 0x10103c0
     field public static final int previewImage = 16843482; // 0x10102da
-    field public static final int primaryContentAlpha = 16843367; // 0x1010267
+    field public static final int primaryContentAlpha = 16844117; // 0x1010555
     field public static final int priority = 16842780; // 0x101001c
     field public static final int privateImeOptions = 16843299; // 0x1010223
     field public static final int process = 16842769; // 0x1010011
@@ -1060,7 +1061,9 @@
     field public static final int requireDeviceUnlock = 16843756; // 0x10103ec
     field public static final int required = 16843406; // 0x101028e
     field public static final int requiredAccountType = 16843734; // 0x10103d6
+    field public static final int requiredFeature = 16844119; // 0x1010557
     field public static final int requiredForAllUsers = 16843728; // 0x10103d0
+    field public static final int requiredNotFeature = 16844120; // 0x1010558
     field public static final int requiresFadingEdge = 16843685; // 0x10103a5
     field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364
     field public static final int resizeClip = 16843983; // 0x10104cf
@@ -1129,7 +1132,7 @@
     field public static final int searchSuggestSelection = 16843224; // 0x10101d8
     field public static final int searchSuggestThreshold = 16843373; // 0x101026d
     field public static final int searchViewStyle = 16843904; // 0x1010480
-    field public static final int secondaryContentAlpha = 16843688; // 0x10103a8
+    field public static final int secondaryContentAlpha = 16844118; // 0x1010556
     field public static final int secondaryProgress = 16843064; // 0x1010138
     field public static final int secondaryProgressTint = 16843879; // 0x1010467
     field public static final int secondaryProgressTintMode = 16843880; // 0x1010468
@@ -4153,6 +4156,7 @@
     field public static final int MODE_ERRORED = 2; // 0x2
     field public static final int MODE_IGNORED = 1; // 0x1
     field public static final java.lang.String OPSTR_ADD_VOICEMAIL = "android:add_voicemail";
+    field public static final java.lang.String OPSTR_ANSWER_PHONE_CALLS = "android:answer_phone_calls";
     field public static final java.lang.String OPSTR_BODY_SENSORS = "android:body_sensors";
     field public static final java.lang.String OPSTR_CALL_PHONE = "android:call_phone";
     field public static final java.lang.String OPSTR_CAMERA = "android:camera";
@@ -5490,6 +5494,7 @@
 
   public final class NotificationChannel implements android.os.Parcelable {
     ctor public NotificationChannel(java.lang.String, java.lang.CharSequence, int);
+    ctor public NotificationChannel(java.lang.String, int, int);
     ctor protected NotificationChannel(android.os.Parcel);
     method public boolean canBypassDnd();
     method public boolean canShowBadge();
@@ -5503,6 +5508,7 @@
     method public int getLightColor();
     method public int getLockscreenVisibility();
     method public java.lang.CharSequence getName();
+    method public int getNameResId();
     method public android.net.Uri getSound();
     method public long[] getVibrationPattern();
     method public void setBypassDnd(boolean);
@@ -6589,6 +6595,7 @@
     method public java.lang.String getIdEntry();
     method public java.lang.String getIdPackage();
     method public java.lang.String getIdType();
+    method public int getInputType();
     method public int getLeft();
     method public int getScrollX();
     method public int getScrollY();
@@ -8702,6 +8709,7 @@
     field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
     field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
     field public static final java.lang.String INPUT_SERVICE = "input";
+    field public static final java.lang.String IPSEC_SERVICE = "ipsec";
     field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
     field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
     field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -10198,9 +10206,11 @@
     method public void unregisterSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
     method public void updateSessionAppIcon(int, android.graphics.Bitmap);
     method public void updateSessionAppLabel(int, java.lang.CharSequence);
+    field public static final java.lang.String ACTION_SESSION_COMMITTED = "android.content.pm.action.SESSION_COMMITTED";
     field public static final java.lang.String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
     field public static final java.lang.String EXTRA_OTHER_PACKAGE_NAME = "android.content.pm.extra.OTHER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.content.pm.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_SESSION = "android.content.pm.extra.SESSION";
     field public static final java.lang.String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
     field public static final java.lang.String EXTRA_STATUS = "android.content.pm.extra.STATUS";
     field public static final java.lang.String EXTRA_STATUS_MESSAGE = "android.content.pm.extra.STATUS_MESSAGE";
@@ -10243,6 +10253,7 @@
     method public android.graphics.Bitmap getAppIcon();
     method public java.lang.CharSequence getAppLabel();
     method public java.lang.String getAppPackageName();
+    method public int getInstallReason();
     method public java.lang.String getInstallerPackageName();
     method public float getProgress();
     method public int getSessionId();
@@ -10373,6 +10384,7 @@
     method public abstract boolean hasSystemFeature(java.lang.String);
     method public abstract boolean hasSystemFeature(java.lang.String, int);
     method public abstract boolean isInstantApp();
+    method public abstract boolean isInstantApp(java.lang.String);
     method public abstract boolean isPermissionReviewModeEnabled();
     method public abstract boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public abstract boolean isSafeMode();
@@ -10505,8 +10517,11 @@
     field public static final int GET_SIGNATURES = 64; // 0x40
     field public static final deprecated int GET_UNINSTALLED_PACKAGES = 8192; // 0x2000
     field public static final int GET_URI_PERMISSION_PATTERNS = 2048; // 0x800
+    field public static final int INSTALL_REASON_DEVICE_RESTORE = 2; // 0x2
+    field public static final int INSTALL_REASON_DEVICE_SETUP = 3; // 0x3
     field public static final int INSTALL_REASON_POLICY = 1; // 0x1
     field public static final int INSTALL_REASON_UNKNOWN = 0; // 0x0
+    field public static final int INSTALL_REASON_USER = 4; // 0x4
     field public static final int MATCH_ALL = 131072; // 0x20000
     field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000
     field public static final int MATCH_DIRECT_BOOT_AWARE = 524288; // 0x80000
@@ -10636,6 +10651,7 @@
     field public android.content.pm.ActivityInfo activityInfo;
     field public android.content.IntentFilter filter;
     field public int icon;
+    field public boolean instantAppAvailable;
     field public boolean isDefault;
     field public int labelRes;
     field public int match;
@@ -13860,12 +13876,12 @@
   }
 
   public final class Icon implements android.os.Parcelable {
+    method public static android.graphics.drawable.Icon createWithAdaptiveBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithContentUri(java.lang.String);
     method public static android.graphics.drawable.Icon createWithContentUri(android.net.Uri);
     method public static android.graphics.drawable.Icon createWithData(byte[], int, int);
     method public static android.graphics.drawable.Icon createWithFilePath(java.lang.String);
-    method public static android.graphics.drawable.Icon createWithMaskableBitmap(android.graphics.Bitmap);
     method public static android.graphics.drawable.Icon createWithResource(android.content.Context, int);
     method public static android.graphics.drawable.Icon createWithResource(java.lang.String, int);
     method public int describeContents();
@@ -20756,6 +20772,26 @@
     field public static final int TYPE_WIRED_HEADSET = 3; // 0x3
   }
 
+  public final class AudioFocusRequest {
+    method public boolean acceptsDelayedFocusGain();
+    method public android.media.AudioAttributes getAudioAttributes();
+    method public int getFocusGain();
+    method public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
+    method public android.os.Handler getOnAudioFocusChangeListenerHandler();
+    method public boolean willPauseWhenDucked();
+  }
+
+  public static final class AudioFocusRequest.Builder {
+    ctor public AudioFocusRequest.Builder(int);
+    ctor public AudioFocusRequest.Builder(android.media.AudioFocusRequest);
+    method public android.media.AudioFocusRequest build();
+    method public android.media.AudioFocusRequest.Builder setAcceptsDelayedFocusGain(boolean);
+    method public android.media.AudioFocusRequest.Builder setAudioAttributes(android.media.AudioAttributes);
+    method public android.media.AudioFocusRequest.Builder setFocusGain(int);
+    method public android.media.AudioFocusRequest.Builder setOnAudioFocusChangeListener(android.media.AudioManager.OnAudioFocusChangeListener, android.os.Handler);
+    method public android.media.AudioFocusRequest.Builder setWillPauseWhenDucked(boolean);
+  }
+
   public final class AudioFormat implements android.os.Parcelable {
     method public int describeContents();
     method public int getChannelCount();
@@ -20832,6 +20868,7 @@
 
   public class AudioManager {
     method public int abandonAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener);
+    method public int abandonAudioFocusRequest(android.media.AudioFocusRequest);
     method public void adjustStreamVolume(int, int, int);
     method public void adjustSuggestedStreamVolume(int, int, int);
     method public void adjustVolume(int, int);
@@ -20868,6 +20905,7 @@
     method public deprecated void registerRemoteControlClient(android.media.RemoteControlClient);
     method public deprecated boolean registerRemoteController(android.media.RemoteController);
     method public int requestAudioFocus(android.media.AudioManager.OnAudioFocusChangeListener, int, int);
+    method public int requestAudioFocus(android.media.AudioFocusRequest);
     method public deprecated void setBluetoothA2dpOn(boolean);
     method public void setBluetoothScoOn(boolean);
     method public void setMicrophoneMute(boolean);
@@ -20911,6 +20949,7 @@
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT = -2; // 0xfffffffe
     field public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK = -3; // 0xfffffffd
     field public static final int AUDIOFOCUS_NONE = 0; // 0x0
+    field public static final int AUDIOFOCUS_REQUEST_DELAYED = 2; // 0x2
     field public static final int AUDIOFOCUS_REQUEST_FAILED = 0; // 0x0
     field public static final int AUDIOFOCUS_REQUEST_GRANTED = 1; // 0x1
     field public static final int AUDIO_SESSION_ID_GENERATE = 0; // 0x0
@@ -24205,17 +24244,79 @@
     method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
     method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
     method public static final android.net.Uri buildRecordedProgramUri(long);
+    method public static final android.net.Uri buildWatchNextProgramUri(long);
     method public static final boolean isChannelUri(android.net.Uri);
     method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
     method public static final boolean isChannelUriForTunerInput(android.net.Uri);
     method public static final boolean isProgramUri(android.net.Uri);
+    field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
+    field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
+    field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
+    field public static final java.lang.String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED";
     field public static final java.lang.String AUTHORITY = "android.media.tv";
+    field public static final java.lang.String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
+    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
+    field public static final java.lang.String EXTRA_PREVIEW_PROGRAM_ID = "android.media.tv.extra.PREVIEW_PROGRAM_ID";
+    field public static final java.lang.String EXTRA_WATCH_NEXT_PROGRAM_ID = "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID";
+  }
+
+  public static abstract interface TvContract.BasePreviewProgramColumns implements android.media.tv.TvContract.BaseProgramColumns {
+    field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+    field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+    field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+    field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+    field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+    field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+    field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+    field public static final java.lang.String COLUMN_AUTHOR = "author";
+    field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
+    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
+    field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
+    field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+    field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
+    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
+    field public static final java.lang.String COLUMN_LIVE = "live";
+    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
+    field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
+    field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+    field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+    field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
+    field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
+    field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+    field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
+    field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+    field public static final java.lang.String COLUMN_TYPE = "type";
+    field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+    field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+    field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+    field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+    field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+    field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
+    field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+    field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+    field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
+    field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
+    field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
+    field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
+    field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
+    field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
+    field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+    field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
+    field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
+    field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+    field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+    field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
   }
 
   public static abstract interface TvContract.BaseProgramColumns implements android.media.tv.TvContract.BaseTvColumns {
     field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
     field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
-    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
     field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
@@ -24248,6 +24349,7 @@
     field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
     field public static final java.lang.String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
     field public static final java.lang.String COLUMN_APP_LINK_TEXT = "app_link_text";
+    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
     field public static final java.lang.String COLUMN_DESCRIPTION = "description";
     field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
     field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
@@ -24320,69 +24422,17 @@
     field public static final java.lang.String CONTENT_DIRECTORY = "logo";
   }
 
-  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BaseProgramColumns {
-    field public static final java.lang.String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
-    field public static final java.lang.String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
-    field public static final java.lang.String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
-    field public static final java.lang.String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
-    field public static final java.lang.String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
-    field public static final java.lang.String AVAILABILITY_FREE_WITH_SUBSCRIPTION = "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
-    field public static final java.lang.String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
-    field public static final java.lang.String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
-    field public static final java.lang.String COLUMN_AUTHOR = "author";
-    field public static final java.lang.String COLUMN_AVAILABILITY = "availability";
-    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
-    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
-    field public static final java.lang.String COLUMN_INTERACTION_COUNT = "interaction_count";
-    field public static final java.lang.String COLUMN_INTERACTION_TYPE = "interaction_type";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
-    field public static final java.lang.String COLUMN_ITEM_COUNT = "item_count";
-    field public static final java.lang.String COLUMN_LAST_PLAYBACK_POSITION_MILLIS = "last_playback_position_millis";
-    field public static final java.lang.String COLUMN_LIVE = "live";
-    field public static final java.lang.String COLUMN_LOGO_URI = "logo_uri";
-    field public static final java.lang.String COLUMN_OFFER_PRICE = "offer_price";
-    field public static final java.lang.String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
-    field public static final java.lang.String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
-    field public static final java.lang.String COLUMN_RELEASE_DATE = "release_date";
-    field public static final java.lang.String COLUMN_REVIEW_RATING = "review_rating";
-    field public static final java.lang.String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
-    field public static final java.lang.String COLUMN_STARTING_PRICE = "starting_price";
-    field public static final java.lang.String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
-    field public static final java.lang.String COLUMN_TYPE = "type";
-    field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_WEIGHT = "weight";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/preview_program";
     field public static final android.net.Uri CONTENT_URI;
-    field public static final java.lang.String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
-    field public static final java.lang.String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
-    field public static final java.lang.String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
-    field public static final java.lang.String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
-    field public static final java.lang.String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
-    field public static final java.lang.String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
-    field public static final java.lang.String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
-    field public static final java.lang.String REVIEW_RATING_STYLE_PERCENTAGE = "REVIEW_RATING_STYLE_PERCENTAGE";
-    field public static final java.lang.String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
-    field public static final java.lang.String REVIEW_RATING_STYLE_THUMBS_UP_DOWN = "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
-    field public static final java.lang.String TYPE_ALBUM = "TYPE_ALBUM";
-    field public static final java.lang.String TYPE_ARTIST = "TYPE_ARTIST";
-    field public static final java.lang.String TYPE_CHANNEL = "TYPE_CHANNEL";
-    field public static final java.lang.String TYPE_CLIP = "TYPE_CLIP";
-    field public static final java.lang.String TYPE_EVENT = "TYPE_EVENT";
-    field public static final java.lang.String TYPE_MOVIE = "TYPE_MOVIE";
-    field public static final java.lang.String TYPE_PLAYLIST = "TYPE_PLAYLIST";
-    field public static final java.lang.String TYPE_STATION = "TYPE_STATION";
-    field public static final java.lang.String TYPE_TRACK = "TYPE_TRACK";
-    field public static final java.lang.String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
-    field public static final java.lang.String TYPE_TV_SEASON = "TYPE_TV_SEASON";
-    field public static final java.lang.String TYPE_TV_SERIES = "TYPE_TV_SERIES";
-    field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
-    field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
-    field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
   }
 
   public static final class TvContract.Programs implements android.media.tv.TvContract.BaseProgramColumns {
     field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
@@ -24418,6 +24468,7 @@
 
   public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseProgramColumns {
     field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
     field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
     field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
     field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
@@ -24430,6 +24481,19 @@
     field public static final android.net.Uri CONTENT_URI;
   }
 
+  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+    ctor public TvContract.WatchNextPrograms();
+    field public static final java.lang.String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS = "last_engagement_time_utc_millis";
+    field public static final java.lang.String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program";
+    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program";
+    field public static final android.net.Uri CONTENT_URI;
+    field public static final java.lang.String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+    field public static final java.lang.String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+    field public static final java.lang.String WATCH_NEXT_TYPE_WATCHLIST = "WATCH_NEXT_TYPE_WATCHLIST";
+  }
+
   public final class TvInputInfo implements android.os.Parcelable {
     method public boolean canRecord();
     method public android.content.Intent createSettingsIntent();
@@ -24479,15 +24543,10 @@
     method public void unregisterCallback(android.media.tv.TvInputManager.TvInputCallback);
     method public void updateTvInputInfo(android.media.tv.TvInputInfo);
     field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
-    field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
     field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
-    field public static final java.lang.String ACTION_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PROGRAM_BROWSABLE_DISABLED";
     field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
     field public static final java.lang.String ACTION_SETUP_INPUTS = "android.media.tv.action.SETUP_INPUTS";
     field public static final java.lang.String ACTION_VIEW_RECORDING_SCHEDULES = "android.media.tv.action.VIEW_RECORDING_SCHEDULES";
-    field public static final java.lang.String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
-    field public static final java.lang.String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
-    field public static final java.lang.String EXTRA_PROGRAM_ID = "android.media.tv.extra.PROGRAM_ID";
     field public static final int INPUT_STATE_CONNECTED = 0; // 0x0
     field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
     field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
@@ -25059,6 +25118,68 @@
     field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
   }
 
+  public final class IpSecAlgorithm implements android.os.Parcelable {
+    ctor public IpSecAlgorithm(java.lang.String, byte[]);
+    ctor public IpSecAlgorithm(java.lang.String, byte[], int);
+    method public int describeContents();
+    method public byte[] getKey();
+    method public java.lang.String getName();
+    method public int getTruncationLengthBits();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final java.lang.String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
+    field public static final java.lang.String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";
+    field public static final java.lang.String ALGO_CRYPT_AES_CBC = "cbc(aes)";
+    field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
+  }
+
+  public final class IpSecManager {
+    method public void applyTransportModeTransform(java.net.Socket, android.net.IpSecTransform) throws java.io.IOException;
+    method public void applyTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform) throws java.io.IOException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
+    method public void removeTransportModeTransform(java.net.Socket, android.net.IpSecTransform);
+    method public void removeTransportModeTransform(java.net.DatagramSocket, android.net.IpSecTransform);
+    method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
+  }
+
+  public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
+  }
+
+  public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
+    method public int getSpi();
+  }
+
+  public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
+    method public void close();
+    method public int getPort();
+    method public java.io.FileDescriptor getSocket();
+  }
+
+  public final class IpSecTransform implements java.lang.AutoCloseable {
+    method public void close();
+    field public static final int DIRECTION_IN = 0; // 0x0
+    field public static final int DIRECTION_OUT = 1; // 0x1
+  }
+
+  public static class IpSecTransform.Builder {
+    ctor public IpSecTransform.Builder(android.content.Context);
+    method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
+    method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
+    method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
+    method public android.net.IpSecTransform.Builder setSpi(int, int);
+    method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
+  }
+
   public class LinkAddress implements android.os.Parcelable {
     method public int describeContents();
     method public java.net.InetAddress getAddress();
@@ -30109,12 +30230,12 @@
     field public static final int BATTERY_PLUGGED_AC = 1; // 0x1
     field public static final int BATTERY_PLUGGED_USB = 2; // 0x2
     field public static final int BATTERY_PLUGGED_WIRELESS = 4; // 0x4
-    field public static final int BATTERY_PROPERTY_BATTERY_STATUS = 6; // 0x6
     field public static final int BATTERY_PROPERTY_CAPACITY = 4; // 0x4
     field public static final int BATTERY_PROPERTY_CHARGE_COUNTER = 1; // 0x1
     field public static final int BATTERY_PROPERTY_CURRENT_AVERAGE = 3; // 0x3
     field public static final int BATTERY_PROPERTY_CURRENT_NOW = 2; // 0x2
     field public static final int BATTERY_PROPERTY_ENERGY_COUNTER = 5; // 0x5
+    field public static final int BATTERY_PROPERTY_STATUS = 6; // 0x6
     field public static final int BATTERY_STATUS_CHARGING = 2; // 0x2
     field public static final int BATTERY_STATUS_DISCHARGING = 3; // 0x3
     field public static final int BATTERY_STATUS_FULL = 5; // 0x5
@@ -36438,7 +36559,6 @@
     field public static final int PURPOSE_ENCRYPT = 1; // 0x1
     field public static final int PURPOSE_SIGN = 4; // 0x4
     field public static final int PURPOSE_VERIFY = 8; // 0x8
-    field public static final int PURPOSE_WRAP_KEY = 16; // 0x10
     field public static final java.lang.String SIGNATURE_PADDING_RSA_PKCS1 = "PKCS1";
     field public static final java.lang.String SIGNATURE_PADDING_RSA_PSS = "PSS";
   }
@@ -36994,6 +37114,7 @@
     method public final void unlockAndRun(java.lang.Runnable);
     field public static final java.lang.String ACTION_QS_TILE = "android.service.quicksettings.action.QS_TILE";
     field public static final java.lang.String ACTION_QS_TILE_PREFERENCES = "android.service.quicksettings.action.QS_TILE_PREFERENCES";
+    field public static final java.lang.String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
     field public static final java.lang.String META_DATA_ACTIVE_TILE = "android.service.quicksettings.ACTIVE_TILE";
   }
 
@@ -38303,6 +38424,7 @@
     field public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 128; // 0x80
     field public static final int PROPERTY_HIGH_DEF_AUDIO = 16; // 0x10
     field public static final int PROPERTY_IS_EXTERNAL_CALL = 64; // 0x40
+    field public static final int PROPERTY_SELF_MANAGED = 256; // 0x100
     field public static final int PROPERTY_WIFI = 8; // 0x8
   }
 
@@ -38316,9 +38438,6 @@
     field public static final int RTT_MODE_VCO = 3; // 0x3
   }
 
-  public static abstract class Call.RttCall.RttAudioMode implements java.lang.annotation.Annotation {
-  }
-
   public final class CallAudioState implements android.os.Parcelable {
     ctor public CallAudioState(boolean, int, int);
     method public static java.lang.String audioRouteToString(int);
@@ -38859,6 +38978,8 @@
   }
 
   public class TelecomManager {
+    method public void acceptRingingCall();
+    method public void acceptRingingCall(int);
     method public void addNewIncomingCall(android.telecom.PhoneAccountHandle, android.os.Bundle);
     method public void cancelMissedCallsNotification();
     method public android.content.Intent createManageBlockedNumbersIntent();
@@ -38873,6 +38994,7 @@
     method public boolean handleMmi(java.lang.String);
     method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle);
     method public boolean isInCall();
+    method public boolean isInManagedCall();
     method public boolean isIncomingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isOutgoingCallPermitted(android.telecom.PhoneAccountHandle);
     method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String);
@@ -38909,6 +39031,7 @@
     field public static final java.lang.String GATEWAY_ORIGINAL_ADDRESS = "android.telecom.extra.GATEWAY_ORIGINAL_ADDRESS";
     field public static final java.lang.String GATEWAY_PROVIDER_PACKAGE = "android.telecom.extra.GATEWAY_PROVIDER_PACKAGE";
     field public static final java.lang.String METADATA_INCLUDE_EXTERNAL_CALLS = "android.telecom.INCLUDE_EXTERNAL_CALLS";
+    field public static final java.lang.String METADATA_INCLUDE_SELF_MANAGED_CALLS = "android.telecom.INCLUDE_SELF_MANAGED_CALLS";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_RINGING = "android.telecom.IN_CALL_SERVICE_RINGING";
     field public static final java.lang.String METADATA_IN_CALL_SERVICE_UI = "android.telecom.IN_CALL_SERVICE_UI";
     field public static final int PRESENTATION_ALLOWED = 1; // 0x1
@@ -39596,6 +39719,7 @@
     method public java.lang.String getDeviceId();
     method public java.lang.String getDeviceId(int);
     method public java.lang.String getDeviceSoftwareVersion();
+    method public java.lang.String[] getForbiddenPlmns();
     method public java.lang.String getGroupIdLevel1();
     method public java.lang.String getIccAuthentication(int, int, java.lang.String);
     method public java.lang.String getLine1Number();
@@ -40447,6 +40571,7 @@
     method public boolean hasSystemFeature(java.lang.String);
     method public boolean hasSystemFeature(java.lang.String, int);
     method public boolean isInstantApp();
+    method public boolean isInstantApp(java.lang.String);
     method public boolean isPermissionReviewModeEnabled();
     method public boolean isPermissionRevokedByPolicy(java.lang.String, java.lang.String);
     method public boolean isSafeMode();
@@ -46183,6 +46308,7 @@
     method public abstract void setFocused(boolean);
     method public abstract void setHint(java.lang.CharSequence);
     method public abstract void setId(int, java.lang.String, java.lang.String, java.lang.String);
+    method public abstract void setInputType(int);
     method public abstract void setLongClickable(boolean);
     method public abstract void setSanitized(boolean);
     method public abstract void setSelected(boolean);
@@ -47436,10 +47562,12 @@
 
   public final class AutoFillType implements android.os.Parcelable {
     method public int describeContents();
+    method public static android.view.autofill.AutoFillType forDate();
     method public static android.view.autofill.AutoFillType forList();
     method public static android.view.autofill.AutoFillType forText(int);
     method public static android.view.autofill.AutoFillType forToggle();
     method public int getSubType();
+    method public boolean isDate();
     method public boolean isList();
     method public boolean isText();
     method public boolean isToggle();
@@ -47449,9 +47577,11 @@
 
   public final class AutoFillValue implements android.os.Parcelable {
     method public int describeContents();
+    method public static android.view.autofill.AutoFillValue forDate(long);
     method public static android.view.autofill.AutoFillValue forList(int);
     method public static android.view.autofill.AutoFillValue forText(java.lang.CharSequence);
     method public static android.view.autofill.AutoFillValue forToggle(boolean);
+    method public long getDateValue();
     method public int getListValue();
     method public java.lang.CharSequence getTextValue();
     method public boolean getToggleValue();
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 1aef363..91520f1 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -547,6 +547,12 @@
                         throw new IllegalArgumentException("Missing inherit package name");
                     }
                     break;
+                case "--pkg":
+                    sessionParams.appPackageName = nextOptionData();
+                    if (sessionParams.appPackageName == null) {
+                        throw new IllegalArgumentException("Missing package name");
+                    }
+                    break;
                 case "-S":
                     final long sizeBytes = Long.parseLong(nextOptionData());
                     if (sizeBytes <= 0) {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 6dd31a8..0f2ce3c 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -249,8 +249,10 @@
     public static final int OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE = 67;
     /** @hide Instant app start foreground service. */
     public static final int OP_INSTANT_APP_START_FOREGROUND = 68;
+    /** @hide Answer incoming phone calls */
+    public static final int OP_ANSWER_PHONE_CALLS = 69;
     /** @hide */
-    public static final int _NUM_OP = 69;
+    public static final int _NUM_OP = 70;
 
     /** Access to coarse location information. */
     public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -356,6 +358,9 @@
     /** @hide */
     public static final String OPSTR_INSTANT_APP_START_FOREGROUND
             = "android:instant_app_start_foreground";
+    /** Answer incoming phone calls */
+    public static final String OPSTR_ANSWER_PHONE_CALLS
+            = "android:answer_phone_calls";
 
     private static final int[] RUNTIME_AND_APPOP_PERMISSIONS_OPS = {
             // RUNTIME PERMISSIONS
@@ -388,6 +393,7 @@
             OP_ADD_VOICEMAIL,
             OP_USE_SIP,
             OP_PROCESS_OUTGOING_CALLS,
+            OP_ANSWER_PHONE_CALLS,
             // Microphone
             OP_RECORD_AUDIO,
             // Camera
@@ -480,6 +486,7 @@
             OP_REQUEST_INSTALL_PACKAGES,
             OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE,
             OP_INSTANT_APP_START_FOREGROUND,
+            OP_ANSWER_PHONE_CALLS
     };
 
     /**
@@ -556,6 +563,7 @@
             null, // OP_REQUEST_INSTALL_PACKAGES
             null,
             OPSTR_INSTANT_APP_START_FOREGROUND,
+            OPSTR_ANSWER_PHONE_CALLS,
     };
 
     /**
@@ -632,6 +640,7 @@
             "REQUEST_INSTALL_PACKAGES",
             "OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE",
             "INSTANT_APP_START_FOREGROUND",
+            "ANSWER_PHONE_CALLS",
     };
 
     /**
@@ -708,6 +717,7 @@
             Manifest.permission.REQUEST_INSTALL_PACKAGES,
             null, // no permission for entering picture-in-picture on hide
             Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
+            Manifest.permission.ANSWER_PHONE_CALLS,
     };
 
     /**
@@ -785,6 +795,7 @@
             null, // REQUEST_INSTALL_PACKAGES
             null, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
             null, // INSTANT_APP_START_FOREGROUND
+            null, // ANSWER_PHONE_CALLS
     };
 
     /**
@@ -861,6 +872,7 @@
             false, // REQUEST_INSTALL_PACKAGES
             false, // ENTER_PICTURE_IN_PICTURE_ON_HIDE
             false, // INSTANT_APP_START_FOREGROUND
+            false, // ANSWER_PHONE_CALLS
     };
 
     /**
@@ -936,6 +948,7 @@
             AppOpsManager.MODE_DEFAULT,  // OP_REQUEST_INSTALL_PACKAGES
             AppOpsManager.MODE_ALLOWED,  // OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE
             AppOpsManager.MODE_DEFAULT,  // OP_INSTANT_APP_START_FOREGROUND
+            AppOpsManager.MODE_ALLOWED, // ANSWER_PHONE_CALLS
     };
 
     /**
@@ -1015,6 +1028,7 @@
             false, // OP_REQUEST_INSTALL_PACKAGES
             false, // OP_ENTER_PICTURE_IN_PICTURE_ON_HIDE
             false,
+            false, // ANSWER_PHONE_CALLS
     };
 
     /**
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0608acb..64e2d49 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -805,9 +805,13 @@
 
     @Override
     public boolean isInstantApp() {
+        return isInstantApp(mContext.getPackageName());
+    }
+
+    @Override
+    public boolean isInstantApp(String packageName) {
         try {
-            return mPM.isInstantApp(mContext.getPackageName(),
-                    mContext.getUserId());
+            return mPM.isInstantApp(packageName, mContext.getUserId());
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7ee93d0..0ab4b80 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2254,11 +2254,10 @@
     }
 
     void setResources(Resources r) {
-        if (mPackageInfo.getTargetSdkVersion() < VERSION_CODES.O) {
-            mResources = new CompatResources(r, this);
-        } else {
-            mResources = r;
+        if (r instanceof CompatResources) {
+            ((CompatResources) r).setContext(this);
         }
+        mResources = r;
     }
 
     void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
diff --git a/core/java/android/app/FragmentTransition.java b/core/java/android/app/FragmentTransition.java
index f62ab8d..780a922 100644
--- a/core/java/android/app/FragmentTransition.java
+++ b/core/java/android/app/FragmentTransition.java
@@ -780,8 +780,10 @@
             names = inTransaction.mSharedElementTargetNames;
         }
 
-        inSharedElements.retainAll(names);
-        if (sharedElementCallback != null) {
+        if (names != null) {
+            inSharedElements.retainAll(names);
+        }
+        if (names != null && sharedElementCallback != null) {
             sharedElementCallback.onMapSharedElements(names, inSharedElements);
             for (int i = names.size() - 1; i >= 0; i--) {
                 String name = names.get(i);
@@ -830,8 +832,9 @@
             FragmentContainerTransition fragments,
             Transition enterTransition, boolean inIsPop) {
         BackStackRecord inTransaction = fragments.lastInTransaction;
-        if (enterTransition != null && inTransaction.mSharedElementSourceNames != null &&
-                !inTransaction.mSharedElementSourceNames.isEmpty()) {
+        if (enterTransition != null && inSharedElements != null
+                && inTransaction.mSharedElementSourceNames != null
+                && !inTransaction.mSharedElementSourceNames.isEmpty()) {
             final String targetName = inIsPop
                     ? inTransaction.mSharedElementSourceNames.get(0)
                     : inTransaction.mSharedElementTargetNames.get(0);
@@ -1096,7 +1099,9 @@
         if (transition != null) {
             viewList = new ArrayList<>();
             View root = fragment.getView();
-            root.captureTransitioningViews(viewList);
+            if (root != null) {
+                root.captureTransitioningViews(viewList);
+            }
             if (sharedElements != null) {
                 viewList.removeAll(sharedElements);
             }
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 64fc44b..34a45dd6 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4040,15 +4040,23 @@
         }
 
         /**
-         * Construct a RemoteViews for the final notification header only
+         * Construct a RemoteViews for the final notification header only. This will not be
+         * colorized.
          *
          * @hide
          */
         public RemoteViews makeNotificationHeader() {
+            Boolean colorized = (Boolean) mN.extras.get(EXTRA_COLORIZED);
+            mN.extras.putBoolean(EXTRA_COLORIZED, false);
             RemoteViews header = new BuilderRemoteViews(mContext.getApplicationInfo(),
                     R.layout.notification_template_header);
             resetNotificationHeader(header);
             bindNotificationHeader(header, false /* ambient */);
+            if (colorized != null) {
+                mN.extras.putBoolean(EXTRA_COLORIZED, colorized);
+            } else {
+                mN.extras.remove(EXTRA_COLORIZED);
+            }
             return header;
         }
 
@@ -4167,8 +4175,6 @@
                     mN.extras.putCharSequence(EXTRA_SUB_TEXT, newSummary);
                 }
             }
-            Boolean colorized = (Boolean) mN.extras.get(EXTRA_COLORIZED);
-            mN.extras.putBoolean(EXTRA_COLORIZED, false);
 
             RemoteViews header = makeNotificationHeader();
 
@@ -4177,11 +4183,6 @@
             } else {
                 mN.extras.remove(EXTRA_SUB_TEXT);
             }
-            if (colorized != null) {
-                mN.extras.putBoolean(EXTRA_COLORIZED, colorized);
-            } else {
-                mN.extras.remove(EXTRA_COLORIZED);
-            }
             mN.color = color;
             return header;
         }
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 1a51608..85e6b85 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -20,8 +20,10 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlSerializer;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringRes;
 import android.annotation.SystemApi;
-import android.graphics.Color;
 import android.media.AudioAttributes;
 import android.net.Uri;
 import android.os.Parcel;
@@ -45,6 +47,7 @@
 
     private static final String TAG_CHANNEL = "channel";
     private static final String ATT_NAME = "name";
+    private static final String ATT_NAME_RES_ID = "name_res_id";
     private static final String ATT_ID = "id";
     private static final String ATT_DELETED = "deleted";
     private static final String ATT_PRIORITY = "priority";
@@ -138,6 +141,7 @@
 
     private final String mId;
     private CharSequence mName;
+    private int mNameResId = 0;
     private int mImportance = DEFAULT_IMPORTANCE;
     private boolean mBypassDnd;
     private int mLockscreenVisibility = DEFAULT_VISIBILITY;
@@ -156,7 +160,9 @@
      * Creates a notification channel.
      *
      * @param id The id of the channel. Must be unique per package.
-     * @param name The user visible name of the channel.
+     * @param name The user visible name of the channel. Unchangeable once created; use this
+     *             constructor if the channel represents a user-defined category that does not
+     *             need to be translated.
      * @param importance The importance of the channel. This controls how interruptive notifications
      *                   posted to this channel are. See e.g.
      *                   {@link NotificationManager#IMPORTANCE_DEFAULT}.
@@ -167,6 +173,21 @@
         this.mImportance = importance;
     }
 
+    /**
+     * Creates a notification channel.
+     *
+     * @param id The id of the channel. Must be unique per package.
+     * @param nameResId The resource id of the string containing the channel name.
+     * @param importance The importance of the channel. This controls how interruptive notifications
+     *                   posted to this channel are. See e.g.
+     *                   {@link NotificationManager#IMPORTANCE_DEFAULT}.
+     */
+    public NotificationChannel(String id, @StringRes int nameResId, int importance) {
+        this.mId = id;
+        this.mNameResId = nameResId;
+        this.mImportance = importance;
+    }
+
     protected NotificationChannel(Parcel in) {
         if (in.readByte() != 0) {
             mId = in.readString();
@@ -174,6 +195,7 @@
             mId = null;
         }
         mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mNameResId = in.readInt();
         mImportance = in.readInt();
         mBypassDnd = in.readByte() != 0;
         mLockscreenVisibility = in.readInt();
@@ -206,6 +228,7 @@
             dest.writeByte((byte) 0);
         }
         TextUtils.writeToParcel(mName, dest, flags);
+        dest.writeInt(mNameResId);
         dest.writeInt(mImportance);
         dest.writeByte(mBypassDnd ? (byte) 1 : (byte) 0);
         dest.writeInt(mLockscreenVisibility);
@@ -382,11 +405,18 @@
     /**
      * Returns the user visible name of this channel.
      */
-    public CharSequence getName() {
+    public @Nullable CharSequence getName() {
         return mName;
     }
 
     /**
+     * Returns the resource id of the user visible name of this channel.
+     */
+    public int getNameResId() {
+        return mNameResId;
+    }
+
+    /**
      * Returns the user specified importance {e.g. @link NotificationManager#IMPORTANCE_LOW} for
      * notifications posted to this channel.
      */
@@ -516,7 +546,10 @@
     public void writeXml(XmlSerializer out) throws IOException {
         out.startTag(null, TAG_CHANNEL);
         out.attribute(null, ATT_ID, getId());
-        out.attribute(null, ATT_NAME, getName().toString());
+        if (getName() != null) {
+            out.attribute(null, ATT_NAME, getName().toString());
+        }
+        out.attribute(null, ATT_NAME_RES_ID, Integer.toString(getNameResId()));
         if (getImportance() != DEFAULT_IMPORTANCE) {
             out.attribute(
                     null, ATT_IMPORTANCE, Integer.toString(getImportance()));
@@ -574,6 +607,7 @@
         JSONObject record = new JSONObject();
         record.put(ATT_ID, getId());
         record.put(ATT_NAME, getName());
+        record.put(ATT_NAME_RES_ID, getNameResId());
         if (getImportance() != DEFAULT_IMPORTANCE) {
             record.put(ATT_IMPORTANCE,
                     NotificationListenerService.Ranking.importanceToString(getImportance()));
@@ -691,6 +725,7 @@
 
         NotificationChannel that = (NotificationChannel) o;
 
+        if (getNameResId() != that.getNameResId()) return false;
         if (getImportance() != that.getImportance()) return false;
         if (mBypassDnd != that.mBypassDnd) return false;
         if (getLockscreenVisibility() != that.getLockscreenVisibility()) return false;
@@ -720,6 +755,7 @@
     public int hashCode() {
         int result = getId() != null ? getId().hashCode() : 0;
         result = 31 * result + (getName() != null ? getName().hashCode() : 0);
+        result = 31 * result + getNameResId();
         result = 31 * result + getImportance();
         result = 31 * result + (mBypassDnd ? 1 : 0);
         result = 31 * result + getLockscreenVisibility();
@@ -741,6 +777,7 @@
         return "NotificationChannel{" +
                 "mId='" + mId + '\'' +
                 ", mName=" + mName +
+                ", mNameResId=" + mNameResId +
                 ", mImportance=" + mImportance +
                 ", mBypassDnd=" + mBypassDnd +
                 ", mLockscreenVisibility=" + mLockscreenVisibility +
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 5205959..d37e209 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -447,6 +447,19 @@
     }
 
     /**
+     * @hide
+     */
+    public void createNotificationChannelsForPackage(String pkg,
+            @NonNull List<NotificationChannel> channels) {
+        INotificationManager service = getService();
+        try {
+            service.createNotificationChannels(pkg, new ParceledListSlice(channels));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns the notification channel settings for a given channel id.
      */
     public NotificationChannel getNotificationChannel(String channelId) {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 52ec045..b42df5e 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -22,6 +22,7 @@
 import android.annotation.Nullable;
 import android.content.pm.ActivityInfo;
 import android.content.res.AssetManager;
+import android.content.res.CompatResources;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -447,7 +448,8 @@
      * or the class loader is different.
      */
     private @NonNull Resources getOrCreateResourcesForActivityLocked(@NonNull IBinder activityToken,
-            @NonNull ClassLoader classLoader, @NonNull ResourcesImpl impl) {
+            @NonNull ClassLoader classLoader, @NonNull ResourcesImpl impl,
+            @NonNull CompatibilityInfo compatInfo) {
         final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
                 activityToken);
 
@@ -466,7 +468,8 @@
             }
         }
 
-        Resources resources = new Resources(classLoader);
+        Resources resources = compatInfo.needsCompatResources() ? new CompatResources(classLoader)
+                : new Resources(classLoader);
         resources.setImpl(impl);
         activityResources.activityResources.add(new WeakReference<>(resources));
         if (DEBUG) {
@@ -481,7 +484,7 @@
      * otherwise creates a new Resources object.
      */
     private @NonNull Resources getOrCreateResourcesLocked(@NonNull ClassLoader classLoader,
-            @NonNull ResourcesImpl impl) {
+            @NonNull ResourcesImpl impl, @NonNull CompatibilityInfo compatInfo) {
         // Find an existing Resources that has this ResourcesImpl set.
         final int refCount = mResourceReferences.size();
         for (int i = 0; i < refCount; i++) {
@@ -498,7 +501,8 @@
         }
 
         // Create a new Resources reference and use the existing ResourcesImpl object.
-        Resources resources = new Resources(classLoader);
+        Resources resources = compatInfo.needsCompatResources() ? new CompatResources(classLoader)
+                : new Resources(classLoader);
         resources.setImpl(impl);
         mResourceReferences.add(new WeakReference<>(resources));
         if (DEBUG) {
@@ -614,7 +618,7 @@
                         Slog.d(TAG, "- using existing impl=" + resourcesImpl);
                     }
                     return getOrCreateResourcesForActivityLocked(activityToken, classLoader,
-                            resourcesImpl);
+                            resourcesImpl, key.mCompatInfo);
                 }
 
                 // We will create the ResourcesImpl object outside of holding this lock.
@@ -629,7 +633,7 @@
                     if (DEBUG) {
                         Slog.d(TAG, "- using existing impl=" + resourcesImpl);
                     }
-                    return getOrCreateResourcesLocked(classLoader, resourcesImpl);
+                    return getOrCreateResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
                 }
 
                 // We will create the ResourcesImpl object outside of holding this lock.
@@ -659,9 +663,9 @@
             final Resources resources;
             if (activityToken != null) {
                 resources = getOrCreateResourcesForActivityLocked(activityToken, classLoader,
-                        resourcesImpl);
+                        resourcesImpl, key.mCompatInfo);
             } else {
-                resources = getOrCreateResourcesLocked(classLoader, resourcesImpl);
+                resources = getOrCreateResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
             }
             return resources;
         }
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 483a7a1..d1b2a15 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -26,6 +26,7 @@
 import android.view.autofill.AutoFillValue;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Assist data automatically created by the platform's implementation
@@ -533,6 +534,7 @@
         String mIdPackage;
         String mIdType;
         String mIdEntry;
+
         // TODO(b/33197203): once we have more flags, it might be better to store the individual
         // fields (viewId and childId) of the field.
         AutoFillId mAutoFillId;
@@ -540,6 +542,7 @@
         AutoFillValue mAutoFillValue;
         String[] mAutoFillOptions;
         boolean mSanitized;
+
         int mX;
         int mY;
         int mScrollX;
@@ -581,6 +584,7 @@
         static final int FLAGS_HAS_ID = 0x00200000;
         static final int FLAGS_HAS_CHILDREN = 0x00100000;
         static final int FLAGS_HAS_URL = 0x00080000;
+        static final int FLAGS_HAS_INPUT_TYPE = 0x00040000;
         static final int FLAGS_ALL_CONTROL = 0xfff00000;
 
         int mFlags;
@@ -589,6 +593,7 @@
         CharSequence mContentDescription;
 
         ViewNodeText mText;
+        int mInputType;
         String mUrl;
         Bundle mExtras;
 
@@ -655,6 +660,9 @@
             if ((flags&FLAGS_HAS_TEXT) != 0) {
                 mText = new ViewNodeText(in, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0);
             }
+            if ((flags&FLAGS_HAS_INPUT_TYPE) != 0) {
+                mInputType = in.readInt();
+            }
             if ((flags&FLAGS_HAS_URL) != 0) {
                 mUrl = in.readString();
             }
@@ -711,6 +719,9 @@
                     flags |= FLAGS_HAS_COMPLEX_TEXT;
                 }
             }
+            if (mInputType != 0) {
+                flags |= FLAGS_HAS_INPUT_TYPE;
+            }
             if (mUrl != null) {
                 flags |= FLAGS_HAS_URL;
             }
@@ -778,6 +789,10 @@
             if ((flags&FLAGS_HAS_TEXT) != 0) {
                 mText.writeToParcel(out, (flags&FLAGS_HAS_COMPLEX_TEXT) == 0, writeSensitive);
             }
+            if ((flags&FLAGS_HAS_INPUT_TYPE) != 0) {
+                out.writeInt(mInputType);
+            }
+
             if ((flags&FLAGS_HAS_URL) != 0) {
                 out.writeString(mUrl);
             }
@@ -867,6 +882,15 @@
             return mAutoFillOptions;
         }
 
+        /**
+         * Gets the {@link android.text.InputType} bits of this structure.
+         *
+         * @return bits as defined by {@link android.text.InputType}.
+         */
+        public int getInputType() {
+            return mInputType;
+        }
+
         /** @hide */
         public boolean isSanitized() {
             return mSanitized;
@@ -1534,6 +1558,11 @@
             mNode.mAutoFillOptions = options;
         }
 
+        @Override
+        public void setInputType(int inputType) {
+            mNode.mInputType = inputType;
+        }
+
         /**
          * @hide
          */
@@ -1664,6 +1693,8 @@
         } else {
             Log.i(TAG, prefix + "AutoFill info: id= " + autoFillId
                     + ", type=" + node.getAutoFillType()
+                    + ", options=" + Arrays.toString(node.getAutoFillOptions())
+                    + ", inputType=" + node.getInputType()
                     + ", value=" + node.getAutoFillValue()
                     + ", sanitized=" + node.isSanitized());
         }
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 687d590..9958a79 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -36,6 +36,7 @@
 import android.graphics.Point;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.CancellationSignal;
 import android.os.DeadObjectException;
@@ -500,7 +501,12 @@
     public ContentResolver(Context context) {
         mContext = context != null ? context : ActivityThread.currentApplication();
         mPackageName = mContext.getOpPackageName();
-        mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
+        if (android.os.Process.myUid() == android.os.Process.PHONE_UID) {
+            // STOPSHIP: Telephony needs to fix b/35792675
+            mTargetSdkVersion = Build.VERSION_CODES.N_MR1;
+        } else {
+            mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
+        }
     }
 
     /** @hide */
@@ -1892,7 +1898,7 @@
                 ContentProvider.getUriWithoutUserId(uri),
                 notifyForDescendants,
                 observer,
-                ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
+                ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
     }
 
     /** @hide - designated user version */
@@ -1976,7 +1982,7 @@
                 ContentProvider.getUriWithoutUserId(uri),
                 observer,
                 syncToNetwork,
-                ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
+                ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
     }
 
     /**
@@ -2010,7 +2016,7 @@
                 ContentProvider.getUriWithoutUserId(uri),
                 observer,
                 flags,
-                ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId()));
+                ContentProvider.getUserIdFromUri(uri, mContext.getUserId()));
     }
 
     /**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index aff00c3..de503c0 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2711,6 +2711,7 @@
             VIBRATOR_SERVICE,
             //@hide: STATUS_BAR_SERVICE,
             CONNECTIVITY_SERVICE,
+            IPSEC_SERVICE,
             //@hide: UPDATE_LOCK_SERVICE,
             //@hide: NETWORKMANAGEMENT_SERVICE,
             NETWORK_STATS_SERVICE,
@@ -2814,6 +2815,9 @@
      *  <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
      *  <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
      *  handling management of network connections.
+     *  <dt> {@link #IPSEC_SERVICE} ("ipsec")
+     *  <dd> A {@link android.net.IpSecManager IpSecManager} for managing IPSec on
+     *  sockets and networks.
      *  <dt> {@link #WIFI_SERVICE} ("wifi")
      *  <dd> A {@link android.net.wifi.WifiManager WifiManager} for management of Wi-Fi
      *  connectivity.  On releases before NYC, it should only be obtained from an application
@@ -3154,6 +3158,15 @@
     public static final String CONNECTIVITY_SERVICE = "connectivity";
 
     /**
+     * Use with {@link #getSystemService} to retrieve a
+     * {@link android.net.IpSecManager} for encrypting Sockets or Networks with
+     * IPSec.
+     *
+     * @see #getSystemService
+     */
+    public static final String IPSEC_SERVICE = "ipsec";
+
+    /**
      * Use with {@link #getSystemService} to retrieve a {@link
      * android.os.IUpdateLock} for managing runtime sequences that
      * must not be interrupted by headless OTA application or similar.
diff --git a/core/java/android/content/pm/BaseParceledListSlice.java b/core/java/android/content/pm/BaseParceledListSlice.java
new file mode 100644
index 0000000..c4e4e06
--- /dev/null
+++ b/core/java/android/content/pm/BaseParceledListSlice.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2011 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 android.content.pm;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Transfer a large list of Parcelable objects across an IPC.  Splits into
+ * multiple transactions if needed.
+ *
+ * Caveat: for efficiency and security, all elements must be the same concrete type.
+ * In order to avoid writing the class name of each object, we must ensure that
+ * each object is the same type, or else unparceling then reparceling the data may yield
+ * a different result if the class name encoded in the Parcelable is a Base type.
+ * See b/17671747.
+ *
+ * @hide
+ */
+abstract class BaseParceledListSlice<T> implements Parcelable {
+    private static String TAG = "ParceledListSlice";
+    private static boolean DEBUG = false;
+
+    /*
+     * TODO get this number from somewhere else. For now set it to a quarter of
+     * the 1MB limit.
+     */
+    private static final int MAX_IPC_SIZE = IBinder.MAX_IPC_SIZE;
+
+    private final List<T> mList;
+
+    public BaseParceledListSlice(List<T> list) {
+        mList = list;
+    }
+
+    @SuppressWarnings("unchecked")
+    BaseParceledListSlice(Parcel p, ClassLoader loader) {
+        final int N = p.readInt();
+        mList = new ArrayList<T>(N);
+        if (DEBUG) Log.d(TAG, "Retrieving " + N + " items");
+        if (N <= 0) {
+            return;
+        }
+
+        Parcelable.Creator<?> creator = readParcelableCreator(p, loader);
+        Class<?> listElementClass = null;
+
+        int i = 0;
+        while (i < N) {
+            if (p.readInt() == 0) {
+                break;
+            }
+
+            final T parcelable = readCreator(creator, p, loader);
+            if (listElementClass == null) {
+                listElementClass = parcelable.getClass();
+            } else {
+                verifySameType(listElementClass, parcelable.getClass());
+            }
+
+            mList.add(parcelable);
+
+            if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1));
+            i++;
+        }
+        if (i >= N) {
+            return;
+        }
+        final IBinder retriever = p.readStrongBinder();
+        while (i < N) {
+            if (DEBUG) Log.d(TAG, "Reading more @" + i + " of " + N + ": retriever=" + retriever);
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            data.writeInt(i);
+            try {
+                retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failure retrieving array; only received " + i + " of " + N, e);
+                return;
+            }
+            while (i < N && reply.readInt() != 0) {
+                final T parcelable = reply.readCreator(creator, loader);
+                verifySameType(listElementClass, parcelable.getClass());
+
+                mList.add(parcelable);
+
+                if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1));
+                i++;
+            }
+            reply.recycle();
+            data.recycle();
+        }
+    }
+
+    private T readCreator(Parcelable.Creator<?> creator, Parcel p, ClassLoader loader) {
+        if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+            Parcelable.ClassLoaderCreator<?> classLoaderCreator =
+                    (Parcelable.ClassLoaderCreator<?>) creator;
+            return (T) classLoaderCreator.createFromParcel(p, loader);
+        }
+        return (T) creator.createFromParcel(p);
+    }
+
+    private static void verifySameType(final Class<?> expected, final Class<?> actual) {
+        if (!actual.equals(expected)) {
+            throw new IllegalArgumentException("Can't unparcel type "
+                    + actual.getName() + " in list of type "
+                    + expected.getName());
+        }
+    }
+
+    public List<T> getList() {
+        return mList;
+    }
+
+    /**
+     * Write this to another Parcel. Note that this discards the internal Parcel
+     * and should not be used anymore. This is so we can pass this to a Binder
+     * where we won't have a chance to call recycle on this.
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        final int N = mList.size();
+        final int callFlags = flags;
+        dest.writeInt(N);
+        if (DEBUG) Log.d(TAG, "Writing " + N + " items");
+        if (N > 0) {
+            final Class<?> listElementClass = mList.get(0).getClass();
+            writeParcelableCreator(mList.get(0), dest);
+            int i = 0;
+            while (i < N && dest.dataSize() < MAX_IPC_SIZE) {
+                dest.writeInt(1);
+
+                final T parcelable = mList.get(i);
+                verifySameType(listElementClass, parcelable.getClass());
+                writeElement(parcelable, dest, callFlags);
+
+                if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
+                i++;
+            }
+            if (i < N) {
+                dest.writeInt(0);
+                Binder retriever = new Binder() {
+                    @Override
+                    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                            throws RemoteException {
+                        if (code != FIRST_CALL_TRANSACTION) {
+                            return super.onTransact(code, data, reply, flags);
+                        }
+                        int i = data.readInt();
+                        if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N);
+                        while (i < N && reply.dataSize() < MAX_IPC_SIZE) {
+                            reply.writeInt(1);
+
+                            final T parcelable = mList.get(i);
+                            verifySameType(listElementClass, parcelable.getClass());
+                            writeElement(parcelable, reply, callFlags);
+
+                            if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
+                            i++;
+                        }
+                        if (i < N) {
+                            if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N);
+                            reply.writeInt(0);
+                        }
+                        return true;
+                    }
+                };
+                if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N + ": retriever=" + retriever);
+                dest.writeStrongBinder(retriever);
+            }
+        }
+    }
+
+    protected abstract void writeElement(T parcelable, Parcel reply, int callFlags);
+
+    protected abstract void writeParcelableCreator(T parcelable, Parcel dest);
+
+    protected abstract Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader);
+}
diff --git a/core/java/android/content/pm/InstantAppInfo.java b/core/java/android/content/pm/InstantAppInfo.java
index 898ee110..67afc92 100644
--- a/core/java/android/content/pm/InstantAppInfo.java
+++ b/core/java/android/content/pm/InstantAppInfo.java
@@ -75,7 +75,7 @@
     }
 
     /**
-     * @return The pakcage name.
+     * @return The package name.
      */
     public @NonNull String getPackageName() {
         if (mApplicationInfo != null) {
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 776492a..c3fd089 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -829,7 +829,7 @@
                 final Bitmap bmp = BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor());
                 if (bmp != null) {
                     BitmapDrawable dr = new BitmapDrawable(mContext.getResources(), bmp);
-                    if (shortcut.hasMaskableBitmap()) {
+                    if (shortcut.hasAdaptiveBitmap()) {
                         return new AdaptiveIconDrawable(null, dr);
                     } else {
                         return dr;
@@ -854,7 +854,7 @@
                             icon.getResId(), shortcut.getUserHandle(), density);
                 }
                 case Icon.TYPE_BITMAP:
-                case Icon.TYPE_BITMAP_MASKABLE: {
+                case Icon.TYPE_ADAPTIVE_BITMAP: {
                     return icon.loadDrawable(mContext);
                 }
                 default:
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 278a6d0..9d04cc9 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -95,6 +95,18 @@
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_SESSION_DETAILS = "android.content.pm.action.SESSION_DETAILS";
 
+    /**
+     * Broadcast Action: Explicit broadcast sent to the last known default launcher when a session
+     * for a new install is committed. For managed profile, this is sent to the default launcher
+     * of the primary profile.
+     * <p>
+     * The associated session is defined in {@link #EXTRA_SESSION} and the user for which this
+     * session was created in {@link Intent#EXTRA_USER}.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SESSION_COMMITTED =
+            "android.content.pm.action.SESSION_COMMITTED";
+
     /** {@hide} */
     public static final String
             ACTION_CONFIRM_PERMISSIONS = "android.content.pm.action.CONFIRM_PERMISSIONS";
@@ -107,6 +119,13 @@
     public static final String EXTRA_SESSION_ID = "android.content.pm.extra.SESSION_ID";
 
     /**
+     * {@link SessionInfo} that an operation is working with.
+     *
+     * @see Intent#getParcelableExtra(String)
+     */
+    public static final String EXTRA_SESSION = "android.content.pm.extra.SESSION";
+
+    /**
      * Package name that an operation is working with.
      *
      * @see Intent#getStringExtra(String)
@@ -1184,6 +1203,8 @@
         /** {@hide} */
         public int mode;
         /** {@hide} */
+        public int installReason;
+        /** {@hide} */
         public long sizeBytes;
         /** {@hide} */
         public String appPackageName;
@@ -1206,6 +1227,7 @@
             active = source.readInt() != 0;
 
             mode = source.readInt();
+            installReason = source.readInt();
             sizeBytes = source.readLong();
             appPackageName = source.readString();
             appIcon = source.readParcelable(null);
@@ -1256,6 +1278,15 @@
             return active;
         }
 
+        /**
+         * Return the reason for installing this package.
+         *
+         * @see PackageManager#INSTALL_REASON_UNKNOWN
+         */
+        public int getInstallReason() {
+            return installReason;
+        }
+
         /** {@hide} */
         @Deprecated
         public boolean isOpen() {
@@ -1324,6 +1355,7 @@
             dest.writeInt(active ? 1 : 0);
 
             dest.writeInt(mode);
+            dest.writeInt(installReason);
             dest.writeLong(sizeBytes);
             dest.writeString(appPackageName);
             dest.writeParcelable(appIcon, flags);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 0482f51..b3b5bcf 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -745,7 +745,8 @@
     public static final int DONT_KILL_APP = 0x00000001;
 
     /** @hide */
-    @IntDef({INSTALL_REASON_UNKNOWN, INSTALL_REASON_POLICY})
+    @IntDef({INSTALL_REASON_UNKNOWN, INSTALL_REASON_POLICY, INSTALL_REASON_DEVICE_RESTORE,
+            INSTALL_REASON_DEVICE_SETUP, INSTALL_REASON_USER})
     @Retention(RetentionPolicy.SOURCE)
     public @interface InstallReason {}
 
@@ -760,6 +761,21 @@
     public static final int INSTALL_REASON_POLICY = 1;
 
     /**
+     * Code indicating that this package was installed as part of restoring from another device.
+     */
+    public static final int INSTALL_REASON_DEVICE_RESTORE = 2;
+
+    /**
+     * Code indicating that this package was installed as part of device setup.
+     */
+    public static final int INSTALL_REASON_DEVICE_SETUP = 3;
+
+    /**
+     * Code indicating that the package installation was initiated by the user.
+     */
+    public static final int INSTALL_REASON_USER = 4;
+
+    /**
      * Installation return code: this is passed to the
      * {@link IPackageInstallObserver} on success.
      *
@@ -3737,10 +3753,11 @@
     public abstract @Nullable Drawable getInstantAppIcon(String packageName);
 
     /**
-     * Gets whether the caller is an instant app.
+     * Gets whether this application is an instant app.
      *
      * @return Whether caller is an instant app.
      *
+     * @see #isInstantApp(String)
      * @see #setInstantAppCookie(byte[])
      * @see #getInstantAppCookie()
      * @see #getInstantAppCookieMaxSize()
@@ -3748,12 +3765,26 @@
     public abstract boolean isInstantApp();
 
     /**
+     * Gets whether the given package is an instant app.
+     *
+     * @param packageName The package to check
+     * @return Whether the given package is an instant app.
+     *
+     * @see #isInstantApp()
+     * @see #setInstantAppCookie(byte[])
+     * @see #getInstantAppCookie()
+     * @see #getInstantAppCookieMaxSize()
+     */
+    public abstract boolean isInstantApp(String packageName);
+
+    /**
      * Gets the maximum size in bytes of the cookie data an instant app
      * can store on the device.
      *
      * @return The max cookie size in bytes.
      *
      * @see #isInstantApp()
+     * @see #isInstantApp(String)
      * @see #setInstantAppCookie(byte[])
      * @see #getInstantAppCookie()
      */
@@ -3770,6 +3801,7 @@
      * @return The cookie.
      *
      * @see #isInstantApp()
+     * @see #isInstantApp(String)
      * @see #setInstantAppCookie(byte[])
      * @see #getInstantAppCookieMaxSize()
      */
@@ -3792,6 +3824,7 @@
      * @return Whether the cookie was set.
      *
      * @see #isInstantApp()
+     * @see #isInstantApp(String)
      * @see #getInstantAppCookieMaxSize()
      * @see #getInstantAppCookie()
      */
@@ -4983,6 +5016,7 @@
      */
     public PackageInfo getPackageArchiveInfo(String archiveFilePath, @PackageInfoFlags int flags) {
         final PackageParser parser = new PackageParser();
+        parser.setCallback(new PackageParser.CallbackImpl(this));
         final File apkFile = new File(archiveFilePath);
         try {
             if ((flags & (MATCH_DIRECT_BOOT_UNAWARE | MATCH_DIRECT_BOOT_AWARE)) != 0) {
@@ -6108,6 +6142,9 @@
      *
      * @see #INSTALL_REASON_UNKNOWN
      * @see #INSTALL_REASON_POLICY
+     * @see #INSTALL_REASON_DEVICE_RESTORE
+     * @see #INSTALL_REASON_DEVICE_SETUP
+     * @see #INSTALL_REASON_USER
      *
      * @hide
      */
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index f801e45..60cc6b0 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -285,6 +285,7 @@
     private String[] mSeparateProcesses;
     private boolean mOnlyCoreApps;
     private DisplayMetrics mMetrics;
+    private Callback mCallback;
     private File mCacheDir;
 
     private static final int SDK_VERSION = Build.VERSION.SDK_INT;
@@ -506,6 +507,37 @@
         mCacheDir = cacheDir;
     }
 
+    /**
+     * Callback interface for retrieving information that may be needed while parsing
+     * a package.
+     */
+    public interface Callback {
+        boolean hasFeature(String feature);
+    }
+
+    /**
+     * Standard implementation of {@link Callback} on top of the public {@link PackageManager}
+     * class.
+     */
+    public static final class CallbackImpl implements Callback {
+        private final PackageManager mPm;
+
+        public CallbackImpl(PackageManager pm) {
+            mPm = pm;
+        }
+
+        @Override public boolean hasFeature(String feature) {
+            return mPm.hasSystemFeature(feature);
+        }
+    }
+
+    /**
+     * Set the {@link Callback} that can be used while parsing.
+     */
+    public void setCallback(Callback cb) {
+        mCallback = cb;
+    }
+
     public static final boolean isApkFile(File file) {
         return isApkPath(file.getName());
     }
@@ -2079,15 +2111,15 @@
                     return null;
                 }
             } else if (tagName.equals(TAG_PERMISSION_GROUP)) {
-                if (parsePermissionGroup(pkg, flags, res, parser, outError) == null) {
+                if (!parsePermissionGroup(pkg, flags, res, parser, outError)) {
                     return null;
                 }
             } else if (tagName.equals(TAG_PERMISSION)) {
-                if (parsePermission(pkg, res, parser, outError) == null) {
+                if (!parsePermission(pkg, res, parser, outError)) {
                     return null;
                 }
             } else if (tagName.equals(TAG_PERMISSION_TREE)) {
-                if (parsePermissionTree(pkg, res, parser, outError) == null) {
+                if (!parsePermissionTree(pkg, res, parser, outError)) {
                     return null;
                 }
             } else if (tagName.equals(TAG_USES_PERMISSION)) {
@@ -2708,22 +2740,44 @@
             }
         }
 
+        final String requiredFeature = sa.getNonConfigurationString(
+                com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredFeature, 0);
+
+        final String requiredNotfeature = sa.getNonConfigurationString(
+                com.android.internal.R.styleable.AndroidManifestUsesPermission_requiredNotFeature, 0);
+
         sa.recycle();
 
-        if ((maxSdkVersion == 0) || (maxSdkVersion >= Build.VERSION.RESOURCES_SDK_INT)) {
-            if (name != null) {
-                int index = pkg.requestedPermissions.indexOf(name);
-                if (index == -1) {
-                    pkg.requestedPermissions.add(name.intern());
-                } else {
-                    Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: "
-                            + name + " in package: " + pkg.packageName + " at: "
-                            + parser.getPositionDescription());
-                }
-            }
+        XmlUtils.skipCurrentTag(parser);
+
+        if (name == null) {
+            return true;
         }
 
-        XmlUtils.skipCurrentTag(parser);
+        if ((maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT)) {
+            return true;
+        }
+
+        // Only allow requesting this permission if the platform supports the given feature.
+        if (requiredFeature != null && mCallback != null && !mCallback.hasFeature(requiredFeature)) {
+            return true;
+        }
+
+        // Only allow requesting this permission if the platform doesn't support the given feature.
+        if (requiredNotfeature != null && mCallback != null
+                && mCallback.hasFeature(requiredNotfeature)) {
+            return true;
+        }
+
+        int index = pkg.requestedPermissions.indexOf(name);
+        if (index == -1) {
+            pkg.requestedPermissions.add(name.intern());
+        } else {
+            Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: "
+                    + name + " in package: " + pkg.packageName + " at: "
+                    + parser.getPositionDescription());
+        }
+
         return true;
     }
 
@@ -2951,7 +3005,7 @@
         return true;
     }
 
-    private PermissionGroup parsePermissionGroup(Package owner, int flags, Resources res,
+    private boolean parsePermissionGroup(Package owner, int flags, Resources res,
             XmlResourceParser parser, String[] outError)
             throws XmlPullParserException, IOException {
         PermissionGroup perm = new PermissionGroup(owner);
@@ -2968,7 +3022,7 @@
                 com.android.internal.R.styleable.AndroidManifestPermissionGroup_banner)) {
             sa.recycle();
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         perm.info.descriptionRes = sa.getResourceId(
@@ -2987,22 +3041,22 @@
         if (!parseAllMetaData(res, parser, "<permission-group>", perm,
                 outError)) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         owner.permissionGroups.add(perm);
 
-        return perm;
+        return true;
     }
 
-    private Permission parsePermission(Package owner, Resources res,
+    private boolean parsePermission(Package owner, Resources res,
             XmlResourceParser parser, String[] outError)
         throws XmlPullParserException, IOException {
-        Permission perm = new Permission(owner);
 
         TypedArray sa = res.obtainAttributes(parser,
                 com.android.internal.R.styleable.AndroidManifestPermission);
 
+        Permission perm = new Permission(owner);
         if (!parsePackageItemInfo(owner, perm.info, outError,
                 "<permission>", sa, true /*nameRequired*/,
                 com.android.internal.R.styleable.AndroidManifestPermission_name,
@@ -3013,7 +3067,7 @@
                 com.android.internal.R.styleable.AndroidManifestPermission_banner)) {
             sa.recycle();
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         // Note: don't allow this value to be a reference to a resource
@@ -3040,7 +3094,7 @@
         if (perm.info.protectionLevel == -1) {
             outError[0] = "<permission> does not specify protectionLevel";
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         perm.info.protectionLevel = PermissionInfo.fixProtectionLevel(perm.info.protectionLevel);
@@ -3052,21 +3106,21 @@
                 outError[0] = "<permission>  protectionLevel specifies a non-ephemeral flag but is "
                         + "not based on signature type";
                 mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-                return null;
+                return false;
             }
         }
 
         if (!parseAllMetaData(res, parser, "<permission>", perm, outError)) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         owner.permissions.add(perm);
 
-        return perm;
+        return true;
     }
 
-    private Permission parsePermissionTree(Package owner, Resources res,
+    private boolean parsePermissionTree(Package owner, Resources res,
             XmlResourceParser parser, String[] outError)
         throws XmlPullParserException, IOException {
         Permission perm = new Permission(owner);
@@ -3084,7 +3138,7 @@
                 com.android.internal.R.styleable.AndroidManifestPermissionTree_banner)) {
             sa.recycle();
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         sa.recycle();
@@ -3097,7 +3151,7 @@
             outError[0] = "<permission-tree> name has less than three segments: "
                 + perm.info.name;
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         perm.info.descriptionRes = 0;
@@ -3107,12 +3161,12 @@
         if (!parseAllMetaData(res, parser, "<permission-tree>", perm,
                 outError)) {
             mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
-            return null;
+            return false;
         }
 
         owner.permissions.add(perm);
 
-        return perm;
+        return true;
     }
 
     private Instrumentation parseInstrumentation(Package owner, Resources res,
diff --git a/core/java/android/content/pm/ParceledListSlice.java b/core/java/android/content/pm/ParceledListSlice.java
index 945858e6..d12e884 100644
--- a/core/java/android/content/pm/ParceledListSlice.java
+++ b/core/java/android/content/pm/ParceledListSlice.java
@@ -16,14 +16,9 @@
 
 package android.content.pm;
 
-import android.os.Binder;
-import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.os.RemoteException;
-import android.util.Log;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -31,171 +26,46 @@
  * Transfer a large list of Parcelable objects across an IPC.  Splits into
  * multiple transactions if needed.
  *
- * Caveat: for efficiency and security, all elements must be the same concrete type.
- * In order to avoid writing the class name of each object, we must ensure that
- * each object is the same type, or else unparceling then reparceling the data may yield
- * a different result if the class name encoded in the Parcelable is a Base type.
- * See b/17671747.
+ * @see BaseParceledListSlice
  *
  * @hide
  */
-public class ParceledListSlice<T extends Parcelable> implements Parcelable {
-    private static String TAG = "ParceledListSlice";
-    private static boolean DEBUG = false;
+public class ParceledListSlice<T extends Parcelable> extends BaseParceledListSlice<T> {
+    public ParceledListSlice(List<T> list) {
+        super(list);
+    }
 
-    /*
-     * TODO get this number from somewhere else. For now set it to a quarter of
-     * the 1MB limit.
-     */
-    private static final int MAX_IPC_SIZE = IBinder.MAX_IPC_SIZE;
-
-    private final List<T> mList;
+    private ParceledListSlice(Parcel in, ClassLoader loader) {
+        super(in, loader);
+    }
 
     public static <T extends Parcelable> ParceledListSlice<T> emptyList() {
         return new ParceledListSlice<T>(Collections.<T> emptyList());
     }
 
-    public ParceledListSlice(List<T> list) {
-        mList = list;
-    }
-
-    @SuppressWarnings("unchecked")
-    private ParceledListSlice(Parcel p, ClassLoader loader) {
-        final int N = p.readInt();
-        mList = new ArrayList<T>(N);
-        if (DEBUG) Log.d(TAG, "Retrieving " + N + " items");
-        if (N <= 0) {
-            return;
-        }
-
-        Parcelable.Creator<?> creator = p.readParcelableCreator(loader);
-        Class<?> listElementClass = null;
-
-        int i = 0;
-        while (i < N) {
-            if (p.readInt() == 0) {
-                break;
-            }
-
-            final T parcelable = p.readCreator(creator, loader);
-            if (listElementClass == null) {
-                listElementClass = parcelable.getClass();
-            } else {
-                verifySameType(listElementClass, parcelable.getClass());
-            }
-
-            mList.add(parcelable);
-
-            if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1));
-            i++;
-        }
-        if (i >= N) {
-            return;
-        }
-        final IBinder retriever = p.readStrongBinder();
-        while (i < N) {
-            if (DEBUG) Log.d(TAG, "Reading more @" + i + " of " + N + ": retriever=" + retriever);
-            Parcel data = Parcel.obtain();
-            Parcel reply = Parcel.obtain();
-            data.writeInt(i);
-            try {
-                retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failure retrieving array; only received " + i + " of " + N, e);
-                return;
-            }
-            while (i < N && reply.readInt() != 0) {
-                final T parcelable = reply.readCreator(creator, loader);
-                verifySameType(listElementClass, parcelable.getClass());
-
-                mList.add(parcelable);
-
-                if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1));
-                i++;
-            }
-            reply.recycle();
-            data.recycle();
-        }
-    }
-
-    private static void verifySameType(final Class<?> expected, final Class<?> actual) {
-        if (!actual.equals(expected)) {
-            throw new IllegalArgumentException("Can't unparcel type "
-                    + actual.getName() + " in list of type "
-                    + expected.getName());
-        }
-    }
-
-    public List<T> getList() {
-        return mList;
-    }
-
     @Override
     public int describeContents() {
         int contents = 0;
-        for (int i=0; i<mList.size(); i++) {
-            contents |= mList.get(i).describeContents();
+        final List<T> list = getList();
+        for (int i=0; i<list.size(); i++) {
+            contents |= list.get(i).describeContents();
         }
         return contents;
     }
 
-    /**
-     * Write this to another Parcel. Note that this discards the internal Parcel
-     * and should not be used anymore. This is so we can pass this to a Binder
-     * where we won't have a chance to call recycle on this.
-     */
     @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        final int N = mList.size();
-        final int callFlags = flags;
-        dest.writeInt(N);
-        if (DEBUG) Log.d(TAG, "Writing " + N + " items");
-        if (N > 0) {
-            final Class<?> listElementClass = mList.get(0).getClass();
-            dest.writeParcelableCreator(mList.get(0));
-            int i = 0;
-            while (i < N && dest.dataSize() < MAX_IPC_SIZE) {
-                dest.writeInt(1);
+    protected void writeElement(T parcelable, Parcel dest, int callFlags) {
+        parcelable.writeToParcel(dest, callFlags);
+    }
 
-                final T parcelable = mList.get(i);
-                verifySameType(listElementClass, parcelable.getClass());
-                parcelable.writeToParcel(dest, callFlags);
+    @Override
+    protected void writeParcelableCreator(T parcelable, Parcel dest) {
+        dest.writeParcelableCreator((Parcelable) parcelable);
+    }
 
-                if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
-                i++;
-            }
-            if (i < N) {
-                dest.writeInt(0);
-                Binder retriever = new Binder() {
-                    @Override
-                    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-                            throws RemoteException {
-                        if (code != FIRST_CALL_TRANSACTION) {
-                            return super.onTransact(code, data, reply, flags);
-                        }
-                        int i = data.readInt();
-                        if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N);
-                        while (i < N && reply.dataSize() < MAX_IPC_SIZE) {
-                            reply.writeInt(1);
-
-                            final T parcelable = mList.get(i);
-                            verifySameType(listElementClass, parcelable.getClass());
-                            parcelable.writeToParcel(reply, callFlags);
-
-                            if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
-                            i++;
-                        }
-                        if (i < N) {
-                            if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N);
-                            reply.writeInt(0);
-                        }
-                        return true;
-                    }
-                };
-                if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N + ": retriever=" + retriever);
-                dest.writeStrongBinder(retriever);
-            }
-        }
+    @Override
+    protected Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader) {
+        return from.readParcelableCreator(loader);
     }
 
     @SuppressWarnings("unchecked")
@@ -210,6 +80,7 @@
             return new ParceledListSlice(in, loader);
         }
 
+        @Override
         public ParceledListSlice[] newArray(int size) {
             return new ParceledListSlice[size];
         }
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
index 50f2d53..650b4c0 100644
--- a/core/java/android/content/pm/ResolveInfo.java
+++ b/core/java/android/content/pm/ResolveInfo.java
@@ -69,6 +69,11 @@
     public AuxiliaryResolveInfo auxiliaryInfo;
 
     /**
+     * Whether or not an instant app is available for the resolved intent.
+     */
+    public boolean instantAppAvailable;
+
+    /**
      * The IntentFilter that was matched for this ResolveInfo.
      */
     public IntentFilter filter;
@@ -325,6 +330,7 @@
         system = orig.system;
         targetUserId = orig.targetUserId;
         handleAllWebDataURI = orig.handleAllWebDataURI;
+        instantAppAvailable = orig.instantAppAvailable;
     }
 
     public String toString() {
@@ -388,6 +394,7 @@
         dest.writeInt(noResourceId ? 1 : 0);
         dest.writeInt(iconResourceId);
         dest.writeInt(handleAllWebDataURI ? 1 : 0);
+        dest.writeInt(instantAppAvailable ? 1 : 0);
     }
 
     public static final Creator<ResolveInfo> CREATOR
@@ -435,6 +442,7 @@
         noResourceId = source.readInt() != 0;
         iconResourceId = source.readInt();
         handleAllWebDataURI = source.readInt() != 0;
+        instantAppAvailable = source.readInt() != 0;
     }
 
     public static class DisplayNameComparator
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index d3d3c66..5201694 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -96,7 +96,7 @@
     public static final int FLAG_IMMUTABLE = 1 << 8;
 
     /** @hide */
-    public static final int FLAG_MASKABLE_BITMAP = 1 << 9;
+    public static final int FLAG_ADAPTIVE_BITMAP = 1 << 9;
 
     /** @hide */
     public static final int FLAG_CHOOSER = 1 << 10;
@@ -118,7 +118,7 @@
             FLAG_DISABLED,
             FLAG_STRINGS_RESOLVED,
             FLAG_IMMUTABLE,
-            FLAG_MASKABLE_BITMAP,
+            FLAG_ADAPTIVE_BITMAP,
             FLAG_CHOOSER,
     })
     @Retention(RetentionPolicy.SOURCE)
@@ -784,7 +784,7 @@
         switch (icon.getType()) {
             case Icon.TYPE_RESOURCE:
             case Icon.TYPE_BITMAP:
-            case Icon.TYPE_BITMAP_MASKABLE:
+            case Icon.TYPE_ADAPTIVE_BITMAP:
                 break; // OK
             default:
                 throw getInvalidIconException();
@@ -917,7 +917,7 @@
          * and will be ignored.
          *
          * <p>Only icons created with {@link Icon#createWithBitmap(Bitmap)},
-         * {@link Icon#createWithMaskableBitmap(Bitmap)}
+         * {@link Icon#createWithAdaptiveBitmap(Bitmap)}
          * and {@link Icon#createWithResource} are supported.
          * Other types, such as URI-based icons, are not supported.
          *
@@ -1615,12 +1615,13 @@
     }
 
     /**
-     * Return whether a shortcut's icon is maskable.
+     * Return whether a shortcut's icon is adaptive bitmap following design guideline
+     * defined in {@link AdaptiveIconDrawable}.
      *
      * @hide internal/unit tests only
      */
-    public boolean hasMaskableBitmap() {
-        return hasFlags(FLAG_MASKABLE_BITMAP);
+    public boolean hasAdaptiveBitmap() {
+        return hasFlags(FLAG_ADAPTIVE_BITMAP);
     }
 
     /**
diff --git a/media/java/android/media/MediaDescrambler.aidl b/core/java/android/content/pm/StringParceledListSlice.aidl
similarity index 69%
copy from media/java/android/media/MediaDescrambler.aidl
copy to core/java/android/content/pm/StringParceledListSlice.aidl
index e789244..345f3a7 100644
--- a/media/java/android/media/MediaDescrambler.aidl
+++ b/core/java/android/content/pm/StringParceledListSlice.aidl
@@ -1,11 +1,11 @@
 /*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright 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
+ *     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,
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.content.pm;
 
-/** @hide */
-parcelable MediaDescrambler.DescrambleInfo cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
+parcelable StringParceledListSlice;
diff --git a/core/java/android/content/pm/StringParceledListSlice.java b/core/java/android/content/pm/StringParceledListSlice.java
new file mode 100644
index 0000000..95407449
--- /dev/null
+++ b/core/java/android/content/pm/StringParceledListSlice.java
@@ -0,0 +1,83 @@
+/*
+ * 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 android.content.pm;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Transfer a large list of Parcelable objects across an IPC.  Splits into
+ * multiple transactions if needed.
+ *
+ * @see BaseParceledListSlice
+ *
+ * @hide
+ */
+public class StringParceledListSlice extends BaseParceledListSlice<String> {
+    public StringParceledListSlice(List<String> list) {
+        super(list);
+    }
+
+    private StringParceledListSlice(Parcel in, ClassLoader loader) {
+        super(in, loader);
+    }
+
+    public static StringParceledListSlice emptyList() {
+        return new StringParceledListSlice(Collections.<String> emptyList());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    protected void writeElement(String parcelable, Parcel reply, int callFlags) {
+        reply.writeString(parcelable);
+    }
+
+    @Override
+    protected void writeParcelableCreator(String parcelable, Parcel dest) {
+        return;
+    }
+
+    @Override
+    protected Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader) {
+        return Parcel.STRING_CREATOR;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static final Parcelable.ClassLoaderCreator<StringParceledListSlice> CREATOR =
+            new Parcelable.ClassLoaderCreator<StringParceledListSlice>() {
+        public StringParceledListSlice createFromParcel(Parcel in) {
+            return new StringParceledListSlice(in, null);
+        }
+
+        @Override
+        public StringParceledListSlice createFromParcel(Parcel in, ClassLoader loader) {
+            return new StringParceledListSlice(in, loader);
+        }
+
+        @Override
+        public StringParceledListSlice[] newArray(int size) {
+            return new StringParceledListSlice[size];
+        }
+    };
+}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 4cf55ba..af953e6 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -776,7 +776,6 @@
      * applications.
      * {@hide}
      */
-    @FastNative
     public native final void setConfiguration(int mcc, int mnc, String locale,
             int orientation, int touchscreen, int density, int keyboard,
             int keyboardHidden, int navigation, int screenWidth, int screenHeight,
@@ -786,18 +785,13 @@
     /**
      * Retrieve the resource identifier for the given resource name.
      */
-    @FastNative
     /*package*/ native final int getResourceIdentifier(String type,
                                                        String name,
                                                        String defPackage);
 
-    @FastNative
     /*package*/ native final String getResourceName(int resid);
-    @FastNative
     /*package*/ native final String getResourcePackageName(int resid);
-    @FastNative
     /*package*/ native final String getResourceTypeName(int resid);
-    @FastNative
     /*package*/ native final String getResourceEntryName(int resid);
     
     private native final long openAsset(String fileName, int accessMode);
@@ -811,19 +805,15 @@
     private native final int readAssetChar(long asset);
     private native final int readAsset(long asset, byte[] b, int off, int len);
     private native final long seekAsset(long asset, long offset, int whence);
-    @FastNative
     private native final long getAssetLength(long asset);
-    @FastNative
     private native final long getAssetRemainingLength(long asset);
 
     /** Returns true if the resource was found, filling in mRetStringBlock and
      *  mRetData. */
-    @FastNative
     private native final int loadResourceValue(int ident, short density, TypedValue outValue,
             boolean resolve);
     /** Returns true if the resource was found, filling in mRetStringBlock and
      *  mRetData. */
-    @FastNative
     private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
                                                boolean resolve);
     /*package*/ static final int STYLE_NUM_ENTRIES = 6;
@@ -836,24 +826,17 @@
     static final int STYLE_CHANGING_CONFIGURATIONS = 4;
 
     /*package*/ static final int STYLE_DENSITY = 5;
-    @FastNative
     /*package*/ native static final void applyStyle(long theme,
             int defStyleAttr, int defStyleRes, long xmlParser,
             int[] inAttrs, int length, long outValuesAddress, long outIndicesAddress);
-    @FastNative
     /*package*/ native static final boolean resolveAttrs(long theme,
             int defStyleAttr, int defStyleRes, int[] inValues,
             int[] inAttrs, int[] outValues, int[] outIndices);
-    @FastNative
     /*package*/ native final boolean retrieveAttributes(
             long xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
-    @FastNative
     /*package*/ native final int getArraySize(int resource);
-    @FastNative
     /*package*/ native final int retrieveArray(int resource, int[] outValues);
-    @FastNative
     private native final int getStringBlockCount();
-    @FastNative
     private native final long getNativeStringBlock(int block);
 
     /**
@@ -886,22 +869,17 @@
     /*package*/ native static final void applyThemeStyle(long theme, int styleRes, boolean force);
     /*package*/ native static final void copyTheme(long dest, long source);
     /*package*/ native static final void clearTheme(long theme);
-    @FastNative
     /*package*/ native static final int loadThemeAttributeValue(long theme, int ident,
                                                                 TypedValue outValue,
                                                                 boolean resolve);
     /*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix);
-    @FastNative
     /*package*/ native static final @NativeConfig int getThemeChangingConfigurations(long theme);
 
     private native final long openXmlAssetNative(int cookie, String fileName);
 
     private native final String[] getArrayStringResource(int arrayRes);
-    @FastNative
     private native final int[] getArrayStringInfo(int arrayRes);
-    @FastNative
     /*package*/ native final int[] getArrayIntResource(int arrayRes);
-    @FastNative
     /*package*/ native final int[] getStyleAttributes(int themeRes);
 
     private native final void init(boolean isSystem);
diff --git a/core/java/android/content/res/CompatResources.java b/core/java/android/content/res/CompatResources.java
index 15575fd..829b6b7 100644
--- a/core/java/android/content/res/CompatResources.java
+++ b/core/java/android/content/res/CompatResources.java
@@ -27,11 +27,17 @@
  */
 public class CompatResources extends Resources {
 
-    private final WeakReference<Context> mContext;
+    private WeakReference<Context> mContext;
 
-    public CompatResources(Resources base, Context context) {
-        super(base.getClassLoader());
-        setImpl(base.getImpl());
+    public CompatResources(ClassLoader cls) {
+        super(cls);
+        mContext = new WeakReference<>(null);
+    }
+
+    /**
+     * @hide
+     */
+    public void setContext(Context context) {
         mContext = new WeakReference<>(context);
     }
 
diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index da35ee9..781e235 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -21,6 +21,8 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.DisplayMetrics;
@@ -78,6 +80,11 @@
     private static final int NEEDS_SCREEN_COMPAT = 8;
 
     /**
+     * Set if the application needs to run in with compat resources.
+     */
+    private static final int NEEDS_COMPAT_RES = 16;
+
+    /**
      * The effective screen density we have selected for this application.
      */
     public final int applicationDensity;
@@ -96,6 +103,9 @@
             boolean forceCompat) {
         int compatFlags = 0;
 
+        if (appInfo.targetSdkVersion < VERSION_CODES.O) {
+            compatFlags |= NEEDS_COMPAT_RES;
+        }
         if (appInfo.requiresSmallestWidthDp != 0 || appInfo.compatibleWidthLimitDp != 0
                 || appInfo.largestWidthLimitDp != 0) {
             // New style screen requirements spec.
@@ -274,6 +284,10 @@
         return (mCompatibilityFlags&NEVER_NEEDS_COMPAT) != 0;
     }
 
+    public boolean needsCompatResources() {
+        return (mCompatibilityFlags&NEEDS_COMPAT_RES) != 0;
+    }
+
     /**
      * Returns the translator which translates the coordinates in compatibility mode.
      * @param params the window's parameter
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 1259de6..72f51cf 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2913,11 +2913,14 @@
         if (callback == null) {
             throw new IllegalArgumentException("null NetworkCallback");
         }
-        if (need == null && action != REQUEST) {
+        if ((need == null) && (action != REQUEST)) {
             throw new IllegalArgumentException("null NetworkCapabilities");
         }
-        // TODO: throw an exception if callback.networkRequest is not null.
-        // http://b/20701525
+        final int targetSdk = mContext.getApplicationInfo().targetSdkVersion;
+        if ((targetSdk > VERSION_CODES.N_MR1) && (callback.networkRequest != null)) {
+            // http://b/20701525
+            throw new IllegalArgumentException("NetworkCallback already registered");
+        }
         final NetworkRequest request;
         try {
             synchronized(sCallbacks) {
diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
new file mode 100644
index 0000000..da5cb37
--- /dev/null
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -0,0 +1,181 @@
+/*
+ * 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 android.net;
+
+import android.annotation.StringDef;
+import android.os.Parcel;
+import android.os.Parcelable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to
+ * RFC 4301.
+ */
+public final class IpSecAlgorithm implements Parcelable {
+
+    /**
+     * AES-CBC Encryption/Ciphering Algorithm.
+     *
+     * <p>Valid lengths for this key are {128, 192, 256}.
+     */
+    public static final String ALGO_CRYPT_AES_CBC = "cbc(aes)";
+
+    /**
+     * MD5 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in new
+     * applications and is provided for legacy compatibility with 3gpp infrastructure.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 128.
+     */
+    public static final String ALGO_AUTH_HMAC_MD5 = "hmac(md5)";
+
+    /**
+     * SHA1 HMAC Authentication/Integrity Algorithm. This algorithm is not recommended for use in
+     * new applications and is provided for legacy compatibility with 3gpp infrastructure.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 160.
+     */
+    public static final String ALGO_AUTH_HMAC_SHA1 = "hmac(sha1)";
+
+    /**
+     * SHA256 HMAC Authentication/Integrity Algorithm.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 96 to (default) 256.
+     */
+    public static final String ALGO_AUTH_HMAC_SHA256 = "hmac(sha256)";
+
+    /**
+     * SHA384 HMAC Authentication/Integrity Algorithm.
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 192 to (default) 384.
+     */
+    public static final String ALGO_AUTH_HMAC_SHA384 = "hmac(sha384)";
+    /**
+     * SHA512 HMAC Authentication/Integrity Algorithm
+     *
+     * <p>Valid truncation lengths are multiples of 8 bits from 256 to (default) 512.
+     */
+    public static final String ALGO_AUTH_HMAC_SHA512 = "hmac(sha512)";
+
+    /** @hide */
+    @StringDef({
+        ALGO_CRYPT_AES_CBC,
+        ALGO_AUTH_HMAC_MD5,
+        ALGO_AUTH_HMAC_SHA1,
+        ALGO_AUTH_HMAC_SHA256,
+        ALGO_AUTH_HMAC_SHA512
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AlgorithmName {}
+
+    private final String mName;
+    private final byte[] mKey;
+    private final int mTruncLenBits;
+
+    /**
+     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
+     * algorithm
+     *
+     * @param algorithm type for IpSec.
+     * @param key non-null Key padded to a multiple of 8 bits.
+     */
+    public IpSecAlgorithm(String algorithm, byte[] key) {
+        this(algorithm, key, key.length * 8);
+    }
+
+    /**
+     * Specify a IpSecAlgorithm of one of the supported types including the truncation length of the
+     * algorithm
+     *
+     * @param algoName precise name of the algorithm to be used.
+     * @param key non-null Key padded to a multiple of 8 bits.
+     * @param truncLenBits the number of bits of output hash to use; only meaningful for
+     *     Authentication.
+     */
+    public IpSecAlgorithm(@AlgorithmName String algoName, byte[] key, int truncLenBits) {
+        if (!isTruncationLengthValid(algoName, truncLenBits)) {
+            throw new IllegalArgumentException("Unknown algorithm or invalid length");
+        }
+        mName = algoName;
+        mKey = key.clone();
+        mTruncLenBits = Math.min(truncLenBits, key.length * 8);
+    }
+
+    /** Retrieve the algorithm name */
+    public String getName() {
+        return mName;
+    }
+
+    /** Retrieve the key for this algorithm */
+    public byte[] getKey() {
+        return mKey.clone();
+    }
+
+    /**
+     * Retrieve the truncation length, in bits, for the key in this algo. By default this will be
+     * the length in bits of the key.
+     */
+    public int getTruncationLengthBits() {
+        return mTruncLenBits;
+    }
+
+    /* Parcelable Implementation */
+    public int describeContents() {
+        return 0;
+    }
+
+    /** Write to parcel */
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mName);
+        out.writeByteArray(mKey);
+        out.writeInt(mTruncLenBits);
+    }
+
+    /** Parcelable Creator */
+    public static final Parcelable.Creator<IpSecAlgorithm> CREATOR =
+            new Parcelable.Creator<IpSecAlgorithm>() {
+                public IpSecAlgorithm createFromParcel(Parcel in) {
+                    return new IpSecAlgorithm(in);
+                }
+
+                public IpSecAlgorithm[] newArray(int size) {
+                    return new IpSecAlgorithm[size];
+                }
+            };
+
+    private IpSecAlgorithm(Parcel in) {
+        mName = in.readString();
+        mKey = in.createByteArray();
+        mTruncLenBits = in.readInt();
+    }
+
+    private static boolean isTruncationLengthValid(String algo, int truncLenBits) {
+        switch (algo) {
+            case ALGO_AUTH_HMAC_MD5:
+                return (truncLenBits >= 96 && truncLenBits <= 128);
+            case ALGO_AUTH_HMAC_SHA1:
+                return (truncLenBits >= 96 && truncLenBits <= 160);
+            case ALGO_AUTH_HMAC_SHA256:
+                return (truncLenBits >= 96 && truncLenBits <= 256);
+            case ALGO_AUTH_HMAC_SHA384:
+                return (truncLenBits >= 192 && truncLenBits <= 384);
+            case ALGO_AUTH_HMAC_SHA512:
+                return (truncLenBits >= 256 && truncLenBits <= 512);
+            default:
+                return false;
+        }
+    }
+};
diff --git a/media/java/android/media/MediaDescrambler.aidl b/core/java/android/net/IpSecConfig.aidl
similarity index 85%
rename from media/java/android/media/MediaDescrambler.aidl
rename to core/java/android/net/IpSecConfig.aidl
index e789244..eaefca7 100644
--- a/media/java/android/media/MediaDescrambler.aidl
+++ b/core/java/android/net/IpSecConfig.aidl
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.media;
+package android.net;
 
 /** @hide */
-parcelable MediaDescrambler.DescrambleInfo cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
+parcelable IpSecConfig;
diff --git a/core/java/android/net/IpSecConfig.java b/core/java/android/net/IpSecConfig.java
new file mode 100644
index 0000000..b58bf42
--- /dev/null
+++ b/core/java/android/net/IpSecConfig.java
@@ -0,0 +1,197 @@
+/*
+ * 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 android.net;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+/** @hide */
+public final class IpSecConfig implements Parcelable {
+    private static final String TAG = IpSecConfig.class.getSimpleName();
+
+    //MODE_TRANSPORT or MODE_TUNNEL
+    int mode;
+
+    // For tunnel mode
+    InetAddress localAddress;
+
+    InetAddress remoteAddress;
+
+    // Limit selection by network interface
+    Network network;
+
+    public static class Flow {
+        // Minimum requirements for identifying a transform
+        // SPI identifying the IPsec flow in packet processing
+        // and a remote IP address
+        int spi;
+
+        // Encryption Algorithm
+        IpSecAlgorithm encryptionAlgo;
+
+        // Authentication Algorithm
+        IpSecAlgorithm authenticationAlgo;
+    }
+
+    Flow[] flow = new Flow[2];
+
+    // For tunnel mode IPv4 UDP Encapsulation
+    // IpSecTransform#ENCAP_ESP_*, such as ENCAP_ESP_OVER_UDP_IKE
+    int encapType;
+    int encapLocalPort;
+    int encapRemotePort;
+
+    // An optional protocol to match with the selector
+    int selectorProto;
+
+    // A bitmask of FEATURE_* indicating which of the fields
+    // of this class are valid.
+    long features;
+
+    // An interval, in seconds between the NattKeepalive packets
+    int nattKeepaliveInterval;
+
+    public InetAddress getLocalIp() {
+        return localAddress;
+    }
+
+    public int getSpi(int direction) {
+        return flow[direction].spi;
+    }
+
+    public InetAddress getRemoteIp() {
+        return remoteAddress;
+    }
+
+    public IpSecAlgorithm getEncryptionAlgo(int direction) {
+        return flow[direction].encryptionAlgo;
+    }
+
+    public IpSecAlgorithm getAuthenticationAlgo(int direction) {
+        return flow[direction].authenticationAlgo;
+    }
+
+    Network getNetwork() {
+        return network;
+    }
+
+    public int getEncapType() {
+        return encapType;
+    }
+
+    public int getEncapLocalPort() {
+        return encapLocalPort;
+    }
+
+    public int getEncapRemotePort() {
+        return encapRemotePort;
+    }
+
+    public int getSelectorProto() {
+        return selectorProto;
+    }
+
+    int getNattKeepaliveInterval() {
+        return nattKeepaliveInterval;
+    }
+
+    public boolean hasProperty(int featureBits) {
+        return (features & featureBits) == featureBits;
+    }
+
+    // Parcelable Methods
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeLong(features);
+        // TODO: Use a byte array or other better method for storing IPs that can also include scope
+        out.writeString((localAddress != null) ? localAddress.getHostAddress() : null);
+        // TODO: Use a byte array or other better method for storing IPs that can also include scope
+        out.writeString((remoteAddress != null) ? remoteAddress.getHostAddress() : null);
+        out.writeParcelable(network, flags);
+        out.writeInt(flow[IpSecTransform.DIRECTION_IN].spi);
+        out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].encryptionAlgo, flags);
+        out.writeParcelable(flow[IpSecTransform.DIRECTION_IN].authenticationAlgo, flags);
+        out.writeInt(flow[IpSecTransform.DIRECTION_OUT].spi);
+        out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].encryptionAlgo, flags);
+        out.writeParcelable(flow[IpSecTransform.DIRECTION_OUT].authenticationAlgo, flags);
+        out.writeInt(encapType);
+        out.writeInt(encapLocalPort);
+        out.writeInt(encapRemotePort);
+        out.writeInt(selectorProto);
+    }
+
+    // Package Private: Used by the IpSecTransform.Builder;
+    // there should be no public constructor for this object
+    IpSecConfig() {
+        flow[IpSecTransform.DIRECTION_IN].spi = 0;
+        flow[IpSecTransform.DIRECTION_OUT].spi = 0;
+        nattKeepaliveInterval = 0; //FIXME constant
+    }
+
+    private static InetAddress readInetAddressFromParcel(Parcel in) {
+        String addrString = in.readString();
+        if (addrString == null) {
+            return null;
+        }
+        try {
+            return InetAddress.getByName(addrString);
+        } catch (UnknownHostException e) {
+            Log.wtf(TAG, "Invalid IpAddress " + addrString);
+            return null;
+        }
+    }
+
+    private IpSecConfig(Parcel in) {
+        features = in.readLong();
+        localAddress = readInetAddressFromParcel(in);
+        remoteAddress = readInetAddressFromParcel(in);
+        network = (Network) in.readParcelable(Network.class.getClassLoader());
+        flow[IpSecTransform.DIRECTION_IN].spi = in.readInt();
+        flow[IpSecTransform.DIRECTION_IN].encryptionAlgo =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
+        flow[IpSecTransform.DIRECTION_IN].authenticationAlgo =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
+        flow[IpSecTransform.DIRECTION_OUT].spi = in.readInt();
+        flow[IpSecTransform.DIRECTION_OUT].encryptionAlgo =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
+        flow[IpSecTransform.DIRECTION_OUT].authenticationAlgo =
+                (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader());
+        encapType = in.readInt();
+        encapLocalPort = in.readInt();
+        encapRemotePort = in.readInt();
+        selectorProto = in.readInt();
+    }
+
+    public static final Parcelable.Creator<IpSecConfig> CREATOR =
+            new Parcelable.Creator<IpSecConfig>() {
+                public IpSecConfig createFromParcel(Parcel in) {
+                    return new IpSecConfig(in);
+                }
+
+                public IpSecConfig[] newArray(int size) {
+                    return new IpSecConfig[size];
+                }
+            };
+}
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
new file mode 100644
index 0000000..2c544e9
--- /dev/null
+++ b/core/java/android/net/IpSecManager.java
@@ -0,0 +1,379 @@
+/*
+ * 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 android.net;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.os.INetworkManagementService;
+import android.os.ParcelFileDescriptor;
+import android.util.AndroidException;
+import dalvik.system.CloseGuard;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.Socket;
+
+/**
+ * This class contains methods for managing IPsec sessions, which will perform kernel-space
+ * encryption and decryption of socket or Network traffic.
+ *
+ * <p>An IpSecManager may be obtained by calling {@link
+ * android.content.Context#getSystemService(String) Context#getSystemService(String)} with {@link
+ * android.content.Context#IPSEC_SERVICE Context#IPSEC_SERVICE}
+ */
+public final class IpSecManager {
+    private static final String TAG = "IpSecManager";
+
+    /**
+     * Indicates that the combination of remote InetAddress and SPI was non-unique for a given
+     * request. If encountered, selection of a new SPI is required before a transform may be
+     * created. Note, this should happen very rarely if the SPI is chosen to be sufficiently random
+     * or reserved using reserveSecurityParameterIndex.
+     */
+    public static final class SpiUnavailableException extends AndroidException {
+        private final int mSpi;
+
+        /**
+         * Construct an exception indicating that a transform with the given SPI is already in use
+         * or otherwise unavailable.
+         *
+         * @param msg Description indicating the colliding SPI
+         * @param spi the SPI that could not be used due to a collision
+         */
+        SpiUnavailableException(String msg, int spi) {
+            super(msg + "(spi: " + spi + ")");
+            mSpi = spi;
+        }
+
+        /** Retrieve the SPI that caused a collision */
+        public int getSpi() {
+            return mSpi;
+        }
+    }
+
+    /**
+     * Indicates that the requested system resource for IPsec, such as a socket or other system
+     * resource is unavailable. If this exception is thrown, try releasing allocated objects of the
+     * type requested.
+     */
+    public static final class ResourceUnavailableException extends AndroidException {
+
+        ResourceUnavailableException(String msg) {
+            super(msg);
+        }
+    }
+
+    private final Context mContext;
+    private final INetworkManagementService mService;
+
+    public static final class SecurityParameterIndex implements AutoCloseable {
+        private final Context mContext;
+        private final InetAddress mDestinationAddress;
+        private final CloseGuard mCloseGuard = CloseGuard.get();
+        private int mSpi;
+
+        /** Return the underlying SPI held by this object */
+        public int getSpi() {
+            return mSpi;
+        }
+
+        private SecurityParameterIndex(Context context, InetAddress destinationAddress, int spi)
+                throws ResourceUnavailableException, SpiUnavailableException {
+            mContext = context;
+            mDestinationAddress = destinationAddress;
+            mSpi = spi;
+            mCloseGuard.open("open");
+        }
+
+        /**
+         * Release an SPI that was previously reserved.
+         *
+         * <p>Release an SPI for use by other users in the system. This will fail if the SPI is
+         * currently in use by an IpSecTransform.
+         *
+         * @param destinationAddress SPIs must be unique for each combination of SPI and destination
+         *     address. Thus, the destinationAddress to which the SPI will communicate must be
+         *     supplied.
+         * @param spi the previously reserved SPI to be freed.
+         */
+        @Override
+        public void close() {
+            mSpi = INVALID_SECURITY_PARAMETER_INDEX; // TODO: Invalid SPI
+            mCloseGuard.close();
+        }
+
+        @Override
+        protected void finalize() {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
+            close();
+        }
+    }
+
+    /**
+     * The Security Parameter Index, SPI, 0 indicates an unknown or invalid index.
+     *
+     * <p>No IPsec packet may contain an SPI of 0.
+     */
+    public static final int INVALID_SECURITY_PARAMETER_INDEX = 0;
+
+    /**
+     * Reserve an SPI for traffic bound towards the specified destination address.
+     *
+     * <p>If successful, this SPI is guaranteed available until released by a call to {@link
+     * SecurityParameterIndex#close()}.
+     *
+     * @param destinationAddress SPIs must be unique for each combination of SPI and destination
+     *     address.
+     * @param requestedSpi the requested SPI, or '0' to allocate a random SPI.
+     * @return the reserved SecurityParameterIndex
+     * @throws ResourceUnavailableException indicating that too many SPIs are currently allocated
+     *     for this user
+     * @throws SpiUnavailableException indicating that a particular SPI cannot be reserved
+     */
+    public SecurityParameterIndex reserveSecurityParameterIndex(
+            InetAddress destinationAddress, int requestedSpi)
+            throws SpiUnavailableException, ResourceUnavailableException {
+        return new SecurityParameterIndex(mContext, destinationAddress, requestedSpi);
+    }
+
+    /**
+     * Apply an active Transport Mode IPsec Transform to a stream socket to perform IPsec
+     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
+     * transform. For security reasons, attempts to send traffic to any IP address other than the
+     * address associated with that transform will throw an IOException. In addition, if the
+     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
+     * send() or receive() until the transform is removed from the socket by calling {@link
+     * #removeTransportModeTransform(Socket, IpSecTransform)};
+     *
+     * @param socket a stream socket
+     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
+     */
+    public void applyTransportModeTransform(Socket socket, IpSecTransform transform)
+            throws IOException {
+        applyTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
+    }
+
+    /**
+     * Apply an active Transport Mode IPsec Transform to a datagram socket to perform IPsec
+     * encapsulation of the traffic flowing between the socket and the remote InetAddress of that
+     * transform. For security reasons, attempts to send traffic to any IP address other than the
+     * address associated with that transform will throw an IOException. In addition, if the
+     * IpSecTransform is later deactivated, the socket will throw an IOException on any calls to
+     * send() or receive() until the transform is removed from the socket by calling {@link
+     * #removeTransportModeTransform(DatagramSocket, IpSecTransform)};
+     *
+     * @param socket a datagram socket
+     * @param transform an {@link IpSecTransform}, which must be an active Transport Mode transform.
+     */
+    public void applyTransportModeTransform(DatagramSocket socket, IpSecTransform transform)
+            throws IOException {
+        applyTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
+    }
+
+    /* Call down to activate a transform */
+    private void applyTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {}
+
+    /**
+     * Apply an active Tunnel Mode IPsec Transform to a network, which will tunnel all traffic to
+     * and from that network's interface with IPsec (applies an outer IP header and IPsec Header to
+     * all traffic, and expects an additional IP header and IPsec Header on all inbound traffic).
+     * Applications should probably not use this API directly. Instead, they should use {@link
+     * VpnService} to provide VPN capability in a more generic fashion.
+     *
+     * @param net a {@link Network} that will be tunneled via IP Sec.
+     * @param transform an {@link IpSecTransform}, which must be an active Tunnel Mode transform.
+     * @hide
+     */
+    @SystemApi
+    public void applyTunnelModeTransform(Network net, IpSecTransform transform) {}
+
+    /**
+     * Remove a transform from a given stream socket. Once removed, traffic on the socket will not
+     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
+     * communication in the clear in the event socket reuse is desired. This operation will succeed
+     * regardless of the underlying state of a transform. If a transform is removed, communication
+     * on all sockets to which that transform was applied will fail until this method is called.
+     *
+     * @param socket a socket that previously had a transform applied to it.
+     * @param transform the IPsec Transform that was previously applied to the given socket
+     */
+    public void removeTransportModeTransform(Socket socket, IpSecTransform transform) {
+        removeTransportModeTransform(ParcelFileDescriptor.fromSocket(socket), transform);
+    }
+
+    /**
+     * Remove a transform from a given datagram socket. Once removed, traffic on the socket will not
+     * be encypted. This allows sockets that have been used for IPsec to be reclaimed for
+     * communication in the clear in the event socket reuse is desired. This operation will succeed
+     * regardless of the underlying state of a transform. If a transform is removed, communication
+     * on all sockets to which that transform was applied will fail until this method is called.
+     *
+     * @param socket a socket that previously had a transform applied to it.
+     * @param transform the IPsec Transform that was previously applied to the given socket
+     */
+    public void removeTransportModeTransform(DatagramSocket socket, IpSecTransform transform) {
+        removeTransportModeTransform(ParcelFileDescriptor.fromDatagramSocket(socket), transform);
+    }
+
+    /* Call down to activate a transform */
+    private void removeTransportModeTransform(ParcelFileDescriptor pfd, IpSecTransform transform) {}
+
+    /**
+     * Remove a Tunnel Mode IPsec Transform from a {@link Network}. This must be used as part of
+     * cleanup if a tunneled Network experiences a change in default route. The Network will drop
+     * all traffic that cannot be routed to the Tunnel's outbound interface. If that interface is
+     * lost, all traffic will drop.
+     *
+     * @param net a network that currently has transform applied to it.
+     * @param transform a Tunnel Mode IPsec Transform that has been previously applied to the given
+     *     network
+     * @hide
+     */
+    @SystemApi
+    public void removeTunnelModeTransform(Network net, IpSecTransform transform) {}
+
+    /**
+     * Class providing access to a system-provided UDP Encapsulation Socket, which may be used for
+     * IKE signalling as well as for inbound and outbound UDP encapsulated IPsec traffic.
+     *
+     * <p>The socket provided by this class cannot be re-bound or closed via the inner
+     * FileDescriptor. Instead, disposing of this socket requires a call to close().
+     */
+    public static final class UdpEncapsulationSocket implements AutoCloseable {
+        private final FileDescriptor mFd;
+        private final Context mContext;
+        private final CloseGuard mCloseGuard = CloseGuard.get();
+
+        private UdpEncapsulationSocket(Context context, int port)
+                throws ResourceUnavailableException {
+            mContext = context;
+            mCloseGuard.open("constructor");
+            // TODO: go down to the kernel and get a socket on the specified
+            mFd = new FileDescriptor();
+        }
+
+        private UdpEncapsulationSocket(Context context) throws ResourceUnavailableException {
+            mContext = context;
+            mCloseGuard.open("constructor");
+            // TODO: go get a random socket on a random port
+            mFd = new FileDescriptor();
+        }
+
+        /** Access the inner UDP Encapsulation Socket */
+        public FileDescriptor getSocket() {
+            return mFd;
+        }
+
+        /** Retrieve the port number of the inner encapsulation socket */
+        public int getPort() {
+            return 0; // TODO get the port number from the Socket;
+        }
+
+        @Override
+        /**
+         * Release the resources that have been reserved for this Socket.
+         *
+         * <p>This method closes the underlying socket, reducing a user's allocated sockets in the
+         * system. This must be done as part of cleanup following use of a socket. Failure to do so
+         * will cause the socket to count against a total allocation limit for IpSec and eventually
+         * fail due to resource limits.
+         *
+         * @param fd a file descriptor previously returned as a UDP Encapsulation socket.
+         */
+        public void close() {
+            // TODO: Go close the socket
+            mCloseGuard.close();
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+
+            close();
+        }
+    };
+
+    /**
+     * Open a socket that is bound to a free UDP port on the system.
+     *
+     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
+     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
+     * Encapsulation port.
+     *
+     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
+     * socket port. Explicitly opening this port is only necessary if communication is desired on
+     * that port.
+     *
+     * @param port a local UDP port to be reserved for UDP Encapsulation. is provided, then this
+     *     method will bind to the specified port or fail. To retrieve the port number, call {@link
+     *     android.system.Os#getsockname(FileDescriptor)}.
+     * @return a {@link UdpEncapsulationSocket} that is bound to the requested port for the lifetime
+     *     of the object.
+     */
+    // Returning a socket in this fashion that has been created and bound by the system
+    // is the only safe way to ensure that a socket is both accessible to the user and
+    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
+    // the port, which could potentially impact the traffic of the next user who binds to that
+    // socket.
+    public UdpEncapsulationSocket openUdpEncapsulationSocket(int port)
+            throws IOException, ResourceUnavailableException {
+        // Temporary code
+        return new UdpEncapsulationSocket(mContext, port);
+    }
+
+    /**
+     * Open a socket that is bound to a port selected by the system.
+     *
+     * <p>By binding in this manner and holding the FileDescriptor, the socket cannot be un-bound by
+     * the caller. This provides safe access to a socket on a port that can later be used as a UDP
+     * Encapsulation port.
+     *
+     * <p>This socket reservation works in conjunction with IpSecTransforms, which may re-use the
+     * socket port. Explicitly opening this port is only necessary if communication is desired on
+     * that port.
+     *
+     * @return a {@link UdpEncapsulationSocket} that is bound to an arbitrarily selected port
+     */
+    // Returning a socket in this fashion that has been created and bound by the system
+    // is the only safe way to ensure that a socket is both accessible to the user and
+    // safely usable for Encapsulation without allowing a user to possibly unbind from/close
+    // the port, which could potentially impact the traffic of the next user who binds to that
+    // socket.
+    public UdpEncapsulationSocket openUdpEncapsulationSocket()
+            throws IOException, ResourceUnavailableException {
+        // Temporary code
+        return new UdpEncapsulationSocket(mContext);
+    }
+
+    /**
+     * Retrieve an instance of an IpSecManager within you application context
+     *
+     * @param context the application context for this manager
+     * @hide
+     */
+    public IpSecManager(Context context, INetworkManagementService service) {
+        mContext = checkNotNull(context, "missing context");
+        mService = checkNotNull(service, "missing service");
+    }
+}
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
new file mode 100644
index 0000000..d6dd28be
--- /dev/null
+++ b/core/java/android/net/IpSecTransform.java
@@ -0,0 +1,471 @@
+/*
+ * 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 android.net;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.system.ErrnoException;
+import android.util.Log;
+import dalvik.system.CloseGuard;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.InetAddress;
+
+/**
+ * This class represents an IpSecTransform, which encapsulates both properties and state of IPsec.
+ *
+ * <p>IpSecTransforms must be built from an IpSecTransform.Builder, and they must persist throughout
+ * the lifetime of the underlying transform. If a transform object leaves scope, the underlying
+ * transform may be disabled automatically, with likely undesirable results.
+ *
+ * <p>An IpSecTransform may either represent a tunnel mode transform that operates on a wide array
+ * of traffic or may represent a transport mode transform operating on a Socket or Sockets.
+ */
+public final class IpSecTransform implements AutoCloseable {
+    private static final String TAG = "IpSecTransform";
+
+    /**
+     * For direction-specific attributes of an IpSecTransform, indicates that an attribute applies
+     * to traffic towards the host.
+     */
+    public static final int DIRECTION_IN = 0;
+
+    /**
+     * For direction-specific attributes of an IpSecTransform, indicates that an attribute applies
+     * to traffic from the host.
+     */
+    public static final int DIRECTION_OUT = 1;
+
+    /** @hide */
+    @IntDef(value = {DIRECTION_IN, DIRECTION_OUT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TransformDirection {}
+
+    /** @hide */
+    private static final int MODE_TUNNEL = 0;
+
+    /** @hide */
+    private static final int MODE_TRANSPORT = 1;
+
+    /** @hide */
+    public static final int ENCAP_NONE = 0;
+
+    /**
+     * IpSec traffic will be encapsulated within UDP as per <a
+     * href="https://tools.ietf.org/html/rfc3948">RFC3498</a>.
+     *
+     * @hide
+     */
+    public static final int ENCAP_ESPINUDP = 1;
+
+    /**
+     * IpSec traffic will be encapsulated within a UDP header with an additional 8-byte header pad
+     * (of '0'-value bytes) that prevents traffic from being interpreted as IKE or as ESP over UDP.
+     *
+     * @hide
+     */
+    public static final int ENCAP_ESPINUDP_NONIKE = 2;
+
+    /** @hide */
+    @IntDef(value = {ENCAP_NONE, ENCAP_ESPINUDP, ENCAP_ESPINUDP_NONIKE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncapType {}
+
+    /**
+     * Sentinel for an invalid transform (means that this transform is inactive).
+     *
+     * @hide
+     */
+    public static final int INVALID_TRANSFORM_ID = -1;
+
+    private IpSecTransform(Context context, IpSecConfig config) {
+        mContext = context;
+        mConfig = config;
+        mTransformId = INVALID_TRANSFORM_ID;
+    }
+
+    private IpSecTransform activate()
+            throws IOException, IpSecManager.ResourceUnavailableException,
+                    IpSecManager.SpiUnavailableException {
+        int transformId;
+        synchronized (this) {
+            //try {
+            transformId = INVALID_TRANSFORM_ID;
+            //} catch (RemoteException e) {
+            //    throw e.rethrowFromSystemServer();
+            //}
+
+            if (transformId < 0) {
+                throw new ErrnoException("addTransform", -transformId).rethrowAsIOException();
+            }
+
+            startKeepalive(mContext); // Will silently fail if not required
+            mTransformId = transformId;
+            Log.d(TAG, "Added Transform with Id " + transformId);
+        }
+        mCloseGuard.open("build");
+
+        return this;
+    }
+
+    /**
+     * Deactivate an IpSecTransform and free all resources for that transform that are managed by
+     * the system for this Transform.
+     *
+     * <p>Deactivating a transform while it is still applied to any Socket will result in sockets
+     * refusing to send or receive data. This method will silently succeed if the specified
+     * transform has already been removed; thus, it is always safe to attempt cleanup when a
+     * transform is no longer needed.
+     */
+    public void close() {
+        Log.d(TAG, "Removing Transform with Id " + mTransformId);
+
+        // Always safe to attempt cleanup
+        if (mTransformId == INVALID_TRANSFORM_ID) {
+            return;
+        }
+        //try {
+        stopKeepalive();
+        //} catch (RemoteException e) {
+        //    transform.setTransformId(transformId);
+        //    throw e.rethrowFromSystemServer();
+        //} finally {
+        mTransformId = INVALID_TRANSFORM_ID;
+        //}
+        mCloseGuard.close();
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (mCloseGuard != null) {
+            mCloseGuard.warnIfOpen();
+        }
+        close();
+    }
+
+    /* Package */
+    IpSecConfig getConfig() {
+        return mConfig;
+    }
+
+    private final IpSecConfig mConfig;
+    private int mTransformId;
+    private final Context mContext;
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+    private ConnectivityManager.PacketKeepalive mKeepalive;
+    private int mKeepaliveStatus = ConnectivityManager.PacketKeepalive.NO_KEEPALIVE;
+    private Object mKeepaliveSyncLock = new Object();
+    private ConnectivityManager.PacketKeepaliveCallback mKeepaliveCallback =
+            new ConnectivityManager.PacketKeepaliveCallback() {
+
+                @Override
+                public void onStarted() {
+                    synchronized (mKeepaliveSyncLock) {
+                        mKeepaliveStatus = ConnectivityManager.PacketKeepalive.SUCCESS;
+                        mKeepaliveSyncLock.notifyAll();
+                    }
+                }
+
+                @Override
+                public void onStopped() {
+                    synchronized (mKeepaliveSyncLock) {
+                        mKeepaliveStatus = ConnectivityManager.PacketKeepalive.NO_KEEPALIVE;
+                        mKeepaliveSyncLock.notifyAll();
+                    }
+                }
+
+                @Override
+                public void onError(int error) {
+                    synchronized (mKeepaliveSyncLock) {
+                        mKeepaliveStatus = error;
+                        mKeepaliveSyncLock.notifyAll();
+                    }
+                }
+            };
+
+    /* Package */
+    void startKeepalive(Context c) {
+        if (mConfig.getNattKeepaliveInterval() == 0) {
+            return;
+        }
+
+        ConnectivityManager cm =
+                (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+        if (mKeepalive != null) {
+            Log.e(TAG, "Keepalive already started for this IpSecTransform.");
+            return;
+        }
+
+        synchronized (mKeepaliveSyncLock) {
+            mKeepalive =
+                    cm.startNattKeepalive(
+                            mConfig.getNetwork(),
+                            mConfig.getNattKeepaliveInterval(),
+                            mKeepaliveCallback,
+                            mConfig.getLocalIp(),
+                            mConfig.getEncapLocalPort(),
+                            mConfig.getRemoteIp());
+            try {
+                mKeepaliveSyncLock.wait(2000);
+            } catch (InterruptedException e) {
+            }
+        }
+        if (mKeepaliveStatus != ConnectivityManager.PacketKeepalive.SUCCESS) {
+            throw new UnsupportedOperationException("Packet Keepalive cannot be started");
+        }
+    }
+
+    /* Package */
+    void stopKeepalive() {
+        if (mKeepalive == null) {
+            return;
+        }
+        mKeepalive.stop();
+        synchronized (mKeepaliveSyncLock) {
+            if (mKeepaliveStatus == ConnectivityManager.PacketKeepalive.SUCCESS) {
+                try {
+                    mKeepaliveSyncLock.wait(2000);
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+    }
+
+    /* Package */
+    void setTransformId(int transformId) {
+        mTransformId = transformId;
+    }
+
+    /* Package */
+    int getTransformId() {
+        return mTransformId;
+    }
+
+    /**
+     * Builder object to facilitate the creation of IpSecTransform objects.
+     *
+     * <p>Apply additional properties to the transform and then call a build() method to return an
+     * IpSecTransform object.
+     *
+     * @see Builder#buildTransportModeTransform(InetAddress)
+     */
+    public static class Builder {
+        private Context mContext;
+        private IpSecConfig mConfig;
+
+        /**
+         * Add an encryption algorithm to the transform for the given direction.
+         *
+         * <p>If encryption is set for a given direction without also providing an SPI for that
+         * direction, creation of an IpSecTransform will fail upon calling a build() method.
+         *
+         * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
+         * @param algo {@link IpSecAlgorithm} specifying the encryption to be applied.
+         */
+        public IpSecTransform.Builder setEncryption(
+                @TransformDirection int direction, IpSecAlgorithm algo) {
+            mConfig.flow[direction].encryptionAlgo = algo;
+            return this;
+        }
+
+        /**
+         * Add an authentication/integrity algorithm to the transform.
+         *
+         * <p>If authentication is set for a given direction without also providing an SPI for that
+         * direction, creation of an IpSecTransform will fail upon calling a build() method.
+         *
+         * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
+         * @param algo {@link IpSecAlgorithm} specifying the authentication to be applied.
+         */
+        public IpSecTransform.Builder setAuthentication(
+                @TransformDirection int direction, IpSecAlgorithm algo) {
+            mConfig.flow[direction].authenticationAlgo = algo;
+            return this;
+        }
+
+        /**
+         * Set the SPI, which uniquely identifies a particular IPsec session from others. Because
+         * IPsec operates at the IP layer, this 32-bit identifier uniquely identifies packets to a
+         * given destination address.
+         *
+         * <p>Care should be chosen when selecting an SPI to ensure that is is as unique as
+         * possible. Random number generation is a reasonable approach to selecting an SPI. For
+         * outbound SPIs, they must be reserved by calling {@link
+         * IpSecManager#reserveSecurityParameterIndex(InetAddress, int)}. Otherwise, Transforms will
+         * fail to build.
+         *
+         * <p>Unless an SPI is set for a given direction, traffic in that direction will be
+         * sent/received without any IPsec applied.
+         *
+         * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
+         * @param spi a unique 32-bit integer to identify transformed traffic
+         */
+        public IpSecTransform.Builder setSpi(@TransformDirection int direction, int spi) {
+            mConfig.flow[direction].spi = spi;
+            return this;
+        }
+
+        /**
+         * Set the SPI, which uniquely identifies a particular IPsec session from others. Because
+         * IPsec operates at the IP layer, this 32-bit identifier uniquely identifies packets to a
+         * given destination address.
+         *
+         * <p>Care should be chosen when selecting an SPI to ensure that is is as unique as
+         * possible. Random number generation is a reasonable approach to selecting an SPI. For
+         * outbound SPIs, they must be reserved by calling {@link
+         * IpSecManager#reserveSecurityParameterIndex(InetAddress, int)}. Otherwise, Transforms will
+         * fail to activate.
+         *
+         * <p>Unless an SPI is set for a given direction, traffic in that direction will be
+         * sent/received without any IPsec applied.
+         *
+         * @param direction either {@link #DIRECTION_IN or #DIRECTION_OUT}
+         * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed
+         *     traffic
+         */
+        public IpSecTransform.Builder setSpi(
+                @TransformDirection int direction, IpSecManager.SecurityParameterIndex spi) {
+            mConfig.flow[direction].spi = spi.getSpi();
+            return this;
+        }
+
+        /**
+         * Specify the network on which this transform will emit its traffic; (otherwise it will
+         * emit on the default network).
+         *
+         * <p>Restricts the transformed traffic to a particular {@link Network}. This is required in
+         * tunnel mode.
+         *
+         * @hide
+         */
+        @SystemApi
+        public IpSecTransform.Builder setUnderlyingNetwork(Network net) {
+            mConfig.network = net;
+            return this;
+        }
+
+        /**
+         * Add UDP encapsulation to an IPv4 transform
+         *
+         * <p>This option allows IPsec traffic to pass through NAT. Refer to RFC 3947 and 3948 for
+         * details on how UDP should be applied to IPsec.
+         *
+         * @param localSocket a {@link IpSecManager.UdpEncapsulationSocket} for sending and
+         *     receiving encapsulating traffic.
+         * @param remotePort the UDP port number of the remote that will send and receive
+         *     encapsulated traffic. In the case of IKE, this is likely port 4500.
+         */
+        public IpSecTransform.Builder setIpv4Encapsulation(
+                IpSecManager.UdpEncapsulationSocket localSocket, int remotePort) {
+            // TODO: check encap type is valid.
+            mConfig.encapType = ENCAP_ESPINUDP;
+            mConfig.encapLocalPort = localSocket.getPort(); // TODO: plug in the encap socket
+            mConfig.encapRemotePort = remotePort;
+            return this;
+        }
+
+        // TODO: Decrease the minimum keepalive to maybe 10?
+        // TODO: Probably a better exception to throw for NATTKeepalive failure
+        // TODO: Specify the needed NATT keepalive permission.
+        /**
+         * Send a NATT Keepalive packet with a given maximum interval. This will create an offloaded
+         * request to do power-efficient NATT Keepalive. If NATT keepalive is requested but cannot
+         * be activated, then the transform will fail to activate and throw an IOException.
+         *
+         * @param intervalSeconds the maximum number of seconds between keepalive packets, no less
+         *     than 20s and no more than 3600s.
+         * @hide
+         */
+        @SystemApi
+        public IpSecTransform.Builder setNattKeepalive(int intervalSeconds) {
+            mConfig.nattKeepaliveInterval = intervalSeconds;
+            return this;
+        }
+
+        /**
+         * Build and return an active {@link IpSecTransform} object as a Transport Mode Transform.
+         * Some parameters have interdependencies that are checked at build time. If a well-formed
+         * transform cannot be created from the supplied parameters, this method will throw an
+         * Exception.
+         *
+         * <p>Upon a successful return from this call, the provided IpSecTransform will be active
+         * and may be applied to sockets. If too many IpSecTransform objects are active for a given
+         * user this operation will fail and throw ResourceUnavailableException. To avoid these
+         * exceptions, unused Transform objects must be cleaned up by calling {@link
+         * IpSecTransform#close()} when they are no longer needed.
+         *
+         * @param remoteAddress the {@link InetAddress} that, when matched on traffic to/from this
+         *     socket will cause the transform to be applied.
+         *     <p>Note that an active transform will not impact any network traffic until it has
+         *     been applied to one or more Sockets. Calling this method is a necessary precondition
+         *     for applying it to a socket, but is not sufficient to actually apply IPsec.
+         * @throws IllegalArgumentException indicating that a particular combination of transform
+         *     properties is invalid.
+         * @throws IpSecManager.ResourceUnavailableException in the event that no more Transforms
+         *     may be allocated
+         * @throws SpiUnavailableException if the SPI collides with an existing transform
+         *     (unlikely).
+         * @throws ResourceUnavailableException if the current user currently has exceeded the
+         *     number of allowed active transforms.
+         */
+        public IpSecTransform buildTransportModeTransform(InetAddress remoteAddress)
+                throws IpSecManager.ResourceUnavailableException,
+                        IpSecManager.SpiUnavailableException, IOException {
+            //FIXME: argument validation here
+            //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation");
+            mConfig.mode = MODE_TRANSPORT;
+            mConfig.remoteAddress = remoteAddress;
+            return new IpSecTransform(mContext, mConfig).activate();
+        }
+
+        /**
+         * Build and return an {@link IpSecTransform} object as a Tunnel Mode Transform. Some
+         * parameters have interdependencies that are checked at build time.
+         *
+         * @param localAddress the {@link InetAddress} that provides the local endpoint for this
+         *     IPsec tunnel. This is almost certainly an address belonging to the {@link Network}
+         *     that will originate the traffic, which is set as the {@link #setUnderlyingNetwork}.
+         * @param remoteAddress the {@link InetAddress} representing the remote endpoint of this
+         *     IPsec tunnel.
+         * @throws IllegalArgumentException indicating that a particular combination of transform
+         *     properties is invalid.
+         * @hide
+         */
+        @SystemApi
+        public IpSecTransform buildTunnelModeTransform(
+                InetAddress localAddress, InetAddress remoteAddress) {
+            //FIXME: argument validation here
+            //throw new IllegalArgumentException("Natt Keepalive requires UDP Encapsulation");
+            mConfig.localAddress = localAddress;
+            mConfig.remoteAddress = remoteAddress;
+            mConfig.mode = MODE_TUNNEL;
+            return new IpSecTransform(mContext, mConfig);
+        }
+
+        /**
+         * Create a new IpSecTransform.Builder to construct an IpSecTransform
+         *
+         * @param context current Context
+         */
+        public Builder(Context context) {
+            mContext = context;
+            mConfig = new IpSecConfig();
+        }
+    }
+}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 1b715af..43fab03 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -19,6 +19,7 @@
 import static android.content.pm.PackageManager.GET_SIGNATURES;
 import static android.net.NetworkPolicy.CYCLE_NONE;
 
+import android.app.ActivityManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -381,4 +382,20 @@
         string.append(")");
         return string.toString();
     }
+
+    /**
+     * Returns true if {@param procState} is considered foreground and as such will be allowed
+     * to access network when the device is idle or in battery saver mode. Otherwise, false.
+     */
+    public static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) {
+        return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+    }
+
+    /**
+     * Returns true if {@param procState} is considered foreground and as such will be allowed
+     * to access network when the device is in data saver mode. Otherwise, false.
+     */
+    public static boolean isProcStateAllowedWhileOnRestrictBackground(int procState) {
+        return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+    }
 }
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index 815d480..7b7a21c 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -103,6 +103,14 @@
     public static final String ACTION_CUSTOM_ENABLE = "android.net.scoring.CUSTOM_ENABLE";
 
     /**
+     * Meta-data specified on a {@link NetworkRecommendationProvider} that provides a user-visible
+     * label of the recommendation service.
+     * @hide
+     */
+    public static final String RECOMMENDATION_SERVICE_LABEL_META_DATA =
+            "android.net.scoring.recommendation_service_label";
+
+    /**
      * Meta-data specified on a {@link NetworkRecommendationProvider} that specified the package
      * name of the application that connects and secures open wifi networks automatically. The
      * specified package must provide an Activity for {@link #ACTION_CUSTOM_ENABLE}.
@@ -265,8 +273,8 @@
      * the {@link #ACTION_CHANGE_ACTIVE} broadcast, or using a custom configuration activity.
      *
      * @return true if the operation succeeded, or false if the new package is not a valid scorer.
-     * @throws SecurityException if the caller does not hold the
-     *         {@link android.Manifest.permission#SCORE_NETWORKS} permission.
+     * @throws SecurityException if the caller is not a system process or does not hold the
+     *         {@link android.Manifest.permission#REQUEST_NETWORK_SCORES} permission
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/net/NetworkScorerAppData.java b/core/java/android/net/NetworkScorerAppData.java
index fca0a2e..5bf1e10 100644
--- a/core/java/android/net/NetworkScorerAppData.java
+++ b/core/java/android/net/NetworkScorerAppData.java
@@ -16,6 +16,8 @@
     /** UID of the scorer app. */
     public final int packageUid;
     private final ComponentName mRecommendationService;
+    /** User visible label in Settings for the recommendation service. */
+    private final String mRecommendationServiceLabel;
     /**
      * The {@link ComponentName} of the Activity to start before enabling the "connect to open
      * wifi networks automatically" feature.
@@ -23,15 +25,17 @@
     private final ComponentName mEnableUseOpenWifiActivity;
 
     public NetworkScorerAppData(int packageUid, ComponentName recommendationServiceComp,
-            ComponentName enableUseOpenWifiActivity) {
+            String recommendationServiceLabel, ComponentName enableUseOpenWifiActivity) {
         this.packageUid = packageUid;
         this.mRecommendationService = recommendationServiceComp;
+        this.mRecommendationServiceLabel = recommendationServiceLabel;
         this.mEnableUseOpenWifiActivity = enableUseOpenWifiActivity;
     }
 
     protected NetworkScorerAppData(Parcel in) {
         packageUid = in.readInt();
         mRecommendationService = ComponentName.readFromParcel(in);
+        mRecommendationServiceLabel = in.readString();
         mEnableUseOpenWifiActivity = ComponentName.readFromParcel(in);
     }
 
@@ -39,6 +43,7 @@
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(packageUid);
         ComponentName.writeToParcel(mRecommendationService, dest);
+        dest.writeString(mRecommendationServiceLabel);
         ComponentName.writeToParcel(mEnableUseOpenWifiActivity, dest);
     }
 
@@ -73,11 +78,17 @@
         return mEnableUseOpenWifiActivity;
     }
 
+    @Nullable
+    public String getRecommendationServiceLabel() {
+        return mRecommendationServiceLabel;
+    }
+
     @Override
     public String toString() {
         return "NetworkScorerAppData{" +
                 "packageUid=" + packageUid +
                 ", mRecommendationService=" + mRecommendationService +
+                ", mRecommendationServiceLabel=" + mRecommendationServiceLabel +
                 ", mEnableUseOpenWifiActivity=" + mEnableUseOpenWifiActivity +
                 '}';
     }
@@ -89,11 +100,13 @@
         NetworkScorerAppData that = (NetworkScorerAppData) o;
         return packageUid == that.packageUid &&
                 Objects.equals(mRecommendationService, that.mRecommendationService) &&
+                Objects.equals(mRecommendationServiceLabel, that.mRecommendationServiceLabel) &&
                 Objects.equals(mEnableUseOpenWifiActivity, that.mEnableUseOpenWifiActivity);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(packageUid, mRecommendationService, mEnableUseOpenWifiActivity);
+        return Objects.hash(packageUid, mRecommendationService, mRecommendationServiceLabel,
+                mEnableUseOpenWifiActivity);
     }
 }
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 9ffe2fe..734d89e 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -211,7 +211,7 @@
     /**
      * Battery charge status, from a BATTERY_STATUS_* value.
      */
-    public static final int BATTERY_PROPERTY_BATTERY_STATUS = 6;
+    public static final int BATTERY_PROPERTY_STATUS = 6;
 
     private final IBatteryStats mBatteryStats;
     private final IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar;
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index b9e4bad..caea202 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -506,7 +506,7 @@
             }
 
             /**
-             * Detect unbuffered input/output operations.
+             * Disable detection of unbuffered input/output operations.
              */
             public Builder permitUnbufferedIo() {
                 return disable(DETECT_UNBUFFERED_IO);
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 78820b5..b525193 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -35,7 +35,6 @@
     private static final String TAG = "SystemProperties";
     private static final boolean TRACK_KEY_ACCESS = false;
 
-    public static final int PROP_NAME_MAX = 31;
     public static final int PROP_VALUE_MAX = 91;
 
     private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
@@ -82,12 +81,8 @@
     /**
      * Get the value for the given key.
      * @return an empty string if the key isn't found
-     * @throws IllegalArgumentException if the key exceeds 32 characters
      */
     public static String get(String key) {
-        if (key.length() > PROP_NAME_MAX) {
-            throw newKeyTooLargeException(key);
-        }
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get(key);
     }
@@ -95,12 +90,8 @@
     /**
      * Get the value for the given key.
      * @return if the key isn't found, return def if it isn't null, or an empty string otherwise
-     * @throws IllegalArgumentException if the key exceeds 32 characters
      */
     public static String get(String key, String def) {
-        if (key.length() > PROP_NAME_MAX) {
-            throw newKeyTooLargeException(key);
-        }
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get(key, def);
     }
@@ -111,12 +102,8 @@
      * @param def a default value to return
      * @return the key parsed as an integer, or def if the key isn't found or
      *         cannot be parsed
-     * @throws IllegalArgumentException if the key exceeds 32 characters
      */
     public static int getInt(String key, int def) {
-        if (key.length() > PROP_NAME_MAX) {
-            throw newKeyTooLargeException(key);
-        }
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get_int(key, def);
     }
@@ -127,12 +114,8 @@
      * @param def a default value to return
      * @return the key parsed as a long, or def if the key isn't found or
      *         cannot be parsed
-     * @throws IllegalArgumentException if the key exceeds 32 characters
      */
     public static long getLong(String key, long def) {
-        if (key.length() > PROP_NAME_MAX) {
-            throw newKeyTooLargeException(key);
-        }
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get_long(key, def);
     }
@@ -148,25 +131,17 @@
      * @param def a default value to return
      * @return the key parsed as a boolean, or def if the key isn't found or is
      *         not able to be parsed as a boolean.
-     * @throws IllegalArgumentException if the key exceeds 32 characters
      */
     public static boolean getBoolean(String key, boolean def) {
-        if (key.length() > PROP_NAME_MAX) {
-            throw newKeyTooLargeException(key);
-        }
         if (TRACK_KEY_ACCESS) onKeyAccess(key);
         return native_get_boolean(key, def);
     }
 
     /**
      * Set the value for the given key.
-     * @throws IllegalArgumentException if the key exceeds 32 characters
      * @throws IllegalArgumentException if the value exceeds 92 characters
      */
     public static void set(String key, String val) {
-        if (key.length() > PROP_NAME_MAX) {
-            throw newKeyTooLargeException(key);
-        }
         if (val != null && val.length() > PROP_VALUE_MAX) {
             throw newValueTooLargeException(key, val);
         }
@@ -196,11 +171,6 @@
         }
     }
 
-    private static IllegalArgumentException newKeyTooLargeException(String key) {
-        return new IllegalArgumentException("system property key '" + key + "' is longer than "
-                + PROP_NAME_MAX + " characters");
-    }
-
     private static IllegalArgumentException newValueTooLargeException(String key, String value) {
         return new IllegalArgumentException("value of system property '" + key + "' is longer than "
                 + PROP_VALUE_MAX + " characters: " + value);
diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java
index bf03cce..8549cff 100644
--- a/core/java/android/os/UpdateEngine.java
+++ b/core/java/android/os/UpdateEngine.java
@@ -26,7 +26,18 @@
 /**
  * UpdateEngine handles calls to the update engine which takes care of A/B OTA
  * updates. It wraps up the update engine Binder APIs and exposes them as
- * SystemApis, which will be called by system apps like GmsCore.
+ * SystemApis, which will be called by the system app responsible for OTAs.
+ * On a Google device, this will be GmsCore.
+ *
+ * The minimal flow is:
+ * <ol>
+ * <li>Create a new UpdateEngine instance.
+ * <li>Call {@link #bind}, optionally providing callbacks.
+ * <li>Call {@link #applyPayload}.
+ * </ol>
+ *
+ * In addition, methods are provided to {@link #cancel} or
+ * {@link #suspend}/{@link #resume} application of an update.
  *
  * The APIs defined in this class and UpdateEngineCallback class must be in
  * sync with the ones in
@@ -80,12 +91,20 @@
 
     private IUpdateEngine mUpdateEngine;
 
+    /**
+     * Creates a new instance.
+     */
     @SystemApi
     public UpdateEngine() {
         mUpdateEngine = IUpdateEngine.Stub.asInterface(
                 ServiceManager.getService(UPDATE_ENGINE_SERVICE));
     }
 
+    /**
+     * Prepares this instance for use. The callback will be notified on any
+     * status change, and when the update completes. A handler can be supplied
+     * to control which thread runs the callback, or null.
+     */
     @SystemApi
     public boolean bind(final UpdateEngineCallback callback, final Handler handler) {
         IUpdateEngineCallback updateEngineCallback = new IUpdateEngineCallback.Stub() {
@@ -125,11 +144,42 @@
         }
     }
 
+    /**
+     * Equivalent to {@code bind(callback, null)}.
+     */
     @SystemApi
     public boolean bind(final UpdateEngineCallback callback) {
         return bind(callback, null);
     }
 
+    /**
+     * Applies the payload found at the given {@code url}. For non-streaming
+     * updates, the URL can be a local file using the {@code file://} scheme.
+     *
+     * <p>The {@code offset} and {@code size} parameters specify the location
+     * of the payload within the file represented by the URL. This is useful
+     * if the downloadable package at the URL contains more than just the
+     * update_engine payload (such as extra metadata). This is true for
+     * Google's OTA system, where the URL points to a zip file in which the
+     * payload is stored uncompressed within the zip file alongside other
+     * data.
+     *
+     * <p>The {@code headerKeyValuePairs} parameter is used to pass metadata
+     * to update_engine. In Google's implementation, this is stored as
+     * {@code payload_properties.txt} in the zip file. It's generated by the
+     * script {@code system/update_engine/scripts/brillo_update_payload}.
+     * The complete list of keys and their documentation is in
+     * {@code system/update_engine/common/constants.cc}, but an example
+     * might be:
+     * <pre>
+     * String[] pairs = {
+     *   "FILE_HASH=lURPCIkIAjtMOyB/EjQcl8zDzqtD6Ta3tJef6G/+z2k=",
+     *   "FILE_SIZE=871903868",
+     *   "METADATA_HASH=tBvj43QOB0Jn++JojcpVdbRLz0qdAuL+uTkSy7hokaw=",
+     *   "METADATA_SIZE=70604"
+     * };
+     * </pre>
+     */
     @SystemApi
     public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) {
         try {
@@ -139,6 +189,15 @@
         }
     }
 
+    /**
+     * Permanently cancels an in-progress update.
+     *
+     * <p>See {@link #resetStatus} to undo a finshed update (only available
+     * before the updated system has been rebooted).
+     *
+     * <p>See {@link #suspend} for a way to temporarily stop an in-progress
+     * update with the ability to resume it later.
+     */
     @SystemApi
     public void cancel() {
         try {
@@ -148,6 +207,10 @@
         }
     }
 
+    /**
+     * Suspends an in-progress update. This can be undone by calling
+     * {@link #resume}.
+     */
     @SystemApi
     public void suspend() {
         try {
@@ -157,6 +220,9 @@
         }
     }
 
+    /**
+     * Resumes a suspended update.
+     */
     @SystemApi
     public void resume() {
         try {
@@ -166,6 +232,15 @@
         }
     }
 
+    /**
+     * Resets the bootable flag on the non-current partition and all internal
+     * update_engine state. This can be used after an unwanted payload has been
+     * successfully applied and the device has not yet been rebooted to signal
+     * that we no longer want to boot into that updated system. After this call
+     * completes, update_engine will no longer report
+     * {@code UPDATED_NEED_REBOOT}, so your callback can remove any outstanding
+     * notification that rebooting into the new system is possible.
+     */
     @SystemApi
     public void resetStatus() {
         try {
diff --git a/core/java/android/os/UpdateEngineCallback.java b/core/java/android/os/UpdateEngineCallback.java
index b3b856f..afff60a 100644
--- a/core/java/android/os/UpdateEngineCallback.java
+++ b/core/java/android/os/UpdateEngineCallback.java
@@ -19,7 +19,8 @@
 import android.annotation.SystemApi;
 
 /**
- * Callback function for UpdateEngine.
+ * Callback function for UpdateEngine. Used to keep the caller up to date
+ * with progress, so the UI (if any) can be updated.
  *
  * The APIs defined in this class and UpdateEngine class must be in sync with
  * the ones in
@@ -31,9 +32,19 @@
 @SystemApi
 public abstract class UpdateEngineCallback {
 
+    /**
+     * Invoked when anything changes. The value of {@code status} will
+     * be one of the values from {@link UpdateEngine.UpdateStatusConstants},
+     * and {@code percent} will be valid [TODO: in which cases?].
+     */
     @SystemApi
     public abstract void onStatusUpdate(int status, float percent);
 
+    /**
+     * Invoked when the payload has been applied, whether successfully or
+     * unsuccessfully. The value of {@code errorCode} will be one of the
+     * values from {@link UpdateEngine.ErrorCodeConstants}.
+     */
     @SystemApi
     public abstract void onPayloadApplicationComplete(int errorCode);
 }
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index 7b63b62..a21e05e 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -435,7 +435,7 @@
             return null;
         }
 
-        final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
+        final Intent intent = new Intent(Intent.ACTION_VIEW);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         intent.setDataAndType(uri, DocumentsContract.Root.MIME_TYPE_ITEM);
 
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 089eaec..62c5dca 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -410,11 +410,13 @@
     /**
      * Sets a {@link PreferenceDataStore} to be used by this Preference instead of using
      * {@link android.content.SharedPreferences}.
-     * <p>
-     * The data store will remain assigned even if the Preference is moved between multiple
-     * instances of {@link PreferenceFragment}.
+     *
+     * <p>The data store will remain assigned even if the Preference is moved around the preference
+     * hierarchy. It will also override a data store propagated from the {@link PreferenceManager}
+     * that owns this Preference.
      *
      * @param dataStore The {@link PreferenceDataStore} to be used by this Preference.
+     * @see PreferenceManager#setPreferenceDataStore(PreferenceDataStore)
      */
     public void setPreferenceDataStore(PreferenceDataStore dataStore) {
         mPreferenceDataStore = dataStore;
@@ -424,6 +426,12 @@
      * Returns {@link PreferenceDataStore} used by this Preference. Returns {@code null} if
      * {@link android.content.SharedPreferences} is used instead.
      *
+     * <p>By default preferences always use {@link android.content.SharedPreferences}. To make this
+     * preference to use the {@link PreferenceDataStore} you need to assign your implementation
+     * to the Preference itself via {@link #setPreferenceDataStore(PreferenceDataStore)} or to its
+     * {@link PreferenceManager} via
+     * {@link PreferenceManager#setPreferenceDataStore(PreferenceDataStore)}.
+     *
      * @return The {@link PreferenceDataStore} used by this Preference or {@code null} if none.
      */
     @Nullable
@@ -1457,12 +1465,12 @@
     }
 
     /**
-     * Implement this to set the initial value of the Preference. 
+     * Implement this to set the initial value of the Preference.
      * <p>
-     * If <var>restorePersistedValue</var> is true, you should restore the 
-     * Preference value from the {@link android.content.SharedPreferences}. If 
-     * <var>restorePersistedValue</var> is false, you should set the Preference 
-     * value to defaultValue that is given (and possibly store to SharedPreferences 
+     * If <var>restorePersistedValue</var> is true, you should restore the
+     * Preference value from the {@link android.content.SharedPreferences}. If
+     * <var>restorePersistedValue</var> is false, you should set the Preference
+     * value to defaultValue that is given (and possibly store to SharedPreferences
      * if {@link #shouldPersist()} is true).
      * <p>
      * This may not always be called. One example is if it should not persist
diff --git a/core/java/android/preference/PreferenceDataStore.java b/core/java/android/preference/PreferenceDataStore.java
index e1a08ac..8caa404 100644
--- a/core/java/android/preference/PreferenceDataStore.java
+++ b/core/java/android/preference/PreferenceDataStore.java
@@ -21,16 +21,32 @@
 import java.util.Set;
 
 /**
- * A data store interface to be implemented and provided to the Preferences framework.
+ * A data store interface to be implemented and provided to the Preferences framework. This can be
+ * used to replace the default {@link android.content.SharedPreferences}, if needed.
  *
- * Use this to replace the default {@link android.content.SharedPreferences}. By default, all "put"
- * methods throw {@link UnsupportedOperationException}.
+ * <p>In most cases you want to use {@link android.content.SharedPreferences} as it is automatically
+ * backed up and migrated to new devices. However, providing custom data store to preferences can be
+ * useful if your app stores its preferences in a local db, cloud or they are device specific like
+ * "Developer settings". It might be also useful when you want to use the preferences UI but
+ * the data are not supposed to be stored at all because they are valid per session only.
+ *
+ * <p>Once a put method is called it is full responsibility of the data store implementation to
+ * safely store the given values. Time expensive operations need to be done in the background to
+ * prevent from blocking the UI. You also need to have a plan on how to serialize the data in case
+ * the activity holding this object gets destroyed.
+ *
+ * <p>By default, all "put" methods throw {@link UnsupportedOperationException}.
+ *
+ * @see Preference#setPreferenceDataStore(PreferenceDataStore)
+ * @see PreferenceManager#setPreferenceDataStore(PreferenceDataStore)
  */
 public interface PreferenceDataStore {
 
     /**
      * Set a String value to the data store.
      *
+     * <p>Once the value is set the data store is responsible for holding it.
+     *
      * @param key The name of the preference to modify.
      * @param value The new value for the preference.
      * @see #getString(String, String)
@@ -42,6 +58,8 @@
     /**
      * Set a set of String value to the data store.
      *
+     * <p>Once the value is set the data store is responsible for holding it.
+     *
      * @param key The name of the preference to modify.
      * @param values The set of new values for the preference.
      * @see #getStringSet(String, Set)
@@ -53,6 +71,8 @@
     /**
      * Set an int value to the data store.
      *
+     * <p>Once the value is set the data store is responsible for holding it.
+     *
      * @param key The name of the preference to modify.
      * @param value The new value for the preference.
      * @see #getInt(String, int)
@@ -64,6 +84,8 @@
     /**
      * Set a long value to the data store.
      *
+     * <p>Once the value is set the data store is responsible for holding it.
+     *
      * @param key The name of the preference to modify.
      * @param value The new value for the preference.
      * @see #getLong(String, long)
@@ -75,6 +97,8 @@
     /**
      * Set a float value to the data store.
      *
+     * <p>Once the value is set the data store is responsible for holding it.
+     *
      * @param key The name of the preference to modify.
      * @param value The new value for the preference.
      * @see #getFloat(String, float)
@@ -86,6 +110,8 @@
     /**
      * Set a boolean value to the data store.
      *
+     * <p>Once the value is set the data store is responsible for holding it.
+     *
      * @param key The name of the preference to modify.
      * @param value The new value for the preference.
      * @see #getBoolean(String, boolean)
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index 756c3f4..2570374 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -208,10 +208,13 @@
 
     /**
      * Sets a {@link PreferenceDataStore} to be used by all Preferences associated with this manager
-     * that don't have a custom {@link PreferenceDataStore} assigned. Also if the data store is set,
-     * the Preferences will no longer use {@link android.content.SharedPreferences}.
+     * that don't have a custom {@link PreferenceDataStore} assigned via
+     * {@link Preference#setPreferenceDataStore(PreferenceDataStore)}. Also if the data store is
+     * set, the child preferences won't use {@link android.content.SharedPreferences} as long as
+     * they are assigned to this manager.
      *
      * @param dataStore The {@link PreferenceDataStore} to be used by this manager.
+     * @see Preference#setPreferenceDataStore(PreferenceDataStore)
      */
     public void setPreferenceDataStore(PreferenceDataStore dataStore) {
         mPreferenceDataStore = dataStore;
@@ -219,9 +222,10 @@
 
     /**
      * Returns the {@link PreferenceDataStore} associated with this manager or {@code null} if
-     * {@link android.content.SharedPreferences} are used instead.
+     * the default {@link android.content.SharedPreferences} are used instead.
      *
      * @return The {@link PreferenceDataStore} associated with this manager or {@code null} if none.
+     * @see #setPreferenceDataStore(PreferenceDataStore)
      */
     @Nullable
     public PreferenceDataStore getPreferenceDataStore() {
@@ -358,8 +362,11 @@
      * Sets the name of the SharedPreferences file that preferences managed by this
      * will use.
      *
+     * <p>If custom {@link PreferenceDataStore} is set, this won't override its usage.
+     *
      * @param sharedPreferencesName The name of the SharedPreferences file.
      * @see Context#getSharedPreferences(String, int)
+     * @see #setPreferenceDataStore(PreferenceDataStore)
      */
     public void setSharedPreferencesName(String sharedPreferencesName) {
         mSharedPreferencesName = sharedPreferencesName;
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 5486162..71a0349 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -162,9 +162,6 @@
     public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
 
     /** {@hide} */
-    public static final String ACTION_BROWSE = "android.provider.action.BROWSE";
-
-    /** {@hide} */
     public static final String
             ACTION_DOCUMENT_ROOT_SETTINGS = "android.provider.action.DOCUMENT_ROOT_SETTINGS";
 
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b55a349..c4a5be7 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1121,7 +1121,7 @@
     public static final String ACTION_ZEN_MODE_SETTINGS = "android.settings.ZEN_MODE_SETTINGS";
 
     /**
-     * Activity Action: Show Zen Mode priority configuration settings.
+     * Activity Action: Show Zen Mode (aka Do Not Disturb) priority configuration settings.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_ZEN_MODE_PRIORITY_SETTINGS
@@ -8282,6 +8282,16 @@
         public static final String NETWORK_RECOMMENDATION_REQUEST_TIMEOUT_MS =
                 "network_recommendation_request_timeout_ms";
 
+        /**
+         * The expiration time in milliseconds for the {@link android.net.WifiKey} request cache in
+         * {@link com.android.server.wifi.RecommendedNetworkEvaluator}.
+         *
+         * Type: long
+         * @hide
+         */
+        public static final String RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS =
+                "recommended_network_evaluator_cache_expiry_ms";
+
        /**
         * Settings to allow BLE scans to be enabled even when Bluetooth is turned off for
         * connectivity.
diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java
index 5461e6b..ad8ad69 100644
--- a/core/java/android/security/keymaster/KeymasterDefs.java
+++ b/core/java/android/security/keymaster/KeymasterDefs.java
@@ -138,8 +138,6 @@
     public static final int KM_PURPOSE_DECRYPT = 1;
     public static final int KM_PURPOSE_SIGN = 2;
     public static final int KM_PURPOSE_VERIFY = 3;
-    public static final int KM_PURPOSE_DERIVE_KEY = 4;
-    public static final int KM_PURPOSE_WRAP_KEY = 5;
 
     // Key formats.
     public static final int KM_KEY_FORMAT_X509 = 0;
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
index c8358a6..3e992ec 100644
--- a/core/java/android/service/notification/ConditionProviderService.java
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -127,7 +127,7 @@
     }
 
     /**
-     * Request that the provider be rebound, after a previous call to (@link requestUnbind).
+     * Request that the provider be rebound, after a previous call to (@link #requestUnbind).
      *
      * <p>This method will fail for providers that have not been granted the permission by the user.
      */
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 8a83b7a..70e0461 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -148,7 +148,7 @@
 
     // Notification cancellation reasons
 
-    /** Notification was canceled by the status bar reporting a click. */
+    /** Notification was canceled by the status bar reporting a notification click. */
     public static final int REASON_DELEGATE_CLICK = 1;
     /** Notification was canceled by the status bar reporting a user dismissal. */
     public static final int REASON_DELEGATE_CANCEL = 2;
@@ -636,7 +636,7 @@
      * <p>The service should wait for the {@link #onListenerConnected()} event
      * before performing this operation.
      *
-     * @return An array of active notifications, sorted in natural order.
+     * @return An array of snoozed notifications, sorted in natural order.
      */
     public final StatusBarNotification[] getSnoozedNotifications() {
         try {
diff --git a/core/java/android/service/notification/StatusBarNotification.java b/core/java/android/service/notification/StatusBarNotification.java
index 85bccf7..6a24aa4 100644
--- a/core/java/android/service/notification/StatusBarNotification.java
+++ b/core/java/android/service/notification/StatusBarNotification.java
@@ -67,6 +67,9 @@
         this.groupKey = groupKey();
     }
 
+    /**
+     * @deprecated Non-system apps should not need to create StatusBarNotifications.
+     */
     @Deprecated
     public StatusBarNotification(String pkg, String opPkg, int id, String tag, int uid,
             int initialPid, int score, Notification notification, UserHandle user,
diff --git a/core/java/android/service/quicksettings/TileService.java b/core/java/android/service/quicksettings/TileService.java
index 1781c2a..2116847 100644
--- a/core/java/android/service/quicksettings/TileService.java
+++ b/core/java/android/service/quicksettings/TileService.java
@@ -126,7 +126,9 @@
     public static final String EXTRA_TOKEN = "token";
 
     /**
-     * @hide
+     * May be included when {@link #ACTION_QS_TILE_PREFERENCES} is launched from a tile.
+     * This extra may contain the {@link ComponentName} of the tile that triggered
+     * the preferences to be opened.
      */
     public static final String EXTRA_COMPONENT = "android.service.quicksettings.extra.COMPONENT";
 
diff --git a/core/java/android/transition/Fade.java b/core/java/android/transition/Fade.java
index b0de711..38b89dc 100644
--- a/core/java/android/transition/Fade.java
+++ b/core/java/android/transition/Fade.java
@@ -103,6 +103,7 @@
         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Fade);
         int fadingMode = a.getInt(R.styleable.Fade_fadingMode, getMode());
         setMode(fadingMode);
+        a.recycle();
     }
 
     @Override
diff --git a/core/java/android/transition/TransitionInflater.java b/core/java/android/transition/TransitionInflater.java
index 4c5a717..0cc981e 100644
--- a/core/java/android/transition/TransitionInflater.java
+++ b/core/java/android/transition/TransitionInflater.java
@@ -276,9 +276,11 @@
                             transition.addTarget(clazz);
                         }
                     } catch (ClassNotFoundException e) {
+                        a.recycle();
                         throw new RuntimeException("Could not create " + className, e);
                     }
                 }
+                a.recycle();
             } else {
                 throw new RuntimeException("Unknown scene name: " + parser.getName());
             }
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index b718696..0ac16c1 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -95,6 +95,11 @@
             IBinder displayToken, int mode);
     private static native void nativeDeferTransactionUntil(long nativeObject,
             IBinder handle, long frame);
+    private static native void nativeDeferTransactionUntilSurface(long nativeObject,
+            long surfaceObject, long frame);
+    private static native void nativeReparentChildren(long nativeObject,
+            IBinder handle);
+    private static native void nativeSeverChildren(long nativeObject);
     private static native void nativeSetOverrideScalingMode(long nativeObject,
             int scalingMode);
     private static native IBinder nativeGetHandle(long nativeObject);
@@ -421,6 +426,18 @@
         nativeDeferTransactionUntil(mNativeObject, handle, frame);
     }
 
+    public void deferTransactionUntil(Surface barrier, long frame) {
+        nativeDeferTransactionUntilSurface(mNativeObject, barrier.mNativeObject, frame);
+    }
+
+    public void reparentChildren(IBinder newParentHandle) {
+        nativeReparentChildren(mNativeObject, newParentHandle);
+    }
+
+    public void detachChildren() {
+        nativeSeverChildren(mNativeObject);
+    }
+
     public void setOverrideScalingMode(int scalingMode) {
         checkNotReleased();
         nativeSetOverrideScalingMode(mNativeObject, scalingMode);
diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java
index 3cf5af4..b5912bc 100644
--- a/core/java/android/view/SurfaceSession.java
+++ b/core/java/android/view/SurfaceSession.java
@@ -27,6 +27,7 @@
     private long mNativeClient; // SurfaceComposerClient*
 
     private static native long nativeCreate();
+    private static native long nativeCreateScoped(long surfacePtr);
     private static native void nativeDestroy(long ptr);
     private static native void nativeKill(long ptr);
 
@@ -35,6 +36,10 @@
         mNativeClient = nativeCreate();
     }
 
+    public SurfaceSession(Surface root) {
+        mNativeClient = nativeCreateScoped(root.mNativeObject);
+    }
+
     /* no user serviceable parts here ... */
     @Override
     protected void finalize() throws Throwable {
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index d2577d4..61b1247 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,6 +16,10 @@
 
 package android.view;
 
+import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_SUBLAYER;
+import static android.view.WindowManagerPolicy.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
+import static android.view.WindowManagerPolicy.APPLICATION_PANEL_SUBLAYER;
+
 import android.content.Context;
 import android.content.res.CompatibilityInfo.Translator;
 import android.content.res.Configuration;
@@ -26,16 +30,12 @@
 import android.graphics.Region;
 import android.os.Handler;
 import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
 
-import com.android.internal.view.BaseIWindow;
 import com.android.internal.view.SurfaceCallbackHelper;
 
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -92,8 +92,8 @@
  * positioned asynchronously.</p>
  */
 public class SurfaceView extends View {
-    static private final String TAG = "SurfaceView";
-    static private final boolean DEBUG = false;
+    private static final String TAG = "SurfaceView";
+    private static final boolean DEBUG = false;
 
     final ArrayList<SurfaceHolder.Callback> mCallbacks
             = new ArrayList<SurfaceHolder.Callback>();
@@ -102,28 +102,23 @@
 
     final ReentrantLock mSurfaceLock = new ReentrantLock();
     final Surface mSurface = new Surface();       // Current surface in use
-    final Surface mNewSurface = new Surface();    // New surface we are switching to
     boolean mDrawingStopped = true;
+    // We use this to track if the application has produced a frame
+    // in to the Surface. Up until that point, we should be careful not to punch
+    // holes.
+    boolean mDrawFinished = false;
 
-    final WindowManager.LayoutParams mLayout
-            = new WindowManager.LayoutParams();
-    IWindowSession mSession;
-    MyWindow mWindow;
-    final Rect mVisibleInsets = new Rect();
-    final Rect mWinFrame = new Rect();
-    final Rect mOverscanInsets = new Rect();
-    final Rect mContentInsets = new Rect();
-    final Rect mStableInsets = new Rect();
-    final Rect mOutsets = new Rect();
-    final Rect mBackdropFrame = new Rect();
+    final Rect mScreenRect = new Rect();
+    SurfaceSession mSurfaceSession;
+
+    SurfaceControl mSurfaceControl;
     final Rect mTmpRect = new Rect();
     final Configuration mConfiguration = new Configuration();
 
     static final int KEEP_SCREEN_ON_MSG = 1;
-    static final int GET_NEW_SURFACE_MSG = 2;
-    static final int UPDATE_WINDOW_MSG = 3;
+    static final int DRAW_FINISHED_MSG = 2;
 
-    int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+    int mSubLayer = APPLICATION_MEDIA_SUBLAYER;
 
     boolean mIsCreating = false;
     private volatile boolean mRtHandlingPositionUpdates = false;
@@ -135,11 +130,9 @@
                 case KEEP_SCREEN_ON_MSG: {
                     setKeepScreenOn(msg.arg1 != 0);
                 } break;
-                case GET_NEW_SURFACE_MSG: {
-                    handleGetNewSurface();
-                } break;
-                case UPDATE_WINDOW_MSG: {
-                    updateWindow();
+                case DRAW_FINISHED_MSG: {
+                    mDrawFinished = true;
+                    invalidate();
                 } break;
             }
         }
@@ -149,7 +142,7 @@
             = new ViewTreeObserver.OnScrollChangedListener() {
                     @Override
                     public void onScrollChanged() {
-                        updateWindow();
+                        updateSurface();
                     }
             };
 
@@ -159,13 +152,14 @@
                 public boolean onPreDraw() {
                     // reposition ourselves where the surface is
                     mHaveFrame = getWidth() > 0 && getHeight() > 0;
-                    updateWindow();
+                    updateSurface();
                     return true;
                 }
             };
 
     boolean mRequestedVisible = false;
     boolean mWindowVisibility = false;
+    boolean mLastWindowVisibility = false;
     boolean mViewVisibility = false;
     int mRequestedWidth = -1;
     int mRequestedHeight = -1;
@@ -181,19 +175,17 @@
     boolean mVisible = false;
     int mWindowSpaceLeft = -1;
     int mWindowSpaceTop = -1;
-    int mWindowSpaceWidth = -1;
-    int mWindowSpaceHeight = -1;
+    int mSurfaceWidth = -1;
+    int mSurfaceHeight = -1;
     int mFormat = -1;
     final Rect mSurfaceFrame = new Rect();
     int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
-    boolean mUpdateWindowNeeded;
-    boolean mReportDrawNeeded;
     private Translator mTranslator;
-    private int mWindowInsetLeft;
-    private int mWindowInsetTop;
 
     private boolean mGlobalListenersAdded;
 
+    private int mSurfaceFlags = SurfaceControl.HIDDEN;
+
     public SurfaceView(Context context) {
         this(context, null);
     }
@@ -227,11 +219,8 @@
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mParent.requestTransparentRegion(this);
-        mSession = getWindowSession();
-        mLayout.token = getWindowToken();
-        mLayout.setTitle("SurfaceView - " + getViewRootImpl().getTitle());
-        mLayout.packageName = mContext.getOpPackageName();
         mViewVisibility = getVisibility() == VISIBLE;
+        mRequestedVisible = mViewVisibility && mWindowVisibility;
 
         if (!mGlobalListenersAdded) {
             ViewTreeObserver observer = getViewTreeObserver();
@@ -246,7 +235,7 @@
         super.onWindowVisibilityChanged(visibility);
         mWindowVisibility = visibility == VISIBLE;
         mRequestedVisible = mWindowVisibility && mViewVisibility;
-        updateWindow();
+        updateSurface();
     }
 
     @Override
@@ -264,7 +253,7 @@
             requestLayout();
         }
         mRequestedVisible = newRequestedVisible;
-        updateWindow();
+        updateSurface();
     }
 
     @Override
@@ -277,19 +266,14 @@
         }
 
         mRequestedVisible = false;
-        updateWindow();
-        mHaveFrame = false;
-        if (mWindow != null) {
-            try {
-                mSession.remove(mWindow);
-            } catch (RemoteException ex) {
-                // Not much we can do here...
-            }
-            mWindow = null;
-        }
-        mSession = null;
-        mLayout.token = null;
 
+        updateSurface();
+        if (mSurfaceControl != null) {
+            mSurfaceControl.destroy();
+        }
+        mSurfaceControl = null;
+
+        mHaveFrame = false;
         super.onDetachedFromWindow();
     }
 
@@ -308,13 +292,13 @@
     @Override
     protected boolean setFrame(int left, int top, int right, int bottom) {
         boolean result = super.setFrame(left, top, right, bottom);
-        updateWindow();
+        updateSurface();
         return result;
     }
 
     @Override
     public boolean gatherTransparentRegion(Region region) {
-        if (mWindowType == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+        if (isAboveParent()) {
             return super.gatherTransparentRegion(region);
         }
 
@@ -341,7 +325,7 @@
 
     @Override
     public void draw(Canvas canvas) {
-        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
+        if (mDrawFinished && !isAboveParent()) {
             // draw() is not called when SKIP_DRAW is set
             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == 0) {
                 // punch a whole in the view-hierarchy below us
@@ -353,8 +337,8 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
-        if (mWindowType != WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
-            // if SKIP_DRAW is cleared, draw() has already punched a hole
+        if (mDrawFinished && !isAboveParent()) {
+            // draw() is not called when SKIP_DRAW is set
             if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
                 // punch a whole in the view-hierarchy below us
                 canvas.drawColor(0, PorterDuff.Mode.CLEAR);
@@ -375,9 +359,8 @@
      * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
      */
     public void setZOrderMediaOverlay(boolean isMediaOverlay) {
-        mWindowType = isMediaOverlay
-                ? WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY
-                : WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+        mSubLayer = isMediaOverlay
+            ? APPLICATION_MEDIA_OVERLAY_SUBLAYER : APPLICATION_MEDIA_SUBLAYER;
     }
 
     /**
@@ -395,12 +378,9 @@
      */
     public void setZOrderOnTop(boolean onTop) {
         if (onTop) {
-            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
-            // ensures the surface is placed below the IME
-            mLayout.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            mSubLayer = APPLICATION_PANEL_SUBLAYER;
         } else {
-            mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
-            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+            mSubLayer = APPLICATION_MEDIA_SUBLAYER;
         }
     }
 
@@ -418,31 +398,32 @@
      */
     public void setSecure(boolean isSecure) {
         if (isSecure) {
-            mLayout.flags |= WindowManager.LayoutParams.FLAG_SECURE;
+            mSurfaceFlags |= SurfaceControl.SECURE;
         } else {
-            mLayout.flags &= ~WindowManager.LayoutParams.FLAG_SECURE;
+            mSurfaceFlags &= ~SurfaceControl.SECURE;
         }
     }
 
-    /**
-     * Hack to allow special layering of windows.  The type is one of the
-     * types in WindowManager.LayoutParams.  This is a hack so:
-     * @hide
-     */
-    public void setWindowType(int type) {
-        mWindowType = type;
+    private Rect getParentSurfaceInsets() {
+        final ViewRootImpl root = getViewRootImpl();
+        if (root == null) {
+            return null;
+        } else {
+            return root.mWindowAttributes.surfaceInsets;
+        }
     }
 
     /** @hide */
-    protected void updateWindow() {
+    protected void updateSurface() {
         if (!mHaveFrame) {
             return;
         }
         ViewRootImpl viewRoot = getViewRootImpl();
-        if (viewRoot != null) {
-            mTranslator = viewRoot.mTranslator;
+        if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
+            return;
         }
 
+        mTranslator = viewRoot.mTranslator;
         if (mTranslator != null) {
             mSurface.setCompatibilityTranslator(mTranslator);
         }
@@ -452,17 +433,15 @@
         int myHeight = mRequestedHeight;
         if (myHeight <= 0) myHeight = getHeight();
 
-        final boolean creating = mWindow == null;
         final boolean formatChanged = mFormat != mRequestedFormat;
-        final boolean sizeChanged = mWindowSpaceWidth != myWidth || mWindowSpaceHeight != myHeight;
+        final boolean creating = (mSurfaceControl == null || formatChanged)
+                && mRequestedVisible;
+        final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
         final boolean visibleChanged = mVisible != mRequestedVisible;
-        final boolean layoutSizeChanged = getWidth() != mLayout.width
-                || getHeight() != mLayout.height;
-
+        final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
         boolean redrawNeeded = false;
 
-        if (creating || formatChanged || sizeChanged || visibleChanged
-            || mUpdateWindowNeeded || mReportDrawNeeded) {
+        if (creating || formatChanged || sizeChanged || visibleChanged || windowVisibleChanged) {
             getLocationInWindow(mLocation);
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
@@ -476,93 +455,77 @@
                 final boolean visible = mVisible = mRequestedVisible;
                 mWindowSpaceLeft = mLocation[0];
                 mWindowSpaceTop = mLocation[1];
-                mWindowSpaceWidth = myWidth;
-                mWindowSpaceHeight = myHeight;
+                mSurfaceWidth = myWidth;
+                mSurfaceHeight = myHeight;
                 mFormat = mRequestedFormat;
+                mLastWindowVisibility = mWindowVisibility;
 
-                // Scaling/Translate window's layout here because mLayout is not used elsewhere.
-
-                // Places the window relative
-                mLayout.x = mWindowSpaceLeft;
-                mLayout.y = mWindowSpaceTop;
-                mLayout.width = getWidth();
-                mLayout.height = getHeight();
+                mScreenRect.left = mWindowSpaceLeft;
+                mScreenRect.top = mWindowSpaceTop;
+                mScreenRect.right = mWindowSpaceLeft + getWidth();
+                mScreenRect.bottom = mWindowSpaceTop + getHeight();
                 if (mTranslator != null) {
-                    mTranslator.translateLayoutParamsInAppWindowToScreen(mLayout);
+                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
-                mLayout.format = mRequestedFormat;
-                mLayout.flags |=WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                              | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
-                              | WindowManager.LayoutParams.FLAG_SCALED
-                              | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
-                              | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
-                              ;
-                if (!creating && !sizeChanged) {
-                    mLayout.privateFlags |=
-                            WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
-                } else {
-                    mLayout.privateFlags &=
-                            ~WindowManager.LayoutParams.PRIVATE_FLAG_PRESERVE_GEOMETRY;
+                final Rect surfaceInsets = getParentSurfaceInsets();
+                mScreenRect.offset(surfaceInsets.left, surfaceInsets.top);
+
+                if (creating) {
+                    mSurfaceSession = new SurfaceSession(viewRoot.mSurface);
+                    mSurfaceControl = new SurfaceControl(mSurfaceSession,
+                            "SurfaceView - " + viewRoot.getTitle().toString(),
+                            mSurfaceWidth, mSurfaceHeight, mFormat,
+                            mSurfaceFlags);
                 }
 
-                if (!getContext().getResources().getCompatibilityInfo().supportsScreen()) {
-                    mLayout.privateFlags |=
-                            WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-                }
-                mLayout.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION
-                    | WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
-
-                if (mWindow == null) {
-                    Display display = getDisplay();
-                    mWindow = new MyWindow(this);
-                    mLayout.type = mWindowType;
-                    mLayout.gravity = Gravity.START|Gravity.TOP;
-                    mSession.addToDisplayWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
-                            mVisible ? VISIBLE : GONE, display.getDisplayId(), mContentInsets,
-                            mStableInsets);
-                }
-
-                boolean realSizeChanged;
-                boolean reportDrawNeeded;
-
-                int relayoutResult;
+                boolean realSizeChanged = false;
 
                 mSurfaceLock.lock();
                 try {
-                    mUpdateWindowNeeded = false;
-                    reportDrawNeeded = mReportDrawNeeded;
-                    mReportDrawNeeded = false;
                     mDrawingStopped = !visible;
 
                     if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
                             + "Cur surface: " + mSurface);
 
-                    relayoutResult = mSession.relayout(
-                        mWindow, mWindow.mSeq, mLayout, mWindowSpaceWidth, mWindowSpaceHeight,
-                            visible ? VISIBLE : GONE,
-                            WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY,
-                            mWinFrame, mOverscanInsets, mContentInsets,
-                            mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame,
-                            mConfiguration, mNewSurface);
-                    if ((relayoutResult & WindowManagerGlobal.RELAYOUT_RES_FIRST_TIME) != 0) {
-                        reportDrawNeeded = true;
+                    SurfaceControl.openTransaction();
+                    try {
+                        mSurfaceControl.setLayer(mSubLayer);
+                        if (mViewVisibility) {
+                            mSurfaceControl.show();
+                        } else {
+                            mSurfaceControl.hide();
+                        }
+
+                        // While creating the surface, we will set it's initial
+                        // geometry. Outside of that though, we should generally
+                        // leave it to the RenderThread.
+                        if (creating || !mRtHandlingPositionUpdates) {
+                            mSurfaceControl.setPosition(mScreenRect.left, mScreenRect.top);
+                            mSurfaceControl.setMatrix(mScreenRect.width() / (float) mSurfaceWidth,
+                                    0.0f, 0.0f,
+                                    mScreenRect.height() / (float) mSurfaceHeight);
+                        }
+                        if (sizeChanged) {
+                            mSurfaceControl.setSize(mSurfaceWidth, mSurfaceHeight);
+                        }
+                    } finally {
+                        SurfaceControl.closeTransaction();
                     }
 
-                    if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
-                            + "New surface: " + mNewSurface
-                            + ", vis=" + visible + ", frame=" + mWinFrame);
+                    if (sizeChanged || creating) {
+                        redrawNeeded = true;
+                    }
 
                     mSurfaceFrame.left = 0;
                     mSurfaceFrame.top = 0;
                     if (mTranslator == null) {
-                        mSurfaceFrame.right = mWinFrame.width();
-                        mSurfaceFrame.bottom = mWinFrame.height();
+                        mSurfaceFrame.right = mSurfaceWidth;
+                        mSurfaceFrame.bottom = mSurfaceHeight;
                     } else {
                         float appInvertedScale = mTranslator.applicationInvertedScale;
-                        mSurfaceFrame.right = (int) (mWinFrame.width() * appInvertedScale + 0.5f);
-                        mSurfaceFrame.bottom = (int) (mWinFrame.height() * appInvertedScale + 0.5f);
+                        mSurfaceFrame.right = (int) (mSurfaceWidth * appInvertedScale + 0.5f);
+                        mSurfaceFrame.bottom = (int) (mSurfaceHeight * appInvertedScale + 0.5f);
                     }
 
                     final int surfaceWidth = mSurfaceFrame.right;
@@ -576,12 +539,11 @@
                 }
 
                 try {
-                    redrawNeeded |= creating | reportDrawNeeded;
+                    redrawNeeded |= visible && !mDrawFinished;
 
                     SurfaceHolder.Callback callbacks[] = null;
 
-                    final boolean surfaceChanged = (relayoutResult
-                            & WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED) != 0;
+                    final boolean surfaceChanged = creating;
                     if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
                         mSurfaceCreated = false;
                         if (mSurface.isValid()) {
@@ -608,7 +570,10 @@
                         }
                     }
 
-                    mSurface.transferFrom(mNewSurface);
+                    if (creating) {
+                        mSurface.copyFrom(mSurfaceControl);
+                    }
+
                     if (visible && mSurface.isValid()) {
                         if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
                             mSurfaceCreated = true;
@@ -641,53 +606,55 @@
                                 callbacks = getSurfaceCallbacks();
                             }
                             SurfaceCallbackHelper sch =
-                                    new SurfaceCallbackHelper(mSession, mWindow);
+                                    new SurfaceCallbackHelper(this::onDrawFinished);
                             sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
                         }
                     }
                 } finally {
                     mIsCreating = false;
-                    mSession.performDeferredDestroy(mWindow);
+                    if (mSurfaceControl != null && !mSurfaceCreated) {
+                        mSurfaceControl.destroy();
+                        mSurfaceControl = null;
+                    }
                 }
-            } catch (RemoteException ex) {
+            } catch (Exception ex) {
                 Log.e(TAG, "Exception from relayout", ex);
             }
             if (DEBUG) Log.v(
-                TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
-                " w=" + mLayout.width + " h=" + mLayout.height +
-                ", frame=" + mSurfaceFrame);
+                TAG, "Layout: x=" + mScreenRect.left + " y=" + mScreenRect.top
+                + " w=" + mScreenRect.width() + " h=" + mScreenRect.height()
+                + ", frame=" + mSurfaceFrame);
         } else {
             // Calculate the window position in case RT loses the window
             // and we need to fallback to a UI-thread driven position update
-            getLocationInWindow(mLocation);
+            getLocationInSurface(mLocation);
             final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
                     || mWindowSpaceTop != mLocation[1];
+            final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
+                    || getHeight() != mScreenRect.height();
             if (positionChanged || layoutSizeChanged) { // Only the position has changed
                 mWindowSpaceLeft = mLocation[0];
                 mWindowSpaceTop = mLocation[1];
-                // For our size changed check, we keep mLayout.width and mLayout.height
+                // For our size changed check, we keep mScreenRect.width() and mScreenRect.height()
                 // in view local space.
-                mLocation[0] = mLayout.width = getWidth();
-                mLocation[1] = mLayout.height = getHeight();
+                mLocation[0] = getWidth();
+                mLocation[1] = getHeight();
 
-                transformFromViewToWindowSpace(mLocation);
-
-                mTmpRect.set(mWindowSpaceLeft, mWindowSpaceTop,
+                mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
                         mLocation[0], mLocation[1]);
 
                 if (mTranslator != null) {
-                    mTranslator.translateRectInAppWindowToScreen(mTmpRect);
+                    mTranslator.translateRectInAppWindowToScreen(mScreenRect);
                 }
 
                 if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
                     try {
-                        if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition UI, " +
+                        if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition UI, " +
                                 "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                                mTmpRect.left, mTmpRect.top,
-                                mTmpRect.right, mTmpRect.bottom));
-                        mSession.repositionChild(mWindow, mTmpRect.left, mTmpRect.top,
-                                mTmpRect.right, mTmpRect.bottom, -1, mTmpRect);
-                    } catch (RemoteException ex) {
+                                mScreenRect.left, mScreenRect.top,
+                                mScreenRect.right, mScreenRect.bottom));
+                        setParentSpaceRectangle(mScreenRect, -1);
+                    } catch (Exception ex) {
                         Log.e(TAG, "Exception from relayout", ex);
                     }
                 }
@@ -695,20 +662,43 @@
         }
     }
 
+    private void onDrawFinished() {
+        if (DEBUG) {
+            Log.i(TAG, System.identityHashCode(this) + " "
+                    + "finishedDrawing");
+        }
+        mHandler.sendEmptyMessage(DRAW_FINISHED_MSG);
+    }
+
+    private void setParentSpaceRectangle(Rect position, long frameNumber) {
+        ViewRootImpl viewRoot = getViewRootImpl();
+
+        SurfaceControl.openTransaction();
+        try {
+            if (frameNumber > 0) {
+                mSurfaceControl.deferTransactionUntil(viewRoot.mSurface, frameNumber);
+            }
+            mSurfaceControl.setPosition(position.left, position.top);
+            mSurfaceControl.setMatrix(position.width() / (float) mSurfaceWidth,
+                    0.0f, 0.0f,
+                    position.height() / (float) mSurfaceHeight);
+        } finally {
+            SurfaceControl.closeTransaction();
+        }
+    }
+
     private Rect mRTLastReportedPosition = new Rect();
 
     /**
      * Called by native by a Rendering Worker thread to update the window position
      * @hide
      */
-    public final void updateWindowPosition_renderWorker(long frameNumber,
+    public final void updateSurfacePosition_renderWorker(long frameNumber,
             int left, int top, int right, int bottom) {
-        IWindowSession session = mSession;
-        MyWindow window = mWindow;
-        if (session == null || window == null) {
-            // Guess we got detached, that sucks
+        if (mSurfaceControl == null) {
             return;
         }
+
         // TODO: This is teensy bit racey in that a brand new SurfaceView moving on
         // its 2nd frame if RenderThread is running slowly could potentially see
         // this as false, enter the branch, get pre-empted, then this comes along
@@ -726,35 +716,29 @@
         }
         try {
             if (DEBUG) {
-                Log.d(TAG, String.format("%d updateWindowPosition RenderWorker, frameNr = %d, " +
+                Log.d(TAG, String.format("%d updateSurfacePosition RenderWorker, frameNr = %d, " +
                         "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
                         frameNumber, left, top, right, bottom));
             }
-            // Just using mRTLastReportedPosition as a dummy rect here
-            session.repositionChild(window, left, top, right, bottom,
-                    frameNumber,
-                    mRTLastReportedPosition);
-            // Now overwrite mRTLastReportedPosition with our values
             mRTLastReportedPosition.set(left, top, right, bottom);
-        } catch (RemoteException ex) {
+            setParentSpaceRectangle(mRTLastReportedPosition, frameNumber);
+            // Now overwrite mRTLastReportedPosition with our values
+        } catch (Exception ex) {
             Log.e(TAG, "Exception from repositionChild", ex);
         }
     }
 
     /**
-     * Called by native on RenderThread to notify that the window is no longer in the
+     * Called by native on RenderThread to notify that the view is no longer in the
      * draw tree. UI thread is blocked at this point.
      * @hide
      */
-    public final void windowPositionLost_uiRtSync(long frameNumber) {
+    public final void surfacePositionLost_uiRtSync(long frameNumber) {
         if (DEBUG) {
             Log.d(TAG, String.format("%d windowPositionLost, frameNr = %d",
                     System.identityHashCode(this), frameNumber));
         }
-        IWindowSession session = mSession;
-        MyWindow window = mWindow;
-        if (session == null || window == null) {
-            // We got detached prior to receiving this, abort
+        if (mSurfaceControl == null) {
             return;
         }
         if (mRtHandlingPositionUpdates) {
@@ -763,19 +747,14 @@
             // safely access other member variables at this time.
             // So do what the UI thread would have done if RT wasn't handling position
             // updates.
-            mTmpRect.set(mLayout.x, mLayout.y,
-                    mLayout.x + mLayout.width,
-                    mLayout.y + mLayout.height);
-
-            if (!mTmpRect.isEmpty() && !mTmpRect.equals(mRTLastReportedPosition)) {
+            if (!mScreenRect.isEmpty() && !mScreenRect.equals(mRTLastReportedPosition)) {
                 try {
-                    if (DEBUG) Log.d(TAG, String.format("%d updateWindowPosition, " +
+                    if (DEBUG) Log.d(TAG, String.format("%d updateSurfacePosition, " +
                             "postion = [%d, %d, %d, %d]", System.identityHashCode(this),
-                            mTmpRect.left, mTmpRect.top,
-                            mTmpRect.right, mTmpRect.bottom));
-                    session.repositionChild(window, mTmpRect.left, mTmpRect.top,
-                            mTmpRect.right, mTmpRect.bottom, frameNumber, mWinFrame);
-                } catch (RemoteException ex) {
+                            mScreenRect.left, mScreenRect.top,
+                            mScreenRect.right, mScreenRect.bottom));
+                    setParentSpaceRectangle(mScreenRect, frameNumber);
+                } catch (Exception ex) {
                     Log.e(TAG, "Exception from relayout", ex);
                 }
             }
@@ -792,10 +771,6 @@
         return callbacks;
     }
 
-    void handleGetNewSurface() {
-        updateWindow();
-    }
-
     /**
      * Check to see if the surface has fixed size dimensions or if the surface's
      * dimensions are dimensions are dependent on its current layout.
@@ -807,65 +782,8 @@
         return (mRequestedWidth != -1 || mRequestedHeight != -1);
     }
 
-    private static class MyWindow extends BaseIWindow {
-        private final WeakReference<SurfaceView> mSurfaceView;
-
-        public MyWindow(SurfaceView surfaceView) {
-            mSurfaceView = new WeakReference<SurfaceView>(surfaceView);
-        }
-
-        @Override
-        public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
-                Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw,
-                Configuration newConfig, Rect backDropRect, boolean forceLayout,
-                boolean alwaysConsumeNavBar, int displayId) {
-            SurfaceView surfaceView = mSurfaceView.get();
-            if (surfaceView != null) {
-                if (DEBUG) Log.v(TAG, surfaceView + " got resized: w=" + frame.width()
-                        + " h=" + frame.height() + ", cur w=" + mCurWidth + " h=" + mCurHeight);
-                surfaceView.mSurfaceLock.lock();
-                try {
-                    if (reportDraw) {
-                        surfaceView.mUpdateWindowNeeded = true;
-                        surfaceView.mReportDrawNeeded = true;
-                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
-                    } else if (surfaceView.mWinFrame.width() != frame.width()
-                            || surfaceView.mWinFrame.height() != frame.height()
-                            || forceLayout) {
-                        surfaceView.mUpdateWindowNeeded = true;
-                        surfaceView.mHandler.sendEmptyMessage(UPDATE_WINDOW_MSG);
-                    }
-                } finally {
-                    surfaceView.mSurfaceLock.unlock();
-                }
-            }
-        }
-
-        @Override
-        public void dispatchAppVisibility(boolean visible) {
-            // The point of SurfaceView is to let the app control the surface.
-        }
-
-        @Override
-        public void dispatchGetNewSurface() {
-            SurfaceView surfaceView = mSurfaceView.get();
-            if (surfaceView != null) {
-                Message msg = surfaceView.mHandler.obtainMessage(GET_NEW_SURFACE_MSG);
-                surfaceView.mHandler.sendMessage(msg);
-            }
-        }
-
-        @Override
-        public void windowFocusChanged(boolean hasFocus, boolean touchEnabled) {
-            Log.w("SurfaceView", "Unexpected focus in surface: focus=" + hasFocus + ", touchEnabled=" + touchEnabled);
-        }
-
-        @Override
-        public void executeCommand(String command, String parameters, ParcelFileDescriptor out) {
-        }
-
-        int mCurWidth = -1;
-        int mCurHeight = -1;
+    private boolean isAboveParent() {
+        return mSubLayer >= 0;
     }
 
     private final SurfaceHolder mSurfaceHolder = new SurfaceHolder() {
@@ -913,15 +831,14 @@
 
         @Override
         public void setFormat(int format) {
-
             // for backward compatibility reason, OPAQUE always
             // means 565 for SurfaceView
             if (format == PixelFormat.OPAQUE)
                 format = PixelFormat.RGB_565;
 
             mRequestedFormat = format;
-            if (mWindow != null) {
-                updateWindow();
+            if (mSurfaceControl != null) {
+                updateSurface();
             }
         }
 
@@ -982,10 +899,10 @@
             mSurfaceLock.lock();
 
             if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + "Locking canvas... stopped="
-                    + mDrawingStopped + ", win=" + mWindow);
+                    + mDrawingStopped + ", surfaceControl=" + mSurfaceControl);
 
             Canvas c = null;
-            if (!mDrawingStopped && mWindow != null) {
+            if (!mDrawingStopped && mSurfaceControl != null) {
                 try {
                     if (hardware) {
                         c = mSurface.lockHardwareCanvas();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1338b05..e349170 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4500,6 +4500,8 @@
                     break;
                 case com.android.internal.R.styleable.View_focusableInTouchMode:
                     if (a.getBoolean(attr, false)) {
+                        // unset auto focus since focusableInTouchMode implies explicit focusable
+                        viewFlagValues &= ~FOCUSABLE_AUTO;
                         viewFlagValues |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE;
                         viewFlagMasks |= FOCUSABLE_IN_TOUCH_MODE | FOCUSABLE_MASK;
                     }
@@ -6471,12 +6473,18 @@
                 }
             }
         }
+
+        // Invisible and gone views are never focusable.
         if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
             return false;
         }
-        return (allowAutoFocus
-                ? getFocusable() != NOT_FOCUSABLE
-                : getFocusable() == FOCUSABLE) && isFocusable();
+
+        // Only use effective focusable value when allowed.
+        if ((allowAutoFocus || getFocusable() != FOCUSABLE_AUTO) && isFocusable()) {
+            return true;
+        }
+
+        return false;
     }
 
     /**
@@ -8666,7 +8674,10 @@
         // which, in touch mode, will not successfully request focus on this view
         // because the focusable in touch mode flag is not set
         setFlags(focusableInTouchMode ? FOCUSABLE_IN_TOUCH_MODE : 0, FOCUSABLE_IN_TOUCH_MODE);
+
+        // Clear FOCUSABLE_AUTO if set.
         if (focusableInTouchMode) {
+            // Clears FOCUSABLE_AUTO if set.
             setFlags(FOCUSABLE, FOCUSABLE_MASK);
         }
     }
@@ -11730,7 +11741,10 @@
                 && isOnScrollbar(event.getX(), event.getY())) {
             awakenScrollBars();
         }
-        if (isHoverable()) {
+
+        // If we consider ourself hoverable, or if we we're already hovered,
+        // handle changing state in response to ENTER and EXIT events.
+        if (isHoverable() || isHovered()) {
             switch (action) {
                 case MotionEvent.ACTION_HOVER_ENTER:
                     setHovered(true);
@@ -12261,12 +12275,13 @@
         // If focusable is auto, update the FOCUSABLE bit.
         int focusableChangedByAuto = 0;
         if (((mViewFlags & FOCUSABLE_AUTO) != 0)
-                && (changed & (FOCUSABLE_MASK | CLICKABLE | FOCUSABLE_IN_TOUCH_MODE)) != 0) {
-            int newFocus = NOT_FOCUSABLE;
-            if ((mViewFlags & (CLICKABLE | FOCUSABLE_IN_TOUCH_MODE)) != 0) {
+                && (changed & (FOCUSABLE_MASK | CLICKABLE)) != 0) {
+            // Heuristic only takes into account whether view is clickable.
+            final int newFocus;
+            if ((mViewFlags & CLICKABLE) != 0) {
                 newFocus = FOCUSABLE;
             } else {
-                mViewFlags = (mViewFlags & ~FOCUSABLE_IN_TOUCH_MODE);
+                newFocus = NOT_FOCUSABLE;
             }
             mViewFlags = (mViewFlags & ~FOCUSABLE) | newFocus;
             focusableChangedByAuto = (old & FOCUSABLE) ^ (newFocus & FOCUSABLE);
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index ffa79bd..3dd3ba8 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1148,18 +1148,21 @@
 
     @Override
     boolean hasFocusable(boolean allowAutoFocus, boolean dispatchExplicit) {
+        // This should probably be super.hasFocusable, but that would change
+        // behavior. Historically, we have not checked the ancestor views for
+        // shouldBlockFocusForTouchscreen() in ViewGroup.hasFocusable.
+
+        // Invisible and gone views are never focusable.
         if ((mViewFlags & VISIBILITY_MASK) != VISIBLE) {
             return false;
         }
 
-        // TODO This should probably be super.hasFocusable, but that would change behavior.
-        // The below is a much simpler check than we do in the superclass implementation,
-        // but it's been this way for a long time and other code likely relies on it.
-        if ((allowAutoFocus ? getFocusable() != NOT_FOCUSABLE : getFocusable() == FOCUSABLE)
-                && isFocusable()) {
+        // Only use effective focusable value when allowed.
+        if ((allowAutoFocus || getFocusable() != FOCUSABLE_AUTO) && isFocusable()) {
             return true;
         }
 
+        // Determine whether we have a focused descendant.
         final int descendantFocusability = getDescendantFocusability();
         if (descendantFocusability != FOCUS_BLOCK_DESCENDANTS) {
             final int count = mChildrenCount;
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 20d960f..f9863b0 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2632,6 +2632,14 @@
         }
     }
 
+    private void onDrawFinished() {
+        try {
+            mWindowSession.finishDrawing(mWindow);
+        } catch (RemoteException e) {
+            // Have fun!
+        }
+    }
+
     private void performDraw() {
         if (mAttachInfo.mDisplayState == Display.STATE_OFF && !mReportNextDraw) {
             return;
@@ -2682,7 +2690,7 @@
             }
 
             if (mSurfaceHolder != null && mSurface.isValid()) {
-                SurfaceCallbackHelper sch = new SurfaceCallbackHelper(mWindowSession, mWindow);
+                SurfaceCallbackHelper sch = new SurfaceCallbackHelper(this::onDrawFinished);
                 SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
 
                 sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java
index 84c2c84..43560f0 100644
--- a/core/java/android/view/ViewStructure.java
+++ b/core/java/android/view/ViewStructure.java
@@ -316,6 +316,13 @@
     public abstract void setAutoFillOptions(String[] options);
 
     /**
+     * Sets the {@link android.text.InputType} bits of this node.
+     *
+     * @param inputType inputType bits as defined by {@link android.text.InputType}.
+     */
+    public abstract void setInputType(int inputType);
+
+    /**
      * Marks this node as sanitized so its content are sent on {@link
      * android.service.autofill.AutoFillService#onFillRequest(android.app.assist.AssistStructure,
      * Bundle, android.os.CancellationSignal, android.service.autofill.FillCallback)}.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index d866927..8094fa6 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3591,6 +3591,7 @@
      * <li><strong>Standard actions</strong> - These are actions that are reported and
      * handled by the standard UI widgets in the platform. For each standard action
      * there is a static constant defined in this class, e.g. {@link #ACTION_FOCUS}.
+     * These actions will have {@code null} labels.
      * </li>
      * <li><strong>Custom actions action</strong> - These are actions that are reported
      * and handled by custom widgets. i.e. ones that are not part of the UI toolkit. For
diff --git a/core/java/android/view/autofill/AutoFillType.java b/core/java/android/view/autofill/AutoFillType.java
index 5d85bfd..e974705 100644
--- a/core/java/android/view/autofill/AutoFillType.java
+++ b/core/java/android/view/autofill/AutoFillType.java
@@ -40,18 +40,13 @@
     private static class DefaultTypesHolder {
         static final AutoFillType TOGGLE = new AutoFillType(TYPE_TOGGLE, 0);
         static final AutoFillType LIST = new AutoFillType(TYPE_LIST, 0);
+        static final AutoFillType DATE = new AutoFillType(TYPE_DATE, 0);
     }
 
     private static final int TYPE_TEXT = 1;
     private static final int TYPE_TOGGLE = 2;
     private static final int TYPE_LIST = 3;
-
-    // TODO(b/33197203): add others, like date picker? That would be trick, because they're set as:
-    // updateDate(int year, int month, int dayOfMonth)
-    // So, we would have to either use a long representing the Date.time(), or a custom long
-    // representing:
-    // year * 10000 + month * 100 + day
-    // Then a custom getDatePickerValue(Bundle) that returns an immutable object with these 3 fields
+    private static final int TYPE_DATE = 4;
 
     private final int mType;
     private final int mSubType;
@@ -65,7 +60,7 @@
      * Checks if this is a type for a text field, which is filled by a {@link CharSequence}.
      *
      * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forText(CharSequence)}, and the value of a bundle passed to auto-fill a
+     * {@link AutoFillValue#forText(CharSequence)}, and the value passed to auto-fill a
      * {@link View} can be fetched through {@link AutoFillValue#getTextValue()}.
      *
      * <p>Sub-type for this type is the value defined by {@link TextView#getInputType()}.
@@ -78,7 +73,7 @@
      * Checks if this is a a type for a togglable field, which is filled by a {@code boolean}.
      *
      * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forToggle(boolean)}, and the value of a bundle passed to auto-fill a
+     * {@link AutoFillValue#forToggle(boolean)}, and the value passed to auto-fill a
      * {@link View} can be fetched through {@link AutoFillValue#getToggleValue()}.
      *
      * <p>This type has no sub-types.
@@ -92,7 +87,7 @@
      * representing the element index inside the list (starting at {@code 0}.
      *
      * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
-     * {@link AutoFillValue#forList(int)}, and the value of a bundle passed to auto-fill a
+     * {@link AutoFillValue#forList(int)}, and the value passed to auto-fill a
      * {@link View} can be fetched through {@link AutoFillValue#getListValue()}.
      *
      * <p>This type has no sub-types.
@@ -101,6 +96,20 @@
         return mType == TYPE_LIST;
     }
 
+    /**
+     * Checks if this is a type for a date and time, which is represented by a long representing
+     * the number of milliseconds since the standard base time known as "the epoch", namely
+     * January 1, 1970, 00:00:00 GMT (see {@link java.util.Date#getTime()}.
+     *
+     * <p>{@link AutoFillValue} instances for auto-filling a {@link View} can be obtained through
+     * {@link AutoFillValue#forDate(long)}, and the values passed to
+     * auto-fill a {@link View} can be fetched through {@link AutoFillValue#getDateValue()}.
+     *
+     * <p>This type has no sub-types.
+     */
+    public boolean isDate() {
+        return mType == TYPE_DATE;
+    }
 
     /**
      * Gets the optional sub-type, representing the {@link View}'s semantic.
@@ -206,4 +215,13 @@
     public static AutoFillType forList() {
         return DefaultTypesHolder.LIST;
     }
+
+    /**
+     * Creates a type that represents a date.
+     *
+     * <p>See {@link #isDate()} for more info.
+     */
+    public static AutoFillType forDate() {
+        return DefaultTypesHolder.DATE;
+    }
 }
diff --git a/core/java/android/view/autofill/AutoFillValue.java b/core/java/android/view/autofill/AutoFillValue.java
index d9afa3b..c24e04e 100644
--- a/core/java/android/view/autofill/AutoFillValue.java
+++ b/core/java/android/view/autofill/AutoFillValue.java
@@ -35,11 +35,13 @@
     private final String mText;
     private final int mListIndex;
     private final boolean mToggle;
+    private final long mDate;
 
-    private AutoFillValue(CharSequence text, int listIndex, boolean toggle) {
+    private AutoFillValue(CharSequence text, int listIndex, boolean toggle, long date) {
         mText = (text == null) ? null : text.toString();
         mListIndex = listIndex;
         mToggle = toggle;
+        mDate = date;
     }
 
     /**
@@ -69,6 +71,17 @@
         return mListIndex;
     }
 
+    /**
+     * Gets the value representing the the number of milliseconds since the standard base time known
+     * as "the epoch", namely January 1, 1970, 00:00:00 GMT (see {@link java.util.Date#getTime()}
+     * of a date field.
+     *
+     * <p>See {@link AutoFillType#isDate()} for more info.
+     */
+    public long getDateValue() {
+        return mDate;
+    }
+
     /////////////////////////////////////
     //  Object "contract" methods. //
     /////////////////////////////////////
@@ -77,9 +90,10 @@
     public int hashCode() {
         final int prime = 31;
         int result = 1;
-        result = prime * result + mListIndex;
         result = prime * result + ((mText == null) ? 0 : mText.hashCode());
+        result = prime * result + mListIndex;
         result = prime * result + (mToggle ? 1231 : 1237);
+        result = prime * result + (int) (mDate ^ (mDate >>> 32));
         return result;
     }
 
@@ -89,13 +103,14 @@
         if (obj == null) return false;
         if (getClass() != obj.getClass()) return false;
         final AutoFillValue other = (AutoFillValue) obj;
-        if (mListIndex != other.mListIndex) return false;
         if (mText == null) {
             if (other.mText != null) return false;
         } else {
             if (!mText.equals(other.mText)) return false;
         }
+        if (mListIndex != other.mListIndex) return false;
         if (mToggle != other.mToggle) return false;
+        if (mDate != other.mDate) return false;
         return true;
     }
 
@@ -113,7 +128,7 @@
             return mText.length() + "_chars";
         }
 
-        return "[listIndex=" + mListIndex + ", toggle=" + mToggle + "]";
+        return "[l=" + mListIndex + ", t=" + mToggle + ", d=" + mDate + "]";
     }
 
     /////////////////////////////////////
@@ -130,12 +145,14 @@
         parcel.writeString(mText);
         parcel.writeInt(mListIndex);
         parcel.writeInt(mToggle ? 1 : 0);
+        parcel.writeLong(mDate);
     }
 
     private AutoFillValue(Parcel parcel) {
         mText = parcel.readString();
         mListIndex = parcel.readInt();
         mToggle = parcel.readInt() == 1;
+        mDate = parcel.readLong();
     }
 
     public static final Parcelable.Creator<AutoFillValue> CREATOR =
@@ -157,31 +174,42 @@
 
     // TODO(b/33197203): add unit tests for each supported type (new / get should return same value)
     /**
-     * Creates a new {@link AutoFillValue} to auto-fill a text field.
+     * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a text field.
      *
      * <p>See {@link AutoFillType#isText()} for more info.
      */
     // TODO(b/33197203): use cache
     @Nullable
     public static AutoFillValue forText(@Nullable CharSequence value) {
-        return value == null ? null : new AutoFillValue(value, 0, false);
+        return value == null ? null : new AutoFillValue(value, 0, false, 0);
     }
 
     /**
-     * Creates a new {@link AutoFillValue} to auto-fill a toggable field.
+     * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a toggable
+     * field.
      *
      * <p>See {@link AutoFillType#isToggle()} for more info.
      */
     public static AutoFillValue forToggle(boolean value) {
-        return new AutoFillValue(null, 0, value);
+        return new AutoFillValue(null, 0, value, 0);
     }
 
     /**
-     * Creates a new {@link AutoFillValue} to auto-fill a selection list field.
+     * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a selection
+     * list.
      *
      * <p>See {@link AutoFillType#isList()} for more info.
      */
     public static AutoFillValue forList(int value) {
-        return new AutoFillValue(null, value, false);
+        return new AutoFillValue(null, value, false, 0);
+    }
+
+    /**
+     * Creates a new {@link AutoFillValue} to auto-fill a {@link View} representing a date.
+     *
+     * <p>See {@link AutoFillType#isDate()} for more info.
+     */
+    public static AutoFillValue forDate(long date) {
+        return new AutoFillValue(null, 0, false, date);
     }
 }
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 887c59a..141b52f 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -591,7 +591,7 @@
 
     @Override
     public AutoFillType getAutoFillType() {
-        return AutoFillType.forToggle();
+        return isEnabled() ? AutoFillType.forToggle() : null;
     }
 
     @Override
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 517e20cd..0ffefd0 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -31,7 +31,11 @@
 import android.util.AttributeSet;
 import android.util.SparseArray;
 import android.view.View;
+import android.view.ViewStructure;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.autofill.AutoFillManager;
+import android.view.autofill.AutoFillType;
+import android.view.autofill.AutoFillValue;
 
 import com.android.internal.R;
 
@@ -170,6 +174,13 @@
         if (firstDayOfWeek != 0) {
             setFirstDayOfWeek(firstDayOfWeek);
         }
+
+        mDelegate.setAutoFillChangeListener((v, y, m, d) -> {
+            final AutoFillManager afm = context.getSystemService(AutoFillManager.class);
+            if (afm != null) {
+                afm.valueChanged(this);
+            }
+        });
     }
 
     private DatePickerDelegate createSpinnerUIDelegate(Context context, AttributeSet attrs,
@@ -503,12 +514,15 @@
                   OnDateChangedListener onDateChangedListener);
 
         void setOnDateChangedListener(OnDateChangedListener onDateChangedListener);
+        void setAutoFillChangeListener(OnDateChangedListener onDateChangedListener);
 
         void updateDate(int year, int month, int dayOfMonth);
+        void updateDate(long date);
 
         int getYear();
         int getMonth();
         int getDayOfMonth();
+        long getDate();
 
         void setFirstDayOfWeek(int firstDayOfWeek);
         int getFirstDayOfWeek();
@@ -558,6 +572,7 @@
 
         // Callbacks
         protected OnDateChangedListener mOnDateChangedListener;
+        protected OnDateChangedListener mAutoFillChangeListener;
         protected ValidationCallback mValidationCallback;
 
         public AbstractDatePickerDelegate(DatePicker delegator, Context context) {
@@ -580,10 +595,28 @@
         }
 
         @Override
+        public void setAutoFillChangeListener(OnDateChangedListener callback) {
+            mAutoFillChangeListener = callback;
+        }
+
+        @Override
         public void setValidationCallback(ValidationCallback callback) {
             mValidationCallback = callback;
         }
 
+        @Override
+        public void updateDate(long date) {
+            Calendar cal = Calendar.getInstance(mCurrentLocale);
+            cal.setTimeInMillis(date);
+            updateDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH),
+                    cal.get(Calendar.DAY_OF_MONTH));
+        }
+
+        @Override
+        public long getDate() {
+            return mCurrentDate.getTimeInMillis();
+        }
+
         protected void onValidationChanged(boolean valid) {
             if (mValidationCallback != null) {
                 mValidationCallback.onValidationChanged(valid);
@@ -723,4 +756,31 @@
     public interface ValidationCallback {
         void onValidationChanged(boolean valid);
     }
+
+    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+
+    @Override
+    public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
+        // This view is self-sufficient for auto-fill, so it needs to call
+        // onProvideAutoFillStructure() to fill itself, but it does not need to call
+        // dispatchProvideAutoFillStructure() to fill its children.
+        onProvideAutoFillStructure(structure, flags);
+    }
+
+    @Override
+    public void autoFill(AutoFillValue value) {
+        if (!isEnabled()) return;
+
+        mDelegate.updateDate(value.getDateValue());
+    }
+
+    @Override
+    public AutoFillType getAutoFillType() {
+        return isEnabled() ? AutoFillType.forDate() : null;
+    }
+
+    @Override
+    public AutoFillValue getAutoFillValue() {
+        return isEnabled() ? AutoFillValue.forDate(mDelegate.getDate()) : null;
+    }
 }
diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java
index 907250a..ca1bf58 100755
--- a/core/java/android/widget/DatePickerCalendarDelegate.java
+++ b/core/java/android/widget/DatePickerCalendarDelegate.java
@@ -390,10 +390,16 @@
     private void onDateChanged(boolean fromUser, boolean callbackToClient) {
         final int year = mCurrentDate.get(Calendar.YEAR);
 
-        if (callbackToClient && mOnDateChangedListener != null) {
+        if (callbackToClient
+                && (mOnDateChangedListener != null || mAutoFillChangeListener != null)) {
             final int monthOfYear = mCurrentDate.get(Calendar.MONTH);
             final int dayOfMonth = mCurrentDate.get(Calendar.DAY_OF_MONTH);
-            mOnDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
+            if (mOnDateChangedListener != null) {
+                mOnDateChangedListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
+            }
+            if (mAutoFillChangeListener != null) {
+                mAutoFillChangeListener.onDateChanged(mDelegator, year, monthOfYear, dayOfMonth);
+            }
         }
 
         mDayPickerView.setDate(mCurrentDate.getTimeInMillis());
diff --git a/core/java/android/widget/DatePickerSpinnerDelegate.java b/core/java/android/widget/DatePickerSpinnerDelegate.java
index 702b2a5..fc2d1fa 100644
--- a/core/java/android/widget/DatePickerSpinnerDelegate.java
+++ b/core/java/android/widget/DatePickerSpinnerDelegate.java
@@ -576,6 +576,10 @@
             mOnDateChangedListener.onDateChanged(mDelegator, getYear(), getMonth(),
                     getDayOfMonth());
         }
+        if (mAutoFillChangeListener != null) {
+            mAutoFillChangeListener.onDateChanged(mDelegator, getYear(), getMonth(),
+                    getDayOfMonth());
+        }
     }
 
     /**
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index bba3a11..be5fc53 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -436,7 +436,7 @@
 
     @Override
     public AutoFillType getAutoFillType() {
-        return AutoFillType.forList();
+        return isEnabled() ? AutoFillType.forList() : null;
     }
 
     @Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index adc6f72..3d10917 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10002,6 +10002,7 @@
                     AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
         }
         structure.setHint(getHint());
+        structure.setInputType(getInputType());
     }
 
     // TODO(b/33197203): add unit/CTS tests for auto-fill methods
@@ -10335,7 +10336,7 @@
                         Selection.setSelection((Spannable) text, start, end);
                         // Make sure selection mode is engaged.
                         if (mEditor != null) {
-                            mEditor.startSelectionActionModeAsync();
+                            mEditor.startSelectionActionMode();
                         }
                         return true;
                     }
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 9f38b04..1df202e 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -23,12 +23,17 @@
 import android.annotation.Widget;
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.icu.util.Calendar;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
 import android.util.MathUtils;
 import android.view.View;
+import android.view.ViewStructure;
 import android.view.accessibility.AccessibilityEvent;
+import android.view.autofill.AutoFillManager;
+import android.view.autofill.AutoFillType;
+import android.view.autofill.AutoFillValue;
 
 import com.android.internal.R;
 
@@ -132,6 +137,12 @@
                         this, context, attrs, defStyleAttr, defStyleRes);
                 break;
         }
+        mDelegate.setAutoFillChangeListener((v, h, m) -> {
+            final AutoFillManager afm = context.getSystemService(AutoFillManager.class);
+            if (afm != null) {
+                afm.valueChanged(this);
+            }
+        });
     }
 
     /**
@@ -348,12 +359,16 @@
         void setMinute(@IntRange(from = 0, to = 59) int minute);
         int getMinute();
 
+        void setDate(long date);
+        long getDate();
+
         void setIs24Hour(boolean is24Hour);
         boolean is24Hour();
 
         boolean validateInput();
 
         void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener);
+        void setAutoFillChangeListener(OnTimeChangedListener autoFillChangeListener);
 
         void setEnabled(boolean enabled);
         boolean isEnabled();
@@ -398,6 +413,7 @@
         protected final Locale mLocale;
 
         protected OnTimeChangedListener mOnTimeChangedListener;
+        protected OnTimeChangedListener mAutoFillChangeListener;
 
         public AbstractTimePickerDelegate(@NonNull TimePicker delegator, @NonNull Context context) {
             mDelegator = delegator;
@@ -410,6 +426,27 @@
             mOnTimeChangedListener = callback;
         }
 
+        @Override
+        public void setAutoFillChangeListener(OnTimeChangedListener callback) {
+            mAutoFillChangeListener = callback;
+        }
+
+        @Override
+        public void setDate(long date) {
+            Calendar cal = Calendar.getInstance(mLocale);
+            cal.setTimeInMillis(date);
+            setHour(cal.get(Calendar.HOUR_OF_DAY));
+            setMinute(cal.get(Calendar.MINUTE));
+        }
+
+        @Override
+        public long getDate() {
+            Calendar cal = Calendar.getInstance(mLocale);
+            cal.set(Calendar.HOUR_OF_DAY, getHour());
+            cal.set(Calendar.MINUTE, getMinute());
+            return cal.getTimeInMillis();
+        }
+
         protected static class SavedState extends View.BaseSavedState {
             private final int mHour;
             private final int mMinute;
@@ -474,4 +511,31 @@
             };
         }
     }
+
+    // TODO(b/33197203): add unit/CTS tests for auto-fill methods (and make sure they handle enable)
+
+    @Override
+    public void dispatchProvideAutoFillStructure(ViewStructure structure, int flags) {
+        // This view is self-sufficient for auto-fill, so it needs to call
+        // onProvideAutoFillStructure() to fill itself, but it does not need to call
+        // dispatchProvideAutoFillStructure() to fill its children.
+        onProvideAutoFillStructure(structure, flags);
+    }
+
+    @Override
+    public void autoFill(AutoFillValue value) {
+        if (!isEnabled()) return;
+
+        mDelegate.setDate(value.getDateValue());
+    }
+
+    @Override
+    public AutoFillType getAutoFillType() {
+        return isEnabled() ? AutoFillType.forDate() : null;
+    }
+
+    @Override
+    public AutoFillValue getAutoFillValue() {
+        return isEnabled() ? AutoFillValue.forDate(mDelegate.getDate()) : null;
+    }
 }
diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java
index 3a09063..3605585 100644
--- a/core/java/android/widget/TimePickerClockDelegate.java
+++ b/core/java/android/widget/TimePickerClockDelegate.java
@@ -671,6 +671,9 @@
         if (mOnTimeChangedListener != null) {
             mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute());
         }
+        if (mAutoFillChangeListener != null) {
+            mAutoFillChangeListener.onTimeChanged(mDelegator, getHour(), getMinute());
+        }
     }
 
     private void tryVibrate() {
@@ -813,8 +816,12 @@
     private final OnValueSelectedListener mOnValueSelectedListener = new OnValueSelectedListener() {
         @Override
         public void onValueSelected(int pickerType, int newValue, boolean autoAdvance) {
+            boolean valueChanged = false;
             switch (pickerType) {
                 case RadialTimePickerView.HOURS:
+                    if (getHour() != newValue) {
+                        valueChanged = true;
+                    }
                     final boolean isTransition = mAllowAutoAdvance && autoAdvance;
                     setHourInternal(newValue, FROM_RADIAL_PICKER, !isTransition);
                     if (isTransition) {
@@ -825,11 +832,14 @@
                     }
                     break;
                 case RadialTimePickerView.MINUTES:
+                    if (getMinute() != newValue) {
+                        valueChanged = true;
+                    }
                     setMinuteInternal(newValue, FROM_RADIAL_PICKER);
                     break;
             }
 
-            if (mOnTimeChangedListener != null) {
+            if (mOnTimeChangedListener != null && valueChanged) {
                 mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(), getMinute());
             }
         }
diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java
index 20a5512..813c30e3 100644
--- a/core/java/android/widget/TimePickerSpinnerDelegate.java
+++ b/core/java/android/widget/TimePickerSpinnerDelegate.java
@@ -495,6 +495,9 @@
             mOnTimeChangedListener.onTimeChanged(mDelegator, getHour(),
                     getMinute());
         }
+        if (mAutoFillChangeListener != null) {
+            mAutoFillChangeListener.onTimeChanged(mDelegator, getHour(), getMinute());
+        }
     }
 
     private void updateHourControl() {
diff --git a/core/java/com/android/internal/app/NightDisplayController.java b/core/java/com/android/internal/app/NightDisplayController.java
index 03cd729..68afe02 100644
--- a/core/java/com/android/internal/app/NightDisplayController.java
+++ b/core/java/com/android/internal/app/NightDisplayController.java
@@ -18,13 +18,13 @@
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.app.ActivityManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.Looper;
-import android.os.UserHandle;
 import android.provider.Settings.Secure;
 import android.util.Slog;
 
@@ -81,7 +81,7 @@
     private Callback mCallback;
 
     public NightDisplayController(@NonNull Context context) {
-        this(context, UserHandle.myUserId());
+        this(context, ActivityManager.getCurrentUser());
     }
 
     public NightDisplayController(@NonNull Context context, int userId) {
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 9fb9cb6..3f1c9ad 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -535,16 +535,7 @@
     @Override
     protected void onRestoreInstanceState(Bundle savedInstanceState) {
         super.onRestoreInstanceState(savedInstanceState);
-        if (mSupportsAlwaysUseOption) {
-            final int checkedPos = mAdapterView.getCheckedItemPosition();
-            final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
-            mLastSelected = checkedPos;
-            setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
-            mOnceButton.setEnabled(hasValidSelection);
-            if (hasValidSelection) {
-                mAdapterView.setSelection(checkedPos);
-            }
-        }
+        resetAlwaysOrOnceButtonBar();
     }
 
     private boolean hasManagedProfile() {
@@ -581,7 +572,13 @@
         boolean enabled = false;
         if (hasValidSelection) {
             ResolveInfo ri = mAdapter.resolveInfoForPosition(checkedPos, filtered);
-            if (ri.targetUserId == UserHandle.USER_CURRENT) {
+            if (ri == null) {
+                Log.e(TAG, "Invalid position supplied to setAlwaysButtonEnabled");
+                return;
+            } else if (ri.targetUserId != UserHandle.USER_CURRENT) {
+                Log.e(TAG, "Attempted to set selection to resolve info for another user");
+                return;
+            } else {
                 enabled = true;
             }
         }
diff --git a/core/java/com/android/internal/notification/SystemNotificationChannels.java b/core/java/com/android/internal/notification/SystemNotificationChannels.java
new file mode 100644
index 0000000..ec3aac2
--- /dev/null
+++ b/core/java/com/android/internal/notification/SystemNotificationChannels.java
@@ -0,0 +1,136 @@
+/*
+ * 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.internal.notification;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.provider.Settings;
+
+import com.android.internal.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+// Manages the NotificationChannels used by the frameworks itself.
+public class SystemNotificationChannels {
+    public static String VIRTUAL_KEYBOARD  = "VIRTUAL_KEYBOARD";
+    public static String PHYSICAL_KEYBOARD = "PHYSICAL_KEYBOARD";
+    public static String SECURITY = "SECURITY";
+    public static String CAR_MODE = "CAR_MODE";
+    public static String ACCOUNT = "ACCOUNT";
+    public static String DEVELOPER = "DEVELOPER";
+    public static String UPDATES = "UPDATES";
+    public static String NETWORK_STATUS = "NETWORK_STATUS";
+    public static String NETWORK_ALERTS = "NETWORK_ALERTS";
+    public static String VPN = "VPN";
+    public static String DEVICE_ADMIN = "DEVICE_ADMIN";
+    public static String ALERTS = "ALERTS";
+    public static String RETAIL_MODE = "RETAIL_MODE";
+    public static String USB = "USB";
+
+    public static void createAll(Context context) {
+        final NotificationManager nm = context.getSystemService(NotificationManager.class);
+        List<NotificationChannel> channelsList = new ArrayList<NotificationChannel>();
+        channelsList.add(new NotificationChannel(
+                VIRTUAL_KEYBOARD,
+                R.string.notification_channel_virtual_keyboard,
+                NotificationManager.IMPORTANCE_LOW));
+
+        final NotificationChannel physicalKeyboardChannel = new NotificationChannel(
+                PHYSICAL_KEYBOARD,
+                R.string.notification_channel_physical_keyboard,
+                NotificationManager.IMPORTANCE_DEFAULT);
+        physicalKeyboardChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
+                Notification.AUDIO_ATTRIBUTES_DEFAULT);
+        channelsList.add(physicalKeyboardChannel);
+
+        channelsList.add(new NotificationChannel(
+                SECURITY,
+                R.string.notification_channel_security,
+                NotificationManager.IMPORTANCE_LOW));
+
+        channelsList.add(new NotificationChannel(
+                CAR_MODE,
+                R.string.notification_channel_car_mode,
+                NotificationManager.IMPORTANCE_LOW));
+
+        channelsList.add(new NotificationChannel(
+                DEVELOPER,
+                R.string.notification_channel_developer,
+                NotificationManager.IMPORTANCE_LOW));
+
+        channelsList.add(new NotificationChannel(
+                UPDATES,
+                R.string.notification_channel_updates,
+                NotificationManager.IMPORTANCE_LOW));
+
+        channelsList.add(new NotificationChannel(
+                NETWORK_STATUS,
+                R.string.notification_channel_network_status,
+                NotificationManager.IMPORTANCE_LOW));
+
+        final NotificationChannel networkAlertsChannel = new NotificationChannel(
+                NETWORK_ALERTS,
+                R.string.notification_channel_network_alerts,
+                NotificationManager.IMPORTANCE_HIGH);
+        networkAlertsChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
+                Notification.AUDIO_ATTRIBUTES_DEFAULT);
+        channelsList.add(networkAlertsChannel);
+
+        channelsList.add(new NotificationChannel(
+                VPN,
+                R.string.notification_channel_vpn,
+                NotificationManager.IMPORTANCE_LOW));
+
+        channelsList.add(new NotificationChannel(
+                DEVICE_ADMIN,
+                R.string.notification_channel_device_admin,
+                NotificationManager.IMPORTANCE_LOW));
+
+        final NotificationChannel alertsChannel = new NotificationChannel(
+                ALERTS,
+                R.string.notification_channel_alerts,
+                NotificationManager.IMPORTANCE_DEFAULT);
+        alertsChannel.setSound(Settings.System.DEFAULT_NOTIFICATION_URI,
+                Notification.AUDIO_ATTRIBUTES_DEFAULT);
+        channelsList.add(alertsChannel);
+
+        channelsList.add(new NotificationChannel(
+                RETAIL_MODE,
+                R.string.notification_channel_retail_mode,
+                NotificationManager.IMPORTANCE_LOW));
+
+        channelsList.add(new NotificationChannel(
+                USB,
+                R.string.notification_channel_usb,
+                NotificationManager.IMPORTANCE_MIN));
+
+        nm.createNotificationChannels(channelsList);
+        createAccountChannelForPackage(context.getPackageName(), context);
+    }
+
+    public static void createAccountChannelForPackage(String pkg, Context context) {
+        final NotificationManager nm = context.getSystemService(NotificationManager.class);
+        nm.createNotificationChannelsForPackage(pkg, Arrays.asList(new NotificationChannel(
+                ACCOUNT,
+                R.string.notification_channel_account,
+                NotificationManager.IMPORTANCE_LOW)));
+    }
+
+    private SystemNotificationChannels() {}
+}
diff --git a/core/java/com/android/internal/util/ParcelableString.java b/core/java/com/android/internal/util/ParcelableString.java
deleted file mode 100644
index 6bd856f..0000000
--- a/core/java/com/android/internal/util/ParcelableString.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2014, 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.internal.util;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Helper class to adapt a simple String to cases where a Parcelable is expected.
- * @hide
- */
-public class ParcelableString implements Parcelable {
-    public String string;
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(string);
-    }
-
-    public static final Parcelable.Creator<ParcelableString> CREATOR =
-            new Parcelable.Creator<ParcelableString>() {
-                @Override
-                public ParcelableString createFromParcel(Parcel in) {
-                    ParcelableString ret = new ParcelableString();
-                    ret.string = in.readString();
-                    return ret;
-                }
-                @Override
-                public ParcelableString[] newArray(int size) {
-                    return new ParcelableString[size];
-                }
-    };
-}
\ No newline at end of file
diff --git a/core/java/com/android/internal/view/SurfaceCallbackHelper.java b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
index 5b6a82c..507b673 100644
--- a/core/java/com/android/internal/view/SurfaceCallbackHelper.java
+++ b/core/java/com/android/internal/view/SurfaceCallbackHelper.java
@@ -17,14 +17,11 @@
 package com.android.internal.view;
 
 import android.os.RemoteException;
-import android.view.IWindow;
-import android.view.IWindowSession;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 
 public class SurfaceCallbackHelper {
-    IWindowSession mSession;
-    IWindow.Stub mWindow;
+    Runnable mRunnable;
 
     int mFinishDrawingCollected = 0;
     int mFinishDrawingExpected = 0;
@@ -37,26 +34,18 @@
                     if (mFinishDrawingCollected < mFinishDrawingExpected) {
                         return;
                     }
-                    try {
-                        mSession.finishDrawing(mWindow);
-                    } catch (RemoteException e) {
-                    }
+                    mRunnable.run();
                 }
             }
     };
 
-    public SurfaceCallbackHelper(IWindowSession session,
-            IWindow.Stub window) {
-        mSession = session;
-        mWindow = window;
+    public SurfaceCallbackHelper(Runnable callbacksCollected) {
+        mRunnable = callbacksCollected;
     }
 
     public void dispatchSurfaceRedrawNeededAsync(SurfaceHolder holder, SurfaceHolder.Callback callbacks[]) {
         if (callbacks == null || callbacks.length == 0) {
-            try {
-                mSession.finishDrawing(mWindow);
-            } catch (RemoteException e) {
-            }
+            mRunnable.run();
             return;
         }
 
diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
index 69e974c..1de0af6 100644
--- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
@@ -388,14 +388,22 @@
             final boolean showOnRight = nextMenuPosition == HORIZ_POSITION_RIGHT;
             mLastPosition = nextMenuPosition;
 
-            final int[] tempLocation = new int[2];
+            // A popup anchored to mAnchorView with (0,0) offset would be shown at this position.
+            final int[] offsetOrigin = new int[2];
+            mAnchorView.getLocationOnScreen(offsetOrigin);
+            offsetOrigin[1] += mAnchorView.getHeight();
 
-            // This popup menu will be positioned relative to the top-left edge
-            // of the view representing its parent menu.
-            parentView.getLocationInWindow(tempLocation);
-            final int parentOffsetLeft = parentInfo.window.getHorizontalOffset() + tempLocation[0];
-            final int parentOffsetTop = parentInfo.window.getVerticalOffset() + tempLocation[1];
+            final int[] parentViewScreenLocation = new int[2];
+            parentView.getLocationOnScreen(parentViewScreenLocation);
 
+            // Translate the parent view location into the offset coordinate space.
+            // If used as horizontal/vertical offsets, these values would position the submenu
+            // at the exact same position as the parent item.
+            final int parentOffsetLeft = parentViewScreenLocation[0] - offsetOrigin[0];
+            final int parentOffsetTop = parentViewScreenLocation[1] - offsetOrigin[1];
+
+            // Adjust the horizontal offset to display the submenu to the right or to the left
+            // of the parent item.
             // By now, mDropDownGravity is the resolved absolute gravity, so
             // this should work in both LTR and RTL.
             final int x;
@@ -412,11 +420,10 @@
                     x = parentOffsetLeft - menuWidth;
                 }
             }
-
             popupWindow.setHorizontalOffset(x);
 
-            final int y = parentOffsetTop;
-            popupWindow.setVerticalOffset(y);
+            // Use the same vertical offset as the parent item.
+            popupWindow.setVerticalOffset(parentOffsetTop);
         } else {
             if (mHasXOffset) {
                 popupWindow.setHorizontalOffset(mXOffset);
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 3ca455d..a196540 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -232,6 +232,73 @@
     return localBitmap->bitmap();
 }
 
+void imageInfo(JNIEnv* env, jobject bitmap, AndroidBitmapInfo* info) {
+    SkASSERT(info);
+    SkASSERT(env);
+    SkASSERT(bitmap);
+    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
+    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
+    LocalScopedBitmap localBitmap(bitmapHandle);
+
+    const SkImageInfo& imageInfo = localBitmap->info();
+    info->width = imageInfo.width();
+    info->height = imageInfo.height();
+    info->stride = localBitmap->rowBytes();
+    info->flags = 0;
+    switch (imageInfo.colorType()) {
+        case kN32_SkColorType:
+            info->format = ANDROID_BITMAP_FORMAT_RGBA_8888;
+            break;
+        case kRGB_565_SkColorType:
+            info->format = ANDROID_BITMAP_FORMAT_RGB_565;
+            break;
+        case kARGB_4444_SkColorType:
+            info->format = ANDROID_BITMAP_FORMAT_RGBA_4444;
+            break;
+        case kAlpha_8_SkColorType:
+            info->format = ANDROID_BITMAP_FORMAT_A_8;
+            break;
+        default:
+            info->format = ANDROID_BITMAP_FORMAT_NONE;
+            break;
+    }
+}
+
+void* lockPixels(JNIEnv* env, jobject bitmap) {
+    SkASSERT(env);
+    SkASSERT(bitmap);
+    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
+    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
+
+    LocalScopedBitmap localBitmap(bitmapHandle);
+    if (!localBitmap->valid()) return nullptr;
+
+    SkPixelRef& pixelRef = localBitmap->bitmap();
+    pixelRef.lockPixels();
+    if (!pixelRef.pixels()) {
+        pixelRef.unlockPixels();
+        return nullptr;
+    }
+    pixelRef.ref();
+    return pixelRef.pixels();
+}
+
+bool unlockPixels(JNIEnv* env, jobject bitmap) {
+    SkASSERT(env);
+    SkASSERT(bitmap);
+    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
+    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_nativePtr);
+
+    LocalScopedBitmap localBitmap(bitmapHandle);
+    if (!localBitmap->valid()) return false;
+
+    SkPixelRef& pixelRef = localBitmap->bitmap();
+    pixelRef.notifyPixelsChanged();
+    pixelRef.unlockPixels();
+    pixelRef.unref();
+    return true;
+}
+
 } // namespace bitmap
 
 } // namespace android
@@ -643,7 +710,7 @@
         if (!bitmap.get()) {
             return NULL;
         }
-        return createBitmap(env, bitmap.release(), kBitmapCreateFlag_None);
+        return createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(isMutable));
     }
 
     SkColorType dstCT = GraphicsJNI::legacyBitmapConfigToColorType(dstConfigHandle);
@@ -1306,7 +1373,7 @@
         doThrowRE(env, "Could not copy a hardware bitmap.");
         return NULL;
     }
-    return createBitmap(env, allocator.getStorageObjAndReset(), kBitmapCreateFlag_None);
+    return createBitmap(env, allocator.getStorageObjAndReset(), getPremulBitmapCreateFlags(false));
 }
 
 static jobject Bitmap_createHardwareBitmap(JNIEnv* env, jobject, jobject graphicBuffer) {
@@ -1316,7 +1383,7 @@
         ALOGW("failed to create hardware bitmap from graphic buffer");
         return NULL;
     }
-    return bitmap::createBitmap(env, bitmap.release(), android::bitmap::kBitmapCreateFlag_None);
+    return bitmap::createBitmap(env, bitmap.release(), getPremulBitmapCreateFlags(false));
 }
 
 static jobject Bitmap_createGraphicBufferHandle(JNIEnv* env, jobject, jlong bitmapPtr) {
diff --git a/core/jni/android/graphics/Bitmap.h b/core/jni/android/graphics/Bitmap.h
index 387a128..a4bfc94 100644
--- a/core/jni/android/graphics/Bitmap.h
+++ b/core/jni/android/graphics/Bitmap.h
@@ -17,6 +17,7 @@
 #define BITMAP_H_
 
 #include <jni.h>
+#include <android/bitmap.h>
 #include <SkBitmap.h>
 #include <SkColorTable.h>
 #include <SkImageInfo.h>
@@ -44,6 +45,13 @@
 Bitmap& toBitmap(JNIEnv* env, jobject bitmap);
 Bitmap& toBitmap(JNIEnv* env, jlong bitmapHandle);
 
+// NDK access
+void imageInfo(JNIEnv* env, jobject bitmap, AndroidBitmapInfo* info);
+// Returns a pointer to the pixels or nullptr if the bitmap is not valid
+void* lockPixels(JNIEnv* env, jobject bitmap);
+// Returns true if unlocked, false if the bitmap is no longer valid (destroyed)
+bool unlockPixels(JNIEnv* env, jobject bitmap);
+
 /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
     sync with isPremultiplied
 */
diff --git a/core/jni/android_hardware_HardwareBuffer.cpp b/core/jni/android_hardware_HardwareBuffer.cpp
index b26b6e1..b91bd5c 100644
--- a/core/jni/android_hardware_HardwareBuffer.cpp
+++ b/core/jni/android_hardware_HardwareBuffer.cpp
@@ -46,7 +46,7 @@
 // ----------------------------------------------------------------------------
 
 // Debug
-static const bool kDebugGraphicBuffer = false;
+static constexpr bool kDebugGraphicBuffer = false;
 
 // ----------------------------------------------------------------------------
 // Types
@@ -92,8 +92,8 @@
     }
     uint64_t producerUsage = 0;
     uint64_t consumerUsage = 0;
-    android_hardware_HardwareBuffer_convertToGrallocUsageBits(usage, 0, &producerUsage,
-            &consumerUsage);
+    android_hardware_HardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, usage,
+            0);
     status_t error;
     sp<GraphicBuffer> buffer(alloc->createGraphicBuffer(width, height, pixelFormat,
             layers, producerUsage, consumerUsage,
@@ -155,8 +155,11 @@
 static jlong android_hardware_HardwareBuffer_getUsage(JNIEnv* env,
     jobject clazz, jlong nativeObject) {
     GraphicBuffer* buffer = GraphicBufferWrapper_to_GraphicBuffer(nativeObject);
-    return android_hardware_HardwareBuffer_convertFromGrallocUsageBits(
+    uint64_t usage0 = 0;
+    uint64_t usage1 = 0;
+    android_hardware_HardwareBuffer_convertFromGrallocUsageBits(&usage0, &usage1,
             buffer->getUsage(), buffer->getUsage());
+    return usage0;
 }
 
 // ----------------------------------------------------------------------------
@@ -228,15 +231,14 @@
     return AHardwareBuffer_convertToPixelFormat(format);
 }
 
-void android_hardware_HardwareBuffer_convertToGrallocUsageBits(uint64_t usage0,
-        uint64_t /*usage1*/, uint64_t* outProducerUsage,
-        uint64_t* outConsumerUsage) {
-    AHardwareBuffer_convertToGrallocUsageBits(usage0, outProducerUsage, outConsumerUsage);
+void android_hardware_HardwareBuffer_convertToGrallocUsageBits(uint64_t* outProducerUsage,
+        uint64_t* outConsumerUsage, uint64_t usage0, uint64_t usage1) {
+    AHardwareBuffer_convertToGrallocUsageBits(outProducerUsage, outConsumerUsage, usage0, usage1);
 }
 
-uint64_t android_hardware_HardwareBuffer_convertFromGrallocUsageBits(
-        uint64_t producerUsage, uint64_t consumerUsage) {
-    return AHardwareBuffer_convertFromGrallocUsageBits(producerUsage, consumerUsage);
+void android_hardware_HardwareBuffer_convertFromGrallocUsageBits(uint64_t* outUsage0,
+        uint64_t* outUsage1, uint64_t producerUsage, uint64_t consumerUsage) {
+    AHardwareBuffer_convertFromGrallocUsageBits(outUsage0, outUsage1, producerUsage, consumerUsage);
 }
 
 }  // namespace android
diff --git a/core/jni/android_os_HwBinder.cpp b/core/jni/android_os_HwBinder.cpp
index 989a557..2439b82 100644
--- a/core/jni/android_os_HwBinder.cpp
+++ b/core/jni/android_os_HwBinder.cpp
@@ -346,7 +346,7 @@
               << serviceName;
 
     ::android::vintf::Transport transport =
-            ::android::hardware::getTransport(ifaceName);
+            ::android::hardware::getTransport(ifaceName, serviceName);
     if (   transport != ::android::vintf::Transport::EMPTY
         && transport != ::android::vintf::Transport::HWBINDER) {
         LOG(ERROR) << "service " << ifaceName << " declares transport method "
diff --git a/core/jni/android_os_seccomp.cpp b/core/jni/android_os_seccomp.cpp
index f1bc76e..dd5622d 100644
--- a/core/jni/android_os_seccomp.cpp
+++ b/core/jni/android_os_seccomp.cpp
@@ -14,128 +14,11 @@
  * limitations under the License.
  */
 
-#include "JNIHelp.h"
 #include "core_jni_helpers.h"
 #include "JniConstants.h"
 #include "utils/Log.h"
-#include "utils/misc.h"
-
-#if defined __arm__ || defined __aarch64__
-
-#include <vector>
-
-#include <sys/prctl.h>
-
-#include <linux/unistd.h>
-#include <linux/audit.h>
-#include <linux/filter.h>
-#include <linux/seccomp.h>
-
 #include "seccomp_policy.h"
 
-#define syscall_nr (offsetof(struct seccomp_data, nr))
-#define arch_nr (offsetof(struct seccomp_data, arch))
-
-typedef std::vector<sock_filter> filter;
-
-// We want to keep the below inline functions for debugging and future
-// development even though they are not all sed currently.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wunused-function"
-
-static inline void Kill(filter& f) {
-    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL));
-}
-
-static inline void Trap(filter& f) {
-    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP));
-}
-
-static inline void Error(filter& f, __u16 retcode) {
-    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO + retcode));
-}
-
-inline static void Trace(filter& f) {
-    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE));
-}
-
-inline static void Allow(filter& f) {
-    f.push_back(BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW));
-}
-
-#pragma clang diagnostic pop
-
-inline static void ExamineSyscall(filter& f) {
-    f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
-}
-
-inline static int SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
-    size_t jump_length = f.size() - offset - 1;
-    auto u8_jump_length = (__u8) jump_length;
-    if (u8_jump_length != jump_length) {
-        ALOGE("Can't set jump greater than 255 - actual jump is %zu",
-              jump_length);
-        return -1;
-    }
-    f[offset] = BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, u8_jump_length, 0);
-    return 0;
-}
-
-inline static size_t ValidateArchitectureAndJumpIfNeeded(filter& f) {
-    f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, arch_nr));
-
-    f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_AARCH64, 2, 0));
-    f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, AUDIT_ARCH_ARM, 1, 0));
-    Trap(f);
-    return f.size() - 2;
-}
-
-static bool install_filter(filter const& f) {
-    struct sock_fprog prog = {
-        (unsigned short) f.size(),
-        (struct sock_filter*) &f[0],
-    };
-
-    if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0) {
-        ALOGE("SECCOMP: Could not set seccomp filter of size %zu: %s", f.size(), strerror(errno));
-        return false;
-    }
-
-    ALOGI("SECCOMP: Global filter of size %zu installed", f.size());
-    return true;
-}
-
-bool set_seccomp_filter() {
-    filter f;
-
-    // Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
-    // jump that must be changed to point to the start of the 32-bit policy
-    // 32 bit syscalls will not hit the policy between here and the call to SetJump
-    auto offset_to_32bit_filter =
-        ValidateArchitectureAndJumpIfNeeded(f);
-
-    // 64-bit filter
-    ExamineSyscall(f);
-
-    // arm64-only filter - autogenerated from bionic syscall usage
-    for (size_t i = 0; i < arm64_filter_size; ++i)
-        f.push_back(arm64_filter[i]);
-    Trap(f);
-
-    if (SetValidateArchitectureJumpTarget(offset_to_32bit_filter, f) != 0)
-        return -1;
-
-    // 32-bit filter
-    ExamineSyscall(f);
-
-    // arm32 filter - autogenerated from bionic syscall usage
-    for (size_t i = 0; i < arm_filter_size; ++i)
-        f.push_back(arm_filter[i]);
-    Trap(f);
-
-    return install_filter(f);
-}
-
 static void Seccomp_setPolicy(JNIEnv* /*env*/) {
     if (!set_seccomp_filter()) {
         ALOGE("Failed to set seccomp policy - killing");
@@ -143,13 +26,6 @@
     }
 }
 
-#else // #if defined __arm__ || defined __aarch64__
-
-static void Seccomp_setPolicy(JNIEnv* /*env*/) {
-}
-
-#endif
-
 static const JNINativeMethod method_table[] = {
     NATIVE_METHOD(Seccomp, setPolicy, "()V"),
 };
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 314595f..c2800e7 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1578,10 +1578,8 @@
         (void*) android_content_AssetManager_readAsset },
     { "seekAsset",      "(JJI)J",
         (void*) android_content_AssetManager_seekAsset },
-    // @FastNative
     { "getAssetLength", "(J)J",
         (void*) android_content_AssetManager_getAssetLength },
-    // @FastNative
     { "getAssetRemainingLength", "(J)J",
         (void*) android_content_AssetManager_getAssetRemainingLength },
     { "addAssetPathNative", "(Ljava/lang/String;Z)I",
@@ -1598,34 +1596,24 @@
         (void*) android_content_AssetManager_getNonSystemLocales },
     { "getSizeConfigurations", "()[Landroid/content/res/Configuration;",
         (void*) android_content_AssetManager_getSizeConfigurations },
-    // @FastNative
     { "setConfiguration", "(IILjava/lang/String;IIIIIIIIIIIIIII)V",
         (void*) android_content_AssetManager_setConfiguration },
-    // @FastNative
     { "getResourceIdentifier","(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
         (void*) android_content_AssetManager_getResourceIdentifier },
-    // @FastNative
     { "getResourceName","(I)Ljava/lang/String;",
         (void*) android_content_AssetManager_getResourceName },
-    // @FastNative
     { "getResourcePackageName","(I)Ljava/lang/String;",
         (void*) android_content_AssetManager_getResourcePackageName },
-    // @FastNative
     { "getResourceTypeName","(I)Ljava/lang/String;",
         (void*) android_content_AssetManager_getResourceTypeName },
-    // @FastNative
     { "getResourceEntryName","(I)Ljava/lang/String;",
         (void*) android_content_AssetManager_getResourceEntryName },
-    // @FastNative
     { "loadResourceValue","(ISLandroid/util/TypedValue;Z)I",
         (void*) android_content_AssetManager_loadResourceValue },
-    // @FastNative
     { "loadResourceBagValue","(IILandroid/util/TypedValue;Z)I",
         (void*) android_content_AssetManager_loadResourceBagValue },
-    // @FastNative
     { "getStringBlockCount","()I",
         (void*) android_content_AssetManager_getStringBlockCount },
-    // @FastNative
     { "getNativeStringBlock","(I)J",
         (void*) android_content_AssetManager_getNativeStringBlock },
     { "getCookieName","(I)Ljava/lang/String;",
@@ -1644,27 +1632,20 @@
         (void*) android_content_AssetManager_copyTheme },
     { "clearTheme", "(J)V",
         (void*) android_content_AssetManager_clearTheme },
-    // @FastNative
     { "loadThemeAttributeValue", "(JILandroid/util/TypedValue;Z)I",
         (void*) android_content_AssetManager_loadThemeAttributeValue },
-    // @FastNative
     { "getThemeChangingConfigurations", "(J)I",
         (void*) android_content_AssetManager_getThemeChangingConfigurations },
     { "dumpTheme", "(JILjava/lang/String;Ljava/lang/String;)V",
         (void*) android_content_AssetManager_dumpTheme },
-    // @FastNative
     { "applyStyle","(JIIJ[IIJJ)V",
         (void*) android_content_AssetManager_applyStyle },
-    // @FastNative
     { "resolveAttrs","(JII[I[I[I[I)Z",
         (void*) android_content_AssetManager_resolveAttrs },
-    // @FastNative
     { "retrieveAttributes","(J[I[I[I)Z",
         (void*) android_content_AssetManager_retrieveAttributes },
-    // @FastNative
     { "getArraySize","(I)I",
         (void*) android_content_AssetManager_getArraySize },
-    // @FastNative
     { "retrieveArray","(I[I)I",
         (void*) android_content_AssetManager_retrieveArray },
 
@@ -1675,13 +1656,10 @@
     // Arrays.
     { "getArrayStringResource","(I)[Ljava/lang/String;",
         (void*) android_content_AssetManager_getArrayStringResource },
-    // @FastNative
     { "getArrayStringInfo","(I)[I",
         (void*) android_content_AssetManager_getArrayStringInfo },
-    // @FastNative
     { "getArrayIntResource","(I)[I",
         (void*) android_content_AssetManager_getArrayIntResource },
-    // @FastNative
     { "getStyleAttributes","(I)[I",
         (void*) android_content_AssetManager_getStyleAttributes },
 
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index c7998a1..1c6ead0 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -111,11 +111,12 @@
 }
 
 static jobject android_view_InputChannel_createInputChannel(JNIEnv* env,
-        NativeInputChannel* nativeInputChannel) {
+        std::unique_ptr<NativeInputChannel> nativeInputChannel) {
     jobject inputChannelObj = env->NewObject(gInputChannelClassInfo.clazz,
             gInputChannelClassInfo.ctor);
     if (inputChannelObj) {
-        android_view_InputChannel_setNativeInputChannel(env, inputChannelObj, nativeInputChannel);
+        android_view_InputChannel_setNativeInputChannel(env, inputChannelObj,
+                 nativeInputChannel.release());
     }
     return inputChannelObj;
 }
@@ -143,13 +144,13 @@
     }
 
     jobject serverChannelObj = android_view_InputChannel_createInputChannel(env,
-            new NativeInputChannel(serverChannel));
+            std::make_unique<NativeInputChannel>(serverChannel));
     if (env->ExceptionCheck()) {
         return NULL;
     }
 
     jobject clientChannelObj = android_view_InputChannel_createInputChannel(env,
-            new NativeInputChannel(clientChannel));
+            std::make_unique<NativeInputChannel>(clientChannel));
     if (env->ExceptionCheck()) {
         return NULL;
     }
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index f221392..6e8c931 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -452,10 +452,6 @@
             const RenderProperties& props = node.properties();
             uirenderer::Rect bounds(props.getWidth(), props.getHeight());
             transform.mapRect(bounds);
-            bounds.left -= info.windowInsetLeft;
-            bounds.right -= info.windowInsetLeft;
-            bounds.top -= info.windowInsetTop;
-            bounds.bottom -= info.windowInsetTop;
 
             if (CC_LIKELY(transform.isPureTranslate())) {
                 // snap/round the computed bounds, so they match the rounding behavior
@@ -627,9 +623,9 @@
 int register_android_view_RenderNode(JNIEnv* env) {
     jclass clazz = FindClassOrDie(env, "android/view/SurfaceView");
     gSurfaceViewPositionUpdateMethod = GetMethodIDOrDie(env, clazz,
-            "updateWindowPosition_renderWorker", "(JIIII)V");
+            "updateSurfacePosition_renderWorker", "(JIIII)V");
     gSurfaceViewPositionLostMethod = GetMethodIDOrDie(env, clazz,
-            "windowPositionLost_uiRtSync", "(J)V");
+            "surfacePositionLost_uiRtSync", "(J)V");
     return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
 }
 
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a81901d..be86f5c 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -693,7 +693,6 @@
     return JNI_TRUE;
 }
 
-
 static void nativeDeferTransactionUntil(JNIEnv* env, jclass clazz, jlong nativeObject,
         jobject handleObject, jlong frameNumber) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
@@ -702,6 +701,27 @@
     ctrl->deferTransactionUntil(handle, frameNumber);
 }
 
+static void nativeDeferTransactionUntilSurface(JNIEnv* env, jclass clazz, jlong nativeObject,
+        jobject surfaceObject, jlong frameNumber) {
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    sp<Surface> barrier = reinterpret_cast<Surface *>(surfaceObject);
+
+    ctrl->deferTransactionUntil(barrier, frameNumber);
+}
+
+static void nativeReparentChildren(JNIEnv* env, jclass clazz, jlong nativeObject,
+        jobject newParentObject) {
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    sp<IBinder> handle = ibinderForJavaObject(env, newParentObject);
+
+    ctrl->reparentChildren(handle);
+}
+
+static void nativeSeverChildren(JNIEnv* env, jclass clazz, jlong nativeObject) {
+    auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+    ctrl->detachChildren();
+}
+
 static void nativeSetOverrideScalingMode(JNIEnv* env, jclass clazz, jlong nativeObject,
         jint scalingMode) {
     auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
@@ -824,6 +844,12 @@
             (void*)nativeSetDisplayPowerMode },
     {"nativeDeferTransactionUntil", "(JLandroid/os/IBinder;J)V",
             (void*)nativeDeferTransactionUntil },
+    {"nativeDeferTransactionUntilSurface", "(JJJ)V",
+            (void*)nativeDeferTransactionUntilSurface },
+    {"nativeReparentChildren", "(JLandroid/os/IBinder;)V",
+            (void*)nativeReparentChildren } ,
+    {"nativeSeverChildren", "(J)V",
+            (void*)nativeSeverChildren } ,
     {"nativeSetOverrideScalingMode", "(JI)V",
             (void*)nativeSetOverrideScalingMode },
     {"nativeGetHandle", "(J)Landroid/os/IBinder;",
diff --git a/core/jni/android_view_SurfaceSession.cpp b/core/jni/android_view_SurfaceSession.cpp
index dad6958..508d897 100644
--- a/core/jni/android_view_SurfaceSession.cpp
+++ b/core/jni/android_view_SurfaceSession.cpp
@@ -24,6 +24,7 @@
 #include <utils/RefBase.h>
 
 #include <gui/SurfaceComposerClient.h>
+#include <gui/Surface.h>
 
 namespace android {
 
@@ -45,6 +46,13 @@
     return reinterpret_cast<jlong>(client);
 }
 
+static jlong nativeCreateScoped(JNIEnv* env, jclass clazz, jlong surfaceObject) {
+    Surface *parent = reinterpret_cast<Surface*>(surfaceObject);
+    SurfaceComposerClient* client = new SurfaceComposerClient(parent->getIGraphicBufferProducer());
+    client->incStrong((void*)nativeCreate);
+    return reinterpret_cast<jlong>(client);
+}
+
 static void nativeDestroy(JNIEnv* env, jclass clazz, jlong ptr) {
     SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr);
     client->decStrong((void*)nativeCreate);
@@ -55,11 +63,12 @@
     client->dispose();
 }
 
-
 static const JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
     { "nativeCreate", "()J",
             (void*)nativeCreate },
+    { "nativeCreateScoped", "(J)J",
+            (void*)nativeCreateScoped },
     { "nativeDestroy", "(J)V",
             (void*)nativeDestroy },
     { "nativeKill", "(J)V",
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 37eae48a..99edf6e 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -178,13 +178,9 @@
             }
         }
         // TODO: This is hacky
-        info.windowInsetLeft = -stagingProperties().getLeft();
-        info.windowInsetTop = -stagingProperties().getTop();
         info.updateWindowPositions = true;
         RenderNode::prepareTree(info);
         info.updateWindowPositions = false;
-        info.windowInsetLeft = 0;
-        info.windowInsetTop = 0;
         info.errorHandler = nullptr;
     }
 
diff --git a/core/jni/include/android_runtime/android_hardware_HardwareBuffer.h b/core/jni/include/android_runtime/android_hardware_HardwareBuffer.h
index a5d0596..3545c56 100644
--- a/core/jni/include/android_runtime/android_hardware_HardwareBuffer.h
+++ b/core/jni/include/android_runtime/android_hardware_HardwareBuffer.h
@@ -41,12 +41,13 @@
 
 /* Convert from AHARDWAREBUFFER_USAGE* flags to to gralloc usage flags. */
 extern void android_hardware_HardwareBuffer_convertToGrallocUsageBits(
-      uint64_t usage0, uint64_t usage1, uint64_t* outProducerUsage,
-      uint64_t* outConsumerUsage);
+      uint64_t* outProducerUsage, uint64_t* outConsumerUsage, uint64_t usage0,
+      uint64_t usage1);
 
 /* Convert from gralloc usage flags to to AHARDWAREBUFFER_USAGE0* flags. */
-extern uint64_t android_hardware_HardwareBuffer_convertFromGrallocUsageBits(
-      uint64_t producerUsage, uint64_t consumerUsage);
+extern void android_hardware_HardwareBuffer_convertFromGrallocUsageBits(
+      uint64_t* outUsage0, uint64_t* outUsage1, uint64_t producerUsage,
+      uint64_t consumerUsage);
 
 } // namespace android
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 054fad2..5bfcda3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -522,6 +522,8 @@
     <protected-broadcast android:name="android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED" />
     <protected-broadcast android:name="com.android.server.wm.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION" />
 
+    <protected-broadcast android:name="android.content.pm.action.SESSION_COMMITTED" />
+
     <!-- ====================================================================== -->
     <!--                          RUNTIME PERMISSIONS                           -->
     <!-- ====================================================================== -->
@@ -895,6 +897,17 @@
         android:description="@string/permdesc_processOutgoingCalls"
         android:protectionLevel="dangerous" />
 
+
+    <!-- Allows the app to answer an incoming phone call.
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.ANSWER_PHONE_CALLS"
+        android:permissionGroup="android.permission-group.PHONE"
+        android:label="@string/permlab_answerPhoneCalls"
+        android:description="@string/permdesc_answerPhoneCalls"
+        android:protectionLevel="dangerous" />
+
+
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device microphone                        -->
     <!-- ====================================================================== -->
@@ -1272,7 +1285,7 @@
     <permission android:name="android.permission.SCORE_NETWORKS"
         android:protectionLevel="signature|privileged" />
 
-    <!-- @SystemApi Allows applications to request network
+    <!-- Allows applications to request network
          recommendations and scores from the NetworkScoreService.
          <p>Not for use by third-party applications. @hide -->
     <permission android:name="android.permission.REQUEST_NETWORK_SCORES"
diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml
index b910211..fd5154a 100644
--- a/core/res/res/layout/notification_template_material_messaging.xml
+++ b/core/res/res/layout/notification_template_material_messaging.xml
@@ -24,7 +24,7 @@
     <LinearLayout
             android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
-            android:layout_height="match_parent"
+            android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:layout_marginTop="@dimen/notification_content_margin_top"
             android:clipToPadding="false"
@@ -38,6 +38,7 @@
             android:paddingStart="@dimen/notification_content_margin_start"
             android:paddingEnd="@dimen/notification_content_margin_end"
             android:minHeight="@dimen/notification_min_content_height"
+            android:layout_marginBottom="@dimen/notification_content_margin_bottom"
             android:clipToPadding="false"
             android:orientation="vertical"
             >
@@ -49,7 +50,6 @@
                 android:id="@+id/notification_messaging"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:paddingBottom="@dimen/notification_content_margin_bottom"
                 android:spacing="@dimen/notification_messaging_spacing" >
                 <com.android.internal.widget.ImageFloatingTextView android:id="@+id/inbox_text0"
                     style="@style/Widget.Material.Notification.MessagingText"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 6f50d5a..c7696b0 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tik om taal en uitleg te kies"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> teken oor ander programme"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g>-program verskyn bo-op."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Dele van hierdie program sal dalk altyd sigbaar wees. Skakel hierdie kenmerk af as dit nie reg werk nie."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"SKAKEL AF"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Berei tans <xliff:g id="NAME">%s</xliff:g> voor"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Kyk tans vir foute"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Nuwe <xliff:g id="NAME">%s</xliff:g> bespeur"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Tik tyd in"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Skakel oor na teksmodus vir die tydinvoer."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Skakel oor na horlosiemodus vir die tydinvoer."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 5d68f37..a031ff8 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ቋንቋ እና አቀማመጥን ለመምረጥ መታ ያድርጉ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> በሌሎች መተግበሪያዎች ላይ ሣል"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> መተግበሪያ ከላይ እየታየ ያለ።"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"የዚህ መተግበሪያ ክፍሎች በሁሉም ጊዜያት የሚታዩ እንደሆኑ ሊቆዩ ይችላሉ። ይህ ባህሪ በትክክል የማይሠራ ከሆነ ያጥፉት።"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"አጥፋ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>ን በማዘጋጀት ላይ"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ስህተቶች ካሉ በመፈተሽ ላይ"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"አዲስ <xliff:g id="NAME">%s</xliff:g> ተገኝቷል"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"ሰዓት ይተይቡ"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ለጊዜ ግቤቱ ወደ የጽሑፍ ግቤት ሁነታ ቀይር።"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ለጊዜ ግቤቱ ወደ የሰዓት ሁነታ ቀይር።"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 92aa4fc..6d55ada 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1247,14 +1247,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"انقر لاختيار لغة وتنسيق"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"يتم عرض <xliff:g id="NAME">%s</xliff:g> فوق التطبيقات الأخرى"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"يتم عرض تطبيق <xliff:g id="NAME">%s</xliff:g> فوق التطبيقات."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"قد تظل أجزاء من هذا التطبيق مرئية في جميع الأوقات. فإذا كانت هذه الميزة لا تعمل بشكل صحيح، يمكنك إيقافها."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"إيقاف"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"جارٍ تحضير <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"جارٍ التحقق من الأخطاء"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"تم اكتشاف <xliff:g id="NAME">%s</xliff:g> جديدة"</string>
@@ -1836,4 +1832,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"يُرجى تحديد الوقت"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"يُرجى التبديل إلى وضع إدخال النص لإدخال الوقت."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"يُرجى التبديل إلى وضع الساعة لإدخال الوقت."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 43f0133..07ea197 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dil və tərtibatı seçmək üçün tıklayın"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCÇDEƏFGĞHİIJKLMNOÖPQRSŞTUÜVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> digər tətbiqlərin üzərinə çəkilir"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> tətbiqi üstdə göstərilir."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Bu tətbiqin hissələri həmişə görünən qala bilər. Bu funksiya düzgün işləmirsə, onu deaktiv edin."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DEAKTİV EDİN"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> hazırlanır"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Səhvlər yoxlanılır"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Yeni <xliff:g id="NAME">%s</xliff:g> aşkarlandı"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Zamanı daxil edin"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Zamanı daxil etmək üçün mətnlə daxiletmə rejiminə keçin"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Zamanı daxil etmək üçün saat rejiminə keçin"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index 9a02a43..894bd28 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1187,14 +1187,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite da biste izabrali jezik i raspored"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Aplikacija <xliff:g id="NAME">%s</xliff:g> se prikazuje preko drugih aplikacija"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Aplikacija <xliff:g id="NAME">%s</xliff:g> se prikazuje preko."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Delovi ove aplikacije mogu da ostanu vidljivi u svakom trenutku. Ako ova funkcija ne radi ispravno, isključite je."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> se priprema"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Proverava se da li postoje greške"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Novi uređaj <xliff:g id="NAME">%s</xliff:g> je otkriven"</string>
@@ -1743,4 +1739,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Unesite vreme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Pređite u režim unosa teksta radi unosa vremena."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Pređite u režim sata radi unosa vremena."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 070dda7..d567c93 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Дакраніцеся, каб выбраць мову і раскладку"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> паверх іншых праграм"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Праграма <xliff:g id="NAME">%s</xliff:g> паказваецца зверху."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Часткі гэтай праграмы могуць заставацца бачнымі ў любы час. Калі гэта функцыя не працуе належным чынам, адключыце яе."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"АДКЛЮЧЫЦЬ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Падрыхтоўка <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Праверка на наяўнасць памылак"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Выяўлены новы носьбіт <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Увядзіце час"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Пераключыцца на рэжым тэксту пры ўводзе часу."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Пераключыцца на рэжым гадзінніка пры ўводзе часу."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 10887a0..90d3bff 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Докоснете, за да изберете език и подредба"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> се изобразява върху други приложения"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> се показва в/у други прилож."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Части от това приложение може да останат видими за постоянно. Ако функцията не работи правилно, изключете я."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ИЗКЛЮЧВАНЕ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>: Подготвя се"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Проверява се за грешки"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Открито е ново хранилище (<xliff:g id="NAME">%s</xliff:g>)"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Въведете часа"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Превключете към режима за въвеждане на текст, за да въведете часа."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Превключете към режима за часовник, за да въведете часа."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index b6ebd71..1f5b0a1 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ভাষা এবং লেআউট নির্বাচন করুন আলতো চাপ দিন"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> অন্যান্য অ্যাপের উপরেও দেখা যায়"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> অ্যাপ সবার উপরে দেখা যাচ্ছে।"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"এই অ্যাপের কিছু কিছু অংশ সব সময় স্ক্রিনে দেখা যেতে পারে। যদি এই বৈশিষ্ট্যটি ঠিক ভাবে কাজ না করে, তাহলে অ্যাপটি বন্ধ করে দিন।"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"বন্ধ করুন"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> প্রস্তুত করা হচ্ছে"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ত্রুটি রয়েছে কিনা পরীক্ষা করা হচ্ছে"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"নতুন <xliff:g id="NAME">%s</xliff:g> সনাক্ত করা হয়েছে"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"সময় টাইপ করুন"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"সময় ইনপুট দেওয়ার জন্য পাঠ্য ইনপুট মোডে যান।"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"সময় ইনপুট দেওয়ার জন্য ঘড়ি মোডে যান।"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index c63f92c..d0017ad 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1190,14 +1190,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite za odabir jezika i rasporeda"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prekriva ostale aplikacije"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Apl. <xliff:g id="NAME">%s</xliff:g> prikazana je na vrhu."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Dijelovi aplikacije mogu ostati vidljivi sve vrijeme. Ako ta funkcija ne radi ispravno, isključite je."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Priprema se <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Provjera grešaka"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Novi uređaj <xliff:g id="NAME">%s</xliff:g> je otkriven"</string>
@@ -1746,4 +1742,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Upišite vrijeme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Prebacite u način unosa teksta za unos vremena."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Prebacite u način rada kao sat za unos vremena."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 507bc59..2402232 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca per seleccionar l\'idioma i el disseny"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> se superposa a altres aplicacions"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"L\'aplicació <xliff:g id="NAME">%s</xliff:g> s\'està superposant."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Algunes parts d\'aquesta aplicació seran visibles en tot moment. Si aquesta funció presenta problemes, desactiva-la."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESACTIVA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"S\'està preparant <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"S\'està comprovant si hi ha errors"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"S\'ha detectat <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Escriu l\'hora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Canvia al mode d\'introducció de text per introduir l\'hora."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Canvia al mode de rellotge per introduir l\'hora."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 41dc69b..7d59c43 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Klepnutím vyberte jazyk a rozvržení"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Aplikace <xliff:g id="NAME">%s</xliff:g> se může vykreslovat přes ostatní aplikace"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Aplikace <xliff:g id="NAME">%s</xliff:g> se zobrazuje nahoře."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Části této aplikace mohou zůstat vždy viditelné. Pokud tato funkce nepracuje správně, vypněte ji."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"VYPNOUT"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Probíhá příprava úložiště <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Kontrola chyb"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Zjištěno nové úložiště <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Zadejte čas"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Chcete-li zadat čas, přepněte na režim textu."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Chcete-li zadat čas, přepněte na režim hodin."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 2d19eb6..c62cece 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tryk for at vælge sprog og layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> vises over andre apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Appen <xliff:g id="NAME">%s</xliff:g> vises øverst."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Dele af denne app kan være synlig hele tiden. Deaktiver denne funktion, hvis den ikke fungerer korrekt."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"SLÅ FRA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Forbereder <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Kontrollerer for fejl"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Der blev registreret et nyt <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Angiv klokkeslæt"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Skift til teksttilstand for at angive klokkeslæt."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Skift til urtilstand for at angive klokkeslæt."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 054af7c..4564231 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Zum Auswählen von Sprache und Layout tippen"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> wird über anderen Apps eingeblendet"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Die App \"<xliff:g id="NAME">%s</xliff:g>\" wird über anderen Apps angezeigt."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Teile dieser App werden die ganze Zeit eingeblendet. Wenn diese Funktion nicht richtig funktioniert, deaktiviere sie."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DEAKTIVIEREN"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> wird vorbereitet"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Nach Fehlern wird gesucht"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Neue <xliff:g id="NAME">%s</xliff:g> entdeckt"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Uhrzeit eingeben"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"In den Texteingabemodus wechseln, um die Uhrzeit einzugeben."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"In den Uhrzeitmodus wechseln, um die Uhrzeit einzugeben."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 48bd718..cd6c67b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Πατήστε για να επιλέξετε γλώσσα και διάταξη"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> επικάλυψε άλλες εφαρμογές"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Η εφαρμογή <xliff:g id="NAME">%s</xliff:g> επικαλύπτει άλλες."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Ορισμένα τμήματα αυτής της εφαρμογής μπορεί να παραμένουν συνεχώς ορατά. Εάν αυτή η λειτουργία δεν εκτελείται σωστά, απενεργοποιήστε την."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ΑΠΕΝΕΡΓΟΠΟΙΗΣΗ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Προετοιμασία <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Έλεγχος για σφάλματα"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Εντοπίστηκε νέο μέσο αποθήκευσης <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Πληκτρολογήστε την ώρα"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Κάντε εναλλαγή στη λειτουργία εισαγωγής κειμένου, για την εισαγωγή της ώρας."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Κάντε εναλλαγή στη λειτουργία ρολογιού, για την εισαγωγή της ώρας."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 08fc5ba..04f9537 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> draw over other apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> app displaying on top."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Parts of this app may remain visible at all times. If this feature isn\'t working correctly, turn it off."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"TURN OFF"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparing <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Checking for errors"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"New <xliff:g id="NAME">%s</xliff:g> detected"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Type in time"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Switch to text input mode for the time input."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Switch to clock mode for the time input."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 08fc5ba..04f9537 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> draw over other apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> app displaying on top."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Parts of this app may remain visible at all times. If this feature isn\'t working correctly, turn it off."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"TURN OFF"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparing <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Checking for errors"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"New <xliff:g id="NAME">%s</xliff:g> detected"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Type in time"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Switch to text input mode for the time input."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Switch to clock mode for the time input."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 08fc5ba..04f9537 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> draw over other apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> app displaying on top."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Parts of this app may remain visible at all times. If this feature isn\'t working correctly, turn it off."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"TURN OFF"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparing <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Checking for errors"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"New <xliff:g id="NAME">%s</xliff:g> detected"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Type in time"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Switch to text input mode for the time input."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Switch to clock mode for the time input."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f294d6f..8aaa2ea 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Presiona para seleccionar el idioma y el diseño"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras apps"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Es posible que ciertas partes de esta app permanezcan visibles todo el tiempo. Si esta función tiene problemas, desactívala."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESACTIVAR"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparando el medio <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Verificando errores"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Se detectó un nuevo medio (<xliff:g id="NAME">%s</xliff:g>)."</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Ingresa la hora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia al modo de entrada de texto para ingresar la hora."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Cambia al modo de reloj para ingresar la hora."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 34aee0d..0ce96e7 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar el idioma y el diseño"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> se muestra sobre otras aplicaciones"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> se muestra en primer plano."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Es posible que algunas partes de esta aplicación permanezcan visibles en todo momento. Desactiva esta función si no funciona correctamente."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESACTIVAR"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparando <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Comprobando errores"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Nueva <xliff:g id="NAME">%s</xliff:g> detectada"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Escribe la hora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia al modo de introducción de texto para escribir la hora."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Cambia al modo de reloj para escribir la hora."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 7acb404..27cd957 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Puudutage keele ja paigutuse valimiseks"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Rakendus <xliff:g id="NAME">%s</xliff:g> joonistab teiste rakenduste peale"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Rakend. <xliff:g id="NAME">%s</xliff:g> kuvatakse kõige peal."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Selle rakenduse osad võivad alati nähtaval olla. Kui see funktsioon ei tööta korralikult, lülitage see välja."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"LÜLITA VÄLJA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Üksuse <xliff:g id="NAME">%s</xliff:g> ettevalmistamine"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Vigade kontrollimine"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Tuvastati uus üksus <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Sisestage kellaaeg"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Aktiveerige kellaaja sisestamiseks tekstisisestusrežiim."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Aktiveerige kellaaja sisestamiseks kellarežiim."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index 2fb79ec..5fb9998 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Hizkuntza eta diseinua hautatzeko, sakatu hau"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> zerbitzuak beste aplikazio batzuk gainjarri ditu pantailan"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> gainjarri da pantailan."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Aplikazioaren atal batzuk ikusgai gera litezke uneoro. Eginbideak behar bezala funtzionatzen ez badu, desaktiba ezazu."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESAKTIBATU"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> prestatzen"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Errorerik dagoen egiaztatzen"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"<xliff:g id="NAME">%s</xliff:g> berria hauteman da"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Idatzi ordua"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Aldatu testu modura ordua zehazteko."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Aldatu erloju modura ordua zehazteko."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 81606dd..51eb178 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"برای انتخاب زبان و چیدمان ضربه بزنید"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"نمایش <xliff:g id="NAME">%s</xliff:g> روی برنامه‌های دیگر"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"نمایش برنامه <xliff:g id="NAME">%s</xliff:g> در بالا."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ممکن است قسمت‌هایی از این برنامه همیشه قابل مشاهده بمانند. اگر این قابلیت به‌درستی کار نمی‌کند، آن را خاموش کنید."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"خاموش کردن"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"در حال آماده‌سازی <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"در حال بررسی برای خطاها"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"<xliff:g id="NAME">%s</xliff:g> جدید شناسایی شد"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"زمان را تایپ کنید"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"برای وارد کردن زمان، به حالت وارد کردن نوشتار تغییر وضعیت دهید."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"برای وارد کردن زمان، به حالت ساعت تغییر وضعیت دهید."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 1169f57..87f3214 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Valitse kieli ja asettelu koskettamalla."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> piirtää muiden sovellusten päälle"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Sovellus <xliff:g id="NAME">%s</xliff:g> näkyy päällä"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Osia sovelluksesta voi olla aina näkyvissä. Jos ominaisuus ei toimi oikein, poista se käytöstä."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"POISTA KÄYTÖSTÄ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Valmistellaan kohdetta <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Tarkistetaan virheiden varalta."</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Uusi <xliff:g id="NAME">%s</xliff:g> on havaittu."</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Kirjoita aika"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Vaihda ajan syöttämiseen tekstitilassa."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Vaihda ajan syöttämiseen kellotilassa."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index 43ff0cf..7b05c74 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Touchez pour sélectionner la langue et la configuration du clavier"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> se superpose aux autres applications"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> s\'affiche par-dessus les autres"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Certaines parties de cette application restent visibles en tout temps. Si cette option ne fonctionne pas correctement, désactivez-la."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DÉSACTIVER"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Préparation de « <xliff:g id="NAME">%s</xliff:g> » en cours"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Recherche d\'erreurs en cours..."</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Une nouvelle mémoire « <xliff:g id="NAME">%s</xliff:g> » a été détectée"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Entrez l\'heure"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Passer au mode Entrée de texte pour entrer l\'heure."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Passer au mode Horloge pour entrer l\'heure."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 50ee5be..40172d0 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Appuyer pour sélectionner la langue et la disposition"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> se superpose aux autres applications"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Superposition de l\'application <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Certaines sections de cette application peuvent rester visibles en permanence. Si cette fonctionnalité ne s\'exécute pas correctement, désactivez-la."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DÉSACTIVER"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Préparation mémoire \"<xliff:g id="NAME">%s</xliff:g>\" en cours"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Recherche d\'erreurs"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Une nouvelle mémoire de stockage \"<xliff:g id="NAME">%s</xliff:g>\" a été détectée."</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Indiquez l\'heure"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Passer en mode saisie de texte pour la saisie de l\'heure."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Passer en mode horloge pour la saisie de l\'heure."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 0ee956a..0e024b4 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar o idioma e o deseño"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> superponse a outras aplicacións"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"A aplicación <xliff:g id="NAME">%s</xliff:g> móstrase enriba."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Partes desta aplicación poden permanecer visibles en todo momento. Se esta función non traballa correctamente, desactívaa."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESACTIVAR"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparando a <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Comprobando se hai erros"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Detectouse unha <xliff:g id="NAME">%s</xliff:g> nova"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Escribe a hora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Cambia ao modo de entrada de texto para introducir a hora."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Cambiar ao modo de reloxo para introducir a hora."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 1693c32..511a843 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ભાષા અને લેઆઉટ પસંદ કરવા માટે ટૅપ કરો"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> અન્ય ઍપ્લિકેશનો પર ડ્રો કરે છે"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> ઍપ્લિકેશન સૌથી ઉપર દેખાઈ રહી છે."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"આ ઍપ્લિકેશનના ભાગ હંમેશાં દૃશ્યક્ષમ રહી શકે છે. જો આ સુવિધા યોગ્ય રીતે કાર્ય કરી રહી ન હોય, તો તેને બંધ કરો."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"બંધ કરો"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> ને તૈયાર કરી રહ્યું છે"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ભૂલો માટે તપાસી રહ્યું છે"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"નવું <xliff:g id="NAME">%s</xliff:g> મળ્યું"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"સમય લખો"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"સમય દાખલ કરવા માટે ટેક્સ્ટ ઇનપુટ મોડમાં સ્વિચ કરો."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"સમય દાખલ કરવા માટે ઘડિયાળ મોડમાં સ્વિચ કરો."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index fbf2eaf..0a5d130 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -148,7 +148,7 @@
     <string name="fcComplete" msgid="3118848230966886575">"सुविधा कोड पूर्ण."</string>
     <string name="fcError" msgid="3327560126588500777">"कनेक्‍शन समस्‍या या अमान्‍य सुविधा कोड."</string>
     <string name="httpErrorOk" msgid="1191919378083472204">"ठीक है"</string>
-    <string name="httpError" msgid="7956392511146698522">"कोई नेटवर्क त्रुटि हुई थी."</string>
+    <string name="httpError" msgid="7956392511146698522">"कोई नेटवर्क गड़बड़ी हुई थी."</string>
     <string name="httpErrorLookup" msgid="4711687456111963163">"URL नहीं मिल सका."</string>
     <string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"साइट प्रमाणीकरण योजना समर्थित नहीं है."</string>
     <string name="httpErrorAuth" msgid="1435065629438044534">"प्रमाणीकृत नहीं किया जा सका."</string>
@@ -163,7 +163,7 @@
     <string name="httpErrorFile" msgid="2170788515052558676">"फ़ाइल पर नहीं पहुंचा जा सका."</string>
     <string name="httpErrorFileNotFound" msgid="6203856612042655084">"अनुरोधित फ़ाइल नहीं मिल सकी."</string>
     <string name="httpErrorTooManyRequests" msgid="1235396927087188253">"बहुत सारे अनुरोधों का संसाधन हो रहा है. बाद में पुन: प्रयास करें."</string>
-    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> के लिए प्रवेश त्रुटि"</string>
+    <string name="notification_title" msgid="8967710025036163822">"<xliff:g id="ACCOUNT">%1$s</xliff:g> के लिए प्रवेश गड़बड़ी"</string>
     <string name="contentServiceSync" msgid="8353523060269335667">"समन्वयन"</string>
     <string name="contentServiceSyncNotificationTitle" msgid="397743349191901458">"समन्वयन"</string>
     <string name="contentServiceTooManyDeletesNotificationDesc" msgid="8100981435080696431">"बहुत से <xliff:g id="CONTENT_TYPE">%s</xliff:g> हटाए जाते हैं."</string>
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा और लेआउट चुनने के लिए टैप करें"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> दूसरे ऐप पर आरेखण करते हैं"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> ऐप ऊपर दिखा रहा है."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"हो सकता है कि इस ऐप के कुछ हिस्से हर समय दृश्यमान रहें. अगर यह सुविधा ठीक तरह से काम नहीं कर रही है, तो इसे बंद कर दें."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"बंद करें"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> को तैयार किया जा रहा है"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"त्रुटियों की जांच कर रहा है"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"नए <xliff:g id="NAME">%s</xliff:g> का पता लगा"</string>
@@ -1258,7 +1254,7 @@
     <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"हमेशा-चालू VPN कनेक्ट हो रहा है…"</string>
     <string name="vpn_lockdown_connected" msgid="8202679674819213931">"हमेशा-चालू VPN कनेक्ट है"</string>
     <string name="vpn_lockdown_disconnected" msgid="4532298952570796327">"हमेशा-चालू VPN डिस्‍कनेक्‍ट है"</string>
-    <string name="vpn_lockdown_error" msgid="6009249814034708175">"हमेशा-चालू VPN त्रुटि"</string>
+    <string name="vpn_lockdown_error" msgid="6009249814034708175">"हमेशा-चालू VPN गड़बड़ी"</string>
     <string name="vpn_lockdown_config" msgid="5099330695245008680">"सेट करने के लिए टैप करें"</string>
     <string name="upload_file" msgid="2897957172366730416">"फ़ाइल चुनें"</string>
     <string name="no_file_chosen" msgid="6363648562170759465">"कोई फ़ाइल चुनी नहीं गई"</string>
@@ -1454,7 +1450,7 @@
     <string name="user_switching_message" msgid="2871009331809089783">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
     <string name="user_logging_out_message" msgid="8939524935808875155">"<xliff:g id="NAME">%1$s</xliff:g> द्वारा प्रस्‍थान किया जा रहा है…"</string>
     <string name="owner_name" msgid="2716755460376028154">"स्वामी"</string>
-    <string name="error_message_title" msgid="4510373083082500195">"त्रुटि"</string>
+    <string name="error_message_title" msgid="4510373083082500195">"गड़बड़ी"</string>
     <string name="error_message_change_not_allowed" msgid="1347282344200417578">"यह बदलाव आपके व्यवस्थापक द्वारा अनुमत नहीं है"</string>
     <string name="app_not_found" msgid="3429141853498927379">"इस कार्यवाही को प्रबंधित करने के लिए कोई ऐप्स  नहीं मिला"</string>
     <string name="revoke" msgid="5404479185228271586">"निरस्‍त करें"</string>
@@ -1542,7 +1538,7 @@
     <string name="mediasize_unknown_portrait" msgid="3088043641616409762">"अज्ञात पोर्ट्रेट"</string>
     <string name="mediasize_unknown_landscape" msgid="4876995327029361552">"अज्ञात लैंडस्केप"</string>
     <string name="write_fail_reason_cancelled" msgid="7091258378121627624">"रद्द कर दी गई"</string>
-    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामग्री लिखने में त्रुटि"</string>
+    <string name="write_fail_reason_cannot_write" msgid="8132505417935337724">"सामग्री लिखने में गड़बड़ी"</string>
     <string name="reason_unknown" msgid="6048913880184628119">"अज्ञात"</string>
     <string name="reason_service_unavailable" msgid="7824008732243903268">"प्रिंट सेवा सक्षम नहीं है"</string>
     <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> सेवा इंस्टॉल की गई"</string>
@@ -1633,8 +1629,8 @@
     <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"सप्ताहांत"</string>
     <string name="zen_mode_default_events_name" msgid="8158334939013085363">"इवेंट"</string>
     <string name="muted_by" msgid="6147073845094180001">"<xliff:g id="THIRD_PARTY">%1$s</xliff:g> द्वारा म्यूट किया गया"</string>
-    <string name="system_error_wipe_data" msgid="6608165524785354962">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई और यह तब तक अस्‍थिर रह सकता है, जब तक आप फ़ैक्‍टरी डेटा रीसेट नहीं करते हैं."</string>
-    <string name="system_error_manufacturer" msgid="8086872414744210668">"आपके डिवाइस के साथ कोई आंतरिक त्रुटि हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string>
+    <string name="system_error_wipe_data" msgid="6608165524785354962">"आपके डिवाइस के साथ कोई आंतरिक गड़बड़ी हुई और यह तब तक अस्‍थिर रह सकता है, जब तक आप फ़ैक्‍टरी डेटा रीसेट नहीं करते हैं."</string>
+    <string name="system_error_manufacturer" msgid="8086872414744210668">"आपके डिवाइस के साथ कोई आंतरिक गड़बड़ी हुई. विवरणों के लिए अपने निर्माता से संपर्क करें."</string>
     <string name="stk_cc_ussd_to_dial" msgid="5202342984749947872">"USSD अनुरोध को DIAL अनुरोध में बदल दिया गया है."</string>
     <string name="stk_cc_ussd_to_ss" msgid="2345360594181405482">"USSD अनुरोध को SS अनुरोध में बदल दिया गया है."</string>
     <string name="stk_cc_ussd_to_ussd" msgid="7466087659967191653">"USSD अनुरोध को नए USSD अनुरोध में बदल दिया गया है."</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"समय लिखें"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"समय इनपुट के लिए लेख इनपुट मोड पर जाएं."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"समय इनपुट के लिए घड़ी मोड पर जाएं."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 1b97a4e..89058a5 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1187,14 +1187,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite da biste odabrali jezik i raspored"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prikazuje se preko drugih aplikacija"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Aplikacija <xliff:g id="NAME">%s</xliff:g> prikazuje se gore."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Dijelovi ove aplikacije mogu ostati vidljivi cijelo vrijeme. Ako ta značajka ne funkcionira pravilno, isključite je."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ISKLJUČI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Priprema uređaja <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Traženje pogrešaka"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Otkriven je novi uređaj <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1743,4 +1739,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Unesite vrijeme"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Prijeđite na način unosa teksta da biste unijeli vrijeme."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Prijeđite na način rada sata da biste unijeli vrijeme."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index b67b29f..a4028ee 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Koppintson a nyelv és a billentyűzetkiosztás kiválasztásához"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"A(z) <xliff:g id="NAME">%s</xliff:g> a többi alkalmazás felett jelenik meg"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"A(z) <xliff:g id="NAME">%s</xliff:g> legfelül jelenik meg."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Előfordulhat, hogy ezen alkalmazás egyes részei mindig láthatók maradnak. Ha ez a funkció nem működik megfelelően, kapcsolja ki."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"KIKAPCSOLÁS"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> előkészítése"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Hibák keresése"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Új <xliff:g id="NAME">%s</xliff:g> észlelve"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Adja meg az időt"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Időbevitelhez váltson szövegbeviteli módba."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Időbevitelhez váltson óramódba."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index fa332b0..ad375eb 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Հպեք՝ լեզուն և դասավորությունն ընտրելու համար"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> ցուցադրել այլ հավելվածների վերևում"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> հավելվածը ցուցադրվում է վերևում։"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Այս հավելվածի որոշ հատվածներ կարող են միշտ տեսանելի լինել։ Եթե այս գործառույթն ինչպես հարկն է չի աշխատում, անջատեք այն։"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ԱՆՋԱՏԵԼ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>-ի նախապատրաստում"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Սխալների ստուգում"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Հայտնաբերվել է նոր <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Մուտքագրեք ժամը"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Ժամը մուտքագրելու համար միացրեք տեքստի մուտքագրման ռեժիմը:"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Ժամը մուտքագրելու համար միացրեք ժամացույցի ռեժիմը:"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index ac898e4..ab32838 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ketuk untuk memilih bahasa dan tata letak"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> muncul di atas aplikasi lain"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Aplikasi <xliff:g id="NAME">%s</xliff:g> muncul di atas."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Sebagian aplikasi ini mungkin selalu terlihat. Jika fitur ini tidak berfungsi dengan baik, nonaktifkan."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"NONAKTIFKAN"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Menyiapkan <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Memeriksa kesalahan"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"<xliff:g id="NAME">%s</xliff:g> baru terdeteksi"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Ketik waktu"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Beralih ke mode masukan teks untuk masukan waktu."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Beralih ke mode jam untuk masukan waktu."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index a1b2be8..3cbc17e 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ýttu til að velja tungumál og útlit"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> teiknar yfir önnur forrit"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> forritið birtist efst."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Hluti af þessu forriti gæti verið ávallt sýnilegur. Ef þessi eiginleiki virkar ekki sem skyldi skaltu slökkva á honum."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"SLÖKKVA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Undirbýr <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Leitar að villum"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Nýtt <xliff:g id="NAME">%s</xliff:g> fannst"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Færðu inn tíma"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Skipta yfir í textastillingu til að færa inn tíma."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Skipta yfir í klukkustillingu til að færa inn tíma."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index f5aab8e..89b0113 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tocca per selezionare la lingua e il layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> visualizzata sopra altre app"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"App <xliff:g id="NAME">%s</xliff:g> visualizzata sulle altre."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Alcune parti di questa app possono rimanere sempre visibili. Disattiva la funzione qualora non funzionasse correttamente."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DISATTIVA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparazione della <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Ricerca errori"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Nuova <xliff:g id="NAME">%s</xliff:g> rilevata"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Digita l\'ora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Passa alla modalità di immissione testo per inserire l\'ora."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Passa alla modalità orologio per inserire l\'ora."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 9f90a38..c6e02d28 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"הקש כדי לבחור שפה ופריסה"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> יכולה להופיע מעל אפליקציות אחרות"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> מופיעה מעל אפליקציות אחרות."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"חלקים באפליקציה הזו עשויים להופיע במסך כל הזמן. כבה את התכונה הזו אם היא לא עובדת כראוי."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"כבה"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"הכנת <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"בודק אם יש שגיאות"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"זוהה <xliff:g id="NAME">%s</xliff:g> חדש"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"הקלד את השעה"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"העבר למצב קלט טקסט לצורך הזנת השעה"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"העבר למצב שעון לצורך הזנת השעה"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index b4d2d83..857999f 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -296,8 +296,8 @@
     <string name="permdesc_receiveSms" msgid="6424387754228766939">"SMSメッセージの受信と処理をアプリに許可します。これにより、アプリが端末に届いたメッセージを表示することなく監視または削除できるようになります。"</string>
     <string name="permlab_receiveMms" msgid="1821317344668257098">"テキストメッセージ(MMS)の受信"</string>
     <string name="permdesc_receiveMms" msgid="533019437263212260">"MMSメッセージの受信と処理をアプリに許可します。これにより、アプリが端末に届いたメッセージを表示することなく監視または削除できるようになります。"</string>
-    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"緊急警報SMSの読み取り"</string>
-    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"端末で受信した緊急警報SMSの読み取りをアプリに許可します。緊急警報は、緊急事態を警告する目的で一部の地域に配信されます。緊急警報の受信時に、悪意のあるアプリによって端末の動作や処理が妨害される恐れがあります。"</string>
+    <string name="permlab_readCellBroadcasts" msgid="1598328843619646166">"緊急速報メール SMS の読み取り"</string>
+    <string name="permdesc_readCellBroadcasts" msgid="6361972776080458979">"端末で受信した緊急速報メール SMS の読み取りをアプリに許可します。緊急速報メールは、緊急事態を警告する目的で一部の地域に配信されます。緊急速報メールの受信時に、悪意のあるアプリによって端末の動作や処理が妨害される恐れがあります。"</string>
     <string name="permlab_subscribedFeedsRead" msgid="4756609637053353318">"登録したフィードの読み取り"</string>
     <string name="permdesc_subscribedFeedsRead" msgid="5557058907906144505">"現在同期されているフィードの詳細を取得することをアプリに許可します。"</string>
     <string name="permlab_sendSms" msgid="7544599214260982981">"SMSメッセージの送信と表示"</string>
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"タップして言語とレイアウトを選択してください"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g>を他のアプリの上に重ねて表示"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g>を重ねて表示中"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"このアプリの一部は常に表示され続けます。この機能が正常に動作しない場合は OFF にしてください。"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"OFF にする"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>を準備中"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"エラーを確認中"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"新しい<xliff:g id="NAME">%s</xliff:g>が検出されました"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"時刻を入力"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"時刻をテキストで入力するモードに切り替えます。"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"時刻を時計で入力するモードに切り替えます。"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 80c9dec..5d970b6 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"შეეხეთ ენისა და განლაგების ასარჩევად"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g>-ის სხვა აპების ინტერფეისზე გადაწერა"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> აპის მიერ ზემოდან ჩვენება."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"აპის გარკვეული ნაწილები შესაძლოა ყოველთვის ხილული იყოს. თუ ეს ფუნქცია გამართულად არ მუშაობს, გამორთეთ."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"გამორთვა"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>-ის მომზადება"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"შეცდომების შემოწმება"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"აღმოჩენილია ახალი <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"აკრიფეთ დრო"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"დროის შეყვანისთვის ტექსტის შეყვანის რეჟიმზე გადართვა."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"დროის შეყვანისთვის საათის რეჟიმზე გადართვა."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 6732ca3..3e77e9c 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> басқа қолданбалардың үстінен көрсетіледі"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> қолданбасы жоғарғы жағында көрсетіледі."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Бұл қолданбаның бір бөлігі үнемі көрініп тұруы мүмкін. Егер бұл функция дұрыс жұмыс істемесе, оны өшіріңіз."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ӨШІРУ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> дайындалуда"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Қателер тексерілуде"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Жаңа <xliff:g id="NAME">%s</xliff:g> анықталды"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Уақытты енгізіңіз"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Уақытты енгізу үшін мәтін енгізу режиміне өтіңіз."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Уақытты енгізу үшін сағат режиміне өтіңіз."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index e906c45..e07bc41 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1169,14 +1169,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ប៉ះដើម្បីជ្រើសភាសា និងប្លង់"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> គូរ​ពីលើ​កម្មវិធី​ផ្សេង​ទៀត"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"កម្មវិធី <xliff:g id="NAME">%s</xliff:g> បង្ហាញ​នៅ​លើ​គេ។"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ផ្នែកខ្លះ​នៃ​កម្មវិធី​នេះនឹង​នៅតែ​អាច​មើល​ឃើញ​បានគ្រប់​ពេល។ ប្រសិនបើ​មុខងារនេះ​ដំណើរការ​មិន​ប្រក្រតី​ទេ សូម​បិទ​វា។"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"បិទ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"កំពុងរៀបចំ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"កំពុងពិនិត្យរកកំហុស"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"បានរកឃើញ <xliff:g id="NAME">%s</xliff:g> ថ្មី"</string>
@@ -1714,4 +1710,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"វាយ​បញ្ចូល​ម៉ោង"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ប្តូរ​ទៅ​មុខងារ​បញ្ចូល​អក្សរ​សម្រាប់​ការ​បញ្ចូល​ម៉ោង។"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ប្តូរ​ទៅ​មុខងារ​នាឡិកា​សម្រាប់​ការ​បញ្ចូល​ម៉ោង។"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 6cccbc2..2fedb79 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ಭಾಷೆ ಮತ್ತು ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"ಇತರ ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಮೇಲೆ <xliff:g id="NAME">%s</xliff:g> ಎಳೆಯಿರಿ"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> ಅಪ್ಲಿಕೇಶನ್ ಮೇಲೆ ಕಾಣಿಸುತ್ತಿದೆ."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ಈ ಅಪ್ಲಿಕೇಶನ್‌ನ ಭಾಗಗಳು ಎಲ್ಲ ಸಮಯದಲ್ಲೂ ಕಾಣುತ್ತಿರುತ್ತದೆ. ಈ ವೈಶಿಷ್ಟ್ಯವು ಸರಿಯಾಗಿ ಕೆಲಸ ಮಾಡದಿದ್ದರೆ, ಆಫ್‌ ಮಾಡಿ."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ಆಫ್ ಮಾಡಿ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> ಅನ್ನು ಸಿದ್ಧಪಡಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ದೋಷಗಳನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"ಹೊಸ <xliff:g id="NAME">%s</xliff:g> ಪತ್ತೆಯಾಗಿದೆ"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"ಸಮಯದಲ್ಲಿ ಟೈಪ್ ಮಾಡಿ"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ಸಮಯವನ್ನು ನಮೂದಿಸಲು ಪಠ್ಯದ ನಮೂನೆಗೆ ಬದಲಿಸಿ."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ಸಮಯವನ್ನು ನಮೂದಿಸಲು ಗಡಿಯಾರದ ನಮೂನೆಗೆ ಬದಲಿಸಿ."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index cf1289c..22d6dc6 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"탭하여 언어와 레이아웃을 선택하세요."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g>이(가) 다른 앱 위에 표시됨"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> 앱이 상단에 표시됨"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"이 앱의 일부는 항상 표시될 수도 있습니다. 기능이 제대로 작동되지 않으면 사용 중지하세요."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"사용 중지"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> 준비 중"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"오류 확인 중"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"새로운 <xliff:g id="NAME">%s</xliff:g> 감지됨"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"시간 입력"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"시간 입력을 위해 텍스트 입력 모드로 전환합니다."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"시간 입력을 위해 시계 모드로 전환합니다."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 33f72db..99d0ffd 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Тил жана калып тандоо үчүн таптап коюңуз"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> колдонмосун башка терезелердин үстүнөн көрсөтүү"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> колд-сун эң үстүндө көрсөтүү"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Бул колдонмонун бөлүктөрү дайыма көрүнүп турушу мүмкүн. Эгер бул функция туура иштебесе, аны өчүрүп коюңуз."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ӨЧҮРҮҮ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> даярдалууда"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Каталар текшерилүүдө"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Жаңы <xliff:g id="NAME">%s</xliff:g> аныкталды"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Убакытты жазыңыз"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Убакытты текст киргизүү режиминде киргизиңиз."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Убакытты дубал саатынын режиминде киргизиңиз."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index ba71473..654d8e6 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ແຕະເພື່ອເລືອກພາສາ ແລະ ໂຄງແປ້ນພິມ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> ແຕ້ມທັບແອັບອື່ນ"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"ແອັບ <xliff:g id="NAME">%s</xliff:g> ກຳລັງສະແດງຢູ່ໜ້າສຸດ."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ບາງພາກສ່ວນຂອງແອັບນີ້ຈະປາກົດຢູ່ຕະຫຼອດເວລາ. ຫາກຄຸນສົມບັດນີ້ໃຊ້ໄດ້ບໍ່ດີ, ໃຫ້ປິດມັນໄວ້."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ປິດໄວ້"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"ກຳ​ລັງ​ກຽມ <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ກຳລັງກວດຫາຂໍ້ຜິດພາດ"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"ກວດ​ພົບ <xliff:g id="NAME">%s</xliff:g> ໃໝ່​ແລ້ວ"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"ພິມເວລາໃສ່"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ສະຫຼັບໄປໃຊ້ໂໝດປ້ອນຂໍ້ຄວາມສຳລັບການປ້ອນເວລາ."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ສະຫຼັບໄປໃຊ້ໂໝດໂມງສຳລັບການປ້ອນເວລາ."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 07e730c..f808a99 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Palieskite, kad pasirinktumėte kalbą ir išdėstymą"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> programa rodoma virš kitų programų"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> programa rodoma virš kitų."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Šios programos dalys gali likti matomos visą laiką. Jei ši funkcija tinkamai neveikia, išjunkite ją."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"IŠJUNGTI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Ruošiama <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Tikrinama, ar nėra klaidų"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Aptikta nauja <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Įveskite laiką"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Laiko įvestį pateikti perjungus į teksto įvesties režimą."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Laiko įvestį pateikti perjungus į laikrodžio režimą."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 06bcd6b..e7b4800 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1187,14 +1187,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Pieskarieties, lai atlasītu valodu un izkārtojumu"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Lietotne <xliff:g id="NAME">%s</xliff:g> tiek rādīta pāri citām lietotnēm"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Lietotne <xliff:g id="NAME">%s</xliff:g> ir redzama virspusē."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Šīs lietotnes daļas joprojām var būt redzamas visu laiku. Ja šī funkcija nedarbojas pareizi, izslēdziet to."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"IZSLĒGT"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Notiek <xliff:g id="NAME">%s</xliff:g> sagatavošana"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Tiek meklētas kļūdas"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Tika atrasta jauna <xliff:g id="NAME">%s</xliff:g>."</string>
@@ -1743,4 +1739,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Ierakstiet laiku"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Lai ievadītu laiku, ieslēdziet teksta ievades režīmu."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Lai ievadītu laiku, ieslēdziet pulksteņa režīmu."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index efb339b..8dae798 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -83,10 +83,10 @@
     <string name="RuacMmi" msgid="7827887459138308886">"Одбивање несакани вознемирувачки повици"</string>
     <string name="CndMmi" msgid="3116446237081575808">"Испорака на повикувачки број"</string>
     <string name="DndMmi" msgid="1265478932418334331">"Не вознемирувај"</string>
-    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Стандардно, повикувачот со овој ИД е ограничен. Следен повик: ограничен"</string>
-    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Стандардно, повикувачот со овој ИД е ограничен. Следен повик: не е ограничен"</string>
-    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Стандардно, повикувачот со овој ИД не е ограничен. Следен повик: ограничен"</string>
-    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Стандардно, повикувачот со овој ИД не е ограничен. Следен повик: не е ограничен"</string>
+    <string name="CLIRDefaultOnNextCallOn" msgid="429415409145781923">"Стандардно, повикувачот со овој ID е ограничен. Следен повик: ограничен"</string>
+    <string name="CLIRDefaultOnNextCallOff" msgid="3092918006077864624">"Стандардно, повикувачот со овој ID е ограничен. Следен повик: не е ограничен"</string>
+    <string name="CLIRDefaultOffNextCallOn" msgid="6179425182856418465">"Стандардно, повикувачот со овој ID не е ограничен. Следен повик: ограничен"</string>
+    <string name="CLIRDefaultOffNextCallOff" msgid="2567998633124408552">"Стандардно, повикувачот со овој ID не е ограничен. Следен повик: не е ограничен"</string>
     <string name="serviceNotProvisioned" msgid="8614830180508686666">"Услугата не е предвидена."</string>
     <string name="CLIRPermanent" msgid="3377371145926835671">"Не може да го промените поставувањето за ID на повикувач."</string>
     <string name="RestrictedOnData" msgid="8653794784690065540">"Услугата за податоци е блокирана."</string>
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Допрете за избирање јазик и распоред"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> пишува врз други апликации"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Апликацијата <xliff:g id="NAME">%s</xliff:g> е одозгора."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Делови од апликацијава може да бидат видливи цело време. Ако функцијава не работи правилно, исклучете ја."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ИСКЛУЧИ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Се подготвува <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Се проверува за грешки"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Откриена е нова <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1715,4 +1711,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Внесете време"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Префрлете се на режимот за внесување текст за да внесете време."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Префрлете се на режимот за часовник за да внесете време."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index 13a2c6b..0226a85 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ഭാഷയും ലേഔട്ടും തിരഞ്ഞെടുക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> മറ്റ് ആപ്പുകൾക്ക് ‌മുകളിൽ പ്രവർത്തിക്കും"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> മുകളിൽ ദൃശ്യമാകുന്നു."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ഈ ആപ്പിന്റെ ‌ഭാഗങ്ങൾ തുടർന്നും ദൃശ്യമായേക്കാം. ഈ ഫീച്ചർ ശരിയായി ‌പ്രവർത്തിക്കുന്നില്ലെങ്കിൽ അത് ഓഫ് ‌ചെയ്യുക."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ഓഫാക്കുക"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> തയ്യാറാകുന്നു"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"പിശകുകളുണ്ടോയെന്നു പരിശോധിക്കുന്നു"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"പുതിയ <xliff:g id="NAME">%s</xliff:g> എന്നതിനെ തിരിച്ചറിഞ്ഞു"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"സമയത്തിൽ ടൈപ്പുചെയ്യുക"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"സമയം നൽകുന്നതിന് ടെക്സ്റ്റ് ഇൻപുട്ട് ‌മോ‌ഡിലേക്ക് ‌മാറുക."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"‌സമയം നൽകുന്നതിന് ക്ലോക്ക് മോഡിലേക്ക് ‌മാറുക."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 7131be3f..2af2a21 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Хэл болон бүдүүвчийг сонгохын тулд дарна уу"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> бусад аппын дээр гарч ирсэн"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> апп дээр харагдаж байна."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Энэ аппын зарим хэсэг нь тогтмол харагдана. Энэ онцлог буруу ажиллаж байвал унтраана уу."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"УНТРААХ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>-ыг бэлдэж байна"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Алдааг шалгаж байна"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Шинэ <xliff:g id="NAME">%s</xliff:g> илэрлээ"</string>
@@ -1710,4 +1706,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Хугацааг бичнэ үү"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Цагийг оруулахын тулд текст оруулах горимд шилжүүлнэ үү."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Цагийг оруулахын тулд цагийн горимд шилжүүлнэ үү."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 370564d..de3bed5 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -515,8 +515,8 @@
     <string name="permdesc_invokeCarrierSetup" msgid="4159549152529111920">"होल्‍डरला वाहकद्वारे-प्रदान केलेल्या कॉन्फिगरेशन अ‍ॅपची विनंती करण्‍याची अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
     <string name="permlab_accessNetworkConditions" msgid="8206077447838909516">"नेटवर्क स्‍थितींवरील निरीक्षणांसाठी ऐका"</string>
     <string name="permdesc_accessNetworkConditions" msgid="6899102075825272211">"अनु्प्रयोगाला नेटवर्क स्‍थितींवरील निरीक्षणे ऐकण्‍यासाठी अनुमती देते. सामान्‍य अ‍ॅप्‍ससाठी कधीही आवश्‍यक नसावे."</string>
-    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डिव्हाइस अंशांकन बदला"</string>
-    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"स्पर्श स्क्रीनची मापन प्राचले सुधारित करण्यासाठी अॅप ला अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यक नसते."</string>
+    <string name="permlab_setInputCalibration" msgid="4902620118878467615">"इनपुट डिव्हाइस कॅलिब्रेशन बदला"</string>
+    <string name="permdesc_setInputCalibration" msgid="4527511047549456929">"स्पर्श स्क्रीनची कॅलिब्रेशन प्राचले सुधारित करण्यासाठी अॅप ला अनुमती देते. सामान्य अॅप्स साठी कधीही आवश्यक नसते."</string>
     <string name="permlab_accessDrmCertificates" msgid="7436886640723203615">"DRM प्रमाणपत्रांवर प्रवेश करा"</string>
     <string name="permdesc_accessDrmCertificates" msgid="8073288354426159089">"DRM प्रमाणपत्रांची तरतूद करण्यासाठी आणि वापरण्यासाठी अनुप्रयोगास अनुमती देते. सामान्य अॅप्सकरिता कधीही आवश्यकता नसते."</string>
     <string name="permlab_handoverStatus" msgid="7820353257219300883">"Android बीम स्थानांतरण स्थिती प्राप्त करा"</string>
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा आणि लेआउट निवडण्यासाठी टॅप करा"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> इतर अॅप्सवर काढा"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> अ‍ॅप शीर्षस्थानी प्रदर्शित होत आहे"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"या अ‍ॅपचे भाग सर्व वेळी दृश्यमान असू शकतात. हे वैशिष्ट्य बरोबर काम करत नसल्यास, ते बंद करा."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"बंद करा"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> तयार करीत आहे"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"त्रुटींसाठी तपासत आहे"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"नवीन <xliff:g id="NAME">%s</xliff:g> आढळले"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"वेळ टाइप करा"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"वेळ इनपुटसाठी मजकूर इनपुट मोडवर स्विच करा."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"वेळ इनपुटसाठी घड्याळ मोडवर स्विच करा."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 39c950a..171a02a 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ketik untuk memilih bahasa dan susun atur"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> melukis di atas apl lain"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Apl <xliff:g id="NAME">%s</xliff:g> dipaparkan di bahagian atas."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Sebahagian daripada apl ini mungkin kekal kelihatan pada sepanjang masa. Jika ciri ini tidak berfungsi dengan betul, matikan ciri ini."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"MATIKAN"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Menyediakan <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Menyemak untuk mengesan ralat"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"<xliff:g id="NAME">%s</xliff:g> baharu dikesan"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Taipkan masa"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Beralih ke mod input teks untuk input masa."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Beralih ke mod jam untuk input masa."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index b9269af..9bd2602 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ဘာသာစကားနှင့် အသွင်အပြင်ရွေးချယ်ရန် တို့ပါ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> သည် အခြားအက်ပ်များအပေါ်တွင် ပေါ်ပါမည်"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> အက်ပ်ကို အပေါ်ဆုံးတွင် ပြမည်။"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ဤအက်ပ်၏ တစ်စိတ်တစ်ဒေသကို အမြဲမြင်တွေ့နိုင်ပါမည်။ အကယ်၍ ဤဝန်ဆောင်မှုသည် မှန်မှန်ကန်ကန် အလုပ်မလုပ်လျှင် ၎င်းကို ပိတ်လိုက်ပါ။"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ပိတ်ပါ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> ပြင်ဆင်နေသည်"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"အမှားအယွင်းများ စစ်ဆေးနေသည်"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"<xliff:g id="NAME">%s</xliff:g> အသစ်တွေ့ရှိပါသည်"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"အချိန်ကို ရိုက်ရန်"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"အချိန်ထည့်သွင်းရန် စာသားထည့်သွင်းမှုမုဒ်သို့ ပြောင်းပါ။"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"အချိန်ထည့်သွင်းမှုအတွက် နာရီမုဒ်သို့ ပြောင်းပါ။"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 090cb9e..8643a2e 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Trykk for å velge språk og layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> ligger over andre apper"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g>-appen vises øverst."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Deler av denne appen kan være synlige til enhver tid. Slå denne funksjonen av hvis den ikke fungerer som den skal."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"SLÅ AV"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Forbereder <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Sjekker for feil"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"<xliff:g id="NAME">%s</xliff:g> ble oppdaget"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Skriv inn klokkeslett"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Bytt til tekstinndatamodus for tidsinndata."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Bytt til klokkemodus for tidsinndata."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 0b028a2..f41269a 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1173,14 +1173,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> लाई अन्य अनुप्रयोगहरूमा देखिन दिनुहोस्"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> अनुप्रयोग शीर्षमा देखाउँदै।"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"यो अनुप्रयोगका केही अंशहरू सधैँ देखिरहन सक्छन्‌। यो सुविधाले सही ढंगले काम गरिरहेको छैन भने, यसलाई बन्द गर्नुहोस्‌।"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"निष्क्रिय पार्नुहोस्"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"तयारी गर्दै <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"त्रुटिहरूको लागि जाँच गर्दै"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"नयाँ <xliff:g id="NAME">%s</xliff:g> भेटियो"</string>
@@ -1718,4 +1714,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"समय टाइप गर्नुहोस्‌"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"समय इनपुट गर्न पाठ इनपुट मोडमा स्विच गर्नुहोस्।"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"समय इनपुट गर्न घडी मोडमा स्विच गर्नुहोस्।"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 1c707f9..60f3363 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tik om een taal en indeling te selecteren"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> wordt weergegeven over andere apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g>-app bovenop weergeven."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Delen van deze app blijven altijd zichtbaar. Als deze functie niet correct werkt, schakel je deze uit."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"UITSCHAKELEN"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> voorbereiden"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Controleren op fouten"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Nieuwe <xliff:g id="NAME">%s</xliff:g> gedetecteerd"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Typ een tijd"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Schakel naar de tekstinvoermodus om de tijd in te voeren."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Schakel naar de klokmodus om de tijd in te voeren."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 182b3a5..34c0396 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ਭਾਸ਼ਾ ਅਤੇ ਖਾਕਾ ਚੁਣਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> ਹੋਰਾਂ ਐਪਾਂ ਉੱਤੇ ਪਸਰ ਸਕਦੀ ਹੈ"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> ਐਪ ਹੋਰ ਐਪਾਂ ਉੱਤੇ ਪਸਰੀ ਦਿਸ ਰਹੀ ਹੈ।"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਇਸ ਐਪ ਦੇ ਕੁਝ ਹਿੱਸੇ ਹਰ ਸਮੇਂ ਵਿਖਾਈ ਦੇਣ। ਜੇਕਰ ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਸਹੀ ਢੰਗ ਨਾਲ ਕੰਮ ਨਹੀਂ ਕਰ ਰਹੀ ਹੈ, ਤਾਂ ਇਸਨੂੰ ਬੰਦ ਕਰੋ।"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ਬੰਦ ਕਰੋ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> ਤਿਆਰ ਹੋ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"ਤਰੁੱਟੀਆਂ ਦੀ ਜਾਂਚ ਕਰ ਰਿਹਾ ਹੈ"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"ਨਵੇਂ <xliff:g id="NAME">%s</xliff:g> ਦਾ ਪਤਾ ਲਗਾਇਆ ਗਿਆ"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"ਸਮਾਂ ਟਾਈਪ ਕਰੋ"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਲਿਖਤ ਇਨਪੁੱਟ ਮੋਡ \'ਤੇ ਬਦਲੀ ਕਰੋ।"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"ਸਮਾਂ ਇਨਪੁੱਟ ਕਰਨ ਲਈ ਘੜੀ ਮੋਡ \'ਤੇ ਬਦਲੀ ਕਰੋ।"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 29c91b6..9ce2f69 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Kliknij, by wybrać język i układ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Aplikacja <xliff:g id="NAME">%s</xliff:g> wyświetla się nad innymi"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Aplikacja <xliff:g id="NAME">%s</xliff:g> jest nad innymi."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Fragmenty tej aplikacji mogą być widoczne przez cały czas. Jeśli ta funkcja nie działa prawidłowo, wyłącz ją."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"WYŁĄCZ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Przygotowuję: <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Sprawdzanie w poszukiwaniu błędów"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Wykryto nowy nośnik: <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Podaj czas"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Aby wprowadzić czas, włącz tryb wprowadzania tekstu."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Aby wprowadzić czas, włącz tryb zegara."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f66df7d..92dcc90b 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Sobreposição do <xliff:g id="NAME">%s</xliff:g> a outros apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> exibido na parte superior da tela."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Partes desse app podem ficar sempre visíveis. Se esse recurso não estiver funcionando corretamente, desative-o."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESATIVAR"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparando <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Procurando erros"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Novo <xliff:g id="NAME">%s</xliff:g> detectado"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Digite o horário"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Alterne para o modo de entrada de texto para informar o horário."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Alterne para o modo de relógio para informar o horário."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index c4e0fbc..dfc64d3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o esquema"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Sobrepor a aplicação <xliff:g id="NAME">%s</xliff:g> a outras aplicações"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Aplic. <xliff:g id="NAME">%s</xliff:g> apresentada por cima."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"É possível que partes desta aplicação permaneçam sempre visíveis. Se esta funcionalidade não estiver a funcionar corretamente, desative-a."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESATIVAR"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"A preparar o <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"A verificar a presença de erros"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Novo <xliff:g id="NAME">%s</xliff:g> detetado"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Introduza a hora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Mude para o modo de introdução de texto para a introdução da hora."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Mude para o modo de relógio para a introdução da hora."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f66df7d..92dcc90b 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Sobreposição do <xliff:g id="NAME">%s</xliff:g> a outros apps"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> exibido na parte superior da tela."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Partes desse app podem ficar sempre visíveis. Se esse recurso não estiver funcionando corretamente, desative-o."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DESATIVAR"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparando <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Procurando erros"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Novo <xliff:g id="NAME">%s</xliff:g> detectado"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Digite o horário"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Alterne para o modo de entrada de texto para informar o horário."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Alterne para o modo de relógio para informar o horário."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index c4416f8..d95e715 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1187,14 +1187,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Atingeți pentru a selecta limba și aspectul"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> afișează deasupra altor aplicații"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> se afișează deasupra."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Este posibil ca unele părți ale acestei aplicații să rămână vizibile permanent. Dacă această caracteristică nu funcționează corect, dezactivați-o."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"DEZACTIVAȚI"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Se pregătește <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Se verifică dacă există erori"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"A fost detectat un nou <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1743,4 +1739,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Introduceți ora"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Pentru a introduce ora, comutați la modul de introducere a textului."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Pentru a introduce ora, comutați la modul ceas."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 518023d..97c7b987 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Нажмите, чтобы выбрать язык и раскладку"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Интерфейс этих приложений показывается поверх других окон: <xliff:g id="NAME">%s</xliff:g>"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g>: показ поверх других окон"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Некоторые элементы интерфейса этого приложения могут всегда находиться поверх других окон. Если функция работает некорректно, отключите ее."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ОТКЛЮЧИТЬ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Подготовка карты \"<xliff:g id="NAME">%s</xliff:g>\"…"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Поиск ошибок"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Обнаружена новая карта \"<xliff:g id="NAME">%s</xliff:g>\""</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Введите время"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Чтобы ввести время, перейдите в режим ввода текста."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Чтобы ввести время, перейдите в режим часов."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index a8f6713..ff0c7d5 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1169,14 +1169,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"භාෂාව හා පිරිසැලසුම තේරීමට තට්ටු කරන්න"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"අනෙක් යෙදුම්වලට උඩින් <xliff:g id="NAME">%s</xliff:g> අදින්න"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> යෙදුම ඉහළින්ම සංදර්ශනය වේ."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"මෙම යෙදුමෙහි කොටස් සැම විටම දෘශ්‍යමානව පවතිනු ඇත. මෙම විශේෂාංගය නිවැරදිව ක්‍රියා නොකරන්නේ නම්, එය ක්‍රියාවිරහිත කරන්න."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ක්‍රියා විරහිත කරන්න"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> සූදානම් කරමින්"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"වැරදි සඳහා පරීක්ෂා කරමින්"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"නව <xliff:g id="NAME">%s</xliff:g> අනාවරණය කරන ලදි"</string>
@@ -1714,4 +1710,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"වේලාව ටයිප් කරන්න"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"වේලා ආදානය සඳහා ආදාන ප්‍රකාරය වෙත මාරු වෙන්න."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"වේලා ආදානය සඳහා ඔරලෝසු ප්‍රකාරය වෙත මාරු වෙන්න."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 20fcda5..660a256 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Klepnutím vyberte jazyk a rozloženie"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Aplikácia <xliff:g id="NAME">%s</xliff:g> sa vykreslí nad ostatnými aplikáciami"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Apl. <xliff:g id="NAME">%s</xliff:g> sa zobrazuje navrchu."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Časti tejto aplikácie môžu zostať neustále viditeľné. Ak táto funkcia nepracuje správne, vypnite ju."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"VYPNÚŤ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Pripravuje sa úložisko <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Prebieha kontrola chýb"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Bolo zistené nové úložisko <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Zadajte čas"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Ak chcete zadať čas, prepnite na textový režim vstupu"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Ak chcete zadať čas, prepnite na režim hodín."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index eca5c21..0abd212 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dotaknite se, če želite izbrati jezik in postavitev."</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Aplikacija <xliff:g id="NAME">%s</xliff:g> riše čez druge aplikacije"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Apl. <xliff:g id="NAME">%s</xliff:g> se prikazuje čez druge."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Deli te aplikacije lahko ostanejo vseskozi vidni. Če ta funkcija ne deluje pravilno, jo izklopite."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"IZKLOP"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Pripravljanje shrambe <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Iskanje napak"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Zaznana je bila nova shramba <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Vnesite uro"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Preklopite na način za vnašanje besedila, da vnesete čas."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Preklopite na način ure, da vnesete čas."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 25905d5..cc740a6 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Trokit për të zgjedhur gjuhën dhe strukturën"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> mbivendoset mbi aplikacionet e tjera"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Aplikacioni <xliff:g id="NAME">%s</xliff:g> po shfaqet në krye."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Disa pjesë të këtij aplikacioni mund të mbeten të dukshme gjatë të gjithë kohës. Nëse ky funksion nuk po funksionon si duhet, çaktivizoje atë."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ÇAKTIVIZO"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Po përgatit <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Po kontrollon për gabime"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"U zbulua karta e re <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Shkruaj kohën"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Kalo te modaliteti i hyrjes së tekstit për hyrjen e kohës."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Kalo te modaliteti i orës për hyrjen e kohës."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index e81f074..27f780a 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1187,14 +1187,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Додирните да бисте изабрали језик и распоред"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"Апликација <xliff:g id="NAME">%s</xliff:g> се приказује преко других апликација"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Апликација <xliff:g id="NAME">%s</xliff:g> се приказује преко."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Делови ове апликације могу да остану видљиви у сваком тренутку. Ако ова функција не ради исправно, искључите је."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ИСКЉУЧИ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> се припрема"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Проверава се да ли постоје грешке"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Нови уређај <xliff:g id="NAME">%s</xliff:g> је откривен"</string>
@@ -1743,4 +1739,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Унесите време"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Пређите у режим уноса текста ради уноса времена."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Пређите у режим сата ради уноса времена."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 4562231..7410322 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tryck om du vill välja språk och layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> gör överlagringar på andra appar"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Appen <xliff:g id="NAME">%s</xliff:g> visas ovanpå."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Delar av den här appen kanske alltid är synliga. Inaktivera funktionen om den inte fungerar som den ska."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"INAKTIVERA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Förbereder ditt <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Söker efter fel"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Nytt <xliff:g id="NAME">%s</xliff:g> har hittats"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Ange tid"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Byt till textinmatningsläget och ange tid."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Byt till klockläget och ange tid."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index a85d1dc..f266496 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1165,14 +1165,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Gonga ili uchague lugha na muundo"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> huchomoza kwenye programu zingine"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Programu ya <xliff:g id="NAME">%s</xliff:g> inaonekana juu ya zingine."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Huenda sehemu za programu hii zikaendelea kuonekana kila wakati. Zima kipengele hiki kama hakifanyi kazi vizuri."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ZIMA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Inaandaa <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Inakagua hitilafu"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"<xliff:g id="NAME">%s</xliff:g> mpya imegunduliwa"</string>
@@ -1710,4 +1706,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Andika wakati"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Badilisha iwe katika hali ya maandishi wakati wa kuweka muda."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Badilisha umbo liwe la saa ya mishale wakati wa kuweka muda."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 4c97780..7ab8c79 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"மொழியையும் தளவமைப்பையும் தேர்ந்தெடுக்க, தட்டவும்"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"பிற பயன்பாடுகளின் மேல் <xliff:g id="NAME">%s</xliff:g> செயல்படும்"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"பிற பயன்பாடுகளின் மேலே <xliff:g id="NAME">%s</xliff:g> பயன்பாடு காட்டப்படுகிறது."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"இந்தப் பயன்பாட்டின் பகுதிகள், எல்லா நேரமும் காட்டப்படக்கூடும். இந்த அம்சம் சரியாகச் செயல்படவில்லை எனில், அதை முடக்கவும்."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"முடக்கு"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> தயாராகிறது"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"பிழைகள் உள்ளதா எனப் பார்க்கிறது"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"புதிய <xliff:g id="NAME">%s</xliff:g> கண்டறியப்பட்டது"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"நேரத்தை உள்ளிடவும்"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"உரை உள்ளீட்டிற்காக, கடிகாரப் பயன்முறைக்கு மாற்றும்."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"நேர உள்ளீட்டிற்காக, கடிகாரப் பயன்முறைக்கு மாற்றும்."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 090b43c..905ccbe 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"భాష మరియు లేఅవుట్‌ను ఎంచుకోవడానికి నొక్కండి"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g>ని ఇతర అనువర్తనాలలో చూపండి"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"ఎగువన <xliff:g id="NAME">%s</xliff:g> అనువర్తనం కనిపిస్తోంది."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ఈ అనువర్తనంలోని భాగాలు అన్ని సమయాల్లో కనిపిస్తూ ఉండవచ్చు. ఈ లక్షణం సరిగ్గా పని చేయకపోతే, దీన్ని ఆఫ్ చేయండి."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ఆఫ్ చేయి"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g>ని సిద్ధం చేస్తోంది"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"లోపాల కోసం తనిఖీ చేస్తోంది"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"కొత్త <xliff:g id="NAME">%s</xliff:g> గుర్తించబడింది"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"సమయంలో టైప్ చేయండి"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"సమయాన్ని నమోదు చేయడం కోసం వచన నమోదు మోడ్‌కి మారండి."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"సమయాన్ని నమోదు చేయడం కోసం గడియారం మోడ్‌కు మారండి."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 992944a..bb893fb 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -322,8 +322,8 @@
     <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"แอปนี้สามารถปรากฏเหนือแอปอื่นๆ หรือส่วนอื่นของหน้าจอ ซึ่งอาจรบกวนการใช้งานตามปกติของแอปและทำให้ลักษณะการแสดงแอปอื่นๆ เปลี่ยนไป"</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"ทำงานในพื้นหลัง"</string>
     <string name="permdesc_runInBackground" msgid="7370142232209999824">"แอปนี้สามารถทำงานในพื้นหลัง ซึ่งอาจทำให้แบตเตอรี่หมดเร็วขึ้น"</string>
-    <string name="permlab_useDataInBackground" msgid="8694951340794341809">"ใช้เน็ตมือถือในพื้นหลัง"</string>
-    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"แอปนี้สามารถใช้เน็ตมือถือในพื้นหลัง ซึ่งอาจเพิ่มปริมาณการใช้อินเทอร์เน็ต"</string>
+    <string name="permlab_useDataInBackground" msgid="8694951340794341809">"ใช้เน็ตในพื้นหลัง"</string>
+    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"แอปนี้สามารถใช้เน็ตในพื้นหลัง ซึ่งอาจเพิ่มปริมาณการใช้อินเทอร์เน็ต"</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"ทำให้แอปพลิเคชันทำงานเสมอ"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"อนุญาตให้แอปพลิเคชันทำให้ส่วนหนึ่งของตัวเองคงอยู่ถาวรในหน่วยความจำ ซึ่งจะจำกัดพื้นที่หน่วยความจำที่ใช้งานได้ของแอปพลิเคชันอื่นๆ และทำให้แท็บเล็ตทำงานช้าลง"</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"อนุญาตให้แอปทำให้บางส่วนของแอปนั้นอยู่ในหน่วยความจำเสมอ ซึ่งอาจจำกัดพื้นที่หน่วยความจำสำหรับแอปอื่นและทำให้ทีวีช้าลง"</string>
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"แตะเพื่อเลือกภาษาและรูปแบบ"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> แสดงทับแอปอื่น"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"แอป <xliff:g id="NAME">%s</xliff:g> แสดงอยู่ด้านบนสุด"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ส่วนต่างๆ ของแอปนี้อาจปรากฏอยู่ตลอดเวลา หากคุณลักษณะนี้ไม่ทำงานอย่างถูกต้อง ให้ปิดแอป"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ปิด"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"กำลังเตรียม <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"กำลังตรวจหาข้อผิดพลาด"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"ตรวจพบ <xliff:g id="NAME">%s</xliff:g> ใหม่"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"พิมพ์เวลา"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"สลับไปโหมดป้อนข้อความเพื่อป้อนเวลา"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"สลับไปโหมดนาฬิกาเพื่อป้อนเวลา"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 4ec0d13..05ae6bf 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"I-tap upang pumili ng wika at layout"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"I-draw over ang <xliff:g id="NAME">%s</xliff:g> sa iba pang app"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Ipinapakita ang <xliff:g id="NAME">%s</xliff:g> app sa itaas."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Maaaring manatiling nakikita ang mga bahagi ng app na ito sa lahat ng oras. Kung hindi gumagana nang tama ang feature na ito, i-off ito."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"I-OFF"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Inihahanda ang <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Sinusuri para sa mga error"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Na-detect ang bagong <xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"I-type ang oras"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Lumipat sa pamamaraan ng pag-input ng text para sa input na oras."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Lumipat sa mode ng orasan para sa input na oras."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index f9cd837..b56d466 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dili ve düzeni seçmek için hafifçe dokunun"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> diğer uygulamaların üzerinde görüntüleniyor"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> üstte gösteriliyor."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Bu uygulamanın bazı bölümleri her zaman görünür durumda kalabilir. Bu özellik düzgün çalışmıyorsa kapatın."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"KAPAT"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> hazırlanıyor"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Hatalar denetleniyor"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Yeni <xliff:g id="NAME">%s</xliff:g> algılandı"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Zamanı yazın"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Zaman girişi için metin girişi moduna geçin."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Zaman girişi için saat moduna geçin."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index acf6614..e99d88b 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1207,14 +1207,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Торкніться, щоб вибрати мову та розкладку"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> відображається поверх інших додатків"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> відображається поверх."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Частина цього додатка може постійно залишатися видимою. Якщо ця функція працює неправильно, вимкніть її."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"ВИМКНУТИ"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Підготовка пристрою пам’яті <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Виявлення помилок"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Виявлено новий пристрій пам’яті (<xliff:g id="NAME">%s</xliff:g>)"</string>
@@ -1774,4 +1770,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Введіть час"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Перейти в текстовий режим, щоб ввести час."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Перейти в режим годинника, щоб ввести час."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 7e8b110..41c265d 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"زبان اور لے آؤٹ منتخب کرنے کیلئے تھپتھپائیں"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> کو دیگر ایپس پر ڈرا کریں"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> ایپ اوپر ڈسپلے ہورہی ہے۔"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"ممکن ہے اس ایپ کے حصے ہر وقت مرئی رہیں۔ اگر یہ خصوصیت ٹھیک سے کام نہیں کررہی ہے، تو اسے آف کردیں۔"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"آف کریں"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> تیار کیا جا رہا ہے"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"خرابیوں کیلئے چیک کیا جا رہا ہے"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"نئے <xliff:g id="NAME">%s</xliff:g> کا پتا چلا"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"وقت ٹائپ کریں"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"وقت ان پٹ کے لیے ٹیکسٹ ان پٹ وضع پر سوئچ کریں۔"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"وقت ان پٹ کے لیے گھڑی و‏ضع پر سوئچ کریں۔"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 3210143..5309181 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1168,14 +1168,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Til va sxemani belgilash uchun bosing"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> boshqa ilovalar ustidan ochiladi"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g> eng tepada ochilgan."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Bu ilovaning ba’zi qismlari har doim ko‘rinib qolishi mumkin. Agar bu funksiya to‘g‘ri ishlamasa, uni o‘chirib qo‘ying."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"O‘CHIRIB QO‘YISH"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> tayyorlanmoqda"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Xatolar qidirilmoqda"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Yangi <xliff:g id="NAME">%s</xliff:g> kartasi aniqlandi"</string>
@@ -1713,4 +1709,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Vaqtni kiriting"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Vaqtni kiritish uchun matn kiritish rejimiga o‘ting."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Vaqtni kiritish uchun soat rejimiga o‘ting."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 4ed7dc9..69e0ec3 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Nhấn để chọn ngôn ngữ và bố cục"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g> vẽ lên các ứng dụng khác"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Ứng dụng <xliff:g id="NAME">%s</xliff:g> hiển thị ở trên cùng."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Các phần của ứng dụng này có thể vẫn hiển thị mọi lúc. Nếu tính năng này không hoạt động bình thường, hãy tắt tính năng này."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"TẮT"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Đang chuẩn bị <xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Đang kiểm tra lỗi"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Đã phát hiện <xliff:g id="NAME">%s</xliff:g> mới"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Nhập thời gian"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Chuyển sang chế độ nhập văn bản để nhập thời gian."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Chuyển sang chế độ đồng hồ để nhập thời gian."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 1e71448..2236f1f 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"点按即可选择语言和布局"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g>会在其他应用的上层显示内容"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g>应用目前显示在上层。"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"此应用的某些部分可能会一直保持可见状态。如果此功能未能正常运行,请将其关闭。"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"关闭"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"正在准备<xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"检查是否有错误"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"检测到新的<xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"请输入时间"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"切换到文字输入模式来输入时间。"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"切换到时钟模式来输入时间。"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index b1273f4..db98761 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"輕按即可選取語言和鍵盤配置"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"「<xliff:g id="NAME">%s</xliff:g>」會覆蓋其他應用程式"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"「<xliff:g id="NAME">%s</xliff:g>」應用程式目前在最上層顯示。"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"畫面上可能會一直保持顯示此應用程式的某些部分。如果此功能無法正常運作,請將其關閉。"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"關閉"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"正在準備<xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"正在檢查錯誤"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"已偵測到新<xliff:g id="NAME">%s</xliff:g>"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"輸入時間"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"切換至文字輸入模式即可輸入時間。"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"切換至時鐘模式即可輸入時間。"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index b3b7e18..7f4c01b 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -321,9 +321,9 @@
     <string name="permlab_systemAlertWindow" msgid="7238805243128138690">"這個應用程式可顯示在其他應用程式上方"</string>
     <string name="permdesc_systemAlertWindow" msgid="2393776099672266188">"這個應用程式可顯示在其他應用程式上方或畫面中的其他位置。你可能會無法照常使用應用程式,且其他應用程式的顯示方式可能會受到影響。"</string>
     <string name="permlab_runInBackground" msgid="7365290743781858803">"在背景執行"</string>
-    <string name="permdesc_runInBackground" msgid="7370142232209999824">"這個應用程式可在背景執行,這樣可能會加快耗電速度。"</string>
+    <string name="permdesc_runInBackground" msgid="7370142232209999824">"這個應用程式可在背景執行,這樣可能導致耗電速度加快。"</string>
     <string name="permlab_useDataInBackground" msgid="8694951340794341809">"在背景使用行動數據連線"</string>
-    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"這個應用程式可在背景使用行動數據連線,這樣可能會增加數據用量。"</string>
+    <string name="permdesc_useDataInBackground" msgid="6049514223791806027">"這個應用程式可在背景使用行動數據連線,這樣可能導致數據用量增加。"</string>
     <string name="permlab_persistentActivity" msgid="8841113627955563938">"一律執行應用程式"</string>
     <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"允許應用程式的部分內容常駐在記憶體中。這項設定可能會限制其他應用程式可用的記憶體,並拖慢平板電腦運作速度。"</string>
     <string name="permdesc_persistentActivity" product="tv" msgid="5086862529499103587">"允許應用程式的部分內容常駐在記憶體中。這項設定可能會限制其他應用程式可用的記憶體,造成電視的運作速度變慢。"</string>
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"輕觸即可選取語言和版面配置"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"<xliff:g id="NAME">%s</xliff:g>會在其他應用程式上層繪製內容"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"<xliff:g id="NAME">%s</xliff:g>應用程式目前顯示在最上層。"</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"這個應用程式的某些部分會一直保持顯示。如果這項功能未正常運作,請將它關閉。"</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"關閉"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"正在準備「<xliff:g id="NAME">%s</xliff:g>」"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"正在檢查錯誤"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"偵測到新的「<xliff:g id="NAME">%s</xliff:g>」"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"輸入時間"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"切換至文字輸入模式來輸入時間。"</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"切換至時鐘模式來輸入時間。"</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 6a82ed5..dadd6c0 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1167,14 +1167,10 @@
     <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Thepha ukuze ukhethe ulimi nesakhiwo"</string>
     <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
     <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
-    <!-- no translation found for alert_windows_notification_channel_name (7443890103456396837) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_title (5399998516035621282) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_message (2456738662997073459) -->
-    <skip />
-    <!-- no translation found for alert_windows_notification_turn_off_action (3367294525884949878) -->
-    <skip />
+    <string name="alert_windows_notification_channel_name" msgid="7443890103456396837">"I-<xliff:g id="NAME">%s</xliff:g> yokudweba ngaphezu kwezinye izinhlelo zokusebenza"</string>
+    <string name="alert_windows_notification_title" msgid="5399998516035621282">"Uhlelo lokusebenza lwe-<xliff:g id="NAME">%s</xliff:g> liboniswa ngaphezulu."</string>
+    <string name="alert_windows_notification_message" msgid="2456738662997073459">"Izingxenye zalolu hlelo lokusebenza zingahlala zibonakala ngazo zonke izikhathi. Uma lesi sici singasebenzi ngokufanelekile, sivale."</string>
+    <string name="alert_windows_notification_turn_off_action" msgid="3367294525884949878">"VALA"</string>
     <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Ilungiselela i-<xliff:g id="NAME">%s</xliff:g>"</string>
     <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Ihlolela amaphutha"</string>
     <string name="ext_media_new_notification_message" msgid="7589986898808506239">"I-<xliff:g id="NAME">%s</xliff:g> entsha itholiwe"</string>
@@ -1712,4 +1708,18 @@
     <string name="time_picker_prompt_label" msgid="7588093983899966783">"Thayipha isikhathi"</string>
     <string name="time_picker_text_input_mode_description" msgid="4148166758173708199">"Shintshela kumodi yokufaka umbhalo ngokufaka isikhathi."</string>
     <string name="time_picker_radial_mode_description" msgid="4953403779779557198">"Shintshela kumodi yewashi ngokufakwa kwesikhathi."</string>
+    <!-- no translation found for autofill_save_title (7081244500504163245) -->
+    <skip />
+    <!-- no translation found for autofill_save_title_with_type (4977385733042555659) -->
+    <skip />
+    <!-- no translation found for autofill_save_yes (6398026094049005921) -->
+    <skip />
+    <!-- no translation found for autofill_save_no (2625132258725581787) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_password (5288448918465971568) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_address (4936707762193009542) -->
+    <skip />
+    <!-- no translation found for autofill_save_type_credit_card (7127694776265563071) -->
+    <skip />
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index be77603..c137ae2 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -804,16 +804,20 @@
         <!-- Action bar styles   -->
         <!-- =================== -->
         <eat-comment />
-        <!-- Default style for tabs within an action bar -->
+        <!-- Default style for tabs within an action bar. -->
         <attr name="actionBarTabStyle" format="reference" />
+        <!-- Reference to a style for the Action Bar Tab Bar. -->
         <attr name="actionBarTabBarStyle" format="reference" />
+        <!-- Reference to a style for the Action Bar Tab text. -->
         <attr name="actionBarTabTextStyle" format="reference" />
+        <!-- Reference to a style for Action Bar overflow buttons. -->
         <attr name="actionOverflowButtonStyle" format="reference" />
+        <!-- Reference to a style for the Action Bar menu. -->
         <attr name="actionOverflowMenuStyle" format="reference" />
         <!-- Reference to a theme that should be used to inflate popups
              shown by widgets in the action bar. -->
         <attr name="actionBarPopupTheme" format="reference" />
-        <!-- Reference to a style for the Action Bar -->
+        <!-- Reference to a style for the Action Bar. -->
         <attr name="actionBarStyle" format="reference" />
         <!-- Reference to a style for the split Action Bar. This style
              controls the split component that holds the menu/action
@@ -851,28 +855,30 @@
         <!-- Action mode styles  -->
         <!-- =================== -->
         <eat-comment />
+        <!-- Reference to a style for the Action Mode. -->
         <attr name="actionModeStyle" format="reference" />
+        <!-- Reference to a style for the Action Mode close button. -->
         <attr name="actionModeCloseButtonStyle" format="reference" />
-        <!-- Background drawable to use for action mode UI -->
+        <!-- Background drawable to use for action mode UI. -->
         <attr name="actionModeBackground" format="reference" />
-        <!-- Background drawable to use for action mode UI in the lower split bar -->
+        <!-- Background drawable to use for action mode UI in the lower split bar. -->
         <attr name="actionModeSplitBackground" format="reference" />
-        <!-- Drawable to use for the close action mode button -->
+        <!-- Drawable to use for the close action mode button. -->
         <attr name="actionModeCloseDrawable" format="reference" />
 
-        <!-- Drawable to use for the Cut action button in Contextual Action Bar -->
+        <!-- Drawable to use for the Cut action button in Contextual Action Bar. -->
         <attr name="actionModeCutDrawable" format="reference" />
-        <!-- Drawable to use for the Copy action button in Contextual Action Bar -->
+        <!-- Drawable to use for the Copy action button in Contextual Action Bar. -->
         <attr name="actionModeCopyDrawable" format="reference" />
-        <!-- Drawable to use for the Paste action button in Contextual Action Bar -->
+        <!-- Drawable to use for the Paste action button in Contextual Action Bar. -->
         <attr name="actionModePasteDrawable" format="reference" />
-        <!-- Drawable to use for the Select all action button in Contextual Action Bar -->
+        <!-- Drawable to use for the Select all action button in Contextual Action Bar. -->
         <attr name="actionModeSelectAllDrawable" format="reference" />
-        <!-- Drawable to use for the Share action button in WebView selection action modes -->
+        <!-- Drawable to use for the Share action button in WebView selection action modes. -->
         <attr name="actionModeShareDrawable" format="reference" />
-        <!-- Drawable to use for the Find action button in WebView selection action modes -->
+        <!-- Drawable to use for the Find action button in WebView selection action modes. -->
         <attr name="actionModeFindDrawable" format="reference" />
-        <!-- Drawable to use for the Web Search action button in WebView selection action modes -->
+        <!-- Drawable to use for the Web Search action button in WebView selection action modes. -->
         <attr name="actionModeWebSearchDrawable" format="reference" />
 
         <!-- PopupWindow style to use for action modes when showing as a window overlay. -->
@@ -969,7 +975,7 @@
 
         <!-- Theme to use for alert dialogs spawned from this theme. -->
         <attr name="alertDialogTheme" format="reference" />
-        <!-- Icon drawable to use for alerts -->
+        <!-- Icon drawable to use for alerts. -->
         <attr name="alertDialogIcon" format="reference" />
 
         <!-- Theme to use for presentations spawned from this theme. -->
@@ -981,19 +987,19 @@
         <!-- Drawable to use for generic horizontal dividers. -->
         <attr name="dividerHorizontal" format="reference" />
 
-        <!-- Style for button bars -->
+        <!-- Style for button bars. -->
         <attr name="buttonBarStyle" format="reference" />
 
-        <!-- Style for buttons within button bars -->
+        <!-- Style for buttons within button bars. -->
         <attr name="buttonBarButtonStyle" format="reference" />
 
-        <!-- Style for the "positive" buttons within button bars -->
+        <!-- Style for the "positive" buttons within button bars. -->
         <attr name="buttonBarPositiveButtonStyle" format="reference" />
 
-        <!-- Style for the "negative" buttons within button bars -->
+        <!-- Style for the "negative" buttons within button bars. -->
         <attr name="buttonBarNegativeButtonStyle" format="reference" />
 
-        <!-- Style for the "neutral" buttons within button bars -->
+        <!-- Style for the "neutral" buttons within button bars. -->
         <attr name="buttonBarNeutralButtonStyle" format="reference" />
 
         <!-- Style for the search query widget. -->
@@ -1012,19 +1018,19 @@
         <!-- Style for buttons without an explicit border, often used in groups. -->
         <attr name="borderlessButtonStyle" format="reference" />
 
-        <!-- Background to use for toasts -->
+        <!-- Background to use for toasts. -->
         <attr name="toastFrameBackground" format="reference" />
 
-        <!-- Background to use for tooltip popups -->
+        <!-- Background to use for tooltip popups. -->
         <attr name="tooltipFrameBackground" format="reference" />
 
-        <!-- Foreground color to use for tooltip popups -->
+        <!-- Foreground color to use for tooltip popups. -->
         <attr name="tooltipForegroundColor" format="reference|color" />
 
-        <!-- Background color to use for tooltip popups -->
+        <!-- Background color to use for tooltip popups. -->
         <attr name="tooltipBackgroundColor" format="reference|color" />
 
-        <!-- Theme to use for Search Dialogs -->
+        <!-- Theme to use for Search Dialogs. -->
         <attr name="searchDialogTheme" format="reference" />
 
         <!-- Specifies a drawable to use for the 'home as up' indicator. -->
@@ -2287,7 +2293,7 @@
             <enum name="auto" value="0x00000010" />
         </attr>
 
-        <!-- Controls the auto-fill behavior for this view -->
+        <!-- Controls the auto-fill behavior for this view. -->
         <attr name="autoFillMode">
             <!-- Inherit the behavior from the parent. If there is no parent it is auto. -->
             <enum name="inherit" value="0" />
@@ -2338,13 +2344,13 @@
              to appear at the edge of the view, ignoring the padding, then you can
              use outsideOverlay or outsideInset.-->
         <attr name="scrollbarStyle">
-            <!-- Inside the padding and overlaid -->
+            <!-- Inside the padding and overlaid. -->
             <enum name="insideOverlay" value="0x0" />
-            <!-- Inside the padding and inset -->
+            <!-- Inside the padding and inset. -->
             <enum name="insideInset" value="0x01000000" />
-            <!-- Edge of the view and overlaid -->
+            <!-- Edge of the view and overlaid. -->
             <enum name="outsideOverlay" value="0x02000000" />
-            <!-- Edge of the view and inset -->
+            <!-- Edge of the view and inset. -->
             <enum name="outsideInset" value="0x03000000" />
         </attr>
 
@@ -2548,7 +2554,7 @@
              (completely opaque). -->
         <attr name="alpha" format="float" />
 
-        <!-- base z depth of the view -->
+        <!-- base z depth of the view. -->
         <attr name="elevation" format="dimension" />
 
         <!-- translation in x of the view. This value is added post-layout to the left
@@ -2617,19 +2623,19 @@
              to inherit, "locale" is used. "locale" falls back to "en-US". "ltr" is the direction
              used in "en-US". The default for this attribute is "inherit". -->
         <attr name="layoutDirection">
-            <!-- Left-to-Right -->
+            <!-- Left-to-Right. -->
             <enum name="ltr" value="0" />
-            <!-- Right-to-Left -->
+            <!-- Right-to-Left. -->
             <enum name="rtl" value="1" />
-            <!-- Inherit from parent -->
+            <!-- Inherit from parent. -->
             <enum name="inherit" value="2" />
-            <!-- Locale -->
+            <!-- Locale. -->
             <enum name="locale" value="3" />
         </attr>
 
         <!-- Defines the direction of the text. -->
          <attr name="textDirection" format="integer">
-            <!-- Default -->
+            <!-- Default. -->
             <enum name="inherit" value="0" />
             <!-- Default for the root view. The first strong directional character determines the
                  paragraph direction.  If there is no strong directional character, the paragraph
@@ -2655,23 +2661,23 @@
 
         <!-- Defines the alignment of the text. -->
         <attr name="textAlignment" format="integer">
-            <!-- Default -->
+            <!-- Default. -->
             <enum name="inherit" value="0" />
             <!-- Default for the root view. The gravity determines the alignment, ALIGN_NORMAL,
                 ALIGN_CENTER, or ALIGN_OPPOSITE, which are relative to each paragraph’s
-                text direction -->
+                text direction. -->
             <enum name="gravity" value="1" />
-            <!-- Align to the start of the paragraph, e.g. ALIGN_NORMAL. -->
+            <!-- Align to the start of the paragraph, for example: ALIGN_NORMAL. -->
             <enum name="textStart" value="2" />
-            <!-- Align to the end of the paragraph, e.g. ALIGN_OPPOSITE. -->
+            <!-- Align to the end of the paragraph, for example: ALIGN_OPPOSITE. -->
             <enum name="textEnd" value="3" />
-            <!-- Center the paragraph, e.g. ALIGN_CENTER. -->
+            <!-- Center the paragraph, for example: ALIGN_CENTER. -->
             <enum name="center" value="4" />
             <!-- Align to the start of the view, which is ALIGN_LEFT if the view’s resolved
                 layoutDirection is LTR, and ALIGN_RIGHT otherwise. -->
             <enum name="viewStart" value="5" />
             <!-- Align to the end of the view, which is ALIGN_RIGHT if the view’s resolved
-                layoutDirection is LTR, and ALIGN_LEFT otherwise -->
+                layoutDirection is LTR, and ALIGN_LEFT otherwise. -->
             <enum name="viewEnd" value="6" />
         </attr>
 
@@ -3148,19 +3154,19 @@
               If both layout_marginHorizontal and any of layout_marginLeft,
               layout_marginRight, layout_marginStart, and layout_marginEnd are
               also specified, the layout_marginHorizontal value will take precedence over the
-              edge-specific values. Also, layout_margin will always take precendent over
+              edge-specific values. Also, layout_margin will always take precedence over
               any of these values, including layout_marginHorizontal.
               This space is outside this view's bounds.
               Margin values should be positive.-->
         <attr name="layout_marginHorizontal" format="dimension"  />
-        <!--  Specifies extra space on the tyop and bottom sides of this view.
+        <!--  Specifies extra space on the top and bottom sides of this view.
               Specifying layout_marginVertical is equivalent to specifying
               layout_marginTop and layout_marginBottom with that same value.
               If both layout_marginVertical and either/both layout_marginTop and
               layout_marginBottom are also specified, the layout_marginVertical value
               will take precedence over the edge-specific values.
-              Also, layout_margin will always take precendent over
-              any of these values, including layout_marginHorizontal.
+              Also, layout_margin will always take precedence over
+              any of these values, including layout_marginVertical.
               This space is outside this view's bounds.
               Margin values should be positive.-->
         <attr name="layout_marginVertical" format="dimension"  />
@@ -3181,7 +3187,7 @@
              method should be considered an option as the default. -->
         <attr name="isDefault" format="boolean" />
         <!-- Set to true if this input method supports ways to switch to
-             a next input method (e.g. a globe key.). When this is true and
+             a next input method (for example, a globe key.). When this is true and
              InputMethodManager#shouldOfferSwitchingToNextInputMethod() returns true,
              the IME has to offer ways to invoke InputMethodManager#switchToNextInputMethod()
              accordingly.
@@ -3190,7 +3196,7 @@
              between IMEs and subtypes. -->
         <attr name="supportsSwitchingToNextInputMethod" format="boolean" />
         <!-- Set to true if this input method supports ways to dismiss the windows assigned to
-             the input method (e.g. a dismiss button rendered by the input method itself).  The
+             the input method (for example, a dismiss button rendered by the input method itself).  The
              System UI may optimize the UI by not showing system-level dismiss button if this
              value is true.
              <p> Must be a boolean value, either "true" or "false". The default value is "false".
@@ -3203,21 +3209,21 @@
         <attr name="supportsDismissingWindow" format="boolean" />
     </declare-styleable>
 
-    <!-- This is the subtype of InputMethod. Subtype can describe locales (e.g. en_US, fr_FR...)
-         and modes (e.g. voice, keyboard...), and is used for IME switch. This subtype allows
-         the system to call the specified subtype of the IME directly. -->
+    <!-- This is the subtype of InputMethod. Subtype can describe locales (for example, en_US and
+         fr_FR) and modes (for example, voice and keyboard), and is used for IME switch. This
+         subtype allows the system to call the specified subtype of the IME directly. -->
     <declare-styleable name="InputMethod_Subtype">
         <!-- The name of the subtype. -->
         <attr name="label" />
         <!-- The icon of the subtype. -->
         <attr name="icon" />
-        <!-- The locale of the subtype. This string should be a locale (e.g. en_US, fr_FR...)
+        <!-- The locale of the subtype. This string should be a locale (for example en_US and fr_FR)
              and will be passed to the IME when the framework calls the IME
              with the subtype. This is also used by the framework to know the supported locales
              of the IME.  -->
         <attr name="imeSubtypeLocale" format="string" />
-        <!-- The mode of the subtype. This string can be a mode (e.g. voice, keyboard...) and this
-             string will be passed to the IME when the framework calls the IME with the
+        <!-- The mode of the subtype. This string can be a mode (for example, voice and keyboard)
+             and this string will be passed to the IME when the framework calls the IME with the
              subtype.  {@link android.view.inputmethod.InputMethodSubtype#getLocale()} returns the
              value specified in this attribute.  -->
         <attr name="imeSubtypeMode" format="string" />
@@ -3264,12 +3270,13 @@
         <attr name="settingsActivity"/>
     </declare-styleable>
 
-    <!-- This is the subtype of the spell checker. Subtype can describe locales (e.g. en_US, fr_FR...) -->
+    <!-- This is the subtype of the spell checker. Subtype can describe locales (for example,
+             en_US and fr_FR). -->
     <declare-styleable name="SpellChecker_Subtype">
         <!-- The name of the subtype. -->
         <attr name="label" />
-        <!-- The locale of the subtype. This string should be a locale (e.g. en_US, fr_FR...)
-             This is also used by the framework to know the supported locales
+        <!-- The locale of the subtype. This string should be a locale (for example, en_US and
+             fr_FR). This is also used by the framework to know the supported locales
              of the spell checker. {@link android.view.textservice.SpellCheckerSubtype#getLocale()}
              returns the value specified in this attribute.  -->
         <attr name="subtypeLocale" format="string" />
@@ -3387,25 +3394,25 @@
              {@link android.accessibilityservice.AccessibilityService#setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)
              android.accessibilityservice.AccessibilityService.setServiceInfo(android.accessibilityservice.AccessibilityServiceInfo)}. -->
         <attr name="accessibilityFlags">
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#DEFAULT} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#DEFAULT}. -->
             <flag name="flagDefault" value="0x00000001" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_INCLUDE_NOT_IMPORTANT_VIEWS}. -->
             <flag name="flagIncludeNotImportantViews" value="0x00000002" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_TOUCH_EXPLORATION_MODE}. -->
             <flag name="flagRequestTouchExplorationMode" value="0x00000004" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ENHANCED_WEB_ACCESSIBILITY}. -->
             <flag name="flagRequestEnhancedWebAccessibility" value="0x00000008" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REPORT_VIEW_IDS}. -->
             <flag name="flagReportViewIds" value="0x00000010" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_FILTER_KEY_EVENTS} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_FILTER_KEY_EVENTS}. -->
             <flag name="flagRequestFilterKeyEvents" value="0x00000020" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS}. -->
             <flag name="flagRetrieveInteractiveWindows" value="0x00000040" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_ENABLE_ACCESSIBILITY_VOLUME} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_ENABLE_ACCESSIBILITY_VOLUME}. -->
             <flag name="flagEnableAccessibilityVolume" value="0x00000080" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_REQUEST_ACCESSIBILITY_BUTTON}. -->
             <flag name="flagRequestAccessibilityButton" value="0x00000100" />
-            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_CAPTURE_FINGERPRINT_GESTURES} -->
+            <!-- Has flag {@link android.accessibilityservice.AccessibilityServiceInfo#FLAG_CAPTURE_FINGERPRINT_GESTURES}. -->
             <flag name="flagCaptureFingerprintGestures" value="0x00000200" />
         </attr>
         <!-- Component name of an activity that allows the user to modify
@@ -3682,7 +3689,7 @@
     <declare-styleable name="CompoundButton">
         <!-- Indicates the initial checked state of this button. -->
         <attr name="checked" format="boolean" />
-        <!-- Drawable used for the button graphic (e.g. checkbox, radio button, etc). -->
+        <!-- Drawable used for the button graphic (for example, checkbox and radio button). -->
         <attr name="button" format="reference" />
         <!-- Tint to apply to the button graphic. -->
         <attr name="buttonTint" format="color" />
@@ -4105,11 +4112,11 @@
         <attr name="minHeight" format="dimension" />
         <attr name="maxHeight" />
         <attr name="interpolator" format="reference" />
-        <!-- Timeout between frames of animation in milliseconds
-             {@deprecated Not used by the framework.} -->
+        <!-- Timeout between frames of animation in milliseconds.
+             {@deprecated Not used by the framework}. -->
         <attr name="animationResolution" format="integer" />
         <!-- Defines if the associated drawables need to be mirrored when in RTL mode.
-             Default is false -->
+             Default is false. -->
         <attr name="mirrorForRtl" format="boolean" />
         <!-- Tint to apply to the progress indicator. -->
         <attr name="progressTint" format="color" />
@@ -4720,12 +4727,12 @@
             <enum name="full" value="2" />
         </attr>
         <!-- Specify the type of auto-size. Note that this feature is not supported by EditText,
-        works only for TextView -->
+        works only for TextView. -->
         <attr name="autoSizeTextType" format="enum">
             <!-- No auto-sizing (default). -->
             <enum name="none" value="0" />
             <!-- Uniform horizontal and vertical text size scaling to fit within the
-            container -->
+            container. -->
             <enum name="uniform" value="1" />
         </attr>
         <!-- Specify the auto-size step size if <code>autoSizeTextType</code> is set to
@@ -4736,9 +4743,9 @@
         <code>autoSizeTextType</code> set to <code>uniform</code>. Overrides
         <code>autoSizeStepGranularity</code> if set. -->
         <attr name="autoSizePresetSizes"/>
-        <!-- The minimum text size constraint to be used when auto-sizing text -->
+        <!-- The minimum text size constraint to be used when auto-sizing text. -->
         <attr name="autoSizeMinTextSize" format="dimension" />
-        <!-- The maximum text size constraint to be used when auto-sizing text -->
+        <!-- The maximum text size constraint to be used when auto-sizing text. -->
         <attr name="autoSizeMaxTextSize" format="dimension" />
     </declare-styleable>
     <declare-styleable name="TextViewAppearance">
@@ -4840,7 +4847,7 @@
     </declare-styleable>
     <declare-styleable name="ViewFlipper">
         <attr name="flipInterval" format="integer" min="0" />
-        <!-- When true, automatically start animating -->
+        <!-- When true, automatically start animating. -->
         <attr name="autoStart" format="boolean" />
     </declare-styleable>
     <declare-styleable name="AdapterViewAnimator">
@@ -4857,7 +4864,7 @@
     </declare-styleable>
     <declare-styleable name="AdapterViewFlipper">
         <attr name="flipInterval" />
-        <!-- When true, automatically start animating -->
+        <!-- When true, automatically start animating. -->
         <attr name="autoStart" />
     </declare-styleable>
     <declare-styleable name="ViewSwitcher">
@@ -5624,7 +5631,7 @@
             <!-- Indicates that the layer is opaque and contains no transparent
                  nor translucent pixels. -->
             <enum name="opaque" value="-1" />
-            <!-- The layer is completely transparent (no pixel will be drawn.) -->
+            <!-- The layer is completely transparent (no pixel will be drawn). -->
             <enum name="transparent" value="-2" />
             <!-- The layer has translucent pixels. -->
             <enum name="translucent" value="-3" />
@@ -5649,10 +5656,10 @@
         <!-- Explicit right padding. Overrides child padding. -->
         <attr name="paddingRight" />
         <!-- Explicit start padding. Overrides child padding. Takes precedence
-             over absolute padding (e.g. left when layout direction is LTR). -->
+             over absolute padding (for example, left when layout direction is LTR). -->
         <attr name="paddingStart" />
         <!-- Explicit end padding. Overrides child padding. Takes precedence
-             over absolute padding (e.g. right when layout direction is LTR). -->
+             over absolute padding (for example, right when layout direction is LTR). -->
         <attr name="paddingEnd" />
     </declare-styleable>
 
@@ -5674,7 +5681,7 @@
         <attr name="end" format="dimension" />
         <!-- Width of the layer. Defaults to the layer's intrinsic width. -->
         <attr name="width" />
-        <!-- Height of the layer. Defaults to the layer's intrinsic height -->
+        <!-- Height of the layer. Defaults to the layer's intrinsic height. -->
         <attr name="height" />
         <!-- Gravity used to align the layer within its container. If no value
              is specified, the default behavior depends on whether an explicit
@@ -5995,7 +6002,7 @@
         <attr name="viewportWidth" format="float"/>
         <!-- The height of the canvas the drawing is on. -->
         <attr name="viewportHeight" format="float"/>
-        <!-- The name of this vector drawable -->
+        <!-- The name of this vector drawable. -->
         <attr name="name" />
         <!-- The opacity of the whole vector drawable, as a value between 0
              (completely transparent) and 1 (completely opaque). -->
@@ -6016,64 +6023,64 @@
 
     <!-- Defines the group used in VectorDrawables. -->
     <declare-styleable name="VectorDrawableGroup">
-        <!-- The name of this group -->
+        <!-- The name of this group. -->
         <attr name="name" />
-        <!-- The amount to rotate the group -->
+        <!-- The amount to rotate the group. -->
         <attr name="rotation" />
-        <!-- The X coordinate of the center of rotation of a group -->
+        <!-- The X coordinate of the center of rotation of a group. -->
         <attr name="pivotX" />
-        <!-- The Y coordinate of the center of rotation of a group -->
+        <!-- The Y coordinate of the center of rotation of a group. -->
         <attr name="pivotY" />
-        <!-- The amount to translate the group on X coordinate -->
+        <!-- The amount to translate the group on X coordinate. -->
         <attr name="translateX" format="float"/>
-        <!-- The amount to translate the group on Y coordinate -->
+        <!-- The amount to translate the group on Y coordinate. -->
         <attr name="translateY" format="float"/>
-        <!-- The amount to scale the group on X coordinate -->
+        <!-- The amount to scale the group on X coordinate. -->
         <attr name="scaleX" />
-        <!-- The amount to scale the group on X coordinate -->
+        <!-- The amount to scale the group on X coordinate. -->
         <attr name="scaleY" />
     </declare-styleable>
 
     <!-- Defines the path used in VectorDrawables. -->
     <declare-styleable name="VectorDrawablePath">
-        <!-- The name of this path -->
+        <!-- The name of this path. -->
         <attr name="name" />
-        <!-- The width a path stroke -->
+        <!-- The width a path stroke. -->
         <attr name="strokeWidth" format="float" />
-        <!-- The color to stroke the path if not defined implies no stroke-->
+        <!-- The color to stroke the path if not defined implies no stroke. -->
         <attr name="strokeColor" format="color" />
         <!-- The opacity of a path stroke, as a value between 0 (completely transparent)
-             and 1 (completely opaque) -->
+             and 1 (completely opaque). -->
         <attr name="strokeAlpha" format="float" />
-        <!-- The color to fill the path if not defined implies no fill-->
+        <!-- The color to fill the path if not defined implies no fill. -->
         <attr name="fillColor" format="color" />
         <!-- The alpha of the path fill, as a value between 0 (completely transparent)
-             and 1 (completely opaque)-->
+             and 1 (completely opaque). -->
         <attr name="fillAlpha" format="float" />
-        <!-- The specification of the operations that define the path  -->
+        <!-- The specification of the operations that define the path. -->
         <attr name="pathData" format="string" />
-        <!-- The fraction of the path to trim from the start from 0 to 1 -->
+        <!-- The fraction of the path to trim from the start from 0 to 1. -->
         <attr name="trimPathStart" format="float" />
-        <!-- The fraction of the path to trim from the end from 0 to 1  -->
+        <!-- The fraction of the path to trim from the end from 0 to 1 . -->
         <attr name="trimPathEnd" format="float" />
-        <!-- Shift trim region (allows visible region to include the start and end) from 0 to 1  -->
+        <!-- Shift trim region (allows visible region to include the start and end) from 0 to 1. -->
         <attr name="trimPathOffset" format="float" />
-        <!-- sets the linecap for a stroked path -->
+        <!-- sets the linecap for a stroked path. -->
         <attr name="strokeLineCap" format="enum">
             <enum name="butt" value="0"/>
             <enum name="round" value="1"/>
             <enum name="square" value="2"/>
         </attr>
-        <!-- sets the lineJoin for a stroked path -->
+        <!-- sets the lineJoin for a stroked path. -->
         <attr name="strokeLineJoin" format="enum">
             <enum name="miter" value="0"/>
             <enum name="round" value="1"/>
             <enum name="bevel" value="2"/>
         </attr>
-        <!-- sets the Miter limit for a stroked path -->
+        <!-- sets the Miter limit for a stroked path. -->
         <attr name="strokeMiterLimit" format="float"/>
         <!-- sets the fillType for a path. It is the same as SVG's "fill-rule" properties.
-             For more details, see https://www.w3.org/TR/SVG/painting.html#FillRuleProperty -->
+             For more details, see https://www.w3.org/TR/SVG/painting.html#FillRuleProperty. -->
         <attr name="fillType" format="enum">
             <enum name="nonZero" value="0"/>
             <enum name="evenOdd" value="1"/>
@@ -6082,9 +6089,9 @@
 
     <!-- Defines the clip path used in VectorDrawables. -->
     <declare-styleable name="VectorDrawableClipPath">
-        <!-- The Name of this path -->
+        <!-- The Name of this path. -->
         <attr name="name" />
-        <!-- The specification of the operations that define the path  -->
+        <!-- The specification of the operations that define the path. -->
         <attr name="pathData"/>
     </declare-styleable>
 
@@ -6101,9 +6108,9 @@
 
     <!-- Defines the target used in the AnimatedVectorDrawable. -->
     <declare-styleable name="AnimatedVectorDrawableTarget">
-        <!-- The name of the target path, group or vector drawable -->
+        <!-- The name of the target path, group or vector drawable. -->
         <attr name="name" />
-        <!-- The animation for the target path, group or vector drawable -->
+        <!-- The animation for the target path, group or vector drawable. -->
         <attr name="animation" />
     </declare-styleable>
 
@@ -6282,13 +6289,13 @@
     </declare-styleable>
 
     <declare-styleable name="PathInterpolator">
-        <!-- The x coordinate of the first control point of the cubic Bezier -->
+        <!-- The x coordinate of the first control point of the cubic Bezier. -->
         <attr name="controlX1" format="float" />
-        <!-- The y coordinate of the first control point of the cubic Bezier -->
+        <!-- The y coordinate of the first control point of the cubic Bezier. -->
         <attr name="controlY1" format="float" />
-        <!-- The x coordinate of the second control point of the cubic Bezier -->
+        <!-- The x coordinate of the second control point of the cubic Bezier. -->
         <attr name="controlX2" format="float" />
-        <!-- The y coordinate of the second control point of the cubic Bezier -->
+        <!-- The y coordinate of the second control point of the cubic Bezier. -->
         <attr name="controlY2" format="float" />
         <!-- The control points defined as a path.
              When pathData is defined, then both of the control points of the
@@ -6526,7 +6533,7 @@
         <attr name="value" />
         <attr name="fraction" format="float" />
         <!-- Defines a per-interval interpolator for this keyframe. This interpolator will be used
-             to interpolate between this keyframe and the previous keyframe.-->
+             to interpolate between this keyframe and the previous keyframe. -->
         <attr name="interpolator" />
     </declare-styleable>
 
@@ -6542,7 +6549,7 @@
         <attr name="propertyXName" format="string"/>
         <!-- Name of the property being animated as the Y coordinate of the pathData. -->
         <attr name="propertyYName" format="string"/>
-        <!-- The path used to animate the properties in the ObjectAnimator -->
+        <!-- The path used to animate the properties in the ObjectAnimator. -->
         <attr name="pathData"/>
     </declare-styleable>
 
@@ -6787,8 +6794,8 @@
 
         <!-- If provided, this is the trigger indicating that the searchable activity
             provides suggestions as well.  The value must be a fully-qualified content provider
-            authority (e.g. "com.example.android.apis.SuggestionProvider") and should match the
-            "android:authorities" tag in your content provider's manifest entry.  <i>Optional
+            authority (for example, "com.example.android.apis.SuggestionProvider") and should match
+            the "android:authorities" tag in your content provider's manifest entry.  <i>Optional
             attribute.</i> -->
         <attr name="searchSuggestAuthority" format="string" />
         <!-- If provided, this will be inserted in the suggestions query Uri, after the authority
@@ -6996,12 +7003,12 @@
             <flag name="FUNCTION" value="0x8" />
         </attr>
 
-        <!-- The numeric shortcut key.  This is the shortcut when using a numeric (e.g., 12-key)
-             keyboard. -->
+        <!-- The numeric shortcut key.  This is the shortcut when using a numeric (for example,
+             12-key) keyboard. -->
         <attr name="numericShortcut" format="string" />
 
-        <!-- The numeric modifier key. This is the modifier when using a numeric (e.g., 12-key)
-             keyboard. The values should be kept in sync with KeyEvent -->
+        <!-- The numeric modifier key. This is the modifier when using a numeric (for example,
+             12-key) keyboard. The values should be kept in sync with KeyEvent -->
         <attr name="numericModifiers">
             <flag name="META" value="0x10000" />
             <flag name="CTRL" value="0x1000" />
@@ -7121,13 +7128,13 @@
     </declare-styleable>
 
     <!-- WARNING:  If adding attributes to Preference, make sure it does not conflict
-                   with a View's attributes.  Some subclasses (e.g., EditTextPreference)
+                   with a View's attributes.  Some subclasses (for example, EditTextPreference)
                    proxy all attributes to its EditText widget. -->
     <eat-comment />
 
     <!-- Base attributes available to Preference. -->
     <declare-styleable name="Preference">
-        <!-- The optional icon for the preference -->
+        <!-- The optional icon for the preference. -->
         <attr name="icon" />
         <!-- The key to store the Preference value. -->
         <attr name="key" format="string" />
@@ -7549,16 +7556,19 @@
         <!-- Reference to the wallpaper's thumbnail bitmap. -->
         <attr name="thumbnail" format="reference" />
 
-        <!-- Name of the author and/or source/collection of this component, e.g. Art Collection, Picasso. -->
+        <!-- Name of the author and/or source/collection of this component, for example,
+             Art Collection, Picasso. -->
         <attr name="author" format="reference" />
 
         <!-- Short description of the component's purpose or behavior. -->
         <attr name="description" />
 
-        <!-- Uri that specifies a link for further context of this wallpaper, e.g. http://www.picasso.org. -->
+        <!-- Uri that specifies a link for further context of this wallpaper, for example,
+             http://www.picasso.org. -->
         <attr name="contextUri" format="reference" />
 
-        <!-- Title of the uri that specifies a link for further context of this wallpaper, e.g. Explore collection. -->
+        <!-- Title of the uri that specifies a link for further context of this wallpaper,
+             for example, Explore collection. -->
         <attr name="contextDescription" format="reference" />
 
         <!-- Whether to show any metadata when previewing the wallpaper. If this value is
@@ -7703,7 +7713,7 @@
         <attr name="detailColumn" format="string" />
         <!-- Flag indicating that detail should be built from SocialProvider. -->
         <attr name="detailSocialSummary" format="boolean" />
-        <!-- Resource representing the term "All Contacts" (e.g. "All Friends" or
+        <!-- Resource representing the term "All Contacts" (for example, "All Friends" or
         "All connections"). Optional (Default is "All Contacts"). -->
         <attr name="allContactsName" format="string" />
     </declare-styleable>
@@ -7728,7 +7738,7 @@
         <attr name="targetDescriptions" format="reference" />
 
         <!-- Reference to an array resource that be used to announce the directions with targets around the circle.
-             {@deprecated Removed.}-->
+             {@deprecated Removed.} -->
         <attr name="directionDescriptions" format="reference" />
     </declare-styleable>
 
@@ -7828,7 +7838,7 @@
     <declare-styleable name="ActionBar">
         <!-- The type of navigation to use. -->
         <attr name="navigationMode">
-            <!-- Normal static title text -->
+            <!-- Normal static title text. -->
             <enum name="normal" value="0" />
             <!-- The action bar will use a selection list for navigation. -->
             <enum name="listMode" value="1" />
@@ -7845,9 +7855,9 @@
             <flag name="showCustom" value="0x10" />
             <flag name="disableHome" value="0x20" />
         </attr>
-        <!-- Specifies title text used for navigationMode="normal" -->
+        <!-- Specifies title text used for navigationMode="normal". -->
         <attr name="title" />
-        <!-- Specifies subtitle text used for navigationMode="normal" -->
+        <!-- Specifies subtitle text used for navigationMode="normal". -->
         <attr name="subtitle" format="string" />
         <!-- Specifies a style to use for title text. -->
         <attr name="titleTextStyle" format="reference" />
@@ -7877,7 +7887,7 @@
         <attr name="indeterminateProgressStyle" format="reference" />
         <!-- Specifies the horizontal padding on either end for an embedded progress bar. -->
         <attr name="progressBarPadding" format="dimension" />
-        <!-- Up navigation glyph -->
+        <!-- Up navigation glyph. -->
         <attr name="homeAsUpIndicator" />
         <!-- Specifies padding that should be applied to the left and right sides of
              system-provided items in the bar. -->
@@ -7902,7 +7912,7 @@
         <!-- Minimum inset for content views within a bar when actions from a menu
              are present. Only valid for some themes and configurations. -->
         <attr name="contentInsetEndWithActions" format="dimension" />
-        <!-- Elevation for the action bar itself -->
+        <!-- Elevation for the action bar itself. -->
         <attr name="elevation" />
         <!-- Reference to a theme that should be used to inflate popups
              shown by widgets in the action bar. -->
@@ -7942,23 +7952,23 @@
         <attr name="imeOptions" />
         <!-- The input type to set on the query text field. -->
         <attr name="inputType" />
-        <!-- Close button icon -->
+        <!-- Close button icon. -->
         <attr name="closeIcon" format="reference" />
-        <!-- Go button icon -->
+        <!-- Go button icon. -->
         <attr name="goIcon" format="reference" />
-        <!-- Search icon -->
+        <!-- Search icon. -->
         <attr name="searchIcon" format="reference" />
-        <!-- Search icon displayed as a text field hint -->
+        <!-- Search icon displayed as a text field hint. -->
         <attr name="searchHintIcon" format="reference" />
-        <!-- Voice button icon -->
+        <!-- Voice button icon. -->
         <attr name="voiceIcon" format="reference" />
-        <!-- Commit icon shown in the query suggestion row -->
+        <!-- Commit icon shown in the query suggestion row. -->
         <attr name="commitIcon" format="reference" />
-        <!-- Layout for query suggestion rows -->
+        <!-- Layout for query suggestion rows. -->
         <attr name="suggestionRowLayout" format="reference" />
-        <!-- Background for the section containing the search query -->
+        <!-- Background for the section containing the search query. -->
         <attr name="queryBackground" format="reference" />
-        <!-- Background for the section containing the action (e.g. voice search) -->
+        <!-- Background for the section containing the action (for example, voice search). -->
         <attr name="submitBackground" format="reference" />
     </declare-styleable>
 
@@ -8001,9 +8011,9 @@
         <attr name="thumbTextPadding" format="dimension" />
         <!-- TextAppearance style for text displayed on the switch thumb. -->
         <attr name="switchTextAppearance" format="reference" />
-        <!-- Minimum width for the switch component -->
+        <!-- Minimum width for the switch component. -->
         <attr name="switchMinWidth" format="dimension" />
-        <!-- Minimum space between the switch and caption text -->
+        <!-- Minimum space between the switch and caption text. -->
         <attr name="switchPadding" format="dimension" />
         <!-- Whether to split the track and leave a gap for the thumb drawable. -->
         <attr name="splitTrack" />
@@ -8012,53 +8022,53 @@
     </declare-styleable>
 
     <declare-styleable name="Pointer">
-        <!-- Reference to a pointer icon drawable with STYLE_ARROW -->
+        <!-- Reference to a pointer icon drawable with STYLE_ARROW. -->
         <attr name="pointerIconArrow" format="reference" />
-        <!-- Reference to a pointer icon drawable with STYLE_SPOT_HOVER -->
+        <!-- Reference to a pointer icon drawable with STYLE_SPOT_HOVER. -->
         <attr name="pointerIconSpotHover" format="reference" />
-        <!-- Reference to a pointer icon drawable with STYLE_SPOT_TOUCH -->
+        <!-- Reference to a pointer icon drawable with STYLE_SPOT_TOUCH. -->
         <attr name="pointerIconSpotTouch" format="reference" />
-        <!-- Reference to a pointer icon drawable with STYLE_SPOT_ANCHOR -->
+        <!-- Reference to a pointer icon drawable with STYLE_SPOT_ANCHOR. -->
         <attr name="pointerIconSpotAnchor" format="reference" />
-        <!-- Reference to a pointer drawable with STYLE_CONTEXT_MENU -->
+        <!-- Reference to a pointer drawable with STYLE_CONTEXT_MENU. -->
         <attr name="pointerIconContextMenu" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_HAND -->
+        <!-- Reference to a pointer drawable with STYLE_HAND. -->
         <attr name="pointerIconHand" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_HELP -->
+        <!-- Reference to a pointer drawable with STYLE_HELP. -->
         <attr name="pointerIconHelp" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_WAIT -->
+        <!-- Reference to a pointer drawable with STYLE_WAIT. -->
         <attr name="pointerIconWait" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_CELL -->
+        <!-- Reference to a pointer drawable with STYLE_CELL. -->
         <attr name="pointerIconCell" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_CROSSHAIR -->
+        <!-- Reference to a pointer drawable with STYLE_CROSSHAIR. -->
         <attr name="pointerIconCrosshair" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_TEXT -->
+        <!-- Reference to a pointer drawable with STYLE_TEXT. -->
         <attr name="pointerIconText" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_VERTICAL_TEXT -->
+        <!-- Reference to a pointer drawable with STYLE_VERTICAL_TEXT. -->
         <attr name="pointerIconVerticalText" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_ALIAS -->
+        <!-- Reference to a pointer drawable with STYLE_ALIAS. -->
         <attr name="pointerIconAlias" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_COPY -->
+        <!-- Reference to a pointer drawable with STYLE_COPY. -->
         <attr name="pointerIconCopy" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_NODROP -->
+        <!-- Reference to a pointer drawable with STYLE_NODROP. -->
         <attr name="pointerIconNodrop" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_ALL_SCROLL -->
+        <!-- Reference to a pointer drawable with STYLE_ALL_SCROLL. -->
         <attr name="pointerIconAllScroll" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_HORIZONTAL_DOUBLE_ARROW -->
+        <!-- Reference to a pointer drawable with STYLE_HORIZONTAL_DOUBLE_ARROW. -->
         <attr name="pointerIconHorizontalDoubleArrow" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_VERTICAL_DOUBLE_ARROW -->
+        <!-- Reference to a pointer drawable with STYLE_VERTICAL_DOUBLE_ARROW. -->
         <attr name="pointerIconVerticalDoubleArrow" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW -->
+        <!-- Reference to a pointer drawable with STYLE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW. -->
         <attr name="pointerIconTopRightDiagonalDoubleArrow" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW -->
+        <!-- Reference to a pointer drawable with STYLE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW. -->
         <attr name="pointerIconTopLeftDiagonalDoubleArrow" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_ZOOM_IN -->
+        <!-- Reference to a pointer drawable with STYLE_ZOOM_IN. -->
         <attr name="pointerIconZoomIn" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_ZOOM_OUT -->
+        <!-- Reference to a pointer drawable with STYLE_ZOOM_OUT. -->
         <attr name="pointerIconZoomOut" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_GRAB -->
+        <!-- Reference to a pointer drawable with STYLE_GRAB. -->
         <attr name="pointerIconGrab" format="reference"/>
-        <!-- Reference to a pointer drawable with STYLE_GRABBING -->
+        <!-- Reference to a pointer drawable with STYLE_GRABBING. -->
         <attr name="pointerIconGrabbing" format="reference"/>
     </declare-styleable>
 
@@ -8072,22 +8082,22 @@
     </declare-styleable>
 
     <declare-styleable name="Storage">
-        <!-- path to mount point for the storage -->
+        <!-- path to mount point for the storage. -->
         <attr name="mountPoint" format="string" />
-        <!-- user visible description of the storage -->
+        <!-- user visible description of the storage. -->
         <attr name="storageDescription" format="string" />
-        <!-- true if the storage is the primary external storage -->
+        <!-- true if the storage is the primary external storage. -->
         <attr name="primary" format="boolean" />
-        <!-- true if the storage is removable -->
+        <!-- true if the storage is removable. -->
         <attr name="removable" format="boolean" />
-        <!-- true if the storage is emulated via the FUSE sdcard daemon -->
+        <!-- true if the storage is emulated via the FUSE sdcard daemon. -->
         <attr name="emulated" format="boolean" />
         <!-- number of megabytes of storage MTP should reserve for free storage
-             (used for emulated storage that is shared with system's data partition) -->
+             (used for emulated storage that is shared with system's data partition). -->
         <attr name="mtpReserve" format="integer" />
-        <!-- true if the storage can be shared via USB mass storage -->
+        <!-- true if the storage can be shared via USB mass storage. -->
         <attr name="allowMassStorage" format="boolean" />
-        <!-- maximum file size for the volume in megabytes, zero or unspecified if it is unbounded -->
+        <!-- maximum file size for the volume in megabytes, zero or unspecified if it is unbounded. -->
         <attr name="maxFileSize" format="integer" />
     </declare-styleable>
 
@@ -8114,9 +8124,9 @@
     <declare-styleable name="SeekBarPreference">
         <attr name="layout" />
         <!-- Attribute indicating whether the slider within this preference can be adjusted, that is
-        pressing left/right keys when this preference is focused will move the slider accordingly (e.g.
-        inline adjustable preferences). False, if the slider within the preference is read-only and
-        cannot be adjusted. By default, the seekbar is adjustable. -->
+        pressing left/right keys when this preference is focused will move the slider accordingly
+        (for example, inline adjustable preferences). False, if the slider within the preference is
+        read-only and cannot be adjusted. By default, the seekbar is adjustable. -->
         <attr name="adjustable" format="boolean" />
         <!-- Flag indicating whether the TextView next to the seekbar that shows the current seekbar value will be
         displayed. If true, the view is VISIBLE; if false, the view will be GONE. By default, this view is VISIBLE. -->
@@ -8208,7 +8218,7 @@
     <declare-styleable name="PagedView">
         <!-- The space between adjacent pages of the PagedView. -->
         <attr name="pageSpacing" format="dimension" />
-        <!-- The padding for the scroll indicator area -->
+        <!-- The padding for the scroll indicator area. -->
         <attr name="scrollIndicatorPaddingLeft" format="dimension" />
         <attr name="scrollIndicatorPaddingRight" format="dimension" />
     </declare-styleable>
@@ -8473,7 +8483,7 @@
 
     <!-- Describes an item of a GradientColor. Minimally need 2 items to define the gradient
          Colors defined in <item> override the simple color attributes such as
-         "startColor / centerColor / endColor" are ignored -->
+         "startColor / centerColor / endColor" are ignored. -->
     <declare-styleable name="GradientColorItem">
         <!-- The offset (or ratio) of this current color item inside the gradient.
              The value is only meaningful when it is between 0 and 1. -->
@@ -8517,7 +8527,7 @@
         <attr name="fontWeight" format="integer" />
     </declare-styleable>
 
-    <!-- Attributes that are read when parsing a <fontfamily> tag, -->
+    <!-- Attributes that are read when parsing a <fontfamily> tag. -->
     <declare-styleable name="FontFamily">
         <attr name="fontProviderAuthority" format="string" />
         <attr name="fontProviderQuery" format="string" />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 76f4a76..deacc24b 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1534,6 +1534,14 @@
              of Android higher than the number given here, the permission will not
              be requested.  -->
         <attr name="maxSdkVersion" format="integer" />
+        <!-- Optional: the system must support this feature for the permission to be
+        requested.  If it doesn't support the feature, it will be as if the manifest didn't
+        request it at all. -->
+        <attr name="requiredFeature" format="string" />
+        <!-- Optional: the system must NOT support this feature for the permission to be
+        requested.  If it does support the feature, it will be as if the manifest didn't
+        request it at all. -->
+        <attr name="requiredNotFeature" format="string" />
     </declare-styleable>
 
     <!-- The <code>uses-configuration</code> tag specifies
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 35aff80..ab2e090 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -239,6 +239,7 @@
         <item>"mobile,0,0,0,-1,true"</item>
         <item>"mobile_mms,2,0,2,60000,true"</item>
         <item>"mobile_supl,3,0,2,60000,true"</item>
+        <item>"mobile_dun,4,0,2,60000,true"</item>
         <item>"mobile_hipri,5,0,3,60000,true"</item>
         <item>"mobile_fota,10,0,2,60000,true"</item>
         <item>"mobile_ims,11,0,2,60000,true"</item>
@@ -1273,19 +1274,6 @@
          config_enableFusedLocationOverlay is false. -->
     <string name="config_fusedLocationProviderPackageName" translatable="false">com.android.location.fused</string>
 
-    <!-- A list of potential packages, in priority order, that may contain a
-         network recommendation provider. A network recommendation provider must:
-             * Be granted the SCORE_NETWORKS permission.
-             * Include a Service for the android.net.scoring.RECOMMEND_NETWORKS action
-               protected by the BIND_NETWORK_RECOMMENDATION_SERVICE permission.
-
-         This may be empty if network scoring and recommending isn't supported.
-         -->
-    <string-array name="config_networkRecommendationPackageNames" translatable="false">
-        <!-- The standard AOSP network recommendation provider -->
-        <item>com.android.networkrecommendation</item>
-    </string-array>
-
     <!-- The package name of the default network recommendation app.
          A network recommendation provider must:
              * Be granted the SCORE_NETWORKS permission.
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 01737e7..15764a9 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2797,6 +2797,10 @@
         <public name="fontProviderAuthority" />
         <public name="fontProviderQuery" />
         <public name="autoFillMode" />
+        <public name="primaryContentAlpha" />
+        <public name="secondaryContentAlpha" />
+        <public name="requiredFeature" />
+        <public name="requiredNotFeature" />
     </public-group>
 
     <public-group type="style" first-id="0x010302e0">
@@ -2806,9 +2810,6 @@
         <public name="textAssist" />
     </public-group>
 
-    <public type="attr" name="primaryContentAlpha" />
-    <public type="attr" name="secondaryContentAlpha" />
-
 
   <!-- ===============================================================
        DO NOT ADD UN-GROUPED ITEMS HERE
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b0c532c..ea06664 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -587,6 +587,48 @@
     <!-- Text shown in place of notification contents when the notification is hidden by policy on a secure lockscreen -->
     <string name="notification_hidden_by_policy_text">Contents hidden by policy</string>
 
+    <!-- Text shown when viewing channel settings for notifications related to the virtual keyboard -->
+    <string name="notification_channel_virtual_keyboard">Virtual keyboard</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to the hardware keyboard -->
+    <string name="notification_channel_physical_keyboard">Physical keyboard</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to security -->
+    <string name="notification_channel_security">Security</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to car mode -->
+    <string name="notification_channel_car_mode">Car mode</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to account status -->
+    <string name="notification_channel_account">Account status</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to developers -->
+    <string name="notification_channel_developer">Developer messages</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to system updates -->
+    <string name="notification_channel_updates">Updates</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to network status -->
+    <string name="notification_channel_network_status">Network status</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to network alerts -->
+    <string name="notification_channel_network_alerts">Network alerts</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to vpn status -->
+    <string name="notification_channel_vpn">VPN status</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to remote device administration -->
+    <string name="notification_channel_device_admin">Device administration</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to important alerts -->
+    <string name="notification_channel_alerts">Alerts</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to being in retail mode -->
+    <string name="notification_channel_retail_mode">Retail demo</string>
+
+    <!-- Text shown when viewing channel settings for notifications related to a usb connection -->
+    <string name="notification_channel_usb">USB connection</string>
+
     <!-- Displayed to the user to tell them that they have started up the phone in "safe mode" -->
     <string name="safeMode">Safe mode</string>
 
@@ -728,6 +770,11 @@
         the call to a different number or abort the call altogether.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_answerPhoneCalls">answer phone calls</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_answerPhoneCalls">Allows the app to answer an incoming phone call.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_receiveSms">receive text messages (SMS)</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_receiveSms">Allows the app to receive and process SMS
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6995d9a..3ba6a27 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2785,7 +2785,6 @@
   <java-symbol type="layout" name="notification_template_material_ambient" />
 
   <!-- Network Recommendation -->
-  <java-symbol type="array" name="config_networkRecommendationPackageNames" />
   <java-symbol type="string" name="config_defaultNetworkRecommendationProviderPackage" />
 
   <!-- Whether allow 3rd party apps on internal storage. -->
@@ -2888,4 +2887,21 @@
 
   <!-- Colon separated list of package names that should be granted Notification Listener access -->
   <java-symbol type="string" name="config_defaultListenerAccessPackages" />
+
+  <!-- system notification channels -->
+  <java-symbol type="string" name="notification_channel_virtual_keyboard" />
+  <java-symbol type="string" name="notification_channel_physical_keyboard" />
+  <java-symbol type="string" name="notification_channel_security" />
+  <java-symbol type="string" name="notification_channel_car_mode" />
+  <java-symbol type="string" name="notification_channel_account" />
+  <java-symbol type="string" name="notification_channel_developer" />
+  <java-symbol type="string" name="notification_channel_updates" />
+  <java-symbol type="string" name="notification_channel_network_status" />
+  <java-symbol type="string" name="notification_channel_network_alerts" />
+  <java-symbol type="string" name="notification_channel_vpn" />
+  <java-symbol type="string" name="notification_channel_device_admin" />
+  <java-symbol type="string" name="notification_channel_alerts" />
+  <java-symbol type="string" name="notification_channel_retail_mode" />
+  <java-symbol type="string" name="notification_channel_usb" />
+
 </resources>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 91ce7a4..7b8c229 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1357,6 +1357,9 @@
             </intent-filter>
         </service>
 
+        <service android:name="android.content.CrossUserContentService"
+                android:exported="true" />
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/graphics/tests/graphicstests/res/color/color1.xml b/core/tests/coretests/res/color/color1.xml
similarity index 100%
rename from graphics/tests/graphicstests/res/color/color1.xml
rename to core/tests/coretests/res/color/color1.xml
diff --git a/graphics/tests/graphicstests/res/color/color_no_default.xml b/core/tests/coretests/res/color/color_no_default.xml
similarity index 100%
rename from graphics/tests/graphicstests/res/color/color_no_default.xml
rename to core/tests/coretests/res/color/color_no_default.xml
diff --git a/graphics/tests/graphicstests/res/drawable-nodpi/landscape.png b/core/tests/coretests/res/drawable-nodpi/landscape.png
similarity index 100%
rename from graphics/tests/graphicstests/res/drawable-nodpi/landscape.png
rename to core/tests/coretests/res/drawable-nodpi/landscape.png
Binary files differ
diff --git a/graphics/tests/graphicstests/res/drawable/test128x96.png b/core/tests/coretests/res/drawable/test128x96.png
similarity index 100%
rename from graphics/tests/graphicstests/res/drawable/test128x96.png
rename to core/tests/coretests/res/drawable/test128x96.png
Binary files differ
diff --git a/graphics/tests/graphicstests/res/drawable/test16x12.png b/core/tests/coretests/res/drawable/test16x12.png
similarity index 100%
rename from graphics/tests/graphicstests/res/drawable/test16x12.png
rename to core/tests/coretests/res/drawable/test16x12.png
Binary files differ
diff --git a/graphics/tests/graphicstests/res/drawable/test256x192.png b/core/tests/coretests/res/drawable/test256x192.png
similarity index 100%
rename from graphics/tests/graphicstests/res/drawable/test256x192.png
rename to core/tests/coretests/res/drawable/test256x192.png
Binary files differ
diff --git a/graphics/tests/graphicstests/res/drawable/test320x240.png b/core/tests/coretests/res/drawable/test320x240.png
similarity index 100%
rename from graphics/tests/graphicstests/res/drawable/test320x240.png
rename to core/tests/coretests/res/drawable/test320x240.png
Binary files differ
diff --git a/graphics/tests/graphicstests/res/drawable/test32x24.png b/core/tests/coretests/res/drawable/test32x24.png
similarity index 100%
rename from graphics/tests/graphicstests/res/drawable/test32x24.png
rename to core/tests/coretests/res/drawable/test32x24.png
Binary files differ
diff --git a/graphics/tests/graphicstests/res/drawable/test64x48.png b/core/tests/coretests/res/drawable/test64x48.png
similarity index 100%
rename from graphics/tests/graphicstests/res/drawable/test64x48.png
rename to core/tests/coretests/res/drawable/test64x48.png
Binary files differ
diff --git a/core/tests/coretests/res/values/colors.xml b/core/tests/coretests/res/values/colors.xml
index f881660..f01af84 100644
--- a/core/tests/coretests/res/values/colors.xml
+++ b/core/tests/coretests/res/values/colors.xml
@@ -23,4 +23,7 @@
     <drawable name="blue">#ff0000ff</drawable>
     <drawable name="green">#ff00ff00</drawable>
     <drawable name="yellow">#ffffff00</drawable>
+    <color name="testcolor1">#ff00ff00</color>
+    <color name="testcolor2">#ffff0000</color>
+    <color name="failColor">#ff0000ff</color>
 </resources>
diff --git a/core/tests/coretests/src/android/app/activity/LocalProvider.java b/core/tests/coretests/src/android/app/activity/LocalProvider.java
index d6a10c2..b7a63ce 100644
--- a/core/tests/coretests/src/android/app/activity/LocalProvider.java
+++ b/core/tests/coretests/src/android/app/activity/LocalProvider.java
@@ -29,6 +29,19 @@
 public class LocalProvider extends ContentProvider {
     private static final String TAG = "LocalProvider";
 
+    private static final String AUTHORITY = "com.android.frameworks.coretests.LocalProvider";
+    private static final String TABLE_DATA_NAME = "data";
+    public static final Uri TABLE_DATA_URI =
+            Uri.parse("content://" + AUTHORITY + "/" + TABLE_DATA_NAME);
+
+    public static final String COLUMN_TEXT_NAME = "text";
+    public static final String COLUMN_INTEGER_NAME = "integer";
+
+    public static final String TEXT1 = "first data";
+    public static final String TEXT2 = "second data";
+    public static final int INTEGER1 = 100;
+    public static final int INTEGER2 = 101;
+
     private SQLiteOpenHelper mOpenHelper;
 
     private static final int DATA = 1;
@@ -51,13 +64,20 @@
 
         @Override
         public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE data (" +
+            db.execSQL("CREATE TABLE " + TABLE_DATA_NAME + " (" +
                        "_id INTEGER PRIMARY KEY," +
-                       "text TEXT, " +
-                       "integer INTEGER);");
+                       COLUMN_TEXT_NAME + " TEXT, " +
+                       COLUMN_INTEGER_NAME + " INTEGER);");
 
             // insert alarms
-            db.execSQL("INSERT INTO data (text, integer) VALUES ('first data', 100);");
+            db.execSQL(getInsertCommand(TEXT1, INTEGER1));
+            db.execSQL(getInsertCommand(TEXT2, INTEGER2));
+        }
+
+        private String getInsertCommand(String textValue, int integerValue) {
+            return "INSERT INTO " + TABLE_DATA_NAME
+                    + " (" + COLUMN_TEXT_NAME + ", " + COLUMN_INTEGER_NAME + ") "
+                    + "VALUES ('" + textValue + "', " + integerValue + ");";
         }
 
         @Override
@@ -74,6 +94,10 @@
     public LocalProvider() {
     }
 
+    static public Uri getTableDataUriForRow(int rowId) {
+        return Uri.parse("content://" + AUTHORITY + "/" + TABLE_DATA_NAME + "/" + rowId);
+    }
+
     @Override
     public boolean onCreate() {
         mOpenHelper = new DatabaseHelper(getContext());
diff --git a/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
new file mode 100644
index 0000000..5f6f62a
--- /dev/null
+++ b/core/tests/coretests/src/android/content/AbstractCrossUserContentResolverTest.java
@@ -0,0 +1,178 @@
+/*
+ * 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 android.content;
+
+
+import static org.junit.Assert.fail;
+
+import android.app.ActivityManager;
+import android.app.activity.LocalProvider;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+abstract class AbstractCrossUserContentResolverTest {
+    private final static int TIMEOUT_SERVICE_CONNECTION_SEC = 4;
+    private final static int TIMEOUT_CONTENT_CHANGE_SEC = 4;
+
+    private Context mContext;
+    protected UserManager mUm;
+    private int mCrossUserId = -1;
+    private CrossUserContentServiceConnection mServiceConnection;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getContext();
+        mUm = UserManager.get(mContext);
+        final UserInfo userInfo = createUser();
+        mCrossUserId = userInfo.id;
+        final PackageManager pm = mContext.getPackageManager();
+        pm.installExistingPackageAsUser(mContext.getPackageName(), mCrossUserId);
+        ActivityManager.getService().startUserInBackground(mCrossUserId);
+
+        final CountDownLatch connectionLatch = new CountDownLatch(1);
+        mServiceConnection = new CrossUserContentServiceConnection(connectionLatch);
+        mContext.bindServiceAsUser(
+                new Intent(mContext, CrossUserContentService.class),
+                mServiceConnection,
+                Context.BIND_AUTO_CREATE,
+                UserHandle.of(mCrossUserId));
+        if (!connectionLatch.await(TIMEOUT_SERVICE_CONNECTION_SEC, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for service connection to establish");
+        }
+    }
+
+    protected abstract UserInfo createUser() throws RemoteException ;
+
+    @After
+    public void tearDown() throws Exception {
+        if (mCrossUserId != -1) {
+            mUm.removeUser(mCrossUserId);
+        }
+        if (mServiceConnection != null) {
+            mContext.unbindService(mServiceConnection);
+        }
+    }
+
+    /**
+     * Register an observer for an URI in another user and verify that it receives
+     * onChange callback when data at the URI changes.
+     */
+    @Test
+    public void testRegisterContentObserver() throws Exception {
+        Context crossUserContext = null;
+        String packageName = null;
+        try {
+            packageName = InstrumentationRegistry.getContext().getPackageName();
+            crossUserContext =
+                    InstrumentationRegistry.getContext().createPackageContextAsUser(
+                            packageName, 0 /* flags */, UserHandle.of(mCrossUserId));
+        } catch (NameNotFoundException e) {
+            fail("Couldn't find package " + packageName + " in u" + mCrossUserId);
+        }
+
+        final CountDownLatch updateLatch = new CountDownLatch(1);
+        final Uri uriToUpdate = LocalProvider.getTableDataUriForRow(2);
+        final TestContentObserver observer = new TestContentObserver(updateLatch,
+                uriToUpdate, mCrossUserId);
+        crossUserContext.getContentResolver().registerContentObserver(
+                LocalProvider.TABLE_DATA_URI, true, observer, mCrossUserId);
+        mServiceConnection.getService().updateContent(uriToUpdate, "New Text", 42);
+        if (!updateLatch.await(TIMEOUT_CONTENT_CHANGE_SEC, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for the content change callback");
+        }
+    }
+
+    /**
+     * Register an observer for an URI in the current user and verify that another user can
+     * notify changes for this URI.
+     */
+    @Test
+    public void testNotifyChange() throws Exception {
+        final CountDownLatch notifyLatch = new CountDownLatch(1);
+        final Uri notifyUri = LocalProvider.TABLE_DATA_URI;
+        final TestContentObserver observer = new TestContentObserver(notifyLatch,
+                notifyUri, UserHandle.myUserId());
+        mContext.getContentResolver().registerContentObserver(notifyUri, true, observer);
+        mServiceConnection.getService().notifyForUriAsUser(notifyUri, UserHandle.myUserId());
+        if (!notifyLatch.await(TIMEOUT_CONTENT_CHANGE_SEC, TimeUnit.SECONDS)) {
+            fail("Timed out waiting for the notify callback");
+        }
+    }
+
+    private static final class CrossUserContentServiceConnection implements ServiceConnection {
+        private ICrossUserContentService mService;
+        private final CountDownLatch mLatch;
+
+        public CrossUserContentServiceConnection(CountDownLatch latch) {
+            mLatch = latch;
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            mService = ICrossUserContentService.Stub.asInterface(service);
+            mLatch.countDown();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+
+        public ICrossUserContentService getService() {
+            return mService;
+        }
+    }
+
+    private static final class TestContentObserver extends ContentObserver {
+        private final CountDownLatch mLatch;
+        private final Uri mExpectedUri;
+        private final int mExpectedUserId;
+
+        public TestContentObserver(CountDownLatch latch, Uri exptectedUri, int expectedUserId) {
+            super(null);
+            mLatch = latch;
+            mExpectedUri = exptectedUri;
+            mExpectedUserId = expectedUserId;
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri, int userId) {
+            if (mExpectedUri.equals(uri) && mExpectedUserId == userId) {
+                mLatch.countDown();
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/content/CrossUserContentService.java b/core/tests/coretests/src/android/content/CrossUserContentService.java
new file mode 100644
index 0000000..9cbe549
--- /dev/null
+++ b/core/tests/coretests/src/android/content/CrossUserContentService.java
@@ -0,0 +1,45 @@
+/*
+ * 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 android.content;
+
+import android.app.Service;
+import android.app.activity.LocalProvider;
+import android.net.Uri;
+import android.os.IBinder;
+
+public class CrossUserContentService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mLocalService.asBinder();
+    }
+
+    private ICrossUserContentService mLocalService = new ICrossUserContentService.Stub() {
+        @Override
+        public void updateContent(Uri uri, String key, int value) {
+            final ContentValues values = new ContentValues();
+            values.put(LocalProvider.COLUMN_TEXT_NAME, key);
+            values.put(LocalProvider.COLUMN_INTEGER_NAME, value);
+            getContentResolver().update(uri, values, null, null);
+        }
+
+        @Override
+        public void notifyForUriAsUser(Uri uri, int userId) {
+            getContentResolver().notifyChange(uri, null, false, userId);
+        }
+    };
+}
\ No newline at end of file
diff --git a/media/java/android/media/ICasListener.aidl b/core/tests/coretests/src/android/content/ICrossUserContentService.aidl
similarity index 71%
rename from media/java/android/media/ICasListener.aidl
rename to core/tests/coretests/src/android/content/ICrossUserContentService.aidl
index 01a5abc..2c5cde4 100644
--- a/media/java/android/media/ICasListener.aidl
+++ b/core/tests/coretests/src/android/content/ICrossUserContentService.aidl
@@ -11,12 +11,14 @@
  * 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.
+ * limitations under the License
  */
 
-package android.media;
+package android.content;
 
-/** @hide */
-interface ICasListener {
-    void onEvent(int event, int arg, in @nullable byte[] data);
+import android.net.Uri;
+
+interface ICrossUserContentService {
+    void updateContent(in Uri uri, String key, int value);
+    void notifyForUriAsUser(in Uri uri, int userId);
 }
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java b/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
new file mode 100644
index 0000000..4856ecd
--- /dev/null
+++ b/core/tests/coretests/src/android/content/ManagedUserContentResolverTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 android.content;
+
+import android.content.pm.UserInfo;
+import android.os.RemoteException;
+import android.os.UserHandle;
+
+/**
+ * To run the tests, use
+ *
+ * runtest -c android.content.ManagedUserContentResolverTest frameworks-core
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksCoreTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+ * Run: adb shell am instrument -e class android.content.ManagedUserContentResolverTest -w \
+ *     com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
+ */
+public class ManagedUserContentResolverTest extends AbstractCrossUserContentResolverTest {
+    @Override
+    protected UserInfo createUser() throws RemoteException {
+        return mUm.createProfileForUser("Managed user",
+                UserInfo.FLAG_MANAGED_PROFILE, UserHandle.myUserId());
+    }
+}
diff --git a/core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java b/core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java
new file mode 100644
index 0000000..7a6e614
--- /dev/null
+++ b/core/tests/coretests/src/android/content/SecondaryUserContentResolverTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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 android.content;
+
+import android.content.pm.UserInfo;
+import android.os.RemoteException;
+
+/**
+ * To run the tests, use
+ *
+ * runtest -c android.content.SecondaryUserContentResolverTest frameworks-core
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksCoreTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
+ * Run: adb shell am instrument -e class android.content.SecondaryUserContentResolverTest -w \
+ *     com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
+ */
+public class SecondaryUserContentResolverTest extends AbstractCrossUserContentResolverTest {
+    @Override
+    protected UserInfo createUser() throws RemoteException {
+        return mUm.createUser("Secondary user", 0);
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java b/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
index e5a92bf..5dd3c2c 100644
--- a/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
+++ b/core/tests/coretests/src/android/content/pm/ParceledListSliceTest.java
@@ -91,6 +91,28 @@
         }
     }
 
+    public void testStringList() throws Exception {
+        final int objectCount = 400;
+        List<String> list = new ArrayList<String>();
+        for (long i = 0; i < objectCount; i++) {
+            list.add(Long.toString(i * (6 - i)));
+        }
+
+        StringParceledListSlice slice;
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.writeParcelable(new StringParceledListSlice(list), 0);
+            parcel.setDataPosition(0);
+            slice = parcel.readParcelable(getClass().getClassLoader());
+        } finally {
+            parcel.recycle();
+        }
+
+        assertNotNull(slice);
+        assertNotNull(slice.getList());
+        assertEquals(list, slice.getList());
+    }
+
     /**
      * Test that only homogeneous elements may be unparceled.
      */
diff --git a/graphics/tests/graphicstests/src/android/graphics/BitmapFactoryTest.java b/core/tests/coretests/src/android/graphics/BitmapFactoryTest.java
similarity index 99%
rename from graphics/tests/graphicstests/src/android/graphics/BitmapFactoryTest.java
rename to core/tests/coretests/src/android/graphics/BitmapFactoryTest.java
index 09820ef..e9e2a4d 100644
--- a/graphics/tests/graphicstests/src/android/graphics/BitmapFactoryTest.java
+++ b/core/tests/coretests/src/android/graphics/BitmapFactoryTest.java
@@ -19,11 +19,11 @@
 import android.os.ParcelFileDescriptor;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import junit.framework.TestCase;
+
 import java.io.ByteArrayOutputStream;
 import java.io.FileDescriptor;
 
-import junit.framework.TestCase;
-
 
 public class BitmapFactoryTest extends TestCase {
 
diff --git a/graphics/tests/graphicstests/src/android/graphics/BitmapTest.java b/core/tests/coretests/src/android/graphics/BitmapTest.java
similarity index 91%
rename from graphics/tests/graphicstests/src/android/graphics/BitmapTest.java
rename to core/tests/coretests/src/android/graphics/BitmapTest.java
index 685a998..3666ddd 100644
--- a/graphics/tests/graphicstests/src/android/graphics/BitmapTest.java
+++ b/core/tests/coretests/src/android/graphics/BitmapTest.java
@@ -17,6 +17,7 @@
 package android.graphics;
 
 import android.test.suitebuilder.annotation.SmallTest;
+
 import junit.framework.TestCase;
 
 
@@ -38,11 +39,11 @@
 
         assertEquals("rowbytes", 400, bm1.getRowBytes());
         assertEquals("rowbytes", 200, bm2.getRowBytes());
-        assertEquals("rowbytes", 200, bm3.getRowBytes());
-        
+        assertEquals("rowbytes", 400, bm3.getRowBytes());
+
         assertEquals("byteCount", 80000, bm1.getByteCount());
         assertEquals("byteCount", 40000, bm2.getByteCount());
-        assertEquals("byteCount", 40000, bm3.getByteCount());
+        assertEquals("byteCount", 80000, bm3.getByteCount());
 
         assertEquals("height", 200, bm1.getHeight());
         assertEquals("height", 200, bm2.getHeight());
@@ -51,10 +52,10 @@
         assertTrue("hasAlpha", bm1.hasAlpha());
         assertFalse("hasAlpha", bm2.hasAlpha());
         assertTrue("hasAlpha", bm3.hasAlpha());
-        
+
         assertTrue("getConfig", bm1.getConfig() == Bitmap.Config.ARGB_8888);
         assertTrue("getConfig", bm2.getConfig() == Bitmap.Config.RGB_565);
-        assertTrue("getConfig", bm3.getConfig() == Bitmap.Config.ARGB_4444);
+        assertTrue("getConfig", bm3.getConfig() == Bitmap.Config.ARGB_8888);
     }
 
     @SmallTest
@@ -181,12 +182,12 @@
         for (int i = 0; i < 256; i++) {
             colors[i] = (i << 24) | (0xFF << 16) | (0x80 << 8) | 0;
         }
-        
+
         Bitmap.Config config = Bitmap.Config.ARGB_8888;
 
         // create a bitmap with the color array specified
         Bitmap bm1 = Bitmap.createBitmap(colors, 16, 16, config);
-        
+
         // create a bitmap with no colors, but then call setPixels
         Bitmap bm2 = Bitmap.createBitmap(16, 16, config);
         bm2.setPixels(colors, 0, 16, 0, 0, 16, 16);
@@ -197,32 +198,32 @@
             int c0 = colors[i];
             int c1 = bm1.getPixel(i % 16, i / 16);
             int c2 = bm2.getPixel(i % 16, i / 16);
-            
+
             // these two should always be identical
             assertEquals("getPixel", c1, c2);
-            
+
             // comparing the original (c0) with the returned color is tricky,
             // since it gets premultiplied during the set(), and unpremultiplied
             // by the get().
             int a0 = Color.alpha(c0);
             int a1 = Color.alpha(c1);
             assertEquals("alpha", a0, a1);
-            
+
             int r0 = Color.red(c0);
             int r1 = Color.red(c1);
             int rr = computePrePostMul(a0, r0);
             assertTrue("red", Math.abs(rr - r1) <= tolerance);
-            
+
             int g0 = Color.green(c0);
             int g1 = Color.green(c1);
             int gg = computePrePostMul(a0, g0);
             assertTrue("green", Math.abs(gg - g1) <= tolerance);
-            
+
             int b0 = Color.blue(c0);
             int b1 = Color.blue(c1);
             int bb = computePrePostMul(a0, b0);
             assertTrue("blue", Math.abs(bb - b1) <= tolerance);
-            
+
             if (false) {
                 int cc = Color.argb(a0, rr, gg, bb);
                 android.util.Log.d("skia", "original " + Integer.toHexString(c0) +
@@ -231,4 +232,16 @@
             }
         }
     }
+
+    @SmallTest
+    public void testCreateHardwareBitmapFromGraphicBuffer() {
+        GraphicBuffer buffer = GraphicBuffer.create(10, 10, PixelFormat.RGBA_8888,
+                GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_SOFTWARE_MASK);
+        Canvas canvas = buffer.lockCanvas();
+        canvas.drawColor(Color.YELLOW);
+        buffer.unlockCanvasAndPost(canvas);
+        Bitmap hardwareBitmap = Bitmap.createHardwareBitmap(buffer);
+        assertTrue(hardwareBitmap.isPremultiplied());
+        assertFalse(hardwareBitmap.isMutable());
+    }
 }
diff --git a/graphics/tests/graphicstests/src/android/graphics/ColorStateListTest.java b/core/tests/coretests/src/android/graphics/ColorStateListTest.java
similarity index 97%
rename from graphics/tests/graphicstests/src/android/graphics/ColorStateListTest.java
rename to core/tests/coretests/src/android/graphics/ColorStateListTest.java
index eb1025c..374d142 100644
--- a/graphics/tests/graphicstests/src/android/graphics/ColorStateListTest.java
+++ b/core/tests/coretests/src/android/graphics/ColorStateListTest.java
@@ -16,13 +16,13 @@
 
 package android.graphics;
 
-import com.android.frameworks.graphicstests.R;
-
-import android.content.res.Resources;
 import android.content.res.ColorStateList;
+import android.content.res.Resources;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.frameworks.coretests.R;
+
 /**
  * Tests of {@link android.graphics.ColorStateList}
  */
diff --git a/graphics/tests/graphicstests/src/android/graphics/GraphicsPerformanceTests.java b/core/tests/coretests/src/android/graphics/GraphicsPerformanceTests.java
similarity index 98%
rename from graphics/tests/graphicstests/src/android/graphics/GraphicsPerformanceTests.java
rename to core/tests/coretests/src/android/graphics/GraphicsPerformanceTests.java
index f60ac7b..164c1aa 100644
--- a/graphics/tests/graphicstests/src/android/graphics/GraphicsPerformanceTests.java
+++ b/core/tests/coretests/src/android/graphics/GraphicsPerformanceTests.java
@@ -16,19 +16,15 @@
 
 package android.graphics;
 
-import junit.framework.Assert;
 import android.content.Context;
 import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.test.AndroidTestCase;
 import android.test.PerformanceTestCase;
 import android.test.suitebuilder.annotation.Suppress;
-import android.util.Log;
 
-import com.android.frameworks.graphicstests.R;
+import com.android.frameworks.coretests.R;
+
+import junit.framework.Assert;
 
 /**
  * Graphics Performance Tests
diff --git a/graphics/tests/graphicstests/src/android/graphics/GraphicsTests.java b/core/tests/coretests/src/android/graphics/GraphicsTests.java
similarity index 100%
rename from graphics/tests/graphicstests/src/android/graphics/GraphicsTests.java
rename to core/tests/coretests/src/android/graphics/GraphicsTests.java
diff --git a/core/tests/coretests/src/android/graphics/PaintTest.java b/core/tests/coretests/src/android/graphics/PaintTest.java
index 2a3d463..5811ca0 100644
--- a/core/tests/coretests/src/android/graphics/PaintTest.java
+++ b/core/tests/coretests/src/android/graphics/PaintTest.java
@@ -156,4 +156,213 @@
             }
         }
     }
+
+    public void testGetTextRunAdvances() {
+        {
+            // LTR
+            String text = "abcdef";
+            assertGetTextRunAdvances(text, 0, text.length(), 0, text.length(), false, true);
+            assertGetTextRunAdvances(text, 1, text.length() - 1, 0, text.length(), false, false);
+        }
+        {
+            // RTL
+            final String text =
+                    "\u0645\u0627\u0020\u0647\u064A\u0020\u0627\u0644\u0634" +
+                            "\u0641\u0631\u0629\u0020\u0627\u0644\u0645\u0648\u062D" +
+                            "\u062F\u0629\u0020\u064A\u0648\u0646\u064A\u0643\u0648" +
+                            "\u062F\u061F";
+            assertGetTextRunAdvances(text, 0, text.length(), 0, text.length(), true, true);
+            assertGetTextRunAdvances(text, 1, text.length() - 1, 0, text.length(), true, false);
+        }
+    }
+
+    private void assertGetTextRunAdvances(String str, int start, int end,
+            int contextStart, int contextEnd, boolean isRtl, boolean compareWithOtherMethods) {
+        Paint p = new Paint();
+
+        final int count = end - start;
+        final float[][] advanceArrays = new float[4][count];
+
+        final float advance = p.getTextRunAdvances(str, start, end, contextStart, contextEnd,
+                isRtl, advanceArrays[0], 0);
+
+        char chars[] = str.toCharArray();
+        final float advance_c = p.getTextRunAdvances(chars, start, count, contextStart,
+                contextEnd - contextStart, isRtl, advanceArrays[1], 0);
+        assertEquals(advance, advance_c, 1.0f);
+
+        for (int c = 1; c < count; ++c) {
+            final float firstPartAdvance = p.getTextRunAdvances(str, start, start + c,
+                    contextStart, contextEnd, isRtl, advanceArrays[2], 0);
+            final float secondPartAdvance = p.getTextRunAdvances(str, start + c, end,
+                    contextStart, contextEnd, isRtl, advanceArrays[2], c);
+            assertEquals(advance, firstPartAdvance + secondPartAdvance, 1.0f);
+
+
+            final float firstPartAdvance_c = p.getTextRunAdvances(chars, start, c,
+                    contextStart, contextEnd - contextStart, isRtl, advanceArrays[3], 0);
+            final float secondPartAdvance_c = p.getTextRunAdvances(chars, start + c,
+                    count - c, contextStart, contextEnd - contextStart, isRtl,
+                    advanceArrays[3], c);
+            assertEquals(advance, firstPartAdvance_c + secondPartAdvance_c, 1.0f);
+            assertEquals(firstPartAdvance, firstPartAdvance_c, 1.0f);
+            assertEquals(secondPartAdvance, secondPartAdvance_c, 1.0f);
+
+            for (int i = 1; i < advanceArrays.length; i++) {
+                for (int j = 0; j < count; j++) {
+                    assertEquals(advanceArrays[0][j], advanceArrays[i][j], 1.0f);
+                }
+            }
+
+            // Compare results with measureText, getRunAdvance, and getTextWidths.
+            if (compareWithOtherMethods && start == contextStart && end == contextEnd) {
+                assertEquals(advance, p.measureText(str, start, end), 1.0f);
+                assertEquals(advance, p.getRunAdvance(
+                        str, start, end, contextStart, contextEnd, isRtl, end), 1.0f);
+
+                final float[] widths = new float[count];
+                p.getTextWidths(str, start, end, widths);
+                for (int i = 0; i < count; i++) {
+                    assertEquals(advanceArrays[0][i], widths[i], 1.0f);
+                }
+            }
+        }
+    }
+
+    public void testGetTextRunAdvances_invalid() {
+        Paint p = new Paint();
+        String text = "test";
+
+        try {
+            p.getTextRunAdvances((String)null, 0, 0, 0, 0, false, null, 0);
+            fail("Should throw an IllegalArgumentException.");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            p.getTextRunAdvances((CharSequence)null, 0, 0, 0, 0, false, null, 0);
+            fail("Should throw an IllegalArgumentException.");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            p.getTextRunAdvances((char[])null, 0, 0, 0, 0, false, null, 0);
+            fail("Should throw an IllegalArgumentException.");
+        } catch (IllegalArgumentException e) {
+        }
+
+        try {
+            p.getTextRunAdvances(text, 0, text.length(), 0, text.length(), false,
+                    new float[text.length() - 1], 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            p.getTextRunAdvances(text, 0, text.length(), 0, text.length(), false,
+                    new float[text.length()], 1);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        // 0 > contextStart
+        try {
+            p.getTextRunAdvances(text, 0, text.length(), -1, text.length(), false, null, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        // contextStart > start
+        try {
+            p.getTextRunAdvances(text, 0, text.length(), 1, text.length(), false, null, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        // start > end
+        try {
+            p.getTextRunAdvances(text, 1, 0, 0, text.length(), false, null, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        // end > contextEnd
+        try {
+            p.getTextRunAdvances(text, 0, text.length(), 0, text.length() - 1, false, null, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        // contextEnd > text.length
+        try {
+            p.getTextRunAdvances(text, 0, text.length(), 0, text.length() + 1, false, null, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    public void testMeasureTextBidi() {
+        Paint p = new Paint();
+        {
+            String bidiText = "abc \u0644\u063A\u0629 def";
+            p.setBidiFlags(Paint.BIDI_LTR);
+            float width = p.measureText(bidiText, 0, 4);
+            p.setBidiFlags(Paint.BIDI_RTL);
+            width += p.measureText(bidiText, 4, 7);
+            p.setBidiFlags(Paint.BIDI_LTR);
+            width += p.measureText(bidiText, 7, bidiText.length());
+            assertEquals(width, p.measureText(bidiText), 1.0f);
+        }
+        {
+            String bidiText = "abc \u0644\u063A\u0629 def";
+            p.setBidiFlags(Paint.BIDI_DEFAULT_LTR);
+            float width = p.measureText(bidiText, 0, 4);
+            width += p.measureText(bidiText, 4, 7);
+            width += p.measureText(bidiText, 7, bidiText.length());
+            assertEquals(width, p.measureText(bidiText), 1.0f);
+        }
+        {
+            String bidiText = "abc \u0644\u063A\u0629 def";
+            p.setBidiFlags(Paint.BIDI_FORCE_LTR);
+            float width = p.measureText(bidiText, 0, 4);
+            width += p.measureText(bidiText, 4, 7);
+            width += p.measureText(bidiText, 7, bidiText.length());
+            assertEquals(width, p.measureText(bidiText), 1.0f);
+        }
+        {
+            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
+            p.setBidiFlags(Paint.BIDI_RTL);
+            float width = p.measureText(bidiText, 0, 4);
+            p.setBidiFlags(Paint.BIDI_LTR);
+            width += p.measureText(bidiText, 4, 7);
+            p.setBidiFlags(Paint.BIDI_RTL);
+            width += p.measureText(bidiText, 7, bidiText.length());
+            assertEquals(width, p.measureText(bidiText), 1.0f);
+        }
+        {
+            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
+            p.setBidiFlags(Paint.BIDI_DEFAULT_RTL);
+            float width = p.measureText(bidiText, 0, 4);
+            width += p.measureText(bidiText, 4, 7);
+            width += p.measureText(bidiText, 7, bidiText.length());
+            assertEquals(width, p.measureText(bidiText), 1.0f);
+        }
+        {
+            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
+            p.setBidiFlags(Paint.BIDI_FORCE_RTL);
+            float width = p.measureText(bidiText, 0, 4);
+            width += p.measureText(bidiText, 4, 7);
+            width += p.measureText(bidiText, 7, bidiText.length());
+            assertEquals(width, p.measureText(bidiText), 1.0f);
+        }
+    }
+
+    public void testSetGetWordSpacing() {
+        Paint p = new Paint();
+        assertEquals(0.0f, p.getWordSpacing());  // The default value should be 0.
+        p.setWordSpacing(1.0f);
+        assertEquals(1.0f, p.getWordSpacing());
+        p.setWordSpacing(-2.0f);
+        assertEquals(-2.0f, p.getWordSpacing());
+    }
 }
diff --git a/graphics/tests/graphicstests/src/android/graphics/PathTest.java b/core/tests/coretests/src/android/graphics/PathTest.java
similarity index 99%
rename from graphics/tests/graphicstests/src/android/graphics/PathTest.java
rename to core/tests/coretests/src/android/graphics/PathTest.java
index 96200bc..78e4959 100644
--- a/graphics/tests/graphicstests/src/android/graphics/PathTest.java
+++ b/core/tests/coretests/src/android/graphics/PathTest.java
@@ -17,6 +17,7 @@
 package android.graphics;
 
 import android.test.suitebuilder.annotation.SmallTest;
+
 import junit.framework.TestCase;
 
 
diff --git a/graphics/tests/graphicstests/src/android/graphics/ThreadBitmapTest.java b/core/tests/coretests/src/android/graphics/ThreadBitmapTest.java
similarity index 97%
rename from graphics/tests/graphicstests/src/android/graphics/ThreadBitmapTest.java
rename to core/tests/coretests/src/android/graphics/ThreadBitmapTest.java
index 84bdc56..909a8d9 100644
--- a/graphics/tests/graphicstests/src/android/graphics/ThreadBitmapTest.java
+++ b/core/tests/coretests/src/android/graphics/ThreadBitmapTest.java
@@ -16,10 +16,10 @@
 
 package android.graphics;
 
-import junit.framework.TestCase;
-import android.graphics.Bitmap;
 import android.test.suitebuilder.annotation.LargeTest;
 
+import junit.framework.TestCase;
+
 public class ThreadBitmapTest extends TestCase {
 
     @Override
diff --git a/graphics/tests/graphicstests/src/android/graphics/VariationParserTest.java b/core/tests/coretests/src/android/graphics/VariationParserTest.java
similarity index 99%
rename from graphics/tests/graphicstests/src/android/graphics/VariationParserTest.java
rename to core/tests/coretests/src/android/graphics/VariationParserTest.java
index c7a46a3..a2ead40 100644
--- a/graphics/tests/graphicstests/src/android/graphics/VariationParserTest.java
+++ b/core/tests/coretests/src/android/graphics/VariationParserTest.java
@@ -18,9 +18,11 @@
 
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.FontConfig;
-import java.util.List;
+
 import junit.framework.TestCase;
 
+import java.util.List;
+
 
 public class VariationParserTest extends TestCase {
 
diff --git a/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
similarity index 97%
rename from graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
rename to core/tests/coretests/src/android/graphics/drawable/IconTest.java
index d3e1a43..b50955b 100644
--- a/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/IconTest.java
@@ -26,14 +26,13 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
+import com.android.frameworks.coretests.R;
+
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
-import java.lang.Override;
-import java.util.Arrays;
 import java.util.ArrayList;
-
-import com.android.frameworks.graphicstests.R;
+import java.util.Arrays;
 
 public class IconTest extends AndroidTestCase {
     public static final String TAG = IconTest.class.getSimpleName();
@@ -109,13 +108,13 @@
     }
 
     @SmallTest
-    public void testWithMaskableBitmap() throws Exception {
+    public void testWithAdaptiveBitmap() throws Exception {
         final Bitmap bm1 = Bitmap.createBitmap(150, 150, Bitmap.Config.ARGB_8888);
 
         final Canvas can1 = new Canvas(bm1);
         can1.drawColor(0xFFFF0000);
 
-        final Icon im1 = Icon.createWithMaskableBitmap(bm1);
+        final Icon im1 = Icon.createWithAdaptiveBitmap(bm1);
 
         final AdaptiveIconDrawable draw1 = (AdaptiveIconDrawable) im1.loadDrawable(mContext);
 
@@ -133,12 +132,12 @@
         L("writing temp bitmaps to %s...", dir);
 
         bm1.compress(Bitmap.CompressFormat.PNG, 100,
-            new FileOutputStream(new File(dir, "maskable-bitmap1-original.png")));
+            new FileOutputStream(new File(dir, "adaptive-bitmap1-original.png")));
         test1.compress(Bitmap.CompressFormat.PNG, 100,
-            new FileOutputStream(new File(dir, "maskable-bitmap1-test.png")));
+            new FileOutputStream(new File(dir, "adaptive-bitmap1-test.png")));
         if (!equalBitmaps(bm1, test1, draw1.getSafeZone())) {
             findBitmapDifferences(bm1, test1);
-            fail("maskable bitmap1 differs, check " + dir);
+            fail("adaptive bitmap1 differs, check " + dir);
         }
     }
 
diff --git a/graphics/tests/graphicstests/src/android/graphics/drawable/StateListDrawableTest.java b/core/tests/coretests/src/android/graphics/drawable/StateListDrawableTest.java
similarity index 99%
rename from graphics/tests/graphicstests/src/android/graphics/drawable/StateListDrawableTest.java
rename to core/tests/coretests/src/android/graphics/drawable/StateListDrawableTest.java
index 0d9f72e..03a9c25 100644
--- a/graphics/tests/graphicstests/src/android/graphics/drawable/StateListDrawableTest.java
+++ b/core/tests/coretests/src/android/graphics/drawable/StateListDrawableTest.java
@@ -16,14 +16,14 @@
 
 package android.graphics.drawable;
 
-import junit.framework.TestCase;
-
 import android.R;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
 import android.util.StateSet;
 import android.view.MockView;
 
+import junit.framework.TestCase;
+
 /**
  * Tests for StateListDrawable
  *
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index b718263..105a351 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -281,6 +281,7 @@
                     Settings.Global.RADIO_NFC,
                     Settings.Global.RADIO_WIFI,
                     Settings.Global.RADIO_WIMAX,
+                    Settings.Global.RECOMMENDED_NETWORK_EVALUATOR_CACHE_EXPIRY_MS,
                     Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT,
                     Settings.Global.REQUIRE_PASSWORD_TO_DECRYPT,
                     Settings.Global.RETAIL_DEMO_MODE_CONSTANTS,
diff --git a/graphics/tests/graphicstests/src/android/view/MockView.java b/core/tests/coretests/src/android/view/MockView.java
similarity index 100%
rename from graphics/tests/graphicstests/src/android/view/MockView.java
rename to core/tests/coretests/src/android/view/MockView.java
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index d8e6db7..76598a0 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -1,8 +1,22 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-    All fonts without names are added to the default list. Fonts are chosen
-    based on a match: full BCP-47 language tag including script, then just
-    language, and finally order (the first font containing the glyph).
+    WARNING: Parsing of this file by third-party apps is not supported. The
+    file, and the font files it refers to, will be renamed and/or moved out
+    from their respective location in the next Android release, and/or the
+    format or syntax of the file may change significantly. You must not
+    parse this file for information about system fonts. Instead, you must
+    call android.text.FontManager#getSystemFonts(). For example, it can be
+    called as context.getSystemService(FontManager.class).getSystemFonts().
+    Note that the returned FontConfig includes data on all the defined font
+    families and all the details about weight, style, etc. It also provides
+    an open file descriptor to each font file. Note that callers of the API
+    should ensure they close the given file descriptors once they are done
+    using them.
+
+    In this file, all fonts without names are added to the default list.
+    Fonts are chosen based on a match: full BCP-47 language tag including
+    script, then just language, and finally order (the first font containing
+    the glyph).
 
     Order of appearance is also the tiebreaker for weight matching. This is
     the reason why the 900 weights of Roboto precede the 700 weights - we
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index ff1312a..8ce7ed0 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -68,7 +68,7 @@
     /** @hide */
     public static final int TYPE_URI      = 4;
     /** @hide */
-    public static final int TYPE_BITMAP_MASKABLE      = 5;
+    public static final int TYPE_ADAPTIVE_BITMAP = 5;
 
     private static final int VERSION_STREAM_SERIALIZER = 1;
 
@@ -103,7 +103,7 @@
      * {@link #TYPE_RESOURCE},
      * {@link #TYPE_DATA}, or
      * {@link #TYPE_URI}.
-     * {@link #TYPE_BITMAP_MASKABLE}
+     * {@link #TYPE_ADAPTIVE_BITMAP}
      * @hide
      */
     public int getType() {
@@ -115,7 +115,7 @@
      * @hide
      */
     public Bitmap getBitmap() {
-        if (mType != TYPE_BITMAP && mType != TYPE_BITMAP_MASKABLE) {
+        if (mType != TYPE_BITMAP && mType != TYPE_ADAPTIVE_BITMAP) {
             throw new IllegalStateException("called getBitmap() on " + this);
         }
         return (Bitmap) mObj1;
@@ -221,7 +221,7 @@
     private static final String typeToString(int x) {
         switch (x) {
             case TYPE_BITMAP: return "BITMAP";
-            case TYPE_BITMAP_MASKABLE: return "BITMAP_MASKABLE";
+            case TYPE_ADAPTIVE_BITMAP: return "BITMAP_MASKABLE";
             case TYPE_DATA: return "DATA";
             case TYPE_RESOURCE: return "RESOURCE";
             case TYPE_URI: return "URI";
@@ -289,7 +289,7 @@
         switch (mType) {
             case TYPE_BITMAP:
                 return new BitmapDrawable(context.getResources(), getBitmap());
-            case TYPE_BITMAP_MASKABLE:
+            case TYPE_ADAPTIVE_BITMAP:
                 return new AdaptiveIconDrawable(null,
                     new BitmapDrawable(context.getResources(), getBitmap()));
             case TYPE_RESOURCE:
@@ -395,7 +395,7 @@
      * @hide
      */
     public void convertToAshmem() {
-        if ((mType == TYPE_BITMAP || mType == TYPE_BITMAP_MASKABLE) &&
+        if ((mType == TYPE_BITMAP || mType == TYPE_ADAPTIVE_BITMAP) &&
             getBitmap().isMutable() &&
             getBitmap().getAllocationByteCount() >= MIN_ASHMEM_ICON_SIZE) {
             setBitmap(getBitmap().createAshmemBitmap());
@@ -416,7 +416,7 @@
 
         switch (mType) {
             case TYPE_BITMAP:
-            case TYPE_BITMAP_MASKABLE:
+            case TYPE_ADAPTIVE_BITMAP:
                 getBitmap().compress(Bitmap.CompressFormat.PNG, 100, dataStream);
                 break;
             case TYPE_DATA:
@@ -452,8 +452,8 @@
             switch (type) {
                 case TYPE_BITMAP:
                     return createWithBitmap(BitmapFactory.decodeStream(inputStream));
-                case TYPE_BITMAP_MASKABLE:
-                    return createWithMaskableBitmap(BitmapFactory.decodeStream(inputStream));
+                case TYPE_ADAPTIVE_BITMAP:
+                    return createWithAdaptiveBitmap(BitmapFactory.decodeStream(inputStream));
                 case TYPE_DATA:
                     final int length = inputStream.readInt();
                     final byte[] data = new byte[length];
@@ -488,7 +488,7 @@
         }
         switch (mType) {
             case TYPE_BITMAP:
-            case TYPE_BITMAP_MASKABLE:
+            case TYPE_ADAPTIVE_BITMAP:
                 return getBitmap() == otherIcon.getBitmap();
             case TYPE_DATA:
                 return getDataLength() == otherIcon.getDataLength()
@@ -566,11 +566,11 @@
      * by {@link AdaptiveIconDrawable}.
      * @param bits A valid {@link android.graphics.Bitmap} object
      */
-    public static Icon createWithMaskableBitmap(Bitmap bits) {
+    public static Icon createWithAdaptiveBitmap(Bitmap bits) {
         if (bits == null) {
             throw new IllegalArgumentException("Bitmap must not be null.");
         }
-        final Icon rep = new Icon(TYPE_BITMAP_MASKABLE);
+        final Icon rep = new Icon(TYPE_ADAPTIVE_BITMAP);
         rep.setBitmap(bits);
         return rep;
     }
@@ -679,7 +679,7 @@
         final StringBuilder sb = new StringBuilder("Icon(typ=").append(typeToString(mType));
         switch (mType) {
             case TYPE_BITMAP:
-            case TYPE_BITMAP_MASKABLE:
+            case TYPE_ADAPTIVE_BITMAP:
                 sb.append(" size=")
                         .append(getBitmap().getWidth())
                         .append("x")
@@ -718,7 +718,7 @@
      * Parcelable interface
      */
     public int describeContents() {
-        return (mType == TYPE_BITMAP || mType == TYPE_BITMAP_MASKABLE || mType == TYPE_DATA)
+        return (mType == TYPE_BITMAP || mType == TYPE_ADAPTIVE_BITMAP || mType == TYPE_DATA)
                 ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
     }
 
@@ -728,7 +728,7 @@
         this(in.readInt());
         switch (mType) {
             case TYPE_BITMAP:
-            case TYPE_BITMAP_MASKABLE:
+            case TYPE_ADAPTIVE_BITMAP:
                 final Bitmap bits = Bitmap.CREATOR.createFromParcel(in);
                 mObj1 = bits;
                 break;
@@ -767,7 +767,7 @@
         dest.writeInt(mType);
         switch (mType) {
             case TYPE_BITMAP:
-            case TYPE_BITMAP_MASKABLE:
+            case TYPE_ADAPTIVE_BITMAP:
                 final Bitmap bits = getBitmap();
                 getBitmap().writeToParcel(dest, flags);
                 break;
diff --git a/graphics/tests/graphicstests/Android.mk b/graphics/tests/graphicstests/Android.mk
deleted file mode 100644
index 8ea44bd..0000000
--- a/graphics/tests/graphicstests/Android.mk
+++ /dev/null
@@ -1,15 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test
-LOCAL_PACKAGE_NAME := FrameworksGraphicsTests
-
-include $(BUILD_PACKAGE)
-
diff --git a/graphics/tests/graphicstests/AndroidManifest.xml b/graphics/tests/graphicstests/AndroidManifest.xml
deleted file mode 100644
index e019e28..0000000
--- a/graphics/tests/graphicstests/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.frameworks.graphicstests">
-    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
-    <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-
- 
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <instrumentation
-    	android:name="android.test.InstrumentationTestRunner"
-    	android:targetPackage="com.android.frameworks.graphicstests"
-    	android:label="Frameworks Graphics Tests" />
-</manifest>
diff --git a/graphics/tests/graphicstests/res/values/colors.xml b/graphics/tests/graphicstests/res/values/colors.xml
deleted file mode 100644
index 7559e65..0000000
--- a/graphics/tests/graphicstests/res/values/colors.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2006, 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.
-*/
--->
-<resources>
-    <color name="testcolor1">#ff00ff00</color>
-    <color name="testcolor2">#ffff0000</color>
-    <color name="failColor">#ff0000ff</color>
-</resources>
-
diff --git a/graphics/tests/graphicstests/src/android/graphics/PaintTest.java b/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
deleted file mode 100644
index 318bfb6..0000000
--- a/graphics/tests/graphicstests/src/android/graphics/PaintTest.java
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Copyright (C) 2015 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 android.graphics;
-
-import android.test.AndroidTestCase;
-
-public class PaintTest extends AndroidTestCase {
-    public void testGetTextRunAdvances() {
-        {
-            // LTR
-            String text = "abcdef";
-            assertGetTextRunAdvances(text, 0, text.length(), 0, text.length(), false, true);
-            assertGetTextRunAdvances(text, 1, text.length() - 1, 0, text.length(), false, false);
-        }
-        {
-            // RTL
-            final String text =
-                    "\u0645\u0627\u0020\u0647\u064A\u0020\u0627\u0644\u0634" +
-                    "\u0641\u0631\u0629\u0020\u0627\u0644\u0645\u0648\u062D" +
-                    "\u062F\u0629\u0020\u064A\u0648\u0646\u064A\u0643\u0648" +
-                    "\u062F\u061F";
-            assertGetTextRunAdvances(text, 0, text.length(), 0, text.length(), true, true);
-            assertGetTextRunAdvances(text, 1, text.length() - 1, 0, text.length(), true, false);
-        }
-    }
-
-    private void assertGetTextRunAdvances(String str, int start, int end,
-            int contextStart, int contextEnd, boolean isRtl, boolean compareWithOtherMethods) {
-        Paint p = new Paint();
-
-        final int count = end - start;
-        final float[][] advanceArrays = new float[4][count];
-
-        final float advance = p.getTextRunAdvances(str, start, end, contextStart, contextEnd,
-                isRtl, advanceArrays[0], 0);
-
-        char chars[] = str.toCharArray();
-        final float advance_c = p.getTextRunAdvances(chars, start, count, contextStart,
-                contextEnd - contextStart, isRtl, advanceArrays[1], 0);
-        assertEquals(advance, advance_c, 1.0f);
-
-        for (int c = 1; c < count; ++c) {
-            final float firstPartAdvance = p.getTextRunAdvances(str, start, start + c,
-                    contextStart, contextEnd, isRtl, advanceArrays[2], 0);
-            final float secondPartAdvance = p.getTextRunAdvances(str, start + c, end,
-                    contextStart, contextEnd, isRtl, advanceArrays[2], c);
-            assertEquals(advance, firstPartAdvance + secondPartAdvance, 1.0f);
-
-
-            final float firstPartAdvance_c = p.getTextRunAdvances(chars, start, c,
-                    contextStart, contextEnd - contextStart, isRtl, advanceArrays[3], 0);
-            final float secondPartAdvance_c = p.getTextRunAdvances(chars, start + c,
-                    count - c, contextStart, contextEnd - contextStart, isRtl,
-                    advanceArrays[3], c);
-            assertEquals(advance, firstPartAdvance_c + secondPartAdvance_c, 1.0f);
-            assertEquals(firstPartAdvance, firstPartAdvance_c, 1.0f);
-            assertEquals(secondPartAdvance, secondPartAdvance_c, 1.0f);
-
-            for (int i = 1; i < advanceArrays.length; i++) {
-                for (int j = 0; j < count; j++) {
-                    assertEquals(advanceArrays[0][j], advanceArrays[i][j], 1.0f);
-                }
-            }
-
-            // Compare results with measureText, getRunAdvance, and getTextWidths.
-            if (compareWithOtherMethods && start == contextStart && end == contextEnd) {
-                assertEquals(advance, p.measureText(str, start, end), 1.0f);
-                assertEquals(advance, p.getRunAdvance(
-                        str, start, end, contextStart, contextEnd, isRtl, end), 1.0f);
-
-                final float[] widths = new float[count];
-                p.getTextWidths(str, start, end, widths);
-                for (int i = 0; i < count; i++) {
-                    assertEquals(advanceArrays[0][i], widths[i], 1.0f);
-                }
-            }
-        }
-    }
-
-    public void testGetTextRunAdvances_invalid() {
-        Paint p = new Paint();
-        String text = "test";
-
-        try {
-            p.getTextRunAdvances((String)null, 0, 0, 0, 0, false, null, 0);
-            fail("Should throw an IllegalArgumentException.");
-        } catch (IllegalArgumentException e) {
-        }
-
-        try {
-            p.getTextRunAdvances((CharSequence)null, 0, 0, 0, 0, false, null, 0);
-            fail("Should throw an IllegalArgumentException.");
-        } catch (IllegalArgumentException e) {
-        }
-
-        try {
-            p.getTextRunAdvances((char[])null, 0, 0, 0, 0, false, null, 0);
-            fail("Should throw an IllegalArgumentException.");
-        } catch (IllegalArgumentException e) {
-        }
-
-        try {
-            p.getTextRunAdvances(text, 0, text.length(), 0, text.length(), false,
-                    new float[text.length() - 1], 0);
-            fail("Should throw an IndexOutOfBoundsException.");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        try {
-            p.getTextRunAdvances(text, 0, text.length(), 0, text.length(), false,
-                    new float[text.length()], 1);
-            fail("Should throw an IndexOutOfBoundsException.");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        // 0 > contextStart
-        try {
-            p.getTextRunAdvances(text, 0, text.length(), -1, text.length(), false, null, 0);
-            fail("Should throw an IndexOutOfBoundsException.");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        // contextStart > start
-        try {
-            p.getTextRunAdvances(text, 0, text.length(), 1, text.length(), false, null, 0);
-            fail("Should throw an IndexOutOfBoundsException.");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        // start > end
-        try {
-            p.getTextRunAdvances(text, 1, 0, 0, text.length(), false, null, 0);
-            fail("Should throw an IndexOutOfBoundsException.");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        // end > contextEnd
-        try {
-            p.getTextRunAdvances(text, 0, text.length(), 0, text.length() - 1, false, null, 0);
-            fail("Should throw an IndexOutOfBoundsException.");
-        } catch (IndexOutOfBoundsException e) {
-        }
-
-        // contextEnd > text.length
-        try {
-            p.getTextRunAdvances(text, 0, text.length(), 0, text.length() + 1, false, null, 0);
-            fail("Should throw an IndexOutOfBoundsException.");
-        } catch (IndexOutOfBoundsException e) {
-        }
-    }
-
-    public void testMeasureTextBidi() {
-        Paint p = new Paint();
-        {
-            String bidiText = "abc \u0644\u063A\u0629 def";
-            p.setBidiFlags(Paint.BIDI_LTR);
-            float width = p.measureText(bidiText, 0, 4);
-            p.setBidiFlags(Paint.BIDI_RTL);
-            width += p.measureText(bidiText, 4, 7);
-            p.setBidiFlags(Paint.BIDI_LTR);
-            width += p.measureText(bidiText, 7, bidiText.length());
-            assertEquals(width, p.measureText(bidiText), 1.0f);
-        }
-        {
-            String bidiText = "abc \u0644\u063A\u0629 def";
-            p.setBidiFlags(Paint.BIDI_DEFAULT_LTR);
-            float width = p.measureText(bidiText, 0, 4);
-            width += p.measureText(bidiText, 4, 7);
-            width += p.measureText(bidiText, 7, bidiText.length());
-            assertEquals(width, p.measureText(bidiText), 1.0f);
-        }
-        {
-            String bidiText = "abc \u0644\u063A\u0629 def";
-            p.setBidiFlags(Paint.BIDI_FORCE_LTR);
-            float width = p.measureText(bidiText, 0, 4);
-            width += p.measureText(bidiText, 4, 7);
-            width += p.measureText(bidiText, 7, bidiText.length());
-            assertEquals(width, p.measureText(bidiText), 1.0f);
-        }
-        {
-            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
-            p.setBidiFlags(Paint.BIDI_RTL);
-            float width = p.measureText(bidiText, 0, 4);
-            p.setBidiFlags(Paint.BIDI_LTR);
-            width += p.measureText(bidiText, 4, 7);
-            p.setBidiFlags(Paint.BIDI_RTL);
-            width += p.measureText(bidiText, 7, bidiText.length());
-            assertEquals(width, p.measureText(bidiText), 1.0f);
-        }
-        {
-            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
-            p.setBidiFlags(Paint.BIDI_DEFAULT_RTL);
-            float width = p.measureText(bidiText, 0, 4);
-            width += p.measureText(bidiText, 4, 7);
-            width += p.measureText(bidiText, 7, bidiText.length());
-            assertEquals(width, p.measureText(bidiText), 1.0f);
-        }
-        {
-            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
-            p.setBidiFlags(Paint.BIDI_FORCE_RTL);
-            float width = p.measureText(bidiText, 0, 4);
-            width += p.measureText(bidiText, 4, 7);
-            width += p.measureText(bidiText, 7, bidiText.length());
-            assertEquals(width, p.measureText(bidiText), 1.0f);
-        }
-    }
-
-    public void testSetGetWordSpacing() {
-        Paint p = new Paint();
-        assertEquals(0.0f, p.getWordSpacing());  // The default value should be 0.
-        p.setWordSpacing(1.0f);
-        assertEquals(1.0f, p.getWordSpacing());
-        p.setWordSpacing(-2.0f);
-        assertEquals(-2.0f, p.getWordSpacing());
-    }
-}
diff --git a/keystore/java/android/security/IKeyChainService.aidl b/keystore/java/android/security/IKeyChainService.aidl
index deea972..b685431 100644
--- a/keystore/java/android/security/IKeyChainService.aidl
+++ b/keystore/java/android/security/IKeyChainService.aidl
@@ -15,7 +15,7 @@
  */
 package android.security;
 
-import android.content.pm.ParceledListSlice;
+import android.content.pm.StringParceledListSlice;
 
 /**
  * Caller is required to ensure that {@link KeyStore#unlock
@@ -39,8 +39,8 @@
     // APIs used by Settings
     boolean deleteCaCertificate(String alias);
     boolean reset();
-    ParceledListSlice getUserCaAliases();
-    ParceledListSlice getSystemCaAliases();
+    StringParceledListSlice getUserCaAliases();
+    StringParceledListSlice getSystemCaAliases();
     boolean containsCaAlias(String alias);
     byte[] getEncodedCaCertificate(String alias, boolean includeDeletedSystem);
     List<String> getCaCertificateChainAliases(String rootAlias, boolean includeDeletedSystem);
diff --git a/keystore/java/android/security/keystore/KeyProperties.java b/keystore/java/android/security/keystore/KeyProperties.java
index bf7a779a..d6b1cf1 100644
--- a/keystore/java/android/security/keystore/KeyProperties.java
+++ b/keystore/java/android/security/keystore/KeyProperties.java
@@ -45,7 +45,6 @@
                 PURPOSE_DECRYPT,
                 PURPOSE_SIGN,
                 PURPOSE_VERIFY,
-                PURPOSE_WRAP_KEY,
                 })
     public @interface PurposeEnum {}
 
@@ -70,12 +69,6 @@
     public static final int PURPOSE_VERIFY = 1 << 3;
 
     /**
-     * Purpose of key: wrapping key for secure key import.
-     */
-    public static final int PURPOSE_WRAP_KEY = 1 << 4;
-
-
-    /**
      * @hide
      */
     public static abstract class Purpose {
@@ -91,8 +84,6 @@
                     return KeymasterDefs.KM_PURPOSE_SIGN;
                 case PURPOSE_VERIFY:
                     return KeymasterDefs.KM_PURPOSE_VERIFY;
-                case PURPOSE_WRAP_KEY:
-                    return KeymasterDefs.KM_PURPOSE_WRAP_KEY;
                 default:
                     throw new IllegalArgumentException("Unknown purpose: " + purpose);
             }
@@ -108,8 +99,6 @@
                     return PURPOSE_SIGN;
                 case KeymasterDefs.KM_PURPOSE_VERIFY:
                     return PURPOSE_VERIFY;
-                case KeymasterDefs.KM_PURPOSE_WRAP_KEY:
-                    return PURPOSE_WRAP_KEY;
                 default:
                     throw new IllegalArgumentException("Unknown purpose: " + purpose);
             }
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index c6fbe2bd5..e39614b 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -91,8 +91,6 @@
     LayerUpdateQueue* layerUpdateQueue = nullptr;
     ErrorHandler* errorHandler = nullptr;
 
-    int32_t windowInsetLeft = 0;
-    int32_t windowInsetTop = 0;
     bool updateWindowPositions = false;
 
     struct Out {
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 117395b..39f11b8 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -197,12 +197,12 @@
             if (needsLayer) {
                 canvas->saveLayer(bounds, &paint);
             }
-            canvas->drawDrawable(displayList->mDrawable.get());
+            displayList->draw(canvas);
             if (needsLayer) {
                 canvas->restore();
             }
         } else {
-            canvas->drawDrawable(displayList->mDrawable.get());
+            displayList->draw(canvas);
         }
     }
 }
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
index b4babcb..496f7ba 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.cpp
@@ -27,10 +27,6 @@
 namespace uirenderer {
 namespace skiapipeline {
 
-SkiaDisplayList::SkiaDisplayList(SkRect bounds) : mDrawable(SkLiteDL::New(bounds)) {
-    SkASSERT(projectionReceiveIndex == -1);
-}
-
 void SkiaDisplayList::syncContents() {
     for (auto& functor : mChildFunctors) {
         functor.syncFunctor();
@@ -41,7 +37,7 @@
 }
 
 bool SkiaDisplayList::reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) {
-    reset(SkRect::MakeEmpty());
+    reset();
     node->attachAvailableList(this);
     return true;
 }
@@ -102,10 +98,10 @@
     return isDirty;
 }
 
-void SkiaDisplayList::reset(SkRect bounds) {
+void SkiaDisplayList::reset() {
     mProjectionReceiver = nullptr;
 
-    mDrawable->reset(bounds);
+    mDisplayList.reset();
 
     mMutableImages.clear();
     mVectorDrawables.clear();
@@ -119,7 +115,7 @@
 
 void SkiaDisplayList::output(std::ostream& output, uint32_t level) {
     DumpOpsCanvas canvas(output, level, *this);
-    mDrawable->draw(&canvas, nullptr);
+    mDisplayList.draw(&canvas);
 }
 
 }; // namespace skiapipeline
diff --git a/libs/hwui/pipeline/skia/SkiaDisplayList.h b/libs/hwui/pipeline/skia/SkiaDisplayList.h
index 439b999..6ee5922 100644
--- a/libs/hwui/pipeline/skia/SkiaDisplayList.h
+++ b/libs/hwui/pipeline/skia/SkiaDisplayList.h
@@ -22,7 +22,7 @@
 
 #include <deque>
 #include <SkLiteDL.h>
-#include <SkPictureRecorder.h>
+#include <SkLiteRecorder.h>
 
 namespace android {
 namespace uirenderer {
@@ -39,22 +39,22 @@
  */
 class SkiaDisplayList : public DisplayList {
 public:
-    SkiaDisplayList(SkRect bounds);
+    SkiaDisplayList() { SkASSERT(projectionReceiveIndex == -1); }
     virtual ~SkiaDisplayList() {
         /* Given that we are using a LinearStdAllocator to store some of the
          * SkDrawable contents we must ensure that any other object that is
          * holding a reference to those drawables is destroyed prior to their
          * deletion.
          */
-        mDrawable.reset();
+        mDisplayList.reset();
     }
 
     /**
      * This resets the DisplayList so that it behaves as if the object were newly
-     * constructed with the provided bounds.  The reuse avoids any overhead
-     * associated with destroying the SkLiteDL as well as the deques and vectors.
+     * constructed.  The reuse avoids any overhead associated with destroying
+     * the SkLiteDL as well as the deques and vectors.
      */
-    void reset(SkRect bounds);
+    void reset();
 
     /**
      * Use the linear allocator to create any SkDrawables needed by the display
@@ -72,7 +72,7 @@
     /**
      * Returns true if the DisplayList does not have any recorded content
      */
-    bool isEmpty() const override { return mDrawable->empty(); }
+    bool isEmpty() const override { return mDisplayList.empty(); }
 
     /**
      * Returns true if this list directly contains a GLFunctor drawing command.
@@ -126,18 +126,24 @@
      */
     inline bool containsProjectionReceiver() const { return mProjectionReceiver; }
 
+    void attachRecorder(SkLiteRecorder* recorder, const SkIRect& bounds) {
+        recorder->reset(&mDisplayList, bounds);
+    }
+
+    void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); }
+
     void output(std::ostream& output, uint32_t level) override;
 
     /**
      * We use std::deque here because (1) we need to iterate through these
-     * elements and (2) mDrawable holds pointers to the elements, so they cannot
-     * relocate.
+     * elements and (2) mDisplayList holds pointers to the elements, so they
+     * cannot relocate.
      */
     std::deque<RenderNodeDrawable> mChildNodes;
     std::deque<GLFunctorDrawable> mChildFunctors;
     std::vector<SkImage*> mMutableImages;
     std::vector<VectorDrawableRoot*> mVectorDrawables;
-    sk_sp<SkLiteDL> mDrawable;
+    SkLiteDL mDisplayList;
 
     //mProjectionReceiver points to a child node (stored in mChildNodes) that is as a projection
     //receiver. It is set at record time and used at both prepare and draw tree traversals to
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index dbe0296..559d268 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -39,14 +39,11 @@
     if (renderNode) {
         mDisplayList = renderNode->detachAvailableList();
     }
-    SkRect bounds = SkRect::MakeWH(width, height);
-    if (mDisplayList) {
-        mDisplayList->reset(bounds);
-    } else {
-        mDisplayList.reset(new SkiaDisplayList(bounds));
+    if (!mDisplayList) {
+        mDisplayList.reset(new SkiaDisplayList());
     }
 
-    mRecorder.reset(mDisplayList->mDrawable.get());
+    mDisplayList->attachRecorder(&mRecorder, SkIRect::MakeWH(width, height));
     SkiaCanvas::reset(&mRecorder);
 }
 
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index f21b3f7..cbea501 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -44,9 +44,9 @@
                 canvas.drawColor(Color::Red_500, SkBlendMode::kSrcOver);
             });
 
-    auto skLiteDL = SkLiteDL::New(SkRect::MakeWH(1, 1));
+    SkLiteDL skLiteDL;
     SkLiteRecorder canvas;
-    canvas.reset(skLiteDL.get());
+    canvas.reset(&skLiteDL, SkIRect::MakeWH(1, 1));
     canvas.translate(100, 100);
     RenderNodeDrawable drawable(rootNode.get(), &canvas);
 
diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
index be460bf..dd8f4b4 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -30,16 +30,13 @@
 using namespace android::uirenderer::skiapipeline;
 
 TEST(SkiaDisplayList, create) {
-    SkRect bounds = SkRect::MakeWH(200, 200);
-    SkiaDisplayList skiaDL(bounds);
+    SkiaDisplayList skiaDL;
     ASSERT_TRUE(skiaDL.isEmpty());
     ASSERT_FALSE(skiaDL.mProjectionReceiver);
-    ASSERT_EQ(skiaDL.mDrawable->getBounds(), bounds);
 }
 
 TEST(SkiaDisplayList, reset) {
-    SkRect bounds = SkRect::MakeWH(200, 200);
-    SkiaDisplayList skiaDL(bounds);
+    SkiaDisplayList skiaDL;
 
     SkCanvas dummyCanvas;
     RenderNodeDrawable drawable(nullptr, &dummyCanvas);
@@ -47,10 +44,9 @@
     skiaDL.mChildFunctors.emplace_back(nullptr, nullptr, &dummyCanvas);
     skiaDL.mMutableImages.push_back(nullptr);
     skiaDL.mVectorDrawables.push_back(nullptr);
-    skiaDL.mDrawable->drawAnnotation(bounds, "testAnnotation", nullptr);
+    skiaDL.mDisplayList.drawAnnotation(SkRect::MakeWH(200, 200), "testAnnotation", nullptr);
     skiaDL.mProjectionReceiver = &drawable;
 
-    ASSERT_EQ(skiaDL.mDrawable->getBounds(), bounds);
     ASSERT_FALSE(skiaDL.mChildNodes.empty());
     ASSERT_FALSE(skiaDL.mChildFunctors.empty());
     ASSERT_FALSE(skiaDL.mMutableImages.empty());
@@ -58,10 +54,8 @@
     ASSERT_FALSE(skiaDL.isEmpty());
     ASSERT_TRUE(skiaDL.mProjectionReceiver);
 
-    bounds = SkRect::MakeWH(100, 100);
-    skiaDL.reset(bounds);
+    skiaDL.reset();
 
-    ASSERT_EQ(skiaDL.mDrawable->getBounds(), bounds);
     ASSERT_TRUE(skiaDL.mChildNodes.empty());
     ASSERT_TRUE(skiaDL.mChildFunctors.empty());
     ASSERT_TRUE(skiaDL.mMutableImages.empty());
@@ -79,7 +73,7 @@
     ASSERT_EQ(availableList.get(), nullptr);
 
     // attach a displayList for reuse
-    SkiaDisplayList skiaDL(SkRect::MakeWH(200, 200));
+    SkiaDisplayList skiaDL;
     ASSERT_TRUE(skiaDL.reuseDisplayList(renderNode.get(), nullptr));
 
     // detach the list that you just attempted to reuse
@@ -93,13 +87,13 @@
 }
 
 TEST(SkiaDisplayList, syncContexts) {
-    SkRect bounds = SkRect::MakeWH(200, 200);
-    SkiaDisplayList skiaDL(bounds);
+    SkiaDisplayList skiaDL;
 
     SkCanvas dummyCanvas;
     TestUtils::MockFunctor functor;
     skiaDL.mChildFunctors.emplace_back(&functor, nullptr, &dummyCanvas);
 
+    SkRect bounds = SkRect::MakeWH(200, 200);
     VectorDrawableRoot vectorDrawable(new VectorDrawable::Group());
     vectorDrawable.mutateStagingProperties()->setBounds(bounds);
     skiaDL.mVectorDrawables.push_back(&vectorDrawable);
@@ -127,7 +121,7 @@
     DamageAccumulator damageAccumulator;
     info.damageAccumulator = &damageAccumulator;
 
-    SkiaDisplayList skiaDL(SkRect::MakeWH(200, 200));
+    SkiaDisplayList skiaDL;
 
     // prepare with a clean VD
     VectorDrawableRoot cleanVD(new VectorDrawable::Group());
@@ -170,8 +164,7 @@
 }
 
 TEST(SkiaDisplayList, updateChildren) {
-    SkRect bounds = SkRect::MakeWH(200, 200);
-    SkiaDisplayList skiaDL(bounds);
+    SkiaDisplayList skiaDL;
 
     sp<RenderNode> renderNode = new RenderNode();
     SkCanvas dummyCanvas;
diff --git a/media/java/android/media/AudioFocusRequest.java b/media/java/android/media/AudioFocusRequest.java
new file mode 100644
index 0000000..1b75a78
--- /dev/null
+++ b/media/java/android/media/AudioFocusRequest.java
@@ -0,0 +1,321 @@
+/*
+ * 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 android.media;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * A class to encapsulate information about an audio focus request.
+ * An {@code AudioFocusRequest} instance is built by {@link Builder}, and is used to
+ * request and abandon audio focus, respectively
+ * with {@link AudioManager#requestAudioFocus(AudioFocusRequest)} and
+ * {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
+ * <p>In the context of describing audio focus, the term "ducking" is used. It describes a temporary
+ * lowering of the audio level of an application in response to another application playing audio
+ * concurrently. An example is during the playback of driving directions,
+ * a user listening to music expects the music to "duck" during the playback of the message
+ * announcing directions.
+ */
+// TODO use this class to provide more documentation about audio focus and the new behaviors
+//      describe up to N, and after.
+public final class AudioFocusRequest {
+
+    // default attributes for the request when not specified
+    private final static AudioAttributes FOCUS_DEFAULT_ATTR = new AudioAttributes.Builder()
+            .setUsage(AudioAttributes.USAGE_MEDIA).build();
+
+    private final OnAudioFocusChangeListener mFocusListener; // may be null
+    private final Handler mListenerHandler;                  // may be null
+    private final AudioAttributes mAttr;                     // never null
+    private final int mFocusGain;
+    private final int mFlags;
+
+    //TODO implement use of optional handler
+    private AudioFocusRequest(OnAudioFocusChangeListener listener, Handler handler,
+            AudioAttributes attr, int focusGain, int flags) {
+        mFocusListener = listener;
+        mListenerHandler = handler;
+        mFocusGain = focusGain;
+        mAttr = attr;
+        mFlags = flags;
+    }
+
+    /**
+     * @hide
+     * Checks whether a focus gain constant is a valid value for an audio focus request.
+     * @param focusGain value to check
+     * @return true if focusGain is a valid value for an audio focus request.
+     */
+    final static boolean isValidFocusGain(int focusGain) {
+        switch (focusGain) {
+            case AudioManager.AUDIOFOCUS_GAIN:
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Returns the focus change listener set for this {@code AudioFocusRequest}.
+     * @return null if no {@link AudioManager.OnAudioFocusChangeListener} was set.
+     */
+    public @Nullable OnAudioFocusChangeListener getOnAudioFocusChangeListener() {
+        return mFocusListener;
+    }
+
+    /**
+     * Returns the {@link Handler} to be used for the focus change listener.
+     * @return the same {@code Handler} set in.
+     *   {@link Builder#setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}, or null
+     *   if no listener was set.
+     */
+    public @Nullable Handler getOnAudioFocusChangeListenerHandler() {
+        return mListenerHandler;
+    }
+
+    /**
+     * Returns the {@link AudioAttributes} set for this {@code AudioFocusRequest}, or the default
+     * attributes if none were set.
+     * @return non-null {@link AudioAttributes}.
+     */
+    public @NonNull AudioAttributes getAudioAttributes() {
+        return mAttr;
+    }
+
+    /**
+     * Returns the type of audio focus request configured for this {@code AudioFocusRequest}.
+     * @return one of {@link AudioManager#AUDIOFOCUS_GAIN},
+     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
+     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
+     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
+     */
+    public int getFocusGain() {
+        return mFocusGain;
+    }
+
+    /**
+     * Returns whether the application that would use this {@code AudioFocusRequest} would pause
+     * when it is requested to duck.
+     * @return the duck/pause behavior.
+     */
+    public boolean willPauseWhenDucked() {
+        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS)
+                == AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS;
+    }
+
+    /**
+     * Returns whether the application that would use this {@code AudioFocusRequest} supports
+     * a focus gain granted after a temporary request failure.
+     * @return whether delayed focus gain is supported.
+     */
+    public boolean acceptsDelayedFocusGain() {
+        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK)
+                == AudioManager.AUDIOFOCUS_FLAG_DELAY_OK;
+    }
+
+    int getFlags() {
+        return mFlags;
+    }
+
+    /**
+     * Builder class for {@link AudioFocusRequest} objects.
+     * <p> Here is an example where {@code Builder} is used to define the
+     * {@link AudioFocusRequest} for requesting audio focus:
+     *
+     * <pre class="prettyprint">
+     * mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
+     * mPlaybackAttributes = new AudioAttributes.Builder()
+     *         .setUsage(AudioAttributes.USAGE_GAME)
+     *         .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+     *         .build();
+     * mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+     *         .setAudioAttributes(mPlaybackAttributes)
+     *         .setAcceptsDelayedFocusGain(true)
+     *         .setOnAudioFocusChangeListener(mMyFocusListener, mMyHandler)
+     *         .build();
+     * mMediaPlayer = new MediaPlayer();
+     *  ...
+     * mMediaPlayer.setAudioAttributes(mPlaybackAttributes);
+     *  ...
+     * mAudioManager.requestAudioFocus(mFocusRequest);
+     *  ...
+     * mAudioManager.abandonAudioFocusRequest(mFocusRequest);
+     * </pre>
+     *
+     */
+    public static final class Builder {
+        private OnAudioFocusChangeListener mFocusListener;
+        private Handler mListenerHandler;
+        private AudioAttributes mAttr = FOCUS_DEFAULT_ATTR;
+        private int mFocusGain;
+        private boolean mPausesOnDuck = false;
+        private boolean mDelayedFocus = false;
+
+        /**
+         * Constructs a new {@code Builder}, and specifies how audio focus
+         * will be requested. Valid values for focus requests are
+         * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
+         * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
+         * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
+         * <p>By default there is no focus change listener, and the <code>AudioAttributes</code>
+         * have a usage of {@link AudioAttributes#USAGE_MEDIA}.
+         * @param focusGain the type of audio focus gain that will be requested
+         * @throws IllegalArgumentException thrown when an invalid focus gain type is used
+         */
+        public Builder(int focusGain) {
+            setFocusGain(focusGain);
+        }
+
+        /**
+         * Constructs a new {@code Builder} with all the properties of the {@code AudioFocusRequest}
+         * passed as parameter.
+         * Use this method when you want a new request to differ only by some properties.
+         * @param requestToCopy the non-null {@code AudioFocusRequest} to build a duplicate from.
+         * @throws IllegalArgumentException thrown when a null {@code AudioFocusRequest} is used.
+         */
+        public Builder(@NonNull AudioFocusRequest requestToCopy) {
+            if (requestToCopy == null) {
+                throw new IllegalArgumentException("Illegal null AudioFocusRequest");
+            }
+            mAttr = requestToCopy.mAttr;
+            mFocusListener = requestToCopy.mFocusListener;
+            mListenerHandler = requestToCopy.mListenerHandler;
+            mFocusGain = requestToCopy.mFocusGain;
+            mPausesOnDuck = requestToCopy.willPauseWhenDucked();
+            mDelayedFocus = requestToCopy.acceptsDelayedFocusGain();
+        }
+
+        /**
+         * Sets the type of focus gain that will be requested.
+         * Use this method to replace the focus gain when building a request by modifying an
+         * existing {@code AudioFocusRequest} instance.
+         * @param focusGain the type of audio focus gain that will be requested.
+         * @return this {@code Builder} instance
+         * @throws IllegalArgumentException thrown when an invalid focus gain type is used
+         */
+        public @NonNull Builder setFocusGain(int focusGain) {
+            if (!isValidFocusGain(focusGain)) {
+                throw new IllegalArgumentException("Illegal audio focus gain type " + focusGain);
+            }
+            mFocusGain = focusGain;
+            return this;
+        }
+
+        /**
+         * Sets the listener called when audio focus changes after being requested with
+         *   {@link AudioManager#requestAudioFocus(AudioFocusRequest)}, and until being abandoned
+         *   with {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
+         *   Note that only focus changes (gains and losses) affecting the focus owner are reported,
+         *   not gains and losses of other focus requesters in the system.
+         * @param listener the listener receiving the focus change notifications.
+         * @param handler the {@link Handler} for the thread on which to execute
+         *   the notifications. If {@code null}, the {@code Handler} associated with the main
+         *   {@link Looper} will be used.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException thrown when a non-null handler is used with a null
+         *   listener.
+         */
+        public @NonNull Builder setOnAudioFocusChangeListener(
+                @Nullable OnAudioFocusChangeListener listener, @Nullable Handler handler) {
+            if (listener == null && handler != null) {
+                throw new IllegalArgumentException(
+                        "Illegal non-null handler without a focus listener");
+            }
+            mFocusListener = listener;
+            mListenerHandler = handler;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioAttributes} to be associated with the focus request, and which
+         * describe the use case describing why focus is requested.
+         * As the focus requests typically precede audio playback, this information is used on
+         * certain platforms to declare the subsequent playback use case. It is therefore good
+         * practice to use in this method the same {@code AudioAttributes} as used for
+         * playback, see for example {@link MediaPlayer#setAudioAttributes(AudioAttributes)} in
+         * {@code MediaPlayer} or {@link AudioTrack.Builder#setAudioAttributes(AudioAttributes)}
+         * in {@code AudioTrack}.
+         * @param attributes the {@link AudioAttributes} for the focus request.
+         * @return this {@code Builder} instance.
+         * @throws IllegalArgumentException thrown when using null for the attributes.
+         */
+        public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes) {
+            if (attributes == null) {
+                throw new IllegalArgumentException("Illegal null AudioAttributes");
+            }
+            mAttr = attributes;
+            return this;
+        }
+
+        /**
+         * Declare the intended behavior of the application with regards to audio ducking.
+         * See more details in the {@link AudioFocusRequest} class documentation.
+         * @param pauseOnDuck use {@code true} if the application intends to pause audio playback
+         *    when losing focus with {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
+         *    If {@code true}, note that you must also set a focus listener to receive such an
+         *    event, with
+         *    {@link #setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}.
+         * @return this {@code Builder} instance.
+         */
+        public @NonNull Builder setWillPauseWhenDucked(boolean pauseOnDuck) {
+            mPausesOnDuck = pauseOnDuck;
+            return this;
+        }
+
+        /**
+         * Marks this focus request as compatible with delayed focus.
+         * See more details about delayed focus in the {@link AudioFocusRequest} class
+         * documentation.
+         * @param acceptsDelayedFocusGain use {@code true} if the application supports delayed
+         *    focus. If {@code true}, note that you must also set a focus listener to be notified
+         *    of delayed focus gain, with
+         *    {@link #setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}.
+         * @return this {@code Builder} instance
+         */
+        public @NonNull Builder setAcceptsDelayedFocusGain(boolean acceptsDelayedFocusGain) {
+            mDelayedFocus = acceptsDelayedFocusGain;
+            return this;
+        }
+
+        /**
+         * Builds a new {@code AudioFocusRequest} instance combining all the information gathered
+         * by this {@code Builder}'s configuration methods.
+         * @return the {@code AudioFocusRequest} instance qualified by all the properties set
+         *   on this {@code Builder}.
+         * @throws IllegalArgumentException thrown when focus request is set to accept delayed
+         *    focus, or to pause on duck, but no focus change listener was set.
+         */
+        public AudioFocusRequest build() {
+            if ((mDelayedFocus || mPausesOnDuck) && (mFocusListener == null)) {
+                throw new IllegalArgumentException(
+                        "Can't use delayed focus or pause on duck without a listener");
+            }
+            final int flags = 0
+                    | (mDelayedFocus ? AudioManager.AUDIOFOCUS_FLAG_DELAY_OK : 0)
+                    | (mPausesOnDuck ? AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS : 0);
+            return new AudioFocusRequest(mFocusListener, mListenerHandler,
+                    mAttr, mFocusGain, flags);
+        }
+    }
+}
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 95d354b..dc69a69 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2209,11 +2209,11 @@
      */
     public static final int AUDIOFOCUS_REQUEST_GRANTED = 1;
      /**
-      * @hide
       * A focus change request whose granting is delayed: the request was successful, but the
       * requester will only be granted audio focus once the condition that prevented immediate
       * granting has ended.
-      * See {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
+      * See {@link #requestAudioFocus(AudioFocusRequest)} and
+      * {@link AudioFocusRequest.Builder#setAcceptsDelayedFocusGain(boolean)}
       */
     public static final int AUDIOFOCUS_REQUEST_DELAYED = 2;
 
@@ -2293,6 +2293,44 @@
             | AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS | AUDIOFOCUS_FLAG_LOCK;
 
     /**
+     * Request audio focus.
+     * See the {@link AudioFocusRequest} for information about the options available to configure
+     * your request, and notification of focus gain and loss.
+     * @param focusRequest a {@link AudioFocusRequest} instance used to configure how focus is
+     *   requested.
+     * @return {@link #AUDIOFOCUS_REQUEST_FAILED}, {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *     or {@link #AUDIOFOCUS_REQUEST_DELAYED}.
+     *     <br>Note that the return value is never {@link #AUDIOFOCUS_REQUEST_DELAYED} when focus
+     *     is requested without building the {@link AudioFocusRequest} with
+     *     {@link AudioFocusRequest.Builder#setAcceptsDelayedFocusGain(boolean)} set to
+     *     {@code true}.
+     * @throws IllegalArgumentException if passed a null argument
+     */
+    public int requestAudioFocus(@NonNull AudioFocusRequest focusRequest) {
+        if (focusRequest == null) {
+            throw new IllegalArgumentException("Illegal null AudioFocusRequest");
+        }
+        return requestAudioFocus(focusRequest.getOnAudioFocusChangeListener(),
+                focusRequest.getAudioAttributes(),
+                focusRequest.getFocusGain(), focusRequest.getFlags(), null /* no AudioPolicy*/);
+    }
+
+    /**
+     *  Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
+     *  @param focusRequest the {@link AudioFocusRequest} that was used when requesting focus
+     *      with {@link #requestAudioFocus(AudioFocusRequest)}.
+     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *  @throws IllegalArgumentException if passed a null argument
+     */
+    public int abandonAudioFocusRequest(@NonNull AudioFocusRequest focusRequest) {
+        if (focusRequest == null) {
+            throw new IllegalArgumentException("Illegal null AudioFocusRequest");
+        }
+        return abandonAudioFocus(focusRequest.getOnAudioFocusChangeListener(),
+                focusRequest.getAudioAttributes());
+    }
+
+    /**
      * @hide
      * Request audio focus.
      * Send a request to obtain the audio focus. This method differs from
@@ -2372,8 +2410,7 @@
         if (requestAttributes == null) {
             throw new IllegalArgumentException("Illegal null AudioAttributes argument");
         }
-        if ((durationHint < AUDIOFOCUS_GAIN) ||
-                (durationHint > AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE)) {
+        if (!AudioFocusRequest.isValidFocusGain(durationHint)) {
             throw new IllegalArgumentException("Invalid duration hint");
         }
         if (flags != (flags & AUDIOFOCUS_FLAGS_SYSTEM)) {
diff --git a/media/java/android/media/ICas.aidl b/media/java/android/media/ICas.aidl
deleted file mode 100644
index 6b2ce4a..0000000
--- a/media/java/android/media/ICas.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 android.media;
-
-import android.media.MediaCas;
-
-/** @hide */
-interface ICas {
-    void setPrivateData(in byte[] pvtData);
-    byte[] openSession(int program_number);
-    byte[] openSessionForStream(int program_number, int elementary_PID);
-    void closeSession(in byte[] sessionId);
-    void setSessionPrivateData(in byte[] sessionId, in byte[] pvtData);
-    void processEcm(in byte[] sessionId, in MediaCas.ParcelableCasData ecm);
-    void processEmm(in MediaCas.ParcelableCasData emm);
-    void sendEvent(int event, int arg, in @nullable byte[] eventData);
-    void provision(String provisionString);
-    void refreshEntitlements(int refreshType, in @nullable byte[] refreshData);
-    void release();
-}
\ No newline at end of file
diff --git a/media/java/android/media/IDescrambler.aidl b/media/java/android/media/IDescrambler.aidl
deleted file mode 100644
index fdf99eb..0000000
--- a/media/java/android/media/IDescrambler.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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 android.media;
-
-import android.media.MediaDescrambler;
-
-/** @hide */
-interface IDescrambler {
-    void setMediaCasSession(in byte[] sessionId);
-    boolean requiresSecureDecoderComponent(String mime);
-    int descramble(in MediaDescrambler.DescrambleInfo descrambleInfo);
-    void release();
-}
\ No newline at end of file
diff --git a/media/java/android/media/IMediaCasService.aidl b/media/java/android/media/IMediaCasService.aidl
deleted file mode 100644
index 44f6825..0000000
--- a/media/java/android/media/IMediaCasService.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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 android.media;
-
-import android.media.IDescrambler;
-import android.media.ICas;
-import android.media.ICasListener;
-import android.media.MediaCas;
-
-/** @hide */
-interface IMediaCasService {
-    MediaCas.ParcelableCasPluginDescriptor[] enumeratePlugins();
-    boolean isSystemIdSupported(int CA_system_id);
-    ICas createPlugin(int CA_system_id, ICasListener listener);
-    boolean isDescramblerSupported(int CA_system_id);
-    IDescrambler createDescrambler(int CA_system_id);
-}
-
diff --git a/media/java/android/media/MediaCas.aidl b/media/java/android/media/MediaCas.aidl
deleted file mode 100644
index cb8d0c6..0000000
--- a/media/java/android/media/MediaCas.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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 android.media;
-
-/** @hide */
-parcelable MediaCas.ParcelableCasPluginDescriptor cpp_header "media/MediaCasDefs.h";
-
-/** @hide */
-parcelable MediaCas.ParcelableCasData cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 1ca9658..d264127 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -3188,9 +3188,55 @@
     /**
      *  Returns Analytics/Metrics data about the current content being
      *
-     * @return a Bundle containint the set of attributes and values available
+     * @return a Bundle containing the set of attributes and values available
      * for the media being handled by this instance of MediaCodec
      *
+     *  <table style="width: 0%">
+     *   <thead>
+     *    <tr>
+     *     <th>Key</th>
+     *     <th>Type</th>
+     *     <th>Description</th>
+     *    </tr>
+     *   </thead>
+     *   <tbody>
+     *    <tr>
+     *     <td>{@code "codec"}</td>
+     *     <td>String</td>
+     *     <td>Identifies the particular codec in use</td>
+     *    </tr><tr>
+     *     <td>{@code "mime"}</td>
+     *     <td>String</td>
+     *     <td>Mime type of the media being encoded/decoded</td>
+     *    </tr><tr>
+     *     <td>{@code "mode"}</td>
+     *     <td>String</td>
+     *     <td>"Audio" or "Video"</td>
+     *    </tr><tr>
+     *     <td>{@code "secure"}</td>
+     *     <td>Integer</td>
+     *     <td>Indicates whether the code is operating on secure content and
+     *         may also use capabilities in android.media.MediaCrypto</td>
+     *    </tr><tr>
+     *     <td>{@code "height"}</td>
+     *     <td>Integer</td>
+     *     <td>Height (pixels); valid only when mode=video</td>
+     *    </tr><tr>
+     *     <td>{@code "width"}</td>
+     *     <td>Integer</td>
+     *     <td>Width (pixels); valid only when mode=video</td>
+     *    </tr><tr>
+     *     <td>{@code "rotation"}</td>
+     *     <td>Integer</td>
+     *     <td>rotation (degrees) to orient the video onto the target surface;
+     *         valid only when mode=video. Note there may be additional
+     *         rotations applied when the surface is mapped to the screen.</td>
+     *    </tr>
+     *   </tbody>
+     *  </table>
+     *
+     *  Additional fields specific to individual codecs will also appear in
+     *  the return value.
      */
     public native Bundle getMetrics();
 
diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java
index 01ae36f..b9e409d 100644
--- a/media/java/android/media/MediaExtractor.java
+++ b/media/java/android/media/MediaExtractor.java
@@ -656,6 +656,33 @@
      * @return the set of keys and values available for the media being
      * handled by this instance of MediaExtractor
      *
+     *  <table style="width: 0%">
+     *   <thead>
+     *    <tr>
+     *     <th>Key</th>
+     *     <th>Type</th>
+     *     <th>Description</th>
+     *    </tr>
+     *   </thead>
+     *   <tbody>
+     *    <tr>
+     *     <td>{@code "fmt"}</td>
+     *     <td>String</td>
+     *     <td>The container format (which determines the handler)</td>
+     *    </tr><tr>
+     *     <td>{@code "mime"}</td>
+     *     <td>String</td>
+     *     <td>Mime type of the container.</td>
+     *    </tr><tr>
+     *     <td>{@code "ntrk"}</td>
+     *     <td>Integer</td>
+     *     <td>Number of tracks in the container</td>
+     *    </tr>
+     *   </tbody>
+     *  </table>
+     *
+     *  Additional fields specific to individual codecs will also appear in
+     *  the return value.
      */
     public native Bundle getMetrics();
 
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 1ebbe85..b85c911 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1251,6 +1251,11 @@
     public void prepare() throws IOException, IllegalStateException {
         _prepare();
         scanInternalSubtitleTracks();
+
+        // DrmInfo, if any, has been resolved by now.
+        synchronized (mDrmLock) {
+            mDrmInfoResolved = true;
+        }
     }
 
     private native void _prepare() throws IOException, IllegalStateException;
@@ -1493,6 +1498,64 @@
      *
      * @return the a map of attributes and values available for this video
      * player or null if no metrics are available.
+     *
+     *  <table style="width: 0%">
+     *   <thead>
+     *    <tr>
+     *     <th>Key</th>
+     *     <th>Type</th>
+     *     <th>Description</th>
+     *    </tr>
+     *   </thead>
+     *   <tbody>
+     *    <tr>
+     *     <td>{@code "video/codec"}</td>
+     *     <td>String</td>
+     *     <td>Identifies the video codec in use</td>
+     *    </tr><tr>
+     *     <td>{@code "video/mime"}</td>
+     *     <td>String</td>
+     *     <td>Mime type of the video being encoded/decoded</td>
+     *    </tr><tr>
+     *     <td>{@code "audio/codec"}</td>
+     *     <td>String</td>
+     *     <td>Identifies the audio codec in use</td>
+     *    </tr><tr>
+     *     <td>{@code "audio/mime"}</td>
+     *     <td>String</td>
+     *     <td>Mime type of the audio being encoded/decoded</td>
+     *    </tr><tr>
+     *     <td>{@code "ht"}</td>
+     *     <td>Integer</td>
+     *     <td>Height (pixels); valid only when mode=video</td>
+     *    </tr><tr>
+     *     <td>{@code "wid"}</td>
+     *     <td>Integer</td>
+     *     <td>Width (pixels); valid only when mode=video</td>
+     *    </tr><tr>
+     *     <td>{@code "frame"}</td>
+     *     <td>Integer</td>
+     *     <td>Number of decoded video frames sent to the display</td>
+     *    </tr><tr>
+     *     <td>{@code "dropped"}</td>
+     *     <td>Integer</td>
+     *     <td>Number of decoded video frames that were not sent to display.
+     *         These frames were dropped by the player.</td>
+     *    </tr><tr>
+     *     <td>{@code "durationMs"}</td>
+     *     <td>Integer</td>
+     *     <td>The length of the media being played (in ms), e.g. "This video lasts for 30000 milliseconds". </td>
+     *    </tr><tr>
+     *     <td>{@code "playingMs"}</td>
+     *     <td>Integer</td>
+     *     <td>The time the media has been played (in ms). If you watch a
+     *         30 second twice through, this will report 60000 ms.</td>
+     *    </tr>
+     *   </tbody>
+     *  </table>
+     *
+     *  Additional fields specific to individual codecs will also appear in
+     *  the return value.
      */
     public native Bundle getMetrics();
 
@@ -3149,12 +3212,6 @@
                     sendMessage(msg2);
                 }
 
-                // MEDIA_DRM_INFO is fired (if available) before MEDIA_PREPARED.
-                // An empty mDrmInfo indicates prepared is done but the source is not DRM protected.
-                // Setting this before the callback so onPreparedListener can call getDrmInfo to
-                // get the right state
-                mDrmInfoResolved = true;
-
                 OnPreparedListener onPreparedListener = mOnPreparedListener;
                 if (onPreparedListener != null)
                     onPreparedListener.onPrepared(mMediaPlayer);
@@ -3166,12 +3223,14 @@
                 if (msg.obj == null) {
                     Log.w(TAG, "MEDIA_DRM_INFO msg.obj=NULL");
                 } else if (msg.obj instanceof Parcel) {
-                    Parcel parcel = (Parcel)msg.obj;
-                    DrmInfo drmInfo = new DrmInfo(parcel);
+                    // The parcel was parsed already in postEventFromNative
+                    DrmInfo drmInfo = null;
 
                     OnDrmInfoHandlerDelegate onDrmInfoHandlerDelegate;
                     synchronized (mDrmLock) {
-                        mDrmInfo = drmInfo.makeCopy();
+                        if (mOnDrmInfoHandlerDelegate != null && mDrmInfo != null) {
+                            drmInfo = mDrmInfo.makeCopy();
+                        }
                         // local copy while keeping the lock
                         onDrmInfoHandlerDelegate = mOnDrmInfoHandlerDelegate;
                     }
@@ -3366,10 +3425,43 @@
             return;
         }
 
-        if (what == MEDIA_INFO && arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
-            // this acquires the wakelock if needed, and sets the client side state
-            mp.start();
+        switch (what) {
+        case MEDIA_INFO:
+            if (arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
+                // this acquires the wakelock if needed, and sets the client side state
+                mp.start();
+            }
+            break;
+
+        case MEDIA_DRM_INFO:
+            // We need to derive mDrmInfo before prepare() returns so processing it here
+            // before the notification is sent to EventHandler below. EventHandler runs in the
+            // notification looper so its handleMessage might process the event after prepare()
+            // has returned.
+            Log.v(TAG, "postEventFromNative MEDIA_DRM_INFO");
+            if (obj instanceof Parcel) {
+                Parcel parcel = (Parcel)obj;
+                DrmInfo drmInfo = new DrmInfo(parcel);
+                synchronized (mp.mDrmLock) {
+                    mp.mDrmInfo = drmInfo;
+                }
+            } else {
+                Log.w(TAG, "MEDIA_DRM_INFO msg.obj of unexpected type " + obj);
+            }
+            break;
+
+        case MEDIA_PREPARED:
+            // By this time, we've learned about DrmInfo's presence or absence. This is meant
+            // mainly for prepareAsync() use case. For prepare(), this still can run to a race
+            // condition b/c MediaPlayerNative releases the prepare() lock before calling notify
+            // so we also set mDrmInfoResolved in prepare().
+            synchronized (mp.mDrmLock) {
+                mp.mDrmInfoResolved = true;
+            }
+            break;
+
         }
+
         if (mp.mEventHandler != null) {
             Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);
             mp.mEventHandler.sendMessage(m);
@@ -4093,16 +4185,16 @@
      * If the device has not been provisioned before, this call also provisions the device
      * which involves accessing the provisioning server and can take a variable time to
      * complete depending on the network connectivity.
-     * If OnDrmPreparedListener is registered, prepareDrm() runs in non-blocking
+     * If {@code OnDrmPreparedListener} is registered, prepareDrm() runs in non-blocking
      * mode by launching the provisioning in the background and returning. The listener
      * will be called when provisioning and preperation has finished. If a
-     * OnDrmPreparedListener is not registered, prepareDrm() waits till provisioning
+     * {@code OnDrmPreparedListener} is not registered, prepareDrm() waits till provisioning
      * and preperation has finished, i.e., runs in blocking mode.
      * <p>
-     * If OnDrmPreparedListener is registered, it is called to indicated the DRM session
-     * being ready regardless of blocking or non-blocking mode. The application should
-     * not make any assumption about its call sequence (e.g., before or after prepareDrm
-     * returns) or the thread context that will execute the listener.
+     * If {@code OnDrmPreparedListener} is registered, it is called to indicate the DRM
+     * session being ready. The application should not make any assumption about its call
+     * sequence (e.g., before or after prepareDrm returns), or the thread context that will
+     * execute the listener (unless the listener is registered with a handler thread).
      * <p>
      *
      * @param uuid The UUID of the crypto scheme.
diff --git a/media/java/android/media/session/ICallback.aidl b/media/java/android/media/session/ICallback.aidl
new file mode 100644
index 0000000..322bffa
--- /dev/null
+++ b/media/java/android/media/session/ICallback.aidl
@@ -0,0 +1,35 @@
+/* Copyright (C) 2016 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 android.media.session;
+
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.media.session.MediaSession;
+import android.view.KeyEvent;
+
+/**
+ * @hide
+ */
+oneway interface ICallback {
+    void onMediaKeyEventDispatchedToMediaSession(in KeyEvent event,
+            in MediaSession.Token sessionToken);
+    void onMediaKeyEventDispatchedToMediaButtonReceiver(in KeyEvent event,
+            in ComponentName mediaButtonReceiver);
+
+    void onAddressedPlayerChangedToMediaSession(in MediaSession.Token sessionToken);
+    void onAddressedPlayerChangedToMediaButtonReceiver(in ComponentName mediaButtonReceiver);
+}
+
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index 8a98773..5fcb430 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -18,8 +18,9 @@
 import android.content.ComponentName;
 import android.media.IRemoteVolumeController;
 import android.media.session.IActiveSessionsListener;
-import android.media.session.IOnVolumeKeyLongPressListener;
+import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
+import android.media.session.IOnVolumeKeyLongPressListener;
 import android.media.session.ISession;
 import android.media.session.ISessionCallback;
 import android.os.Bundle;
@@ -45,7 +46,7 @@
     // For PhoneWindowManager to precheck media keys
     boolean isGlobalPriorityActive();
 
+    void setCallback(in ICallback callback);
     void setOnVolumeKeyLongPressListener(in IOnVolumeKeyLongPressListener listener);
     void setOnMediaKeyListener(in IOnMediaKeyListener listener);
 }
-
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 80d2a0c..83793ae 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -71,6 +71,7 @@
 
     private Context mContext;
 
+    private CallbackImpl mCallback;
     private OnVolumeKeyLongPressListenerImpl mOnVolumeKeyLongPressListener;
     private OnMediaKeyListenerImpl mOnMediaKeyListener;
 
@@ -411,6 +412,36 @@
     }
 
     /**
+     * Set a {@link Callback}.
+     *
+     * <p>System can only have a single callback, and the callback can only be set by
+     * Bluetooth service process.
+     *
+     * @param callback A {@link Callback}. {@code null} to reset.
+     * @param handler The handler on which the callback should be invoked, or {@code null}
+     *            if the callback should be invoked on the calling thread's looper.
+     * @hide
+     */
+    public void setCallback(@Nullable Callback callback, @Nullable Handler handler) {
+        synchronized (mLock) {
+            try {
+                if (callback == null) {
+                    mCallback = null;
+                    mService.setCallback(null);
+                } else {
+                    if (handler == null) {
+                        handler = new Handler();
+                    }
+                    mCallback = new CallbackImpl(callback, handler);
+                    mService.setCallback(mCallback);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set media key callback", e);
+            }
+        }
+    }
+
+    /**
      * Listens for changes to the list of active sessions. This can be added
      * using {@link #addOnActiveSessionsChangedListener}.
      */
@@ -439,12 +470,65 @@
     public interface OnMediaKeyListener {
         /**
          * Called when the media key is pressed.
+         * <p>If the listener consumes the initial down event (i.e. ACTION_DOWN with
+         * repeat count zero), it must also comsume all following key events.
+         * (i.e. ACTION_DOWN with repeat count more than zero, and ACTION_UP).
          * <p>If it takes more than 1s to return, the key event will be sent to
          * other media sessions.
          */
         boolean onMediaKey(KeyEvent event);
     }
 
+    /**
+     * Callbacks for the media session service.
+     *
+     * <p>Called when a media key event is dispatched or the addressed player is changed.
+     * The addressed player is either the media session or the media button receiver that will
+     * receive media key events.
+     * @hide
+     */
+    public static abstract class Callback {
+        /**
+         * Called when a media key event is dispatched to the media session
+         * through the media session service.
+         *
+         * @param event Dispatched media key event.
+         * @param sessionToken The media session's token.
+         */
+        public abstract void onMediaKeyEventDispatched(KeyEvent event,
+                MediaSession.Token sessionToken);
+
+        /**
+         * Called when a media key event is dispatched to the media button receiver
+         * through the media session service.
+         * <p>MediaSessionService may broadcast key events to the media button receiver
+         * when reviving playback after the media session is released.
+         *
+         * @param event Dispatched media key event.
+         * @param mediaButtonReceiver The media button receiver.
+         */
+        public abstract void onMediaKeyEventDispatched(KeyEvent event,
+                ComponentName mediaButtonReceiver);
+
+        /**
+         * Called when the addressed player is changed to a media session.
+         * <p>One of the {@ #onAddressedPlayerChanged} will be also called immediately after
+         * {@link #setCallback} if the addressed player exists.
+         *
+         * @param sessionToken The media session's token.
+         */
+        public abstract void onAddressedPlayerChanged(MediaSession.Token sessionToken);
+
+        /**
+         * Called when the addressed player is changed to the media button receiver.
+         * <p>One of the {@ #onAddressedPlayerChanged} will be also called immediately after
+         * {@link #setCallback} if the addressed player exists.
+         *
+         * @param mediaButtonReceiver The media button receiver.
+         */
+        public abstract void onAddressedPlayerChanged(ComponentName mediaButtonReceiver);
+    }
+
     private static final class SessionsChangedWrapper {
         private Context mContext;
         private OnActiveSessionsChangedListener mListener;
@@ -534,9 +618,64 @@
                 public void run() {
                     boolean handled = mListener.onMediaKey(event);
                     Log.d(TAG, "The media key listener is returned " + handled);
-                    result.send(
-                            handled ? RESULT_MEDIA_KEY_HANDLED : RESULT_MEDIA_KEY_NOT_HANDLED,
-                            null);
+                    if (result != null) {
+                        result.send(
+                                handled ? RESULT_MEDIA_KEY_HANDLED : RESULT_MEDIA_KEY_NOT_HANDLED,
+                                null);
+                    }
+                }
+            });
+        }
+    }
+
+    private static final class CallbackImpl extends ICallback.Stub {
+        private final Callback mCallback;
+        private final Handler mHandler;
+
+        public CallbackImpl(@NonNull Callback callback, @NonNull Handler handler) {
+            mCallback = callback;
+            mHandler = handler;
+        }
+
+        @Override
+        public void onMediaKeyEventDispatchedToMediaSession(KeyEvent event,
+                MediaSession.Token sessionToken) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onMediaKeyEventDispatched(event, sessionToken);
+                }
+            });
+        }
+
+        @Override
+        public void onMediaKeyEventDispatchedToMediaButtonReceiver(KeyEvent event,
+                ComponentName mediaButtonReceiver) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onMediaKeyEventDispatched(event, mediaButtonReceiver);
+                }
+            });
+        }
+
+        @Override
+        public void onAddressedPlayerChangedToMediaSession(MediaSession.Token sessionToken) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onAddressedPlayerChanged(sessionToken);
+                }
+            });
+        }
+
+        @Override
+        public void onAddressedPlayerChangedToMediaButtonReceiver(
+                ComponentName mediaButtonReceiver) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onAddressedPlayerChanged(mediaButtonReceiver);
                 }
             });
         }
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 1b53d72..6e15d8d 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -70,9 +70,79 @@
     private static final String PATH_PROGRAM = "program";
     private static final String PATH_RECORDED_PROGRAM = "recorded_program";
     private static final String PATH_PREVIEW_PROGRAM = "preview_program";
+    private static final String PATH_WATCH_NEXT_PROGRAM = "watch_next_program";
     private static final String PATH_PASSTHROUGH = "passthrough";
 
     /**
+     * Activity Action: sent by an application telling the system to set the given channel as
+     * browsable. This is only relevant to channels with {@link Channels#TYPE_PREVIEW} type.
+     *
+     * <p>The intent must contain the following bundle parameters:
+     * <ul>
+     *     <li>{@link #EXTRA_CHANNEL_ID}: ID for the {@link Channels#TYPE_PREVIEW} channel as a long
+     *     integer.</li>
+     *     <li>{@link #EXTRA_PACKAGE_NAME}: the package name of the requesting application.</li>
+     * </ul>
+     */
+    public static final String ACTION_MAKE_CHANNEL_BROWSABLE =
+            "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
+
+    /**
+     * Broadcast Action: sent by the system to tell the target TV input that one of its preview
+     * program's browsable state is disabled, i.e., it will no longer be shown to users, which, for
+     * example, might be a result of users' interaction with UI. The input is expected to delete the
+     * preview program from the content provider.
+     *
+     * <p>The intent must contain the following bundle parameter:
+     * <ul>
+     *     <li>{@link #EXTRA_PREVIEW_PROGRAM_ID}: the disabled preview program ID.</li>
+     * </ul>
+     */
+    public static final String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED =
+            "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
+
+    /**
+     * Broadcast Action: sent by the system to tell the target TV input that one of its "watch next"
+     * program's browsable state is disabled, i.e., it will no longer be shown to users, which, for
+     * example, might be a result of users' interaction with UI. The input is expected to delete the
+     * "watch next" program from the content provider.
+     *
+     * <p>The intent must contain the following bundle parameter:
+     * <ul>
+     *     <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the disabled "watch next" program ID.</li>
+     * </ul>
+     */
+    public static final String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED =
+            "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED";
+
+    /**
+     * Broadcast Action: sent by the system to tell the target TV input that one of its existing
+     * preview programs is added to the watch next programs table by user.
+     *
+     * <p>The intent must contain the following bundle parameters:
+     * <ul>
+     *     <li>{@link #EXTRA_PREVIEW_PROGRAM_ID}: the ID of the existing preview program.</li>
+     *     <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the ID of the new watch next program.</li>
+     * </ul>
+     */
+    public static final String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT =
+            "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
+
+    /** The key for a bundle parameter containing a channel ID as a long integer */
+    public static final String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
+
+    /** The key for a bundle parameter containing a package name as a string. */
+    public static final String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
+
+    /** The key for a bundle parameter containing a program ID as a long integer. */
+    public static final String EXTRA_PREVIEW_PROGRAM_ID =
+            "android.media.tv.extra.PREVIEW_PROGRAM_ID";
+
+    /** The key for a bundle parameter containing a watch next program ID as a long integer. */
+    public static final String EXTRA_WATCH_NEXT_PROGRAM_ID =
+            "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID";
+
+    /**
      * The method name to get existing columns in the given table of the specified content provider.
      *
      * <p>The method caller must provide the following parameter:
@@ -421,6 +491,15 @@
     }
 
     /**
+     * Builds a URI that points to a specific watch next program.
+     *
+     * @param watchNextProgramId The ID of the watch next program to point to.
+     */
+    public static final Uri buildWatchNextProgramUri(long watchNextProgramId) {
+        return ContentUris.withAppendedId(WatchNextPrograms.CONTENT_URI, watchNextProgramId);
+    }
+
+    /**
      * Builds a URI that points to a specific program the user watched.
      *
      * @param watchedProgramId The ID of the watched program to point to.
@@ -492,17 +571,6 @@
      */
     public interface BaseProgramColumns extends BaseTvColumns {
         /**
-         * The ID of the TV channel that provides this TV program.
-         *
-         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
-         *
-         * <p>This is a required field.
-         *
-         * <p>Type: INTEGER (long)
-         */
-        public static final String COLUMN_CHANNEL_ID = "channel_id";
-
-        /**
          * The title of this TV program.
          *
          * <p>If this program is an episodic TV show, it is recommended that the title is the series
@@ -766,6 +834,591 @@
         public static final String COLUMN_VERSION_NUMBER = "version_number";
     }
 
+    /**
+     * Common base for the tables of preview programs.
+     */
+    public interface BasePreviewProgramColumns extends BaseProgramColumns {
+
+        /** @hide */
+        @StringDef({
+                TYPE_MOVIE,
+                TYPE_TV_SERIES,
+                TYPE_TV_SEASON,
+                TYPE_TV_EPISODE,
+                TYPE_CLIP,
+                TYPE_EVENT,
+                TYPE_CHANNEL,
+                TYPE_TRACK,
+                TYPE_ALBUM,
+                TYPE_ARTIST,
+                TYPE_PLAYLIST,
+                TYPE_STATION,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Type {}
+
+        /**
+         * The program type for movie.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_MOVIE = "TYPE_MOVIE";
+
+        /**
+         * The program type for TV series.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+
+        /**
+         * The program type for TV season.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+
+        /**
+         * The program type for TV episode.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+
+        /**
+         * The program type for clip.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_CLIP = "TYPE_CLIP";
+
+        /**
+         * The program type for event.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_EVENT = "TYPE_EVENT";
+
+        /**
+         * The program type for channel.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_CHANNEL = "TYPE_CHANNEL";
+
+        /**
+         * The program type for track.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_TRACK = "TYPE_TRACK";
+
+        /**
+         * The program type for album.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ALBUM = "TYPE_ALBUM";
+
+        /**
+         * The program type for artist.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ARTIST = "TYPE_ARTIST";
+
+        /**
+         * The program type for playlist.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+
+        /**
+         * The program type for station.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_STATION = "TYPE_STATION";
+
+        /** @hide */
+        @StringDef({
+                ASPECT_RATIO_16_9,
+                ASPECT_RATIO_3_2,
+                ASPECT_RATIO_1_1,
+                ASPECT_RATIO_2_3,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface AspectRatio {}
+
+        /**
+         * The aspect ratio for 16:9.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+
+        /**
+         * The aspect ratio for 3:2.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+
+        /**
+         * The aspect ratio for 1:1.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+
+        /**
+         * The aspect ratio for 2:3.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+
+        /** @hide */
+        @StringDef({
+                AVAILABILITY_AVAILABLE,
+                AVAILABILITY_FREE_WITH_SUBSCRIPTION,
+                AVAILABILITY_PAID_CONTENT,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Availability {}
+
+        /**
+         * The availability for "available to this user".
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        public static final String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+
+        /**
+         * The availability for "free with subscription".
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        public static final String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
+                "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
+
+        /**
+         * The availability for "paid content, either to-own or rental
+         * (user has not purchased/rented).
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+
+        /** @hide */
+        @StringDef({
+                INTERACTION_TYPE_LISTENS,
+                INTERACTION_TYPE_FOLLOWERS,
+                INTERACTION_TYPE_FANS,
+                INTERACTION_TYPE_LIKES,
+                INTERACTION_TYPE_THUMBS,
+                INTERACTION_TYPE_VIEWS,
+                INTERACTION_TYPE_VIEWERS,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface InteractionType {}
+
+        /**
+         * The interaction type for "listens".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+
+        /**
+         * The interaction type for "followers".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+
+        /**
+         * The interaction type for "fans".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+
+        /**
+         * The interaction type for "likes".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+
+        /**
+         * The interaction type for "thumbs".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+
+        /**
+         * The interaction type for "views".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+
+        /**
+         * The interaction type for "viewers".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+
+        /** @hide */
+        @StringDef({
+                REVIEW_RATING_STYLE_STARS,
+                REVIEW_RATING_STYLE_THUMBS_UP_DOWN,
+                REVIEW_RATING_STYLE_PERCENTAGE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ReviewRatingStyle {}
+
+        /**
+         * The review rating style for five star rating.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+
+        /**
+         * The review rating style for thumbs-up and thumbs-down rating.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
+                "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
+
+        /**
+         * The review rating style for 0 to 100 point system.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String REVIEW_RATING_STYLE_PERCENTAGE =
+                "REVIEW_RATING_STYLE_PERCENTAGE";
+
+        /**
+         * The type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #TYPE_MOVIE},
+         * {@link #TYPE_TV_SERIES},
+         * {@link #TYPE_TV_SEASON},
+         * {@link #TYPE_TV_EPISODE},
+         * {@link #TYPE_CLIP},
+         * {@link #TYPE_EVENT},
+         * {@link #TYPE_CHANNEL},
+         * {@link #TYPE_TRACK},
+         * {@link #TYPE_ALBUM},
+         * {@link #TYPE_ARTIST},
+         * {@link #TYPE_PLAYLIST}, and
+         * {@link #TYPE_STATION}.
+         *
+         * <p>This is a required field if the program is from a {@link Channels#TYPE_PREVIEW}
+         * channel.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_TYPE = "type";
+
+        /**
+         * The aspect ratio of the poster art for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #ASPECT_RATIO_16_9},
+         * {@link #ASPECT_RATIO_3_2},
+         * {@link #ASPECT_RATIO_1_1}, and
+         * {@link #ASPECT_RATIO_2_3}.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+
+        /**
+         * The aspect ratio of the thumbnail for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #ASPECT_RATIO_16_9},
+         * {@link #ASPECT_RATIO_3_2},
+         * {@link #ASPECT_RATIO_1_1}, and
+         * {@link #ASPECT_RATIO_2_3}.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+
+        /**
+         * The URI for the logo of this TV program.
+         *
+         * <p>This is a small badge shown on top of the poster art or thumbnail representing the
+         * source of the content.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_LOGO_URI = "logo_uri";
+
+        /**
+         * The availability of this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #AVAILABILITY_AVAILABLE},
+         * {@link #AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and
+         * {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_AVAILABILITY = "availability";
+
+        /**
+         * The starting price of this TV program.
+         *
+         * <p>This indicates the lowest regular acquisition cost of the content. It is only used
+         * if the availability of the program is {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_OFFER_PRICE
+         */
+        public static final String COLUMN_STARTING_PRICE = "starting_price";
+
+        /**
+         * The offer price of this TV program.
+         *
+         * <p>This is the promotional cost of the content. It is only used if the availability of
+         * the program is {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_STARTING_PRICE
+         */
+        public static final String COLUMN_OFFER_PRICE = "offer_price";
+
+        /**
+         * The release date of this TV program.
+         *
+         * <p>The value should be in the form of either "yyyy-MM-dd" or "yyyy".
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_RELEASE_DATE = "release_date";
+
+        /**
+         * The count of the items included in this TV program.
+         *
+         * <p>This is only relevant if the program represents a collection of items such as series,
+         * episodes, or music tracks.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_ITEM_COUNT = "item_count";
+
+        /**
+         * The flag indicating whether this TV program is live or not.
+         *
+         * <p>A value of 1 indicates that the content is airing and should be consumed now, a value
+         * of 0 indicates that the content is off the air and does not need to be consumed at the
+         * present time. If not specified, the value is set to 0 (not live) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_LIVE = "live";
+
+        /**
+         * The internal ID used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+
+        /**
+         * The URI for the preview video.
+         *
+         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}. The data in the column must be
+         * a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+
+        /**
+         * The last playback position (in milliseconds) of the preview video.
+         *
+         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
+                "last_playback_position_millis";
+
+        /**
+         * The duration (in milliseconds) of the preview video.
+         *
+         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_DURATION_MILLIS = "duration_millis";
+
+        /**
+         * The intent URI which is launched when the preview video is selected.
+         *
+         * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
+         * and converted back to the original intent with {@link Intent#parseUri}. The intent is
+         * launched when the user selects the preview video item.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_APP_LINK_INTENT_URI =
+                "app_link_intent_uri";
+
+        /**
+         * The flag indicating whether this program is transient or not.
+         *
+         * <p>A value of 1 indicates that the channel will be automatically removed by the system on
+         * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not
+         * specified, this value is set to 0 (not transient) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @see Channels#COLUMN_TRANSIENT
+         * @hide
+         */
+        @SystemApi
+        public static final String COLUMN_TRANSIENT = "transient";
+
+        /**
+         * The type of interaction for this TV program.
+         *
+         * <p> The value should match one of the followings:
+         * {@link #INTERACTION_TYPE_LISTENS},
+         * {@link #INTERACTION_TYPE_FOLLOWERS},
+         * {@link #INTERACTION_TYPE_FANS},
+         * {@link #INTERACTION_TYPE_LIKES},
+         * {@link #INTERACTION_TYPE_THUMBS},
+         * {@link #INTERACTION_TYPE_VIEWS}, and
+         * {@link #INTERACTION_TYPE_VIEWERS}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_INTERACTION_COUNT
+         */
+        public static final String COLUMN_INTERACTION_TYPE = "interaction_type";
+
+        /**
+         * The interaction count for this program.
+         *
+         * <p>This indicates the number of times interaction has happened.
+         *
+         * <p>Type: INTEGER (long)
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        public static final String COLUMN_INTERACTION_COUNT = "interaction_count";
+
+        /**
+         * The author or artist of this content.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_AUTHOR = "author";
+
+        /**
+         * The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
+         *
+         * <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS},
+         * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_REVIEW_RATING
+         */
+        public static final String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+
+        /**
+         * The review rating score for this program.
+         *
+         * <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the
+         * style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between
+         * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN},
+         * the value should be two integers, one for thumbs-up count and the other for thumbs-down
+         * count, with a comma between them. (e.g. "200,40") If the style is
+         * {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and
+         * 100. (e.g. "99.9")
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        public static final String COLUMN_REVIEW_RATING = "review_rating";
+
+        /**
+         * The flag indicating whether this TV program is browsable or not.
+         *
+         * <p>This column can only be set by applications having proper system permission. For
+         * other applications, this is a read-only column.
+         *
+         * <p>A value of 1 indicates that the program is browsable and can be shown to users in
+         * the UI. A value of 0 indicates that the program should be hidden from users and the
+         * application who changes this value to 0 should send
+         * {@link #ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED} to the owner of the program
+         * to notify this change.
+         *
+         * <p>This value is set to 1 (browsable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_BROWSABLE = "browsable";
+
+        /**
+         * The content ID of this TV program.
+         *
+         * <p>A public ID of the content which allows the application to apply the same operation to
+         * all the program copies in different channels.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_CONTENT_ID = "content_id";
+
+    }
+
     /** Column definitions for the TV channels table. */
     public static final class Channels implements BaseTvColumns {
 
@@ -1279,14 +1932,15 @@
         /**
          * The flag indicating whether this TV channel is browsable or not.
          *
+         * <p>This column can only be set by applications having proper system permission. For
+         * other applications, this is a read-only column.
+         *
          * <p>A value of 1 indicates the channel is included in the channel list that applications
          * use to browse channels, a value of 0 indicates the channel is not included in the list.
          * If not specified, this value is set to 0 (not browsable) by default.
          *
          * <p>Type: INTEGER (boolean)
-         * @hide
          */
-        @SystemApi
         public static final String COLUMN_BROWSABLE = "browsable";
 
         /**
@@ -1587,6 +2241,17 @@
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
 
         /**
+         * The ID of the TV channel that provides this TV program.
+         *
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+        /**
          * The season number of this TV program for episodic TV shows.
          *
          * <p>Can be empty.
@@ -1890,6 +2555,17 @@
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
 
         /**
+         * The ID of the TV channel that provides this recorded program.
+         *
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+        /**
          * The ID of the TV input service that is associated with this recorded program.
          *
          * <p>Use {@link #buildInputId} to build the ID.
@@ -1988,7 +2664,7 @@
     /**
      * Column definitions for the preview TV programs table.
      */
-    public static final class PreviewPrograms implements BaseProgramColumns {
+    public static final class PreviewPrograms implements BasePreviewProgramColumns {
 
         /** The content:// style URI for this table. */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
@@ -2000,522 +2676,16 @@
         /** The MIME type of a single preview TV program. */
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program";
 
-        /** @hide */
-        @StringDef({
-                TYPE_MOVIE,
-                TYPE_TV_SERIES,
-                TYPE_TV_SEASON,
-                TYPE_TV_EPISODE,
-                TYPE_CLIP,
-                TYPE_EVENT,
-                TYPE_CHANNEL,
-                TYPE_TRACK,
-                TYPE_ALBUM,
-                TYPE_ARTIST,
-                TYPE_PLAYLIST,
-                TYPE_STATION,
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface Type {}
-
         /**
-         * The program type for movie.
+         * The ID of the TV channel that provides this TV program.
          *
-         * @see #COLUMN_TYPE
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
          */
-        public static final String TYPE_MOVIE = "TYPE_MOVIE";
-
-        /**
-         * The program type for TV series.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_TV_SERIES = "TYPE_TV_SERIES";
-
-        /**
-         * The program type for TV season.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_TV_SEASON = "TYPE_TV_SEASON";
-
-        /**
-         * The program type for TV episode.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
-
-        /**
-         * The program type for clip.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_CLIP = "TYPE_CLIP";
-
-        /**
-         * The program type for event.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_EVENT = "TYPE_EVENT";
-
-        /**
-         * The program type for channel.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_CHANNEL = "TYPE_CHANNEL";
-
-        /**
-         * The program type for track.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_TRACK = "TYPE_TRACK";
-
-        /**
-         * The program type for album.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_ALBUM = "TYPE_ALBUM";
-
-        /**
-         * The program type for artist.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_ARTIST = "TYPE_ARTIST";
-
-        /**
-         * The program type for playlist.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_PLAYLIST = "TYPE_PLAYLIST";
-
-        /**
-         * The program type for station.
-         *
-         * @see #COLUMN_TYPE
-         */
-        public static final String TYPE_STATION = "TYPE_STATION";
-
-        /** @hide */
-        @StringDef({
-                WATCH_NEXT_TYPE_CONTINUE,
-                WATCH_NEXT_TYPE_NEXT,
-                WATCH_NEXT_TYPE_NEW,
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface WatchNextType {}
-
-        /**
-         * The watch next type for CONTINUE.
-         *
-         * @see #COLUMN_WATCH_NEXT_TYPE
-         */
-        public static final String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
-
-        /**
-         * The watch next type for NEXT.
-         *
-         * @see #COLUMN_WATCH_NEXT_TYPE
-         */
-        public static final String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
-
-        /**
-         * The watch next type for NEW.
-         *
-         * @see #COLUMN_WATCH_NEXT_TYPE
-         */
-        public static final String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
-
-        /** @hide */
-        @StringDef({
-                ASPECT_RATIO_16_9,
-                ASPECT_RATIO_3_2,
-                ASPECT_RATIO_1_1,
-                ASPECT_RATIO_2_3,
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface AspectRatio {}
-
-        /**
-         * The aspect ratio for 16:9.
-         *
-         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
-         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
-         */
-        public static final String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
-
-        /**
-         * The aspect ratio for 3:2.
-         *
-         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
-         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
-         */
-        public static final String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
-
-        /**
-         * The aspect ratio for 1:1.
-         *
-         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
-         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
-         */
-        public static final String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
-
-        /**
-         * The aspect ratio for 2:3.
-         *
-         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
-         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
-         */
-        public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
-
-        /** @hide */
-        @StringDef({
-                AVAILABILITY_AVAILABLE,
-                AVAILABILITY_FREE_WITH_SUBSCRIPTION,
-                AVAILABILITY_PAID_CONTENT,
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface Availability {}
-
-        /**
-         * The availability for "available to this user".
-         *
-         * @see #COLUMN_AVAILABILITY
-         */
-        public static final String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
-
-        /**
-         * The availability for "free with subscription".
-         *
-         * @see #COLUMN_AVAILABILITY
-         */
-        public static final String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
-                "AVAILABILITY_FREE_WITH_SUBSCRIPTION";
-
-        /**
-         * The availability for "paid content, either to-own or rental
-         * (user has not purchased/rented).
-         *
-         * @see #COLUMN_AVAILABILITY
-         */
-        public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
-
-        /** @hide */
-        @StringDef({
-                INTERACTION_TYPE_LISTENS,
-                INTERACTION_TYPE_FOLLOWERS,
-                INTERACTION_TYPE_FANS,
-                INTERACTION_TYPE_LIKES,
-                INTERACTION_TYPE_THUMBS,
-                INTERACTION_TYPE_VIEWS,
-                INTERACTION_TYPE_VIEWERS,
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface InteractionType {}
-
-        /**
-         * The interaction type for "listens".
-         *
-         * @see #COLUMN_INTERACTION_TYPE
-         */
-        public static final String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
-
-        /**
-         * The interaction type for "followers".
-         *
-         * @see #COLUMN_INTERACTION_TYPE
-         */
-        public static final String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
-
-        /**
-         * The interaction type for "fans".
-         *
-         * @see #COLUMN_INTERACTION_TYPE
-         */
-        public static final String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
-
-        /**
-         * The interaction type for "likes".
-         *
-         * @see #COLUMN_INTERACTION_TYPE
-         */
-        public static final String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
-
-        /**
-         * The interaction type for "thumbs".
-         *
-         * @see #COLUMN_INTERACTION_TYPE
-         */
-        public static final String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
-
-        /**
-         * The interaction type for "views".
-         *
-         * @see #COLUMN_INTERACTION_TYPE
-         */
-        public static final String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
-
-        /**
-         * The interaction type for "viewers".
-         *
-         * @see #COLUMN_INTERACTION_TYPE
-         */
-        public static final String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
-
-        /** @hide */
-        @StringDef({
-                REVIEW_RATING_STYLE_STARS,
-                REVIEW_RATING_STYLE_THUMBS_UP_DOWN,
-                REVIEW_RATING_STYLE_PERCENTAGE,
-        })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface ReviewRatingStyle {}
-
-        /**
-         * The review rating style for five star rating.
-         *
-         * @see #COLUMN_REVIEW_RATING_STYLE
-         */
-        public static final String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
-
-        /**
-         * The review rating style for thumbs-up and thumbs-down rating.
-         *
-         * @see #COLUMN_REVIEW_RATING_STYLE
-         */
-        public static final String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
-                "REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
-
-        /**
-         * The review rating style for 0 to 100 point system.
-         *
-         * @see #COLUMN_REVIEW_RATING_STYLE
-         */
-        public static final String REVIEW_RATING_STYLE_PERCENTAGE =
-                "REVIEW_RATING_STYLE_PERCENTAGE";
-
-        /**
-         * The type of this program content.
-         *
-         * <p>The value should match one of the followings:
-         * {@link #TYPE_MOVIE},
-         * {@link #TYPE_TV_SERIES},
-         * {@link #TYPE_TV_SEASON},
-         * {@link #TYPE_TV_EPISODE},
-         * {@link #TYPE_CLIP},
-         * {@link #TYPE_EVENT},
-         * {@link #TYPE_CHANNEL},
-         * {@link #TYPE_TRACK},
-         * {@link #TYPE_ALBUM},
-         * {@link #TYPE_ARTIST},
-         * {@link #TYPE_PLAYLIST}, and
-         * {@link #TYPE_STATION}.
-         *
-         * <p>This is a required field if the program is from a {@link Channels#TYPE_PREVIEW}
-         * channel.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_TYPE = "type";
-
-        /**
-         * The "watch next" type of this program content.
-         *
-         * <p>The value should match one of the followings:
-         * {@link #WATCH_NEXT_TYPE_CONTINUE},
-         * {@link #WATCH_NEXT_TYPE_NEXT}, and
-         * {@link #WATCH_NEXT_TYPE_NEW}.
-         *
-         * <p>Can be empty.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
-
-        /**
-         * The aspect ratio of the poster art for this TV program.
-         *
-         * <p>The value should match one of the followings:
-         * {@link #ASPECT_RATIO_16_9},
-         * {@link #ASPECT_RATIO_3_2},
-         * {@link #ASPECT_RATIO_1_1}, and
-         * {@link #ASPECT_RATIO_2_3}.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
-
-        /**
-         * The aspect ratio of the thumbnail for this TV program.
-         *
-         * <p>The value should match one of the followings:
-         * {@link #ASPECT_RATIO_16_9},
-         * {@link #ASPECT_RATIO_3_2},
-         * {@link #ASPECT_RATIO_1_1}, and
-         * {@link #ASPECT_RATIO_2_3}.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
-
-        /**
-         * The URI for the logo of this TV program.
-         *
-         * <p>This is a small badge shown on top of the poster art or thumbnail representing the
-         * source of the content.
-         *
-         * <p>The data in the column must be a URL, or a URI in one of the following formats:
-         *
-         * <ul>
-         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
-         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
-         * </li>
-         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
-         * </ul>
-         *
-         * <p>Can be empty.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_LOGO_URI = "logo_uri";
-
-        /**
-         * The availability of this TV program.
-         *
-         * <p>The value should match one of the followings:
-         * {@link #AVAILABILITY_AVAILABLE},
-         * {@link #AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and
-         * {@link #AVAILABILITY_PAID_CONTENT}.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_AVAILABILITY = "availability";
-
-        /**
-         * The starting price of this TV program.
-         *
-         * <p>This indicates the lowest regular acquisition cost of the content. It is only used
-         * if the availability of the program is {@link #AVAILABILITY_PAID_CONTENT}.
-         *
-         * <p>Type: TEXT
-         * @see #COLUMN_OFFER_PRICE
-         */
-        public static final String COLUMN_STARTING_PRICE = "starting_price";
-
-        /**
-         * The offer price of this TV program.
-         *
-         * <p>This is the promotional cost of the content. It is only used if the availability of
-         * the program is {@link #AVAILABILITY_PAID_CONTENT}.
-         *
-         * <p>Type: TEXT
-         * @see #COLUMN_STARTING_PRICE
-         */
-        public static final String COLUMN_OFFER_PRICE = "offer_price";
-
-        /**
-         * The release date of this TV program.
-         *
-         * <p>The value should be in the form of either "yyyy-MM-dd" or "yyyy".
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_RELEASE_DATE = "release_date";
-
-        /**
-         * The count of the items included in this TV program.
-         *
-         * <p>This is only relevant if the program represents a collection of items such as series,
-         * episodes, or music tracks.
-         *
-         * <p>Type: INTEGER
-         */
-        public static final String COLUMN_ITEM_COUNT = "item_count";
-
-        /**
-         * The flag indicating whether this TV program is live or not.
-         *
-         * <p>A value of 1 indicates that the content is airing and should be consumed now, a value
-         * of 0 indicates that the content is off the air and does not need to be consumed at the
-         * present time. If not specified, the value is set to 0 (not live) by default.
-         *
-         * <p>Type: INTEGER (boolean)
-         */
-        public static final String COLUMN_LIVE = "live";
-
-        /**
-         * The internal ID used by individual TV input services.
-         *
-         * <p>This is internal to the provider that inserted it, and should not be decoded by other
-         * apps.
-         *
-         * <p>Can be empty.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
-
-        /**
-         * The URI for the preview video.
-         *
-         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}. The data in the column must be
-         * a URL, or a URI in one of the following formats:
-         *
-         * <ul>
-         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
-         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
-         * </li>
-         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
-         * </ul>
-         *
-         * <p>Can be empty.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
-
-        /**
-         * The last playback position (in milliseconds) of the preview video.
-         *
-         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
-         *
-         * <p>Can be empty.
-         *
-         * <p>Type: INTEGER
-         */
-        public static final String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
-                "last_playback_position_millis";
-
-        /**
-         * The duration (in milliseconds) of the preview video.
-         *
-         * <p>This is only relevant to {@link Channels#TYPE_PREVIEW}.
-         *
-         * <p>Can be empty.
-         *
-         * <p>Type: INTEGER
-         */
-        public static final String COLUMN_DURATION_MILLIS = "duration_millis";
-
-        /**
-         * The intent URI which is launched when the preview video is selected.
-         *
-         * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
-         * and converted back to the original intent with {@link Intent#parseUri}. The intent is
-         * launched when the user selects the preview video item.
-         *
-         * <p>Can be empty.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_APP_LINK_INTENT_URI =
-                "app_link_intent_uri";
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
 
         /**
          * The weight of the preview program within the channel.
@@ -2531,100 +2701,107 @@
          */
         public static final String COLUMN_WEIGHT = "weight";
 
-        /**
-         * The flag indicating whether this program is transient or not.
-         *
-         * <p>A value of 1 indicates that the channel will be automatically removed by the system on
-         * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not
-         * specified, this value is set to 0 (not transient) by default.
-         *
-         * <p>Type: INTEGER (boolean)
-         * @see Channels#COLUMN_TRANSIENT
-         * @hide
-         */
-        @SystemApi
-        public static final String COLUMN_TRANSIENT = "transient";
+        private PreviewPrograms() {}
+    }
+
+    /**
+     * Column definitions for the "watch next" TV programs table.
+     */
+    public static final class WatchNextPrograms implements BasePreviewProgramColumns {
+
+        /** The content:// style URI for this table. */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_WATCH_NEXT_PROGRAM);
+
+        /** The MIME type of a directory of "watch next" TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program";
+
+        /** The MIME type of a single preview TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program";
+
+        /** @hide */
+        @StringDef({
+                WATCH_NEXT_TYPE_CONTINUE,
+                WATCH_NEXT_TYPE_NEXT,
+                WATCH_NEXT_TYPE_NEW,
+                WATCH_NEXT_TYPE_WATCHLIST,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface WatchNextType {}
 
         /**
-         * The type of interaction for this TV program.
+         * The watch next type for CONTINUE. Use this type when the user has already watched more
+         * than 1 minute of this content.
          *
-         * <p> The value should match one of the followings:
-         * {@link #INTERACTION_TYPE_LISTENS},
-         * {@link #INTERACTION_TYPE_FOLLOWERS},
-         * {@link #INTERACTION_TYPE_FANS},
-         * {@link #INTERACTION_TYPE_LIKES},
-         * {@link #INTERACTION_TYPE_THUMBS},
-         * {@link #INTERACTION_TYPE_VIEWS}, and
-         * {@link #INTERACTION_TYPE_VIEWERS}.
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final String WATCH_NEXT_TYPE_CONTINUE = "WATCH_NEXT_TYPE_CONTINUE";
+
+        /**
+         * The watch next type for NEXT. Use this type when the user has watched one or more
+         * complete episodes from some episodic content, but there remains more than one episode
+         * remaining or there is one last episode remaining, but it is not “new” in that it was
+         * released before the user started watching the show.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final String WATCH_NEXT_TYPE_NEXT = "WATCH_NEXT_TYPE_NEXT";
+
+        /**
+         * The watch next type for NEW. Use this type when the user had watched all of the available
+         * episodes from some episodic content, but a new episode became available since the user
+         * started watching the first episode and now there is exactly one unwatched episode. This
+         * could also work for recorded events in a series e.g. soccer matches or football games.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final String WATCH_NEXT_TYPE_NEW = "WATCH_NEXT_TYPE_NEW";
+
+        /**
+         * The watch next type for WATCHLIST. Use this type when the user has elected to explicitly
+         * add a movie, event or series to a “watchlist” as a manual way of curating what they
+         * want to watch next.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final String WATCH_NEXT_TYPE_WATCHLIST = "WATCH_NEXT_TYPE_WATCHLIST";
+
+        /**
+         * The "watch next" type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #WATCH_NEXT_TYPE_CONTINUE},
+         * {@link #WATCH_NEXT_TYPE_NEXT},
+         * {@link #WATCH_NEXT_TYPE_NEW}, and
+         * {@link #WATCH_NEXT_TYPE_WATCHLIST}.
+         *
+         * <p>This is a required field.
          *
          * <p>Type: TEXT
-         * @see #COLUMN_INTERACTION_COUNT
          */
-        public static final String COLUMN_INTERACTION_TYPE = "interaction_type";
+        public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
 
         /**
-         * The interaction count for this program.
+         * The last UTC time that the user engaged in this TV program, in milliseconds since the
+         * epoch. This is a hint for the application that is used for ordering of "watch next"
+         * programs.
          *
-         * <p>This indicates the number of times interaction has happened.
+         * <p>The meaning of the value varies depending on the {@link #COLUMN_WATCH_NEXT_TYPE}:
+         * <ul>
+         *     <li>{@link #WATCH_NEXT_TYPE_CONTINUE}: the date that the user was last watching the
+         *     content.</li>
+         *     <li>{@link #WATCH_NEXT_TYPE_NEXT}: the date of the last episode watched.</li>
+         *     <li>{@link #WATCH_NEXT_TYPE_NEW}: the release date of the new episode.</li>
+         *     <li>{@link #WATCH_NEXT_TYPE_WATCHLIST}: the date the item was added to the Watchlist.
+         *     </li>
+         * </ul>
+         *
+         * <p>This is a required field.
          *
          * <p>Type: INTEGER (long)
-         * @see #COLUMN_INTERACTION_TYPE
          */
-        public static final String COLUMN_INTERACTION_COUNT = "interaction_count";
-
-        /**
-         * The author or artist of this content.
-         *
-         * <p>Type: TEXT
-         */
-        public static final String COLUMN_AUTHOR = "author";
-
-        /**
-         * The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
-         *
-         * <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS},
-         * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
-         *
-         * <p>Type: TEXT
-         * @see #COLUMN_REVIEW_RATING
-         */
-        public static final String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
-
-        /**
-         * The review rating score for this program.
-         *
-         * <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the
-         * style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between
-         * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN},
-         * the value should be two integers, one for thumbs-up count and the other for thumbs-down
-         * count, with a comma between them. (e.g. "200,40") If the style is
-         * {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and
-         * 100. (e.g. "99.9")
-         *
-         * <p>Type: TEXT
-         * @see #COLUMN_REVIEW_RATING_STYLE
-         */
-        public static final String COLUMN_REVIEW_RATING = "review_rating";
-
-        /**
-         * The flag indicating whether this TV program is browsable or not.
-         *
-         * <p>This column can only be set by system apps. For other applications, it is a read-only
-         * column. Trying to modify it may cause {@link SecurityException}.
-         *
-         * <p>A value of 1 indicates that the program is browsable and can be shown to users in
-         * the UI. A value of 0 indicates that the program should be hidden from users and the
-         * application who changes this value to 0 should send
-         * {@link TvInputManager#ACTION_PROGRAM_BROWSABLE_DISABLED} to the owner of the program
-         * to notify this change.
-         *
-         * <p>This value is set to 1 (browsable) by default.
-         *
-         * <p>Type: INTEGER (boolean)
-         */
-        public static final String COLUMN_BROWSABLE = "browsable";
-
-        private PreviewPrograms() {}
+        public static final String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS =
+                "last_engagement_time_utc_millis";
     }
 
     /**
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 4c2b031..1eae8db 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -324,40 +324,6 @@
     public static final String ACTION_VIEW_RECORDING_SCHEDULES =
             "android.media.tv.action.VIEW_RECORDING_SCHEDULES";
 
-    /**
-     * Action sent by the system to tell the target TV input that one of its program's browsable
-     * state is disabled, i.e., it will no longer be shown to users, which, for example, might
-     * be a result of users' interaction with UI.
-     *
-     * <p>The intent must contain the following bundle parameter:
-     * <ul>
-     *     <li>{@link #EXTRA_PROGRAM_ID} the program ID as a long integer.
-     * </ul>
-     */
-    public static final String ACTION_PROGRAM_BROWSABLE_DISABLED =
-            "android.media.tv.action.PROGRAM_BROWSABLE_DISABLED";
-
-    /**
-     * Action sent by an application telling the system to set the given channel as browsable.
-     *
-     * <p>The intent must contain the following bundle parameters:
-     * <ul>
-     *     <li>{@link #EXTRA_CHANNEL_ID} the channel ID as a long integer.
-     *     <li>{@link #EXTRA_PACKAGE_NAME} the package name of the requesting application.
-     * </ul>
-     */
-    public static final String ACTION_MAKE_CHANNEL_BROWSABLE
-            = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
-
-    /** The key for a bundle parameter containing a channel ID as a long integer */
-    public static final String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
-
-    /** The key for a bundle parameter containing a package name as a string. */
-    public static final String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
-
-    /** The key for a bundle parameter containing a program ID as a long integer */
-    public static final String EXTRA_PROGRAM_ID = "android.media.tv.extra.PROGRAM_ID";
-
     private final ITvInputManager mService;
 
     private final Object mLock = new Object();
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index aee9d38e..e5af357 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -776,8 +776,8 @@
         mSurface = null;
         mSurfaceView = new SurfaceView(getContext(), mAttrs, mDefStyleAttr) {
             @Override
-            protected void updateWindow() {
-                super.updateWindow();
+            protected void updateSurface() {
+                super.updateSurface();
                 relayoutSessionOverlayView();
             }};
         // The surface view's content should be treated as secure all the time.
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index e2623d4..3ede2ee 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -139,27 +139,16 @@
     ANativeActivity_setWindowFlags;
     ANativeActivity_setWindowFormat;
     ANativeActivity_showSoftInput;
-    AHardwareBuffer_acquire; # introduced=26
-    AHardwareBuffer_allocate; # introduced=26
-    AHardwareBuffer_describe; # introduced=26
-    AHardwareBuffer_fromHardwareBuffer; # introduced=26
-    AHardwareBuffer_getNativeHandle; # introduced=26
-    AHardwareBuffer_lock; # introduced=26
-    AHardwareBuffer_recvHandleFromUnixSocket; # introduced=26
-    AHardwareBuffer_release; # introduced=26
-    AHardwareBuffer_sendHandleToUnixSocket; # introduced=26
-    AHardwareBuffer_toHardwareBuffer; # introduced=26
-    AHardwareBuffer_unlock; # introduced=26
-    ANativeWindow_acquire;
-    ANativeWindow_fromSurface;
-    ANativeWindow_fromSurfaceTexture; # introduced-arm=13 introduced-mips=13 introduced-x86=13
-    ANativeWindow_getFormat;
-    ANativeWindow_getHeight;
-    ANativeWindow_getWidth;
-    ANativeWindow_lock;
-    ANativeWindow_release;
-    ANativeWindow_setBuffersGeometry;
-    ANativeWindow_unlockAndPost;
+    ANativeWindow_acquire; # removed=26
+    ANativeWindow_fromSurface; # removed=26
+    ANativeWindow_fromSurfaceTexture; # removed=26
+    ANativeWindow_getFormat; # removed=26
+    ANativeWindow_getHeight; # removed=26
+    ANativeWindow_getWidth; # removed=26
+    ANativeWindow_lock; # removed=26
+    ANativeWindow_release; # removed=26
+    ANativeWindow_setBuffersGeometry; # removed=26
+    ANativeWindow_unlockAndPost; # removed=26
     AObbInfo_delete;
     AObbInfo_getFlags;
     AObbInfo_getPackageName;
@@ -170,14 +159,20 @@
     ASensorEventQueue_getEvents;
     ASensorEventQueue_hasEvents;
     ASensorEventQueue_setEventRate;
+    ASensorManager_configureDirectReport; # introduced=26
     ASensorManager_createEventQueue;
+    ASensorManager_createHardwareBufferDirectChannel; # introduced=26
+    ASensorManager_createSharedMemoryDirectChannel; # introduced=26
+    ASensorManager_destroyDirectChannel; # introduced=26
     ASensorManager_destroyEventQueue;
     ASensorManager_getDefaultSensor;
     ASensorManager_getDefaultSensorEx; # introduced=21
     ASensorManager_getInstance;
+    ASensorManager_getInstanceForPackage; # introduced=26
     ASensorManager_getSensorList;
     ASensor_getFifoMaxEventCount; # introduced=21
     ASensor_getFifoReservedEventCount; # introduced=21
+    ASensor_getHighestDirectReportRateLevel; # introduced=26
     ASensor_getMinDelay;
     ASensor_getName;
     ASensor_getReportingMode; # introduced=21
@@ -185,6 +180,7 @@
     ASensor_getStringType; # introduced=21
     ASensor_getType;
     ASensor_getVendor;
+    ASensor_isDirectChannelTypeSupported; # introduced=26
     ASensor_isWakeUpSensor; # introduced=21
     ASharedMemory_create; # introduced=26
     ASharedMemory_getSize; # introduced=26
diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp
index 5cfe300..c7bc885 100644
--- a/native/android/sensor.cpp
+++ b/native/android/sensor.cpp
@@ -17,16 +17,17 @@
 #define LOG_TAG "sensor"
 #include <utils/Log.h>
 
+#include <android/hardware_buffer.h>
 #include <android/looper.h>
 #include <android/sensor.h>
-
-#include <utils/RefBase.h>
-#include <utils/Looper.h>
-#include <utils/Timers.h>
-
+#include <android/sharedmem.h>
+#include <cutils/native_handle.h>
 #include <gui/Sensor.h>
 #include <gui/SensorManager.h>
 #include <gui/SensorEventQueue.h>
+#include <utils/Looper.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
 
 #include <poll.h>
 
@@ -38,6 +39,22 @@
 using android::String16;
 
 /*****************************************************************************/
+#define ERROR_INVALID_PARAMETER(message) ALOGE("%s: " message, __func__)
+
+// frequently used check
+#define RETURN_IF_MANAGER_IS_NULL(retval) do {\
+        if (manager == nullptr) { \
+            ERROR_INVALID_PARAMETER("manager cannot be NULL"); \
+            return retval; \
+        } \
+    } while (false)
+#define RETURN_IF_SENSOR_IS_NULL(retval) do {\
+        if (sensor == nullptr) { \
+            ERROR_INVALID_PARAMETER("sensor cannot be NULL"); \
+            return retval; \
+        } \
+    } while (false)
+
 ASensorManager* ASensorManager_getInstance()
 {
     return ASensorManager_getInstanceForPackage(NULL);
@@ -103,6 +120,78 @@
     return 0;
 }
 
+int ASensorManager_createSharedMemoryDirectChannel(
+        ASensorManager *manager, int fd, size_t size) {
+    RETURN_IF_MANAGER_IS_NULL(android::BAD_VALUE);
+
+    if (fd < 0) {
+        ERROR_INVALID_PARAMETER("fd is invalid.");
+        return android::BAD_VALUE;
+    }
+
+    if (size < sizeof(ASensorEvent)) {
+        ERROR_INVALID_PARAMETER("size has to be greater or equal to sizeof(ASensorEvent).");
+    }
+
+    native_handle_t *resourceHandle = native_handle_create(1 /* nFd */, 0 /* nInt */);
+    if (!resourceHandle) {
+        return android::NO_MEMORY;
+    }
+
+    resourceHandle->data[0] = fd;
+    int ret = static_cast<SensorManager *>(manager)->createDirectChannel(
+            size, ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY, resourceHandle);
+    native_handle_delete(resourceHandle);
+    return ret;
+}
+
+int ASensorManager_createHardwareBufferDirectChannel(
+        ASensorManager *manager, AHardwareBuffer const *buffer, size_t size) {
+    RETURN_IF_MANAGER_IS_NULL(android::BAD_VALUE);
+
+    if (buffer == nullptr) {
+        ERROR_INVALID_PARAMETER("buffer cannot be NULL");
+        return android::BAD_VALUE;
+    }
+
+    if (size < sizeof(ASensorEvent)) {
+        ERROR_INVALID_PARAMETER("size has to be greater or equal to sizeof(ASensorEvent).");
+    }
+
+    const native_handle_t *resourceHandle = AHardwareBuffer_getNativeHandle(buffer);
+    if (!resourceHandle) {
+        return android::NO_MEMORY;
+    }
+
+    return static_cast<SensorManager *>(manager)->createDirectChannel(
+            size, ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER, resourceHandle);
+}
+
+void ASensorManager_destroyDirectChannel(ASensorManager *manager, int channelId) {
+    RETURN_IF_MANAGER_IS_NULL(void());
+
+    static_cast<SensorManager *>(manager)->destroyDirectChannel(channelId);
+}
+
+int ASensorManager_configureDirectReport(
+        ASensorManager *manager, ASensor const *sensor, int channelId, int rate) {
+    RETURN_IF_MANAGER_IS_NULL(android::BAD_VALUE);
+
+    int sensorHandle;
+    if (sensor == nullptr) {
+        if (rate != ASENSOR_DIRECT_RATE_STOP) {
+            ERROR_INVALID_PARAMETER(
+                "sensor cannot be null when rate is not ASENSOR_DIRECT_RATE_STOP");
+            return android::BAD_VALUE;
+        }
+        sensorHandle = -1;
+    } else {
+        sensorHandle = static_cast<Sensor const *>(sensor)->getHandle();
+    }
+    return static_cast<SensorManager *>(manager)->configureDirectChannel(
+            channelId, sensorHandle, rate);
+}
+
 /*****************************************************************************/
 
 int ASensorEventQueue_registerSensor(ASensorEventQueue* queue, ASensor const* sensor,
@@ -211,3 +300,13 @@
 {
     return static_cast<Sensor const*>(sensor)->isWakeUpSensor();
 }
+
+bool ASensor_isDirectChannelTypeSupported(ASensor const *sensor, int channelType) {
+    RETURN_IF_SENSOR_IS_NULL(false);
+    return static_cast<Sensor const *>(sensor)->isDirectChannelTypeSupported(channelType);
+}
+
+int ASensor_getHighestDirectReportRateLevel(ASensor const *sensor) {
+    RETURN_IF_SENSOR_IS_NULL(ASENSOR_DIRECT_RATE_STOP);
+    return static_cast<Sensor const *>(sensor)->getHighestDirectReportRateLevel();
+}
diff --git a/native/graphics/jni/bitmap.cpp b/native/graphics/jni/bitmap.cpp
index 6d2de98..bf5cabb 100644
--- a/native/graphics/jni/bitmap.cpp
+++ b/native/graphics/jni/bitmap.cpp
@@ -15,11 +15,7 @@
  */
 
 #include <android/bitmap.h>
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-parameter"
-#include <GraphicsJNI.h>
-#pragma GCC diagnostic pop
+#include <Bitmap.h>
 
 int AndroidBitmap_getInfo(JNIEnv* env, jobject jbitmap,
                           AndroidBitmapInfo* info) {
@@ -27,32 +23,8 @@
         return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
     }
 
-    SkBitmap bm;
-    GraphicsJNI::getSkBitmap(env, jbitmap, &bm);
-
     if (info) {
-        info->width     = bm.width();
-        info->height    = bm.height();
-        info->stride    = bm.rowBytes();
-        info->flags     = 0;
-
-        switch (bm.colorType()) {
-            case kN32_SkColorType:
-                info->format = ANDROID_BITMAP_FORMAT_RGBA_8888;
-                break;
-            case kRGB_565_SkColorType:
-                info->format = ANDROID_BITMAP_FORMAT_RGB_565;
-                break;
-            case kARGB_4444_SkColorType:
-                info->format = ANDROID_BITMAP_FORMAT_RGBA_4444;
-                break;
-            case kAlpha_8_SkColorType:
-                info->format = ANDROID_BITMAP_FORMAT_A_8;
-                break;
-            default:
-                info->format = ANDROID_BITMAP_FORMAT_NONE;
-                break;
-        }
+        android::bitmap::imageInfo(env, jbitmap, info);
     }
     return ANDROID_BITMAP_RESULT_SUCCESS;
 }
@@ -62,19 +34,11 @@
         return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
     }
 
-    SkPixelRef* pixelRef = GraphicsJNI::refSkPixelRef(env, jbitmap);
-    if (!pixelRef) {
+    void* addr = android::bitmap::lockPixels(env, jbitmap);
+    if (!addr) {
         return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
     }
 
-    pixelRef->lockPixels();
-    void* addr = pixelRef->pixels();
-    if (NULL == addr) {
-        pixelRef->unlockPixels();
-        pixelRef->unref();
-        return ANDROID_BITMAP_RESULT_ALLOCATION_FAILED;
-    }
-
     if (addrPtr) {
         *addrPtr = addr;
     }
@@ -86,26 +50,10 @@
         return ANDROID_BITMAP_RESULT_BAD_PARAMETER;
     }
 
-    SkPixelRef* pixelRef = GraphicsJNI::refSkPixelRef(env, jbitmap);
-    if (!pixelRef) {
+    bool unlocked = android::bitmap::unlockPixels(env, jbitmap);
+    if (!unlocked) {
         return ANDROID_BITMAP_RESULT_JNI_EXCEPTION;
     }
-
-    // notifyPixelsChanged() needs be called to apply writes to GL-backed
-    // bitmaps.  Note that this will slow down read-only accesses to the
-    // bitmaps, but the NDK methods are primarily intended to be used for
-    // writes.
-    pixelRef->notifyPixelsChanged();
-
-    pixelRef->unlockPixels();
-    // Awkward in that we need to double-unref as the call to get the SkPixelRef
-    // did a ref(), so we need to unref() for the local ref and for the previous
-    // AndroidBitmap_lockPixels(). However this keeps GraphicsJNI a bit safer
-    // if others start using it without knowing about android::Bitmap's "fun"
-    // ref counting mechanism(s).
-    pixelRef->unref();
-    pixelRef->unref();
-
     return ANDROID_BITMAP_RESULT_SUCCESS;
 }
 
diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java b/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
index 84745b2..19c2c14 100644
--- a/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
+++ b/packages/MtpDocumentsProvider/src/com/android/mtp/ReceiverActivity.java
@@ -46,8 +46,8 @@
                 final Uri uri = DocumentsContract.buildRootUri(
                         MtpDocumentsProvider.AUTHORITY, deviceRootId);
 
-                final Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
-                intent.setData(uri);
+                final Intent intent = new Intent(Intent.ACTION_VIEW);
+                intent.setDataAndType(uri, DocumentsContract.Root.MIME_TYPE_ITEM);
                 intent.addCategory(Intent.CATEGORY_DEFAULT);
                 this.startActivity(intent);
             } catch (IOException exception) {
diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml
index f36167e..36465a1 100644
--- a/packages/PrintSpooler/res/values-hi/strings.xml
+++ b/packages/PrintSpooler/res/values-hi/strings.xml
@@ -79,7 +79,7 @@
     </plurals>
     <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> प्रिंट हो रहा है"</string>
     <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द हो रहा है"</string>
-    <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर त्रुटि <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
+    <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर गड़बड़ी <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="blocked_notification_title_template" msgid="1175435827331588646">"प्रिंटर अवरोधित <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string>
     <string name="cancel" msgid="4373674107267141885">"अभी नहीं"</string>
     <string name="restart" msgid="2472034227037808749">"पुन: आरंभ करें"</string>
diff --git a/packages/SettingsLib/res/layout/drawer_category.xml b/packages/SettingsLib/res/layout/drawer_category.xml
deleted file mode 100644
index 72cfddb..0000000
--- a/packages/SettingsLib/res/layout/drawer_category.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<!--
-    Copyright (C) 2015 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.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingTop="8dp"
-    android:orientation="vertical">
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:background="?android:attr/listDivider" />
-
-    <TextView
-        style="@style/TextAppearanceSmall"
-        android:id="@android:id/title"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:minHeight="48dp"
-        android:paddingTop="16dp"
-        android:paddingBottom="16dp"
-        android:paddingStart="16dp" />
-
-</LinearLayout>
diff --git a/packages/SettingsLib/res/layout/drawer_item.xml b/packages/SettingsLib/res/layout/drawer_item.xml
deleted file mode 100644
index d492ddf..0000000
--- a/packages/SettingsLib/res/layout/drawer_item.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<!--
-    Copyright (C) 2015 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.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/tile_item"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="48dp"
-    android:orientation="horizontal" >
-
-    <ImageView
-        android:id="@android:id/icon"
-        android:layout_width="@dimen/drawer_icon_size"
-        android:layout_height="@dimen/drawer_icon_size"
-        android:layout_marginStart="@dimen/drawer_icon_margin"
-        android:layout_marginEnd="@dimen/drawer_icon_margin"
-        android:layout_marginTop="@dimen/drawer_item_top_bottom_margin"
-        android:layout_marginBottom="@dimen/drawer_item_top_bottom_margin"
-        android:scaleType="fitCenter"
-        android:layout_gravity="center_vertical"
-        android:tint="?android:attr/colorAccent"/>
-
-    <TextView
-        android:textAppearance="@style/TextAppearanceMedium"
-        android:id="@android:id/title"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:textColor="?android:attr/colorControlNormal" />
-
-</LinearLayout>
diff --git a/packages/SettingsLib/res/layout/drawer_spacer.xml b/packages/SettingsLib/res/layout/drawer_spacer.xml
deleted file mode 100644
index 98120cf..0000000
--- a/packages/SettingsLib/res/layout/drawer_spacer.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
-    Copyright (C) 2016 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.
--->
-<Space
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/spacer"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/drawer_spacer_height" />
diff --git a/packages/SettingsLib/res/layout/settings_with_drawer.xml b/packages/SettingsLib/res/layout/settings_with_drawer.xml
index b659cee..e9c175f 100644
--- a/packages/SettingsLib/res/layout/settings_with_drawer.xml
+++ b/packages/SettingsLib/res/layout/settings_with_drawer.xml
@@ -47,13 +47,4 @@
             android:layout_height="fill_parent"
             android:background="?android:attr/windowBackground" />
     </LinearLayout>
-    <!-- The navigation drawer -->
-    <ListView android:id="@+id/left_drawer"
-        android:layout_width="@dimen/drawer_width"
-        android:layout_height="match_parent"
-        android:layout_gravity="start"
-        android:choiceMode="singleChoice"
-        android:divider="@android:color/transparent"
-        android:dividerHeight="0dp"
-        android:background="?android:attr/colorBackground" />
 </android.support.v4.widget.DrawerLayout>
diff --git a/packages/SettingsLib/res/values/config.xml b/packages/SettingsLib/res/values/config.xml
index ee69b56..64f21b5 100755
--- a/packages/SettingsLib/res/values/config.xml
+++ b/packages/SettingsLib/res/values/config.xml
@@ -26,9 +26,6 @@
     <!-- Whether to send a custom package name with the PSD.-->
     <bool name="config_sendPackageName">false</bool>
 
-    <!-- Whether to enable the left nav drawer in all Settings UI.-->
-    <bool name="config_enable_nav_drawer">false</bool>
-
     <!-- Name for the set of keys associating package names -->
     <string name="config_helpPackageNameKey" translatable="false"></string>
 
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index aa36617..3322839 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -51,12 +51,6 @@
 
     <dimen name="usage_graph_dot_size">.75dp</dimen>
     <dimen name="usage_graph_dot_interval">7dp</dimen>
-    <dimen name="drawer_icon_size">24dp</dimen>
-    <dimen name="normal_icon_size">24dp</dimen>
-    <dimen name="drawer_icon_margin">24dp</dimen>
-    <dimen name="drawer_width">300dp</dimen>
-    <dimen name="drawer_item_top_bottom_margin">4dp</dimen>
-    <dimen name="drawer_spacer_height">32dp</dimen>
 
     <dimen name="battery_height">14.5dp</dimen>
     <dimen name="battery_width">9.5dp</dimen>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
index 7f7249f0..b06b032 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/AppUtils.java
@@ -28,6 +28,7 @@
 import android.util.Log;
 
 import com.android.settingslib.R;
+import com.android.settingslib.applications.instantapps.InstantAppDataProvider;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -35,6 +36,13 @@
 public class AppUtils {
     private static final String TAG = "AppUtils";
 
+    /**
+     * This should normally only be set in robolectric tests, to avoid getting a method not found
+     * exception when calling the isInstantApp method of the ApplicationInfo class, because
+     * robolectric does not yet have an implementation of it.
+     */
+    private static InstantAppDataProvider sInstantAppDataProvider = null;
+
     public static CharSequence getLaunchByDefaultSummary(ApplicationsState.AppEntry appEntry,
             IUsbManager usbManager, PackageManager pm, Context context) {
         String packageName = appEntry.info.packageName;
@@ -74,7 +82,11 @@
      * Returns a boolean indicating whether the given package should be considered an instant app
      */
     public static boolean isInstant(ApplicationInfo info) {
-        if (info.isInstantApp()) {
+        if (sInstantAppDataProvider != null) {
+            if (sInstantAppDataProvider.isInstantApp(info)) {
+                return true;
+            }
+        } else if (info.isInstantApp()) {
             return true;
         }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
index acb0650..2183573 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/StorageStatsSource.java
@@ -20,6 +20,7 @@
 import android.app.usage.StorageStatsManager;
 import android.content.Context;
 import android.os.UserHandle;
+import android.support.annotation.VisibleForTesting;
 
 /**
  * StorageStatsSource wraps the StorageStatsManager for testability purposes.
@@ -40,6 +41,12 @@
         return new StorageStatsSource.AppStorageStatsImpl(mStorageStatsManager.queryStatsForUid(volumeUuid, uid));
     }
 
+    public StorageStatsSource.AppStorageStats getStatsForPackage(
+            String volumeUuid, String packageName, UserHandle user) {
+        return new StorageStatsSource.AppStorageStatsImpl(
+                mStorageStatsManager.queryStatsForPackage(volumeUuid, packageName, user));
+    }
+
     /**
      * Static class that provides methods for querying the amount of external storage available as
      * well as breaking it up into several media types.
@@ -50,11 +57,10 @@
         public long videoBytes;
         public long imageBytes;
 
-        /**
-         * Convenience method for testing.
-         */
-        public ExternalStorageStats(long totalBytes, long audioBytes, long videoBytes,
-                long imageBytes) {
+        /** Convenience method for testing. */
+        @VisibleForTesting
+        public ExternalStorageStats(
+                long totalBytes, long audioBytes, long videoBytes, long imageBytes) {
             this.totalBytes = totalBytes;
             this.audioBytes = audioBytes;
             this.videoBytes = videoBytes;
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/instantapps/InstantAppDataProvider.java b/packages/SettingsLib/src/com/android/settingslib/applications/instantapps/InstantAppDataProvider.java
new file mode 100644
index 0000000..8b15715
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/instantapps/InstantAppDataProvider.java
@@ -0,0 +1,28 @@
+/*
+ * 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.settingslib.applications.instantapps;
+
+import android.content.pm.ApplicationInfo;
+
+/**
+ * This helps deal with the fact that robolectric does not yet have an implementation of the
+ * isInstantApp method of ApplicationInfo, so we get a method not found exception when running tests
+ * if we try to call it directly.
+ */
+public interface InstantAppDataProvider {
+    public boolean isInstantApp(ApplicationInfo info);
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
index a8cab17..457ce76 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerActivity.java
@@ -5,7 +5,7 @@
  * 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
+ * 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,
@@ -18,7 +18,6 @@
 import android.annotation.LayoutRes;
 import android.annotation.Nullable;
 import android.app.Activity;
-import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
@@ -29,20 +28,15 @@
 import android.os.AsyncTask;
 import android.os.Bundle;
 import android.provider.Settings;
-import android.support.v4.widget.DrawerLayout;
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
-import android.view.Gravity;
 import android.view.LayoutInflater;
-import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager.LayoutParams;
-import android.widget.AdapterView;
 import android.widget.FrameLayout;
-import android.widget.ListView;
 import android.widget.Toolbar;
 
 import com.android.settingslib.R;
@@ -67,10 +61,7 @@
     private final PackageReceiver mPackageReceiver = new PackageReceiver();
     private final List<CategoryListener> mCategoryListeners = new ArrayList<>();
 
-    private SettingsDrawerAdapter mDrawerAdapter;
     private FrameLayout mContentHeaderContainer;
-    private DrawerLayout mDrawerLayout;
-    private boolean mShowingMenu;
 
     // Remove below after new IA
     @Deprecated
@@ -94,122 +85,50 @@
         }
         super.setContentView(R.layout.settings_with_drawer);
         mContentHeaderContainer = (FrameLayout) findViewById(R.id.content_header_container);
-        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
-        if (mDrawerLayout == null) {
-            return;
-        }
+
         Toolbar toolbar = (Toolbar) findViewById(R.id.action_bar);
         if (theme.getBoolean(android.R.styleable.Theme_windowNoTitle, false)) {
             toolbar.setVisibility(View.GONE);
-            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
-            mDrawerLayout = null;
             return;
         }
-        if (!isNavDrawerEnabled()) {
-            setIsDrawerPresent(false);
-        }
-        if (!isDashboardFeatureEnabled()) {
-            getDashboardCategories();
-        }
         setActionBar(toolbar);
-        mDrawerAdapter = new SettingsDrawerAdapter(this);
-        ListView listView = (ListView) findViewById(R.id.left_drawer);
-        listView.setAdapter(mDrawerAdapter);
-        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-            public void onItemClick(android.widget.AdapterView<?> parent, View view, int position,
-                    long id) {
-                onTileClicked(mDrawerAdapter.getTile(position));
-            }
-        });
 
-        if (DEBUG_TIMING) Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
-                + " ms");
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        if (mShowingMenu && mDrawerLayout != null && item.getItemId() == android.R.id.home
-                && mDrawerAdapter.getCount() != 0) {
-            openDrawer();
-            return true;
+        if (DEBUG_TIMING) {
+            Log.d(TAG, "onCreate took " + (System.currentTimeMillis() - startTime)
+                    + " ms");
         }
-        return super.onOptionsItemSelected(item);
     }
 
     @Override
     public boolean onNavigateUp() {
-        if (!isNavDrawerEnabled()) {
-            finish();
-            return true;
-        }
-        return super.onNavigateUp();
+        finish();
+        return true;
     }
 
     @Override
     protected void onResume() {
         super.onResume();
+        final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+        filter.addDataScheme("package");
+        registerReceiver(mPackageReceiver, filter);
 
-        if (mDrawerLayout != null) {
-            final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
-            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
-            filter.addDataScheme("package");
-            registerReceiver(mPackageReceiver, filter);
-
-            if (isDashboardFeatureEnabled()) {
-                new CategoriesUpdateTask().execute();
-            } else {
-                new CategoriesUpdater().execute();
-            }
-        }
+        new CategoriesUpdateTask().execute();
         final Intent intent = getIntent();
-        if (intent != null) {
-            if (intent.hasExtra(EXTRA_SHOW_MENU)) {
-                if (intent.getBooleanExtra(EXTRA_SHOW_MENU, false)) {
-                    // Intent explicitly set to show menu.
-                    showMenuIcon();
-                }
-            } else if (isNavDrawerEnabled() && isTopLevelTile(intent)) {
-                showMenuIcon();
-            }
+        if (intent != null && intent.getBooleanExtra(EXTRA_SHOW_MENU, false)) {
+            // Intent explicitly set to show menu.
+            showMenuIcon();
         }
     }
 
     @Override
     protected void onPause() {
-        if (mDrawerLayout != null) {
-            unregisterReceiver(mPackageReceiver);
-        }
-
+        unregisterReceiver(mPackageReceiver);
         super.onPause();
     }
 
-    private boolean isTopLevelTile(Intent intent) {
-        final ComponentName componentName = intent.getComponent();
-        if (componentName == null) {
-            return false;
-        }
-        if (isDashboardFeatureEnabled()) {
-            final DashboardCategory homepageCategories = CategoryManager.get(this)
-                    .getTilesByCategory(this, CategoryKey.CATEGORY_HOMEPAGE, getSettingPkg());
-            return homepageCategories ==
-                    null ? false : homepageCategories.containsComponent(componentName);
-        } else {
-            // Look for a tile that has the same component as incoming intent
-            final List<DashboardCategory> categories = getDashboardCategories();
-            for (DashboardCategory category : categories) {
-                if (category.containsComponent(componentName)) {
-                    return true;
-                }
-            }
-            if (DEBUG) {
-                Log.d(TAG, "Intent is not for top level settings " + intent);
-            }
-            return false;
-        }
-    }
-
     /**
      * Gets the name of the intent action of the default setting app. Used to launch setting app
      * when Settings Home is clicked.
@@ -226,30 +145,6 @@
         mCategoryListeners.remove(listener);
     }
 
-    public void setIsDrawerPresent(boolean isPresent) {
-        if (isPresent) {
-            mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
-            updateDrawer();
-        } else {
-            if (mDrawerLayout != null) {
-                mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
-                mDrawerLayout = null;
-            }
-        }
-    }
-
-    public void openDrawer() {
-        if (mDrawerLayout != null) {
-            mDrawerLayout.openDrawer(Gravity.START);
-        }
-    }
-
-    public void closeDrawer() {
-        if (mDrawerLayout != null) {
-            mDrawerLayout.closeDrawers();
-        }
-    }
-
     public void setContentHeaderView(View headerView) {
         mContentHeaderContainer.removeAllViews();
         if (headerView != null) {
@@ -276,31 +171,8 @@
         ((ViewGroup) findViewById(R.id.content_frame)).addView(view, params);
     }
 
-    public void updateDrawer() {
-        if (mDrawerLayout == null) {
-            return;
-        }
-        // TODO: Do this in the background with some loading.
-        if (isDashboardFeatureEnabled()) {
-            mDrawerAdapter.updateHomepageCategories(getSettingPkg());
-        } else {
-            mDrawerAdapter.updateCategories();
-        }
-        if (mDrawerAdapter.getCount() != 0) {
-            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
-        } else {
-            mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
-        }
-    }
-
     public void showMenuIcon() {
         getActionBar().setDisplayHomeAsUpEnabled(true);
-        if (isNavDrawerEnabled()) {
-            mShowingMenu = true;
-            getActionBar().setHomeAsUpIndicator(R.drawable.ic_menu);
-            getActionBar().setHomeActionContentDescription(
-                    R.string.content_description_menu_button);
-        }
     }
 
     public List<DashboardCategory> getDashboardCategories() {
@@ -315,51 +187,12 @@
     }
 
     protected void onCategoriesChanged() {
-        updateDrawer();
         final int N = mCategoryListeners.size();
         for (int i = 0; i < N; i++) {
             mCategoryListeners.get(i).onCategoriesChanged();
         }
     }
 
-    @Deprecated
-    public boolean openTile(Tile tile) {
-        closeDrawer();
-        if (tile == null) {
-            Intent intent = new Intent(getSettingAction()).addFlags(
-                        Intent.FLAG_ACTIVITY_CLEAR_TASK);
-            startActivity(intent);
-            return true;
-        }
-        try {
-            ProfileSelectDialog.updateUserHandlesIfNeeded(this /* context */, tile);
-            int numUserHandles = tile.userHandle.size();
-            if (numUserHandles > 1) {
-                ProfileSelectDialog.show(getFragmentManager(), tile);
-                return false;
-            } else if (numUserHandles == 1) {
-                // Show menu on top level items.
-                tile.intent.putExtra(EXTRA_SHOW_MENU, true);
-                tile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
-                startActivityAsUser(tile.intent, tile.userHandle.get(0));
-            } else {
-                // Show menu on top level items.
-                tile.intent.putExtra(EXTRA_SHOW_MENU, true);
-                tile.intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
-                startActivity(tile.intent);
-            }
-        } catch (ActivityNotFoundException e) {
-            Log.w(TAG, "Couldn't find tile " + tile.intent, e);
-        }
-        return true;
-    }
-
-    protected void onTileClicked(Tile tile) {
-        if (openTile(tile)) {
-            finish();
-        }
-    }
-
     public void onProfileTileOpen() {
         finish();
     }
@@ -375,8 +208,8 @@
                 sTileBlacklist.add(component);
             }
             pm.setComponentEnabledSetting(component, enabled
-                    ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
-                    : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                            ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+                            : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                     PackageManager.DONT_KILL_APP);
         }
     }
@@ -385,11 +218,7 @@
      * Updates dashboard categories. Only necessary to call this after setTileEnabled
      */
     public void updateCategories() {
-        if (isDashboardFeatureEnabled()) {
-            new CategoriesUpdateTask().execute();
-        } else {
-            new CategoriesUpdater().execute();
-        }
+        new CategoriesUpdateTask().execute();
     }
 
     public String getSettingPkg() {
@@ -400,42 +229,6 @@
         void onCategoriesChanged();
     }
 
-    /**
-     * @deprecated remove after new IA
-     */
-    @Deprecated
-    private class CategoriesUpdater extends AsyncTask<Void, Void, List<DashboardCategory>> {
-        @Override
-        protected List<DashboardCategory> doInBackground(Void... params) {
-            if (sConfigTracker.applyNewConfig(getResources())) {
-                sTileCache.clear();
-            }
-            return TileUtils.getCategories(SettingsDrawerActivity.this, sTileCache);
-        }
-
-        @Override
-        protected void onPreExecute() {
-            if (sConfigTracker == null || sTileCache == null) {
-                getDashboardCategories();
-            }
-        }
-
-        @Override
-        protected void onPostExecute(List<DashboardCategory> dashboardCategories) {
-            for (int i = 0; i < dashboardCategories.size(); i++) {
-                DashboardCategory category = dashboardCategories.get(i);
-                for (int j = 0; j < category.tiles.size(); j++) {
-                    Tile tile = category.tiles.get(j);
-                    if (sTileBlacklist.contains(tile.intent.getComponent())) {
-                        category.tiles.remove(j--);
-                    }
-                }
-            }
-            sDashboardCategories = dashboardCategories;
-            onCategoriesChanged();
-        }
-    }
-
     private class CategoriesUpdateTask extends AsyncTask<Void, Void, Void> {
 
         private final CategoryManager mCategoryManager;
@@ -457,25 +250,10 @@
         }
     }
 
-    /**
-     * @return {@code true} if IA (Information Architecture) is enabled.
-     */
-    protected boolean isDashboardFeatureEnabled() {
-        return false;
-    }
-
-    boolean isNavDrawerEnabled() {
-        return getResources().getBoolean(R.bool.config_enable_nav_drawer);
-    }
-
     private class PackageReceiver extends BroadcastReceiver {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (isDashboardFeatureEnabled()) {
-                new CategoriesUpdateTask().execute();
-            } else {
-                new CategoriesUpdater().execute();
-            }
+            new CategoriesUpdateTask().execute();
         }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerAdapter.java b/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerAdapter.java
deleted file mode 100644
index 75942f9..0000000
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/SettingsDrawerAdapter.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2015 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.settingslib.drawer;
-
-import android.graphics.drawable.Icon;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.settingslib.R;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class SettingsDrawerAdapter extends BaseAdapter {
-
-    private final ArrayList<Item> mItems = new ArrayList<>();
-    private final SettingsDrawerActivity mActivity;
-
-    public SettingsDrawerAdapter(SettingsDrawerActivity activity) {
-        mActivity = activity;
-    }
-
-    /**
-     * @deprecated Remove after new IA
-     */
-    @Deprecated
-    void updateCategories() {
-        List<DashboardCategory> categories = mActivity.getDashboardCategories();
-        mItems.clear();
-        // Spacer.
-        mItems.add(null);
-        Item tile = new Item();
-        tile.label = mActivity.getString(R.string.home);
-        tile.icon = Icon.createWithResource(mActivity, R.drawable.home);
-        mItems.add(tile);
-        for (int i = 0; i < categories.size(); i++) {
-            Item category = new Item();
-            category.icon = null;
-            DashboardCategory dashboardCategory = categories.get(i);
-            category.label = dashboardCategory.title;
-            mItems.add(category);
-            for (int j = 0; j < dashboardCategory.tiles.size(); j++) {
-                tile = new Item();
-                Tile dashboardTile = dashboardCategory.tiles.get(j);
-                tile.label = dashboardTile.title;
-                tile.icon = dashboardTile.icon;
-                tile.tile = dashboardTile;
-                mItems.add(tile);
-            }
-        }
-        notifyDataSetChanged();
-    }
-
-    public void updateHomepageCategories(String settingPkg) {
-        final DashboardCategory category = CategoryManager.get(mActivity)
-                        .getTilesByCategory(mActivity, CategoryKey.CATEGORY_HOMEPAGE, settingPkg);
-        mItems.clear();
-        // Spacer.
-        mItems.add(null);
-        Item tile = new Item();
-        tile.label = mActivity.getString(R.string.home);
-        tile.icon = Icon.createWithResource(mActivity, R.drawable.home);
-        mItems.add(tile);
-        for (int j = 0; j < category.tiles.size(); j++) {
-            tile = new Item();
-            Tile dashboardTile = category.tiles.get(j);
-            tile.label = dashboardTile.title;
-            tile.icon = dashboardTile.icon;
-            tile.tile = dashboardTile;
-            mItems.add(tile);
-        }
-        notifyDataSetChanged();
-    }
-
-    public Tile getTile(int position) {
-        return mItems.get(position) != null ? mItems.get(position).tile : null;
-    }
-
-    @Override
-    public int getCount() {
-        return mItems.size();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return mItems.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return mItems.get(position) != null && mItems.get(position).icon != null;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        Item item = mItems.get(position);
-        if (item == null) {
-            if (convertView == null || convertView.getId() != R.id.spacer) {
-                convertView = LayoutInflater.from(mActivity).inflate(R.layout.drawer_spacer,
-                        parent, false);
-            }
-            return convertView;
-        }
-        if (convertView != null && convertView.getId() == R.id.spacer) {
-            convertView = null;
-        }
-        boolean isTile = item.icon != null;
-        if (convertView == null || (isTile != (convertView.getId() == R.id.tile_item))) {
-            convertView = LayoutInflater.from(mActivity).inflate(isTile ? R.layout.drawer_item
-                            : R.layout.drawer_category,
-                    parent, false);
-        }
-        if (isTile) {
-            ((ImageView) convertView.findViewById(android.R.id.icon)).setImageIcon(item.icon);
-        }
-        ((TextView) convertView.findViewById(android.R.id.title)).setText(item.label);
-        return convertView;
-    }
-
-    private static class Item {
-        public Icon icon;
-        public CharSequence label;
-        public Tile tile;
-    }
-}
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
index 3f6f5b5..55be137 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
@@ -396,7 +396,7 @@
                             .applicationInfo);
         }
         return LocaleHelper.toSentenceCase(
-                ListFormatter.getInstance(locale).format(subtypeNames), locale);
+                ListFormatter.getInstance(locale).format((Object[]) subtypeNames), locale);
     }
 
     @NonNull
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
index 69da548..50972c7 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPointPreference.java
@@ -23,6 +23,7 @@
 import android.graphics.drawable.StateListDrawable;
 import android.net.NetworkBadging;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
 import android.os.Looper;
 import android.os.UserHandle;
 import android.support.v7.preference.Preference;
@@ -222,7 +223,8 @@
         }
 
         final Context context = getContext();
-        int level = mAccessPoint.getLevel();
+        int level = WifiManager.calculateSignalLevel(
+                mAccessPoint.getRssi(), WifiManager.RSSI_LEVELS);
         int wifiBadge = mAccessPoint.getBadge();
         if (level != mLevel || wifiBadge != mWifiBadge) {
             mLevel = level;
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
index c3f2f73..752b5b0 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/drawer/SettingsDrawerActivityTest.java
@@ -86,16 +86,6 @@
                 .check(matches(isDisplayed()));
     }
 
-    @Test
-    public void startActivity_shouldNotHaveNavDrawer() {
-        Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
-        Activity activity = instrumentation.startActivitySync(
-                new Intent(instrumentation.getTargetContext(), TestActivity.class));
-
-        assertThat(((SettingsDrawerActivity) activity).isNavDrawerEnabled())
-                .isFalse();
-    }
-
     /**
      * Test Activity in this test.
      *
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarter.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/ActivityStarter.java
rename to packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
index a4d8a10..b58ea00 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarter.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/ActivityStarter.java
@@ -12,17 +12,21 @@
  * permissions and limitations under the License.
  */
 
-package com.android.systemui;
+package com.android.systemui.plugins;
 
 import android.app.PendingIntent;
 import android.content.Intent;
 
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
 /**
  * An interface to start activities. This is used as a callback from the views to
  * {@link PhoneStatusBar} to allow custom handling for starting the activity, i.e. dismissing the
  * Keyguard.
  */
+@ProvidesInterface(version = ActivityStarter.VERSION)
 public interface ActivityStarter {
+    int VERSION = 1;
 
     void startPendingIntentDismissingKeyguard(PendingIntent intent);
     void startActivity(Intent intent, boolean dismissShade);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
new file mode 100644
index 0000000..25ce3dd
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/PluginDependency.java
@@ -0,0 +1,31 @@
+/*
+ * 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.systemui.plugins;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+@ProvidesInterface(version = PluginDependency.VERSION)
+public class PluginDependency {
+    public static final int VERSION = 1;
+    static DependencyProvider sProvider;
+
+    public static <T> T get(Plugin p, Class<T> cls) {
+        return sProvider.get(p, cls);
+    }
+
+    static abstract class DependencyProvider {
+        abstract <T> T get(Plugin p, Class<T> cls);
+    }
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
index ddee89e..674ed5a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java
@@ -19,7 +19,7 @@
 import com.android.systemui.plugins.Plugin;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
 
-@ProvidesInterface(action = NavGesture.ACTION, version = NavBarButtonProvider.VERSION)
+@ProvidesInterface(action = NavGesture.ACTION, version = NavGesture.VERSION)
 public interface NavGesture extends Plugin {
 
     public static final String ACTION = "com.android.systemui.action.PLUGIN_NAV_GESTURE";
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 073a6dc..d63fc0e 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Skermkiekies"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Algemene boodskappe"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Berging"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Kitsprogramme"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Kitsprogramme hoef nie geïnstalleer te word nie."</string>
     <string name="app_info" msgid="6856026610594615344">"Programinligting"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index f33b663..4bfebd2 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"ቅጽበታዊ ገጽ እይታዎች"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"አጠቃላይ መልዕክቶች"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"ማከማቻ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"የቅጽበት መተግበሪያዎች"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ቅጽበታዊ መተግበሪያዎች መጫን አያስፈልጋቸውም።"</string>
     <string name="app_info" msgid="6856026610594615344">"የመተግበሪያ መረጃ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 94810bd..1381cb3 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -704,9 +704,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"لقطات الشاشة"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"رسائل عامة"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"سعة التخزين"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"التطبيقات الفورية"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"لا تتطلب التطبيقات الفورية إجراء التثبيت."</string>
     <string name="app_info" msgid="6856026610594615344">"معلومات عن التطبيق"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index dea9a57..c90e442 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Skrinşotlar"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Ümumi Mesajlar"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Yaddaş"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Ani Tətbiqlər"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Ani tətbiqlər quraşdırma tələb etmir."</string>
     <string name="app_info" msgid="6856026610594615344">"Tətbiq məlumatı"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index eaeabc9..59a925e 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -695,9 +695,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Snimci ekrana"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Opšte poruke"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Memorijski prostor"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant aplikacije"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant aplikacije ne zahtevaju instalaciju."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 89191fa..efbf39e 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -700,9 +700,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Здымкі экрана"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Агульныя паведамленні"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Захоўванне"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Імгненныя праграмы"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Імгненныя праграмы не патрабуюць усталёўкі."</string>
     <string name="app_info" msgid="6856026610594615344">"Інфармацыя пра праграму"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 3816775..3ebfcc8 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Екранни снимки"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Общи съобщения"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Хранилище"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Мигновени приложения"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"За мигновените приложения не се изисква инсталиране."</string>
     <string name="app_info" msgid="6856026610594615344">"Информация за приложението"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 76a882f..476e27c 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"স্ক্রীনশটস"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"সাধারণ বার্তাগুলি"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"সঞ্চয়স্থান"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"ঝটপট অ্যাপ"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ঝটপট অ্যাপ ইনস্টল করার প্রয়োজন হয় না।"</string>
     <string name="app_info" msgid="6856026610594615344">"অ্যাপ্লিকেশানের তথ্য"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 208befe..c318501 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -697,9 +697,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Snimci ekrana"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Općenite poruke"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Pohrana"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant-aplikacije"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Za instant aplikacije nije potrebna instalacija"</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index ccb3114..14455b3 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Captures de pantalla"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Missatges generals"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Emmagatzematge"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplicacions instantànies"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"No cal instal·lar les aplicacions instantànies."</string>
     <string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 534e7bf..2cb79c9 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -700,9 +700,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Snímky obrazovek"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Všeobecné zprávy"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Úložiště"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Okamžité aplikace"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Okamžité aplikace není třeba instalovat."</string>
     <string name="app_info" msgid="6856026610594615344">"Informace o aplikaci"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index f694924..681f747 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Generelle meddelelser"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagerplads"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps kræver ingen installation."</string>
     <string name="app_info" msgid="6856026610594615344">"Oplysninger om appen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index dbbb4f9..cb6c4b3 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Nachrichten"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Speicher"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant-Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Bei Instant-Apps ist keine vorherige Installation erforderlich."</string>
     <string name="app_info" msgid="6856026610594615344">"App-Informationen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index 688084b..0998797 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Στιγμιότυπα οθόνης"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Γενικά μηνύματα"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Αποθηκευτικός χώρος"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Εφαρμογές"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Οι Instant Εφαρμογές δεν απαιτούν εγκατάσταση."</string>
     <string name="app_info" msgid="6856026610594615344">"Πληροφορίες εφαρμογής"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index bcac06f..eba837a 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"General Messages"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index bcac06f..eba837a 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"General Messages"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index bcac06f..eba837a 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"General Messages"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant apps don\'t require installation."</string>
     <string name="app_info" msgid="6856026610594615344">"App info"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index b0ccb27..c2a41f1 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Capturas de pantalla"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mensajes generales"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Almacenamiento"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Apps instantáneas"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Las Apps instantáneas no requieren instalación."</string>
     <string name="app_info" msgid="6856026610594615344">"Información de la app"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 59fe471..503eb64 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Capturas de pantalla"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mensajes generales"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Almacenamiento"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplicaciones Instantáneas"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"No es necesario instalar las Aplicaciones Instantáneas."</string>
     <string name="app_info" msgid="6856026610594615344">"Información de la aplicación"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 3afebd7..94577f5 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Ekraanipildid"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Üldised sõnumid"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Salvestusruum"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Installimata avatavad rakendused"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Installimata avatavaid rakendusi pole vaja installida."</string>
     <string name="app_info" msgid="6856026610594615344">"Rakenduse teave"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 399d9ec..72d8ecb 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Pantaila-argazkiak"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mezu orokorrak"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Memoria"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Zuzeneko aplikazioak"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Zuzeneko aplikazioak ez dira instalatu behar."</string>
     <string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index f38bd46..b8e8ed1 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"عکس‌های صفحه‌نمایش"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"پیام‌های عمومی"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"فضای ذخیره‌سازی"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"برنامه‌های فوری"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"برنامه‌های فوری نیاز به نصب ندارند."</string>
     <string name="app_info" msgid="6856026610594615344">"اطلاعات برنامه"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index b29a0f5..2480ac8 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Kuvakaappaukset"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Yleiset viestit"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Tallennustila"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Pikasovelluksia ei tarvitse asentaa."</string>
     <string name="app_info" msgid="6856026610594615344">"Sovelluksen tiedot"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 21f7498..121b137 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Saisies d\'écran"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Messages généraux"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Stockage"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Applications instantanées"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Les applications instantanées ne nécessitent pas d\'installation."</string>
     <string name="app_info" msgid="6856026610594615344">"Détails de l\'application"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index c65e0ea..6d677ae 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Captures d\'écran"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Nouveaux messages"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Espace de stockage"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Applis instantanées"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Les applis instantanées ne nécessitent pas d\'installation."</string>
     <string name="app_info" msgid="6856026610594615344">"Infos sur l\'appli"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 3579ebe..e5df1d3 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Capturas de pantalla"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mensaxes xerais"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Almacenamento"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplicacións instantáneas"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"As aplicacións instantáneas non precisan instalación."</string>
     <string name="app_info" msgid="6856026610594615344">"Información da aplicación"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index acc3890..381476f 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"સ્ક્રીનશૉટ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"સામાન્ય સંદેશા"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"સ્ટોરેજ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"ઝટપટ ઍપ્લિકેશનો"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ઝટપટ ઍપ્લિકેશનો માટે ઇન્સ્ટૉલેશનની જરૂર નથી."</string>
     <string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index a318ea3..27a5918 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"स्‍क्रीनशॉट"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"सामान्य संदेश"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"जगह"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"झटपट ऐप्स"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"झटपट ऐप्स के लिए इंस्टॉलेशन ज़रूरी नहीं है."</string>
     <string name="app_info" msgid="6856026610594615344">"ऐप की जानकारी"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 2ce11af..7957f2c 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -695,9 +695,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Snimke zaslona"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Općenite poruke"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Pohrana"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant aplikacije"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant aplikacije nije potrebno instalirati."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 288b25f..629867b 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Képernyőképek"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Általános üzenetek"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Tárhely"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Azonnali alkalmazások"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Az azonnali alkalmazásokat nem kell telepíteni."</string>
     <string name="app_info" msgid="6856026610594615344">"Alkalmazásinformáció"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 3b8dac7..f090714 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Էկրանի պատկերներ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Ընդհանուր հաղորդագրություններ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Հիշողություն"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Ակնթարթորեն գործարկվող հավելվածներ"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Ակնթարթորեն գործարկվող հավելվածները տեղադրում չեն պահանջում։"</string>
     <string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 8efc3a9..12acc55 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshot"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Pesan Umum"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Penyimpanan"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplikasi Instan"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikasi instan tidak perlu diinstal."</string>
     <string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index c1fa058..a355771 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Skjámyndir"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Almenn skilaboð"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Geymslurými"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Skyndiforrit"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Skyndiforrit þurfa ekki uppsetningu."</string>
     <string name="app_info" msgid="6856026610594615344">"Forritsupplýsingar"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 481d80c..be648e7 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshot"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Messaggi generali"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Spazio di archiviazione"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"App istantanee"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Le app istantanee non richiedono l\'installazione."</string>
     <string name="app_info" msgid="6856026610594615344">"Informazioni app"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f22dec5..d20d590 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -698,9 +698,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"צילומי מסך"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"הודעות כלליות"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"אחסון"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"אפליקציות אינסטנט"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"אפליקציות אינסטנט לא דורשות התקנה."</string>
     <string name="app_info" msgid="6856026610594615344">"פרטי אפליקציה"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index d4c381e..00405ac 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"スクリーンショット"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"一般メッセージ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"ストレージ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant Apps はインストールせずに利用できます。"</string>
     <string name="app_info" msgid="6856026610594615344">"アプリ情報"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 674f308..b5bc2408 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"ეკრანის ანაბეჭდები"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"ზოგადი შეტყობინებები"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"მეხსიერება"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"მყისიერი აპები"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"მყისიერი აპები ინსტალაციას არ საჭიროებს."</string>
     <string name="app_info" msgid="6856026610594615344">"აპის შესახებ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index dba10da..3e5fe2d 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Скриншоттар"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Жалпы хабарлар"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Жад"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Лездік қолданбаларды орнатудың қажеті жоқ."</string>
     <string name="app_info" msgid="6856026610594615344">"Қолданба ақпараты"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index f91c80a..4856e3c 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"រូបថត​អេក្រង់"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"សារ​ទូទៅ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"ទំហំផ្ទុក"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"កម្មវិធី​ប្រើ​ភ្លាមៗ"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"កម្មវិធី​ប្រើ​ភ្លាមៗ​មិន​តម្រូវ​ឲ្យ​មានការ​ដំឡើង​ទេ។"</string>
     <string name="app_info" msgid="6856026610594615344">"ព័ត៌មាន​កម្មវិធី"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index b94c0bf..65b89b8 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"ಸ್ಕ್ರೀನ್‌ಶಾಟ್‌ಗಳು"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"ಸಾಮಾನ್ಯ ಸಂದೇಶಗಳು"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"ಸಂಗ್ರಹಣೆ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"ತತ್‌ಕ್ಷಣ ಆಪ್‌ಗಳು"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ತತ್‌ಕ್ಷಣ ಆಪ್‌ಗಳಿಗೆ ಸ್ಥಾಪನೆಯ ಅಗತ್ಯವಿಲ್ಲ."</string>
     <string name="app_info" msgid="6856026610594615344">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index d46c0af..9c277b0 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"스크린샷"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"일반 메시지"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"저장소"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"빠른 실행 앱"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"빠른 실행 앱은 설치가 필요하지 않습니다."</string>
     <string name="app_info" msgid="6856026610594615344">"앱 정보"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index ec61db1..9080df8 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Скриншоттор"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Жалпы билдирүүлөр"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Сактагыч"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Ыкчам ачылуучу колдонмолор"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Ыкчам ачылуучу колдонмолорду орнотуу талап кылынбайт."</string>
     <string name="app_info" msgid="6856026610594615344">"Колдонмо тууралуу"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 87f008b..3ccbe92 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"ຮູບຖ່າຍໜ້າຈໍ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"ຂໍ້ຄວາມທົ່ວໄປ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"ບ່ອນເກັບຂໍ້ມູນ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"ອິນສະແຕນແອັບ"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ອິນສະແຕນແອັບບໍ່ຈຳເປັນຕ້ອງມີການຕິດຕັ້ງ."</string>
     <string name="app_info" msgid="6856026610594615344">"ຂໍ້ມູນແອັບ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index f2df152..fa4ab0d 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -698,9 +698,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Ekrano kopijos"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Bendrieji pranešimai"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Saugykla"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Akimirksniu įkeliamos programėlės"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Akimirksniu įkeliamų programėlių nereikia įdiegti."</string>
     <string name="app_info" msgid="6856026610594615344">"Programos informacija"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index e5970d4..cb7c413 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -695,9 +695,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Ekrānuzņēmumi"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Vispārīgi ziņojumi"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Krātuve"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Tūlītējās lietotnes"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Tūlītējām lietotnēm nav nepieciešama instalēšana."</string>
     <string name="app_info" msgid="6856026610594615344">"Lietotnes informācija"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index dc5f44d..cdadb0a 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Слики од екранот"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Општи пораки"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Меморија"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Инстант апликации"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Инстант апликациите нема потреба да се инсталираат."</string>
     <string name="app_info" msgid="6856026610594615344">"Информации за апликација"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 4e3da1b..38769cf 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"സ്‌ക്രീൻഷോട്ടുകൾ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"പൊതുവായ സന്ദേശങ്ങൾ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"സ്റ്റോറേജ്"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"ഇൻസ്റ്റന്റ് ആപ്പ്"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ഇൻസ്‌റ്റ‌ന്റ് ആപ്പിന് ഇൻസ്‌റ്റലേഷൻ ആവശ്യമില്ല."</string>
     <string name="app_info" msgid="6856026610594615344">"ആപ്പ് വിവരം"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 1ec28b2..206a9cc 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Дэлгэцийн зураг дарах"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Энгийн зурвас"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Хадгалах сан"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Шуурхай апп"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Шуурхай аппыг суулгах шаардлагагүй."</string>
     <string name="app_info" msgid="6856026610594615344">"Апп-н мэдээлэл"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index cce2635..266d0c9 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"स्क्रीनशॉट"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"सर्वसाधारण संदेश"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"संचय"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"इन्सटंट अ‍ॅप्स"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"इन्सटंट अॅप्सना स्थापनेची आवश्यकता नसते."</string>
     <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index afc9541..441b4c1 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Tangkapan skrin"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mesej Am"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storan"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Apl Segera"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Apl segera tidak memerlukan pemasangan."</string>
     <string name="app_info" msgid="6856026610594615344">"Maklumat apl"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 26cc72c..9b9359e 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"မျက်နှာပြင်ဓာတ်ပုံများ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"အထွေထွေ မက်ဆေ့ဂျ်များ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"သိုလှောင်မှုများ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ချက်ခြင်းသုံးအက်ပ်များကို ထည့်သွင်းစရာမလိုပါ။"</string>
     <string name="app_info" msgid="6856026610594615344">"အက်ပ်အချက်အလက်"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index ccee80e..1744729 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Skjermdumper"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Generelle meldinger"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagring"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Du trenger ikke å installere instant-apper."</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index cc63dfb..a634b91 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"स्क्रिनशटहरू"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"सामान्य सन्देशहरू"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"भण्डारण"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"तात्कालिक अनुप्रयोगहरू"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"तात्कालिक अनुप्रयोगहरूलाई स्थापना गर्नु पर्दैन|"</string>
     <string name="app_info" msgid="6856026610594615344">"अनुप्रयोगका बारे जानकारी"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 3fdf5a4..b5b741c 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Screenshots"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Algemene berichten"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Opslag"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant-apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant-apps hoeven niet te worden geïnstalleerd."</string>
     <string name="app_info" msgid="6856026610594615344">"App-info"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index bcdfb4c..abd0a70 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"ਸਕ੍ਰੀਨਸ਼ਾਟ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"ਆਮ ਸੁਨੇਹੇ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"ਸਟੋਰੇਜ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"ਤਤਕਾਲ ਐਪਾਂ"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ਤਤਕਾਲ ਐਪਾਂ ਨੂੰ ਸਥਾਪਨਾ ਦੀ ਲੋੜ ਨਹੀਂ ਹੈ।"</string>
     <string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index d2bf88e..09159ab 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -698,9 +698,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Zrzuty ekranu"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Wiadomości"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Miejsce"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplikacje błyskawiczne"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikacji błyskawicznych nie trzeba instalować."</string>
     <string name="app_info" msgid="6856026610594615344">"O aplikacji"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 56ec9bc..19c3c28 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Capturas de tela"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mensagens gerais"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Armazenamento"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Os Instant Apps não requerem instalação."</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 4daf104..d221f3a 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Capturas de ecrã"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mensagens gerais"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Armazenamento"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplicações instantâneas"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"As Aplicações instantâneas não requerem instalação."</string>
     <string name="app_info" msgid="6856026610594615344">"Informações da aplicação"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 56ec9bc..19c3c28 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Capturas de tela"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mensagens gerais"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Armazenamento"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Os Instant Apps não requerem instalação."</string>
     <string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 2315e3b..2f32f6b 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -697,9 +697,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Capturi de ecran"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mesaje generale"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Stocare"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplicații instantanee"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Aplicațiile instantanee nu necesită instalare."</string>
     <string name="app_info" msgid="6856026610594615344">"Informații despre aplicație"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index ab26879..744e322 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -700,9 +700,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Скриншоты"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Сообщения"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Хранилище"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Приложения с мгновенным запуском"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Приложения с мгновенным запуском не требуется устанавливать."</string>
     <string name="app_info" msgid="6856026610594615344">"О приложении"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 5040eb7..1b60299 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"තිර රු"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"පොදු පණිවිඩ"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"ගබඩාව"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"ක්ෂණික යෙදුම්"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"ක්ෂණික යෙදුම් ස්ථාපනය කිරීම අවශ්‍ය නොවේ."</string>
     <string name="app_info" msgid="6856026610594615344">"යෙදුම් තොරතුරු"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 5e163c2..4ff18ba 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -700,9 +700,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Snímky obrazovky"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Všeobecné správy"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Úložisko"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Okamžité aplikácie"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Okamžité aplikácie nevyžadujú inštaláciu."</string>
     <string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index ee33c0b..a689699 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -700,9 +700,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Posnetki zaslona"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Splošna sporočila"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Shramba"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplikacije brez nameščanja"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikacij brez nameščanja ni treba namestiti."</string>
     <string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index aab5942..757714fa 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Pamjet e ekranit"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mesazhe të përgjithshme"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Hapësira ruajtëse"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Aplikacionet e çastit"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Aplikacionet e çastit nuk kërkojnë instalim."</string>
     <string name="app_info" msgid="6856026610594615344">"Informacioni mbi aplikacionin"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 0d6aa7b..f02e935 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -695,9 +695,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Снимци екрана"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Опште поруке"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Меморијски простор"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Инстант апликације"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Инстант апликације не захтевају инсталацију."</string>
     <string name="app_info" msgid="6856026610594615344">"Информације о апликацији"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index fb8df95..6778c73 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Skärmdumpar"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Allmänna meddelanden"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Lagring"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Snabbappar behöver inte installeras."</string>
     <string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 15cc6aa..f97a582 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Picha za skrini"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Ujumbe wa Jumla"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Hifadhi"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Programu Zinazofunguka Papo Hapo"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Huhitaji kusakinisha programu zinazofunguka papo hapo."</string>
     <string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 20ba620..c7166bd 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"ஸ்கிரீன் ஷாட்டுகள்"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"பொதுச் செய்திகள்"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"சேமிப்பிடம்"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"இன்ஸ்டண்ட் பயன்பாடுகள்"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"இன்ஸ்டண்ட் பயன்பாடுகளுக்கு நிறுவல் தேவையில்லை."</string>
     <string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index e824a35..e55fa84 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"స్క్రీన్‌షాట్‌లు"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"సాధారణ సందేశాలు"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"నిల్వ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"తక్షణ అనువర్తనాలు"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"తక్షణ అనువర్తనాలకు ఇన్‌స్టాలేషన్ అవసరం లేదు."</string>
     <string name="app_info" msgid="6856026610594615344">"అనువర్తన సమాచారం"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 667b106..c501195 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"ภาพหน้าจอ"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"ข้อความทั่วไป"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"พื้นที่เก็บข้อมูล"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant App"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Instant Apps ไม่ต้องใช้การติดตั้ง"</string>
     <string name="app_info" msgid="6856026610594615344">"ข้อมูลแอป"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 2f6fdb2..1789606 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Mga Screenshot"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Mga Pangkalahatang Mensahe"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Storage"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Instant Apps"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Hindi kailangang i-install ang mga instant na app."</string>
     <string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index b2e7365..7675450 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Ekran görüntüleri"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Genel Mesajlar"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Depolama alanı"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Hazır Uygulamalar"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Hazır uygulamaların yüklenmesi gerekmez."</string>
     <string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 7eb84e4..774a663 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -700,9 +700,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Знімки екрана"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Загальні повідомлення"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Пам’ять"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Додатки з миттєвим запуском"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Додатки з миттєвим запуском не потрібно встановлювати."</string>
     <string name="app_info" msgid="6856026610594615344">"Про додаток"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 6a0b92b..ee42e12 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"اسکرین شاٹس"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"عمومی پیغامات"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"اسٹوریج"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"فوری ایپس"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"فوری ایپس کو انسٹالیشن کی ضرورت نہیں ہے۔"</string>
     <string name="app_info" msgid="6856026610594615344">"ایپ کی معلومات"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 810902d..28bb21a 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Skrinshotlar"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Umumiy xabarlar"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Xotira"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Darhol ochiladigan ilovalar"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Darhol ochiladigan ilovalarni o‘rnatish shart emas."</string>
     <string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index a3ac98e..82b614d 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Ảnh chụp màn hình"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Thông báo chung"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Bộ nhớ"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Ứng dụng tức thì"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Ứng dụng tức thì không yêu cầu cài đặt."</string>
     <string name="app_info" msgid="6856026610594615344">"Thông tin ứng dụng"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 30db51a..9c7435a 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"屏幕截图"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"常规消息"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"存储空间"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"免安装应用"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"免安装应用无需安装就能使用。"</string>
     <string name="app_info" msgid="6856026610594615344">"应用信息"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index ee1dbb7..26fc99b 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -694,9 +694,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"螢幕擷取畫面"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"一般訊息"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"儲存空間"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"即時應用程式"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"即時應用程式無需安裝即可使用。"</string>
     <string name="app_info" msgid="6856026610594615344">"應用程式資料"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 35468dd..fc756f4 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"螢幕擷取畫面"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"一般訊息"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"儲存空間"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"免安裝應用程式"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"免安裝應用程式不必安裝就能使用。"</string>
     <string name="app_info" msgid="6856026610594615344">"應用程式資訊"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 6007ea2..38580ec 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -692,9 +692,7 @@
     <string name="notification_channel_screenshot" msgid="6314080179230000938">"Izithombe-skrini"</string>
     <string name="notification_channel_general" msgid="4525309436693914482">"Imilayezo ejwayelekile"</string>
     <string name="notification_channel_storage" msgid="3077205683020695313">"Isitoreji"</string>
-    <!-- no translation found for instant_apps (6647570248119804907) -->
-    <skip />
-    <!-- no translation found for instant_apps_message (8116608994995104836) -->
-    <skip />
+    <string name="instant_apps" msgid="6647570248119804907">"Izinhlelo zokusebenza ezisheshayo"</string>
+    <string name="instant_apps_message" msgid="8116608994995104836">"Izinhlelo zokusebenza ezisheshayo azidingi ukufakwa."</string>
     <string name="app_info" msgid="6856026610594615344">"Ulwazi lohlelo lokusebenza"</string>
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
index 14c67fe..e58538d 100644
--- a/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/ActivityStarterDelegate.java
@@ -17,6 +17,8 @@
 import android.app.PendingIntent;
 import android.content.Intent;
 
+import com.android.systemui.plugins.ActivityStarter;
+
 /**
  * Single common instance of ActivityStarter that can be gotten and referenced from anywhere, but
  * delegates to an actual implementation such as StatusBar, assuming it exists.
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index ac7ab9d..bb7e19d 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -23,10 +23,12 @@
 import android.util.ArrayMap;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.NightDisplayController;
 import com.android.internal.util.Preconditions;
 import com.android.systemui.assist.AssistManager;
-import com.android.systemui.fragments.FragmentHostManager;
 import com.android.systemui.fragments.FragmentService;
+import com.android.systemui.plugins.ActivityStarter;
+import com.android.systemui.plugins.PluginDependencyProvider;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
 import com.android.systemui.statusbar.phone.DarkIconDispatcherImpl;
@@ -179,6 +181,9 @@
         mProviders.put(BatteryController.class, () ->
                 new BatteryControllerImpl(mContext));
 
+        mProviders.put(NightDisplayController.class, () ->
+                new NightDisplayController(mContext));
+
         mProviders.put(ManagedProfileController.class, () ->
                 new ManagedProfileControllerImpl(mContext));
 
@@ -238,6 +243,9 @@
         mProviders.put(ExtensionController.class, () ->
                 new ExtensionControllerImpl());
 
+        mProviders.put(PluginDependencyProvider.class, () ->
+                new PluginDependencyProvider(get(PluginManager.class)));
+
         // Put all dependencies above here so the factory can override them if it wants.
         SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index b9ae585..e1aaaa3 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -47,6 +47,7 @@
         Key.QS_DATA_SAVER_DIALOG_SHOWN,
         Key.QS_INVERT_COLORS_ADDED,
         Key.QS_WORK_ADDED,
+        Key.QS_NIGHTDISPLAY_ADDED,
     })
     public @interface Key {
         @Deprecated
@@ -67,6 +68,7 @@
         String QS_DATA_SAVER_DIALOG_SHOWN = "QsDataSaverDialogShown";
         String QS_INVERT_COLORS_ADDED = "QsInvertColorsAdded";
         String QS_WORK_ADDED = "QsWorkAdded";
+        String QS_NIGHTDISPLAY_ADDED = "QsNightDisplayAdded";
     }
 
     public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
new file mode 100644
index 0000000..59f6d56
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginDependencyProvider.java
@@ -0,0 +1,50 @@
+/*
+ * 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.systemui.plugins;
+
+import android.util.ArrayMap;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.plugins.PluginDependency.DependencyProvider;
+
+public class PluginDependencyProvider extends DependencyProvider {
+
+    private final ArrayMap<Class<?>, Object> mDependencies = new ArrayMap<>();
+    private final PluginManager mManager;
+
+    public PluginDependencyProvider(PluginManager manager) {
+        mManager = manager;
+        PluginDependency.sProvider = this;
+    }
+
+    public <T> void allowPluginDependency(Class<T> cls) {
+        allowPluginDependency(cls, Dependency.get(cls));
+    }
+
+    public <T> void allowPluginDependency(Class<T> cls, T obj) {
+        mDependencies.put(cls, obj);
+    }
+
+    @Override
+    <T> T get(Plugin p, Class<T> cls) {
+        if (!mManager.dependsOn(p, cls)) {
+            throw new IllegalArgumentException(p.getClass() + " does not depend on " + cls);
+        }
+        if (!mDependencies.containsKey(cls)) {
+            throw new IllegalArgumentException("Unknown dependency " + cls);
+        }
+        return (T) mDependencies.get(cls);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
index e895fa2..58670da 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginInstanceManager.java
@@ -161,6 +161,16 @@
         mContext.sendBroadcast(intent);
     }
 
+    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
+        ArrayList<PluginInfo> plugins = new ArrayList<>(mPluginHandler.mPlugins);
+        for (PluginInfo info : plugins) {
+            if (info.mPlugin.getClass().getName().equals(p.getClass().getName())) {
+                return info.mVersion != null && info.mVersion.hasClass(cls);
+            }
+        }
+        return false;
+    }
+
     private class MainHandler extends Handler {
         private static final int PLUGIN_CONNECTED = 1;
         private static final int PLUGIN_DISCONNECTED = 2;
@@ -304,9 +314,9 @@
                 // legacy version check.
                 T plugin = (T) pluginClass.newInstance();
                 try {
-                    checkVersion(pluginClass, plugin, mVersion);
+                    VersionInfo version = checkVersion(pluginClass, plugin, mVersion);
                     if (DEBUG) Log.d(TAG, "createPlugin");
-                    return new PluginInfo(pkg, cls, plugin, pluginContext);
+                    return new PluginInfo(pkg, cls, plugin, pluginContext, version);
                 } catch (InvalidVersionException e) {
                     final int icon = mContext.getResources().getIdentifier("tuner", "drawable",
                             mContext.getPackageName());
@@ -354,7 +364,7 @@
             }
         }
 
-        private void checkVersion(Class<?> pluginClass, T plugin, VersionInfo version)
+        private VersionInfo checkVersion(Class<?> pluginClass, T plugin, VersionInfo version)
                 throws InvalidVersionException {
             VersionInfo pv = new VersionInfo().addClass(pluginClass);
             if (pv.hasVersionInfo()) {
@@ -364,7 +374,9 @@
                 if (fallbackVersion != version.getDefaultVersion()) {
                     throw new InvalidVersionException("Invalid legacy version", false);
                 }
+                return null;
             }
+            return pv;
         }
     }
 
@@ -396,15 +408,18 @@
 
     static class PluginInfo<T> {
         private final Context mPluginContext;
+        private final VersionInfo mVersion;
         private String mClass;
         T mPlugin;
         String mPackage;
 
-        public PluginInfo(String pkg, String cls, T plugin, Context pluginContext) {
+        public PluginInfo(String pkg, String cls, T plugin, Context pluginContext,
+                VersionInfo info) {
             mPlugin = plugin;
             mClass = cls;
             mPackage = pkg;
             mPluginContext = pluginContext;
+            mVersion = info;
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java
index 0c3e40c..9ad862d 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManager.java
@@ -29,6 +29,7 @@
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.SystemProperties;
@@ -39,6 +40,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.systemui.Dependency;
 import com.android.systemui.plugins.PluginInstanceManager.PluginContextWrapper;
 import com.android.systemui.plugins.PluginInstanceManager.PluginInfo;
 import com.android.systemui.plugins.annotations.ProvidesInterface;
@@ -93,6 +95,14 @@
         PluginExceptionHandler uncaughtExceptionHandler = new PluginExceptionHandler(
                 defaultHandler);
         Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
+        if (isDebuggable) {
+            new Handler(mBackgroundThread.getLooper()).post(() -> {
+                // Plugin dependencies that don't have another good home can go here, but
+                // dependencies that have better places to init can happen elsewhere.
+                Dependency.get(PluginDependencyProvider.class)
+                        .allowPluginDependency(ActivityStarter.class);
+            });
+        }
     }
 
     public <T extends Plugin> T getOneShotPlugin(Class<T> cls) {
@@ -268,11 +278,6 @@
         return mParentClassLoader;
     }
 
-    public Context getAllPluginContext(Context context) {
-        return new PluginContextWrapper(context,
-                new AllPluginClassLoader(context.getClassLoader()));
-    }
-
     public Context getContext(ApplicationInfo info, String pkg) throws NameNotFoundException {
         ClassLoader classLoader = getClassLoader(info.sourceDir, pkg);
         return new PluginContextWrapper(mContext.createApplicationContext(info, 0), classLoader);
@@ -289,26 +294,13 @@
         return info.action();
     }
 
-    private class AllPluginClassLoader extends ClassLoader {
-        public AllPluginClassLoader(ClassLoader classLoader) {
-            super(classLoader);
-        }
-
-        @Override
-        public Class<?> loadClass(String s) throws ClassNotFoundException {
-            try {
-                return super.loadClass(s);
-            } catch (ClassNotFoundException e) {
-                for (ClassLoader classLoader : mClassLoaders.values()) {
-                    try {
-                        return classLoader.loadClass(s);
-                    } catch (ClassNotFoundException e1) {
-                        // Will re-throw e if all fail.
-                    }
-                }
-                throw e;
+    public <T> boolean dependsOn(Plugin p, Class<T> cls) {
+        for (int i = 0; i < mPluginMap.size(); i++) {
+            if (mPluginMap.valueAt(i).dependsOn(p, cls)) {
+                return true;
             }
         }
+        return false;
     }
 
     @VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/VersionInfo.java b/packages/SystemUI/src/com/android/systemui/plugins/VersionInfo.java
index 84f7761..b69a7b4 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/VersionInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/VersionInfo.java
@@ -103,6 +103,10 @@
         return null;
     }
 
+    public <T> boolean hasClass(Class<T> cls) {
+        return mVersions.containsKey(cls);
+    }
+
     public static class InvalidVersionException extends RuntimeException {
         private final boolean mTooNew;
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index a20b7ba..7df124a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -37,7 +37,7 @@
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.BaseStatusBarHeader;
 import com.android.systemui.plugins.qs.QS.Callback;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 1835afd..d6c2447 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -37,7 +37,7 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.phone.QSTileHost;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.statusbar.policy.SecurityController;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 0829ae5..c02067e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -32,7 +32,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.systemui.Dependency;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.QSTile.State;
 import com.android.systemui.qs.external.TileServices;
@@ -45,8 +45,6 @@
 
 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
 
-import com.android.systemui.R;
-
 /**
  * Base quick-settings tile, extend this to create a new tile.
  *
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
index cdde6ea0..b28b0e7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java
@@ -30,17 +30,13 @@
 import android.service.quicksettings.IQSTileService;
 import android.service.quicksettings.Tile;
 import android.service.quicksettings.TileService;
-import android.text.SpannableStringBuilder;
-import android.text.style.ForegroundColorSpan;
 import android.util.Log;
 import android.view.IWindowManager;
-import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.R;
 import com.android.systemui.Dependency;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener;
 import com.android.systemui.statusbar.phone.QSTileHost;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
index f7bfc1e..62aa466 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BatteryTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BatterySaverTile.java
@@ -23,16 +23,18 @@
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
 import android.text.style.RelativeSizeSpan;
+import android.util.Log;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.Button;
 import android.widget.Checkable;
 import android.widget.ImageView;
+import android.widget.Switch;
 import android.widget.TextView;
+
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.settingslib.BatteryInfo;
 import com.android.settingslib.graph.BatteryMeterDrawableBase;
@@ -43,9 +45,8 @@
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.BatteryController;
 
-import java.text.NumberFormat;
-
-public class BatteryTile extends QSTile<QSTile.State> implements BatteryController.BatteryStateChangeCallback {
+public class BatterySaverTile extends QSTile<QSTile.BooleanState> implements
+        BatteryController.BatteryStateChangeCallback {
 
     private final BatteryController mBatteryController;
     private final BatteryDetail mBatteryDetail = new BatteryDetail();
@@ -56,19 +57,14 @@
     private boolean mDetailShown;
     private boolean mPluggedIn;
 
-    public BatteryTile(Host host) {
+    public BatterySaverTile(Host host) {
         super(host);
         mBatteryController = Dependency.get(BatteryController.class);
     }
 
     @Override
-    public State newTileState() {
-        return new QSTile.State();
-    }
-
-    @Override
-    public DetailAdapter getDetailAdapter() {
-        return mBatteryDetail;
+    public BooleanState newTileState() {
+        return new BooleanState();
     }
 
     @Override
@@ -109,22 +105,15 @@
     }
 
     @Override
-    protected void handleUpdateState(State state, Object arg) {
-        int level = (arg != null) ? (Integer) arg : mLevel;
-        String percentage = NumberFormat.getPercentInstance().format((double) level / 100.0);
-
+    protected void handleUpdateState(BooleanState state, Object arg) {
         state.state = mCharging ? Tile.STATE_UNAVAILABLE
                 : mPowerSave ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
         state.icon = ResourceIcon.get(R.drawable.ic_qs_battery_saver);
         state.label = mContext.getString(R.string.battery_detail_switch_title);
-        state.contentDescription = mContext.getString(R.string.accessibility_quick_settings_battery,
-                percentage) + "," +
-                (mPowerSave ? mContext.getString(R.string.battery_saver_notification_title)
-                        : mCharging ? mContext.getString(R.string.expanded_header_battery_charging)
-                                : "")
-                + "," + mContext.getString(R.string.accessibility_battery_details);
+        state.contentDescription = state.label;
+        state.value = mPowerSave;
         state.minimalAccessibilityClassName = state.expandedAccessibilityClassName
-                = Button.class.getName();
+                = Switch.class.getName();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
index 4b56ecd..5d7508b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java
@@ -34,7 +34,7 @@
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.QSDetailItems;
 import com.android.systemui.qs.QSDetailItems.Item;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 3c28f76..c501c91 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -30,7 +30,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.QSDetailItems;
 import com.android.systemui.qs.QSDetailItems.Item;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index bae163f..1a04a51 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -31,7 +31,7 @@
 import com.android.settingslib.net.DataUsageController;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.QSIconView;
 import com.android.systemui.qs.QSTile;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 4072b44..d554a17 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -39,7 +39,7 @@
 import com.android.systemui.Prefs;
 import com.android.systemui.R;
 import com.android.systemui.SysUIToast;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.ZenModeController;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
index fcc9596..aeea75d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/IntentTile.java
@@ -32,7 +32,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSTile;
 
 import java.util.Arrays;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 423a1df..e61a953 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -26,7 +26,7 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.QSTile;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.LocationController;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 796967c..83dc1c2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -33,7 +33,7 @@
 import com.android.settingslib.wifi.AccessPoint;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.QSDetailItems;
 import com.android.systemui.qs.QSDetailItems.Item;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 98787f7..d4997ea 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -923,12 +923,6 @@
         mOnActivatedListener = onActivatedListener;
     }
 
-    public void reset() {
-        setTintColor(0);
-        resetBackgroundAlpha();
-        setBelowSpeedBump(false);
-    }
-
     public boolean hasSameBgColor(ActivatableNotificationView otherView) {
         return calculateBgColor() == otherView.calculateBgColor();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index bfe4bb2..602c3df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -16,6 +16,8 @@
 
 package com.android.systemui.statusbar;
 
+import static com.android.systemui.statusbar.notification.NotificationInflater.InflationExceptionHandler;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -42,6 +44,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.Chronometer;
 import android.widget.ImageView;
+import android.widget.RemoteViews;
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -52,6 +55,8 @@
 import com.android.systemui.classifier.FalsingManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.MenuItem;
 import com.android.systemui.statusbar.notification.HybridNotificationView;
+import com.android.systemui.statusbar.notification.InflationException;
+import com.android.systemui.statusbar.notification.NotificationInflater;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -70,6 +75,7 @@
 
     private static final int DEFAULT_DIVIDER_ALPHA = 0x29;
     private static final int COLORED_DIVIDER_ALPHA = 0x7B;
+    private final NotificationInflater mNotificationInflater;
     private int mIconTransformContentShift;
     private int mIconTransformContentShiftNoIcon;
     private int mNotificationMinHeightLegacy;
@@ -152,14 +158,15 @@
     private OnClickListener mExpandClickListener = new OnClickListener() {
         @Override
         public void onClick(View v) {
-            if (!mShowingPublic && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
+            if (!mShowingPublic && (!mIsLowPriority || isExpanded())
+                    && mGroupManager.isSummaryOfGroup(mStatusBarNotification)) {
                 mGroupExpansionChanging = true;
                 final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
                 boolean nowExpanded = mGroupManager.toggleGroupExpansion(mStatusBarNotification);
                 mOnExpandClickListener.onExpandClicked(mEntry, nowExpanded);
                 MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER,
                         nowExpanded);
-                logExpansionEvent(true /* userAction */, wasExpanded);
+                onExpansionChanged(true /* userAction */, wasExpanded);
             } else {
                 if (v.isAccessibilityFocused()) {
                     mPrivateLayout.setFocusOnVisibilityChange();
@@ -246,6 +253,7 @@
         }
         if (mIsSummaryWithChildren) {
             setIconAnimationRunningForChild(running, mChildrenContainer.getHeaderView());
+            setIconAnimationRunningForChild(running, mChildrenContainer.getLowPriorityHeaderView());
             List<ExpandableNotificationRow> notificationChildren =
                     mChildrenContainer.getNotificationChildren();
             for (int i = 0; i < notificationChildren.size(); i++) {
@@ -298,17 +306,22 @@
         }
     }
 
-    public void onNotificationUpdated(NotificationData.Entry entry) {
+    public void updateNotification(NotificationData.Entry entry) throws InflationException {
         mEntry = entry;
         mStatusBarNotification = entry.notification;
+        mNotificationInflater.inflateNotificationViews();
+        onNotificationUpdated();
+    }
+
+    private void onNotificationUpdated() {
         for (NotificationContentView l : mLayouts) {
-            l.onNotificationUpdated(entry);
+            l.onNotificationUpdated(mEntry);
         }
         mIsColorized = mStatusBarNotification.getNotification().isColorized();
         mShowingPublicInitialized = false;
         updateNotificationColor();
         if (mIsSummaryWithChildren) {
-            mChildrenContainer.recreateNotificationHeader(mExpandClickListener, mEntry.notification);
+            mChildrenContainer.recreateNotificationHeader(mExpandClickListener);
             mChildrenContainer.onNotificationUpdated();
         }
         if (mIconAnimationRunning) {
@@ -458,6 +471,9 @@
         boolean childInGroup = StatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
         mNotificationParent = childInGroup ? parent : null;
         mPrivateLayout.setIsChildInGroup(childInGroup);
+        if (mNotificationInflater.setIsChildInGroup(childInGroup)) {
+            onNotificationUpdated();
+        }
         resetBackgroundAlpha();
         updateBackgroundForGroupState();
         updateClickAndFocus();
@@ -671,9 +687,13 @@
         return mPrivateLayout.getNotificationHeader();
     }
 
-    private NotificationHeaderView getVisibleNotificationHeader() {
+    /**
+     * @return the currently visible notification header. This can be different from
+     * {@link #getNotificationHeader()} in case it is a low-priority group.
+     */
+    public NotificationHeaderView getVisibleNotificationHeader() {
         if (mIsSummaryWithChildren && !mShowingPublic) {
-            return mChildrenContainer.getHeaderView();
+            return mChildrenContainer.getVisibleHeader();
         }
         return getShowingLayout().getVisibleNotificationHeader();
     }
@@ -711,7 +731,7 @@
         }
     }
 
-    public void reInflateViews() {
+    public void onDensityOrFontScaleChanged() {
         initDimens();
         if (mIsSummaryWithChildren) {
             if (mChildrenContainer != null) {
@@ -742,6 +762,8 @@
         for (NotificationContentView l : mLayouts) {
             l.reInflateViews();
         }
+        mNotificationInflater.onDensityOrFontScaleChanged();
+        onNotificationUpdated();
     }
 
     public void setContentBackground(int customBackgroundColor, boolean animate,
@@ -891,7 +913,7 @@
     }
 
     public View getNotificationIcon() {
-        NotificationHeaderView notificationHeader = getNotificationHeader();
+        NotificationHeaderView notificationHeader = getVisibleNotificationHeader();
         if (notificationHeader != null) {
             return notificationHeader.getIcon();
         }
@@ -1008,17 +1030,32 @@
     public void setIsLowPriority(boolean isLowPriority) {
         mIsLowPriority = isLowPriority;
         mPrivateLayout.setIsLowPriority(isLowPriority);
+        mNotificationInflater.setIsLowPriority(mIsLowPriority);
         if (mChildrenContainer != null) {
             mChildrenContainer.setIsLowPriority(isLowPriority);
         }
     }
 
+    public boolean isLowPriority() {
+        return mIsLowPriority;
+    }
+
     public void setUseIncreasedCollapsedHeight(boolean use) {
         mUseIncreasedCollapsedHeight = use;
+        mNotificationInflater.setUsesIncreasedHeight(use);
     }
 
     public void setUseIncreasedHeadsUpHeight(boolean use) {
         mUseIncreasedHeadsUpHeight = use;
+        mNotificationInflater.setUsesIncreasedHeadsUpHeight(use);
+    }
+
+    public void setRemoteViewClickHandler(RemoteViews.OnClickHandler remoteViewClickHandler) {
+        mNotificationInflater.setRemoteViewClickHandler(remoteViewClickHandler);
+    }
+
+    public void setInflateExceptionHandler(InflationExceptionHandler inflateExceptionHandler) {
+        mNotificationInflater.setInflateExceptionHandler(inflateExceptionHandler);
     }
 
     public interface ExpansionLogger {
@@ -1028,6 +1065,7 @@
     public ExpandableNotificationRow(Context context, AttributeSet attrs) {
         super(context, attrs);
         mFalsingManager = FalsingManager.getInstance(context);
+        mNotificationInflater = new NotificationInflater(this);
         initDimens();
     }
 
@@ -1063,26 +1101,8 @@
     /**
      * Resets this view so it can be re-used for an updated notification.
      */
-    @Override
     public void reset() {
-        super.reset();
-        final boolean wasExpanded = isExpanded();
-        mExpandable = false;
-        mHasUserChangedExpansion = false;
-        mUserLocked = false;
-        mShowingPublic = false;
-        mSensitive = false;
         mShowingPublicInitialized = false;
-        mIsSystemExpanded = false;
-        mOnKeyguard = false;
-        mPublicLayout.reset();
-        mPrivateLayout.reset();
-        resetHeight();
-        resetTranslation();
-        logExpansionEvent(false, wasExpanded);
-    }
-
-    public void resetHeight() {
         onHeightReset();
         requestLayout();
     }
@@ -1124,7 +1144,7 @@
             public void onInflate(ViewStub stub, View inflated) {
                 mChildrenContainer = (NotificationChildrenContainer) inflated;
                 mChildrenContainer.setIsLowPriority(mIsLowPriority);
-                mChildrenContainer.setNotificationParent(ExpandableNotificationRow.this);
+                mChildrenContainer.setContainingNotification(ExpandableNotificationRow.this);
                 mChildrenContainer.onNotificationUpdated();
                 mTranslateableViews.add(mChildrenContainer);
             }
@@ -1253,9 +1273,7 @@
         if (mChildrenContainer != null) {
             mChildrenContainer.setVisibility(!mShowingPublic && mIsSummaryWithChildren ? VISIBLE
                     : INVISIBLE);
-            mChildrenContainer.updateHeaderVisibility(!mShowingPublic && mIsSummaryWithChildren
-                    ? VISIBLE
-                    : INVISIBLE);
+            mChildrenContainer.setHeaderVisible(!mShowingPublic && mIsSummaryWithChildren);
         }
         // The limits might have changed if the view suddenly became a group or vice versa
         updateLimits();
@@ -1323,7 +1341,6 @@
      */
     public void setUserExpanded(boolean userExpanded) {
         setUserExpanded(userExpanded, false /* allowChildExpansion */);
-        updateShelfIconColor();
     }
 
     /**
@@ -1334,22 +1351,28 @@
      */
     public void setUserExpanded(boolean userExpanded, boolean allowChildExpansion) {
         mFalsingManager.setNotificationExpanded();
-        if (mIsSummaryWithChildren && !mShowingPublic && allowChildExpansion) {
+        if (mIsSummaryWithChildren && !mShowingPublic && allowChildExpansion
+                && !mChildrenContainer.showingAsLowPriority()) {
             final boolean wasExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
             mGroupManager.setGroupExpanded(mStatusBarNotification, userExpanded);
-            logExpansionEvent(true /* userAction */, wasExpanded);
+            onExpansionChanged(true /* userAction */, wasExpanded);
             return;
         }
         if (userExpanded && !mExpandable) return;
         final boolean wasExpanded = isExpanded();
         mHasUserChangedExpansion = true;
         mUserExpanded = userExpanded;
-        logExpansionEvent(true, wasExpanded);
+        onExpansionChanged(true /* userAction */, wasExpanded);
     }
 
     public void resetUserExpansion() {
+        boolean changed = mUserExpanded;
         mHasUserChangedExpansion = false;
         mUserExpanded = false;
+        if (changed && mIsSummaryWithChildren) {
+            mChildrenContainer.onExpansionChanged();
+        }
+        updateShelfIconColor();
     }
 
     public boolean isUserLocked() {
@@ -1383,9 +1406,8 @@
         if (expand != mIsSystemExpanded) {
             final boolean wasExpanded = isExpanded();
             mIsSystemExpanded = expand;
-            updateShelfIconColor();
             notifyHeightChanged(false /* needsAnimation */);
-            logExpansionEvent(false, wasExpanded);
+            onExpansionChanged(false /* userAction */, wasExpanded);
             if (mIsSummaryWithChildren) {
                 mChildrenContainer.updateGroupOverflow();
             }
@@ -1399,7 +1421,7 @@
         if (onKeyguard != mOnKeyguard) {
             final boolean wasExpanded = isExpanded();
             mOnKeyguard = onKeyguard;
-            logExpansionEvent(false, wasExpanded);
+            onExpansionChanged(false /* userAction */, wasExpanded);
             if (wasExpanded != isExpanded()) {
                 if (mIsSummaryWithChildren) {
                     mChildrenContainer.updateGroupOverflow();
@@ -1470,8 +1492,8 @@
         mIsSummaryWithChildren = StatusBar.ENABLE_CHILD_NOTIFICATIONS
                 && mChildrenContainer != null && mChildrenContainer.getNotificationChildCount() > 0;
         if (mIsSummaryWithChildren && mChildrenContainer.getHeaderView() == null) {
-            mChildrenContainer.recreateNotificationHeader(mExpandClickListener,
-                    mEntry.notification);
+            mChildrenContainer.recreateNotificationHeader(mExpandClickListener
+            );
         }
         getShowingLayout().updateBackgroundColor(false /* animate */);
         mPrivateLayout.updateExpandButtons(isExpandable());
@@ -1526,7 +1548,7 @@
      * the top.
      */
     private void updateContentShiftHeight() {
-        NotificationHeaderView notificationHeader = getNotificationHeader();
+        NotificationHeaderView notificationHeader = getVisibleNotificationHeader();
         if (notificationHeader != null) {
             CachingIconView icon = notificationHeader.getIcon();
             mIconTransformContentShift = getRelativeTopPadding(icon) + icon.getHeight();
@@ -1737,7 +1759,17 @@
 
     @Override
     public void setActualHeight(int height, boolean notifyListeners) {
+        boolean changed = height != getActualHeight();
         super.setActualHeight(height, notifyListeners);
+        if (changed && isRemoved()) {
+            // TODO: remove this once we found the gfx bug for this.
+            // This is a hack since a removed view sometimes would just stay blank. it occured
+            // when sending yourself a message and then clicking on it.
+            ViewGroup parent = (ViewGroup) getParent();
+            if (parent != null) {
+                parent.invalidate();
+            }
+        }
         if (mGuts != null && mGuts.isExposed()) {
             mGuts.setActualHeight(height);
             return;
@@ -1828,9 +1860,9 @@
         return mShowingPublic ? mPublicLayout : mPrivateLayout;
     }
 
-    public void setShowingLegacyBackground(boolean showing) {
+    public void setLegacy(boolean legacy) {
         for (NotificationContentView l : mLayouts) {
-            l.setShowingLegacyBackground(showing);
+            l.setLegacy(legacy);
         }
     }
 
@@ -1910,7 +1942,7 @@
             if (isGroupExpanded()) {
                 return 1.0f;
             } else if (isUserLocked()) {
-                return mChildrenContainer.getGroupExpandFraction();
+                return mChildrenContainer.getIncreasedPaddingAmount();
             }
         } else if (isColorized() && (!mIsLowPriority || isExpanded())) {
             return -1.0f;
@@ -1933,13 +1965,19 @@
         return super.disallowSingleClick(event);
     }
 
-    private void logExpansionEvent(boolean userAction, boolean wasExpanded) {
+    private void onExpansionChanged(boolean userAction, boolean wasExpanded) {
         boolean nowExpanded = isExpanded();
-        if (mIsSummaryWithChildren) {
+        if (mIsSummaryWithChildren && (!mIsLowPriority || wasExpanded)) {
             nowExpanded = mGroupManager.isGroupExpanded(mStatusBarNotification);
         }
-        if (wasExpanded != nowExpanded && mLogger != null) {
-            mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded) ;
+        if (nowExpanded != wasExpanded) {
+            updateShelfIconColor();
+            if (mLogger != null) {
+                mLogger.logNotificationExpansion(mLoggingKey, userAction, nowExpanded);
+            }
+            if (mIsSummaryWithChildren) {
+                mChildrenContainer.onExpansionChanged();
+            }
         }
     }
 
@@ -1980,7 +2018,8 @@
 
     @Override
     public boolean isAboveShelf() {
-        return mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf);
+        return !isOnKeyguard()
+                && (mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf));
     }
 
     public void setShowAmbient(boolean showAmbient) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index 57d2e1c..74e65fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -80,7 +80,7 @@
     private boolean mDark;
     private boolean mAnimate;
     private boolean mIsHeadsUp;
-    private boolean mShowingLegacyBackground;
+    private boolean mLegacy;
     private boolean mIsChildInGroup;
     private int mSmallHeight;
     private int mHeadsUpHeight;
@@ -140,7 +140,6 @@
                 R.dimen.min_notification_layout_height);
         mNotificationContentMarginEnd = getResources().getDimensionPixelSize(
                 com.android.internal.R.dimen.notification_content_margin_end);
-        reset();
     }
 
     public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight,
@@ -329,41 +328,6 @@
         updateVisibility();
     }
 
-    public void reset() {
-        mPreviousExpandedRemoteInputIntent = null;
-        if (mExpandedRemoteInput != null) {
-            mExpandedRemoteInput.onNotificationUpdateOrReset();
-            if (mExpandedRemoteInput.isActive()) {
-                mPreviousExpandedRemoteInputIntent = mExpandedRemoteInput.getPendingIntent();
-                mCachedExpandedRemoteInput = mExpandedRemoteInput;
-                mExpandedRemoteInput.dispatchStartTemporaryDetach();
-                ((ViewGroup)mExpandedRemoteInput.getParent()).removeView(mExpandedRemoteInput);
-            }
-        }
-        if (mExpandedChild != null) {
-            mExpandedChild.animate().cancel();
-            removeView(mExpandedChild);
-            mExpandedRemoteInput = null;
-        }
-        mPreviousHeadsUpRemoteInputIntent = null;
-        if (mHeadsUpRemoteInput != null) {
-            mHeadsUpRemoteInput.onNotificationUpdateOrReset();
-            if (mHeadsUpRemoteInput.isActive()) {
-                mPreviousHeadsUpRemoteInputIntent = mHeadsUpRemoteInput.getPendingIntent();
-                mCachedHeadsUpRemoteInput = mHeadsUpRemoteInput;
-                mHeadsUpRemoteInput.dispatchStartTemporaryDetach();
-                ((ViewGroup)mHeadsUpRemoteInput.getParent()).removeView(mHeadsUpRemoteInput);
-            }
-        }
-        if (mHeadsUpChild != null) {
-            mHeadsUpChild.animate().cancel();
-            removeView(mHeadsUpChild);
-            mHeadsUpRemoteInput = null;
-        }
-        mExpandedChild = null;
-        mHeadsUpChild = null;
-    }
-
     public View getContractedChild() {
         return mContractedChild;
     }
@@ -394,8 +358,30 @@
 
     public void setExpandedChild(View child) {
         if (mExpandedChild != null) {
+            mPreviousExpandedRemoteInputIntent = null;
+            if (mExpandedRemoteInput != null) {
+                mExpandedRemoteInput.onNotificationUpdateOrReset();
+                if (mExpandedRemoteInput.isActive()) {
+                    mPreviousExpandedRemoteInputIntent = mExpandedRemoteInput.getPendingIntent();
+                    mCachedExpandedRemoteInput = mExpandedRemoteInput;
+                    mExpandedRemoteInput.dispatchStartTemporaryDetach();
+                    ((ViewGroup)mExpandedRemoteInput.getParent()).removeView(mExpandedRemoteInput);
+                }
+            }
             mExpandedChild.animate().cancel();
             removeView(mExpandedChild);
+            mExpandedRemoteInput = null;
+        }
+        if (child == null) {
+            mExpandedChild = null;
+            mExpandedWrapper = null;
+            if (mVisibleType == VISIBLE_TYPE_EXPANDED) {
+                mVisibleType = VISIBLE_TYPE_CONTRACTED;
+            }
+            if (mTransformationStartVisibleType == VISIBLE_TYPE_EXPANDED) {
+                mTransformationStartVisibleType = UNDEFINED;
+            }
+            return;
         }
         addView(child);
         mExpandedChild = child;
@@ -405,8 +391,30 @@
 
     public void setHeadsUpChild(View child) {
         if (mHeadsUpChild != null) {
+            mPreviousHeadsUpRemoteInputIntent = null;
+            if (mHeadsUpRemoteInput != null) {
+                mHeadsUpRemoteInput.onNotificationUpdateOrReset();
+                if (mHeadsUpRemoteInput.isActive()) {
+                    mPreviousHeadsUpRemoteInputIntent = mHeadsUpRemoteInput.getPendingIntent();
+                    mCachedHeadsUpRemoteInput = mHeadsUpRemoteInput;
+                    mHeadsUpRemoteInput.dispatchStartTemporaryDetach();
+                    ((ViewGroup)mHeadsUpRemoteInput.getParent()).removeView(mHeadsUpRemoteInput);
+                }
+            }
             mHeadsUpChild.animate().cancel();
             removeView(mHeadsUpChild);
+            mHeadsUpRemoteInput = null;
+        }
+        if (child == null) {
+            mHeadsUpChild = null;
+            mHeadsUpWrapper = null;
+            if (mVisibleType == VISIBLE_TYPE_HEADSUP) {
+                mVisibleType = VISIBLE_TYPE_CONTRACTED;
+            }
+            if (mTransformationStartVisibleType == VISIBLE_TYPE_HEADSUP) {
+                mTransformationStartVisibleType = UNDEFINED;
+            }
+            return;
         }
         addView(child);
         mHeadsUpChild = child;
@@ -623,7 +631,7 @@
     }
 
     public int getMinHeight(boolean likeGroupExpanded) {
-        if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded() || mIsLowPriority) {
+        if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
             return mContractedChild.getHeight();
         } else {
             return mSingleLineView.getHeight();
@@ -897,7 +905,7 @@
                 height = mContentHeight;
             }
             int expandedVisualType = getVisualTypeForHeight(height);
-            int collapsedVisualType = mIsChildInGroup && !isGroupExpanded() && !mIsLowPriority
+            int collapsedVisualType = mIsChildInGroup && !isGroupExpanded()
                     ? VISIBLE_TYPE_SINGLELINE
                     : getVisualTypeForHeight(mContainingNotification.getCollapsedHeight());
             return mTransformationStartVisibleType == collapsedVisualType
@@ -918,7 +926,7 @@
         if (!noExpandedChild && viewHeight == mExpandedChild.getHeight()) {
             return VISIBLE_TYPE_EXPANDED;
         }
-        if (!mUserExpanding && mIsChildInGroup && !isGroupExpanded() && !mIsLowPriority) {
+        if (!mUserExpanding && mIsChildInGroup && !isGroupExpanded()) {
             return VISIBLE_TYPE_SINGLELINE;
         }
 
@@ -978,25 +986,37 @@
         return false;
     }
 
-    public void setShowingLegacyBackground(boolean showing) {
-        mShowingLegacyBackground = showing;
-        updateShowingLegacyBackground();
+    public void setLegacy(boolean legacy) {
+        mLegacy = legacy;
+        updateLegacy();
     }
 
-    private void updateShowingLegacyBackground() {
+    private void updateLegacy() {
         if (mContractedChild != null) {
-            mContractedWrapper.setShowingLegacyBackground(mShowingLegacyBackground);
+            mContractedWrapper.setLegacy(mLegacy);
         }
         if (mExpandedChild != null) {
-            mExpandedWrapper.setShowingLegacyBackground(mShowingLegacyBackground);
+            mExpandedWrapper.setLegacy(mLegacy);
         }
         if (mHeadsUpChild != null) {
-            mHeadsUpWrapper.setShowingLegacyBackground(mShowingLegacyBackground);
+            mHeadsUpWrapper.setLegacy(mLegacy);
         }
     }
 
     public void setIsChildInGroup(boolean isChildInGroup) {
         mIsChildInGroup = isChildInGroup;
+        if (mContractedChild != null) {
+            mContractedWrapper.setIsChildInGroup(mIsChildInGroup);
+        }
+        if (mExpandedChild != null) {
+            mExpandedWrapper.setIsChildInGroup(mIsChildInGroup);
+        }
+        if (mHeadsUpChild != null) {
+            mHeadsUpWrapper.setIsChildInGroup(mIsChildInGroup);
+        }
+        if (mAmbientChild != null) {
+            mAmbientWrapper.setIsChildInGroup(mIsChildInGroup);
+        }
         updateSingleLineView();
     }
 
@@ -1005,19 +1025,19 @@
         mBeforeN = entry.targetSdk < Build.VERSION_CODES.N;
         updateSingleLineView();
         if (mContractedChild != null) {
-            mContractedWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
+            mContractedWrapper.notifyContentUpdated(entry.row);
         }
         if (mExpandedChild != null) {
-            mExpandedWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
+            mExpandedWrapper.notifyContentUpdated(entry.row);
         }
         if (mHeadsUpChild != null) {
-            mHeadsUpWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
+            mHeadsUpWrapper.notifyContentUpdated(entry.row);
         }
         if (mAmbientChild != null) {
-            mAmbientWrapper.notifyContentUpdated(entry.notification, mIsLowPriority);
+            mAmbientWrapper.notifyContentUpdated(entry.row);
         }
         applyRemoteInput(entry);
-        updateShowingLegacyBackground();
+        updateLegacy();
         mForceSelectNextLayout = true;
         setDark(mDark, false /* animate */, 0 /* delay */);
         mPreviousExpandedRemoteInputIntent = null;
@@ -1176,7 +1196,8 @@
         mExpandable = expandable;
         // if the expanded child has the same height as the collapsed one we hide it.
         if (mExpandedChild != null && mExpandedChild.getHeight() != 0) {
-            if (!mIsHeadsUp || mHeadsUpChild == null || mContainingNotification.isOnKeyguard()) {
+            if ((!mIsHeadsUp && !mHeadsUpAnimatingAway)
+                    || mHeadsUpChild == null || mContainingNotification.isOnKeyguard()) {
                 if (mExpandedChild.getHeight() == mContractedChild.getHeight()) {
                     expandable = false;
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 81db429..8f8d966 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -34,6 +34,7 @@
 
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.NotificationColorUtil;
+import com.android.systemui.statusbar.notification.InflationException;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -65,7 +66,6 @@
         public ExpandableNotificationRow row; // the outer expanded view
         private boolean interruption;
         public boolean autoRedacted; // whether the redacted notification was generated by us
-        public boolean legacy; // whether the notification has a legacy, dark background
         public int targetSdk;
         private long lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
         public RemoteViews cachedContentView;
@@ -95,118 +95,20 @@
          * Resets the notification entry to be re-used.
          */
         public void reset() {
-            // NOTE: Icon needs to be preserved for now.
-            // We should fix this at some point.
-            autoRedacted = false;
-            legacy = false;
             lastFullScreenIntentLaunchTime = NOT_LAUNCHED_YET;
             if (row != null) {
                 row.reset();
             }
         }
 
-        public View getContentView() {
-            return row.getPrivateLayout().getContractedChild();
-        }
-
         public View getExpandedContentView() {
             return row.getPrivateLayout().getExpandedChild();
         }
 
-        public View getHeadsUpContentView() {
-            return row.getPrivateLayout().getHeadsUpChild();
-        }
-
         public View getPublicContentView() {
             return row.getPublicLayout().getContractedChild();
         }
 
-        public View getAmbientContentView() {
-            return row.getPrivateLayout().getAmbientChild();
-        }
-
-        public boolean cacheContentViews(Context ctx, Notification updatedNotification,
-                boolean isLowPriority, boolean useIncreasedCollapsedView,
-                boolean useIncreasedHeadsUp) {
-            boolean applyInPlace = false;
-            if (updatedNotification != null) {
-                final Notification.Builder updatedNotificationBuilder
-                        = Notification.Builder.recoverBuilder(ctx, updatedNotification);
-                final RemoteViews newContentView = createContentView(updatedNotificationBuilder,
-                        isLowPriority, useIncreasedCollapsedView);
-                final RemoteViews newBigContentView = createBigContentView(
-                        updatedNotificationBuilder, isLowPriority);
-                final RemoteViews newHeadsUpContentView =
-                        updatedNotificationBuilder.createHeadsUpContentView(useIncreasedHeadsUp);
-                final RemoteViews newPublicNotification
-                        = updatedNotificationBuilder.makePublicContentView();
-                final RemoteViews newAmbientNotification
-                        = updatedNotificationBuilder.makeAmbientNotification();
-
-                boolean sameCustomView = Objects.equals(
-                        notification.getNotification().extras.getBoolean(
-                                Notification.EXTRA_CONTAINS_CUSTOM_VIEW),
-                        updatedNotification.extras.getBoolean(
-                                Notification.EXTRA_CONTAINS_CUSTOM_VIEW));
-                applyInPlace = compareRemoteViews(cachedContentView, newContentView)
-                        && compareRemoteViews(cachedBigContentView, newBigContentView)
-                        && compareRemoteViews(cachedHeadsUpContentView, newHeadsUpContentView)
-                        && compareRemoteViews(cachedPublicContentView, newPublicNotification)
-                        && compareRemoteViews(cachedAmbientContentView, newAmbientNotification)
-                        && sameCustomView;
-                cachedPublicContentView = newPublicNotification;
-                cachedHeadsUpContentView = newHeadsUpContentView;
-                cachedBigContentView = newBigContentView;
-                cachedContentView = newContentView;
-                cachedAmbientContentView = newAmbientNotification;
-            } else {
-                final Notification.Builder builder
-                        = Notification.Builder.recoverBuilder(ctx, notification.getNotification());
-
-                cachedContentView = createContentView(builder, isLowPriority,
-                        useIncreasedCollapsedView);
-                cachedBigContentView = createBigContentView(builder, isLowPriority);
-                cachedHeadsUpContentView = builder.createHeadsUpContentView(useIncreasedHeadsUp);
-                cachedPublicContentView = builder.makePublicContentView();
-                cachedAmbientContentView = builder.makeAmbientNotification();
-
-                applyInPlace = false;
-            }
-            return applyInPlace;
-        }
-
-        private RemoteViews createBigContentView(Notification.Builder builder,
-                boolean isLowPriority) {
-            RemoteViews bigContentView = builder.createBigContentView();
-            if (bigContentView != null) {
-                return bigContentView;
-            }
-            if (isLowPriority) {
-                RemoteViews contentView = builder.createContentView();
-                Notification.Builder.makeHeaderExpanded(contentView);
-                return contentView;
-            }
-            return null;
-        }
-
-        private RemoteViews createContentView(Notification.Builder builder,
-                boolean isLowPriority, boolean useLarge) {
-            if (isLowPriority) {
-                return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
-            }
-            return builder.createContentView(useLarge);
-        }
-
-        // Returns true if the RemoteViews are the same.
-        private boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
-            return (a == null && b == null) ||
-                    (a != null && b != null
-                    && b.getPackage() != null
-                    && a.getPackage() != null
-                    && a.getPackage().equals(b.getPackage())
-                    && a.getLayoutId() == b.getLayoutId());
-        }
-
         public void notifyFullScreenIntentLaunched() {
             lastFullScreenIntentLaunchTime = SystemClock.elapsedRealtime();
         }
@@ -219,13 +121,14 @@
          * Create the icons for a notification
          * @param context the context to create the icons with
          * @param sbn the notification
-         * @throws IconException
+         * @throws InflationException
          */
-        public void createIcons(Context context, StatusBarNotification sbn) throws IconException {
+        public void createIcons(Context context, StatusBarNotification sbn)
+                throws InflationException {
             Notification n = sbn.getNotification();
             final Icon smallIcon = n.getSmallIcon();
             if (smallIcon == null) {
-                throw new IconException("No small icon in notification from "
+                throw new InflationException("No small icon in notification from "
                         + sbn.getPackageName());
             }
 
@@ -248,7 +151,7 @@
             if (!icon.set(ic) || !expandedIcon.set(ic)) {
                 icon = null;
                 expandedIcon = null;
-                throw new IconException("Couldn't create icon: " + ic);
+                throw new InflationException("Couldn't create icon: " + ic);
             }
             expandedIcon.setVisibility(View.INVISIBLE);
             expandedIcon.setOnVisibilityChangedListener(
@@ -270,9 +173,9 @@
          * Update the notification icons.
          * @param context the context to create the icons with.
          * @param n the notification to read the icon from.
-         * @throws IconException
+         * @throws InflationException
          */
-        public void updateIcons(Context context, Notification n) throws IconException {
+        public void updateIcons(Context context, Notification n) throws InflationException {
             if (icon != null) {
                 // Update the icon
                 final StatusBarIcon ic = new StatusBarIcon(
@@ -285,7 +188,7 @@
                 icon.setNotification(n);
                 expandedIcon.setNotification(n);
                 if (!icon.set(ic) || !expandedIcon.set(ic)) {
-                    throw new IconException("Couldn't update icon: " + ic);
+                    throw new InflationException("Couldn't update icon: " + ic);
                 }
             }
         }
@@ -612,10 +515,4 @@
         public String getCurrentMediaNotificationKey();
         public NotificationGroupManager getGroupManager();
     }
-
-    public static class IconException extends Exception {
-        IconException(String error) {
-            super(error);
-        }
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 9703235..807d902 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -72,11 +72,6 @@
     private StatusBarNotification mStatusBarNotification;
     private NotificationChannel mNotificationChannel;
 
-    private ImageView mAutoButton;
-    private TextView mImportanceSummary;
-    private TextView mImportanceTitle;
-    private boolean mAuto;
-
     private TextView mNumChannelsView;
     private View mChannelDisabledView;
     private Switch mChannelEnabledSwitch;
@@ -105,8 +100,10 @@
         int appUid = -1;
         String appName = pkg;
         Drawable pkgicon = null;
+        CharSequence channelNameText = "";
+        ApplicationInfo info = null;
         try {
-            final ApplicationInfo info = pm.getApplicationInfo(pkg,
+            info = pm.getApplicationInfo(pkg,
                     PackageManager.MATCH_UNINSTALLED_PACKAGES
                             | PackageManager.MATCH_DISABLED_COMPONENTS
                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
@@ -115,6 +112,7 @@
                 appUid = info.uid;
                 appName = String.valueOf(pm.getApplicationLabel(info));
                 pkgicon = pm.getApplicationIcon(info);
+
             }
         } catch (PackageManager.NameNotFoundException e) {
             // app is gone, just show package name and generic icon
@@ -135,11 +133,15 @@
                 R.plurals.notification_num_channels_desc, numChannels), numChannels));
 
         // If this is the placeholder channel, don't use our channel-specific text.
-        CharSequence channelNameText;
         if (channel.getId().equals(NotificationChannel.DEFAULT_CHANNEL_ID)) {
             channelNameText = mContext.getString(R.string.notification_header_default_channel);
         } else {
-            channelNameText = channel.getName();
+            if (info != null && channel.getNameResId() != 0) {
+                channelNameText = pm.getText(pkg, channel.getNameResId(), info);
+            }
+            if (channel.getName() != null) {
+                channelNameText = channel.getName();
+            }
         }
         ((TextView) findViewById(R.id.pkgname)).setText(appName);
         ((TextView) findViewById(R.id.channel_name)).setText(channelNameText);
@@ -171,8 +173,8 @@
 
         boolean nonBlockable = false;
         try {
-            final PackageInfo info = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
-            nonBlockable = Utils.isSystemPackage(getResources(), pm, info);
+            final PackageInfo pkgInfo = pm.getPackageInfo(pkg, PackageManager.GET_SIGNATURES);
+            nonBlockable = Utils.isSystemPackage(getResources(), pm, pkgInfo);
         } catch (PackageManager.NameNotFoundException e) {
             // unlikely.
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 1cd909ea..36ed551 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -443,7 +443,8 @@
             }
             int shelfColor = icon.getStaticDrawableColor();
             if (!noIcon && shelfColor != StatusBarIconView.NO_COLOR) {
-                int notificationColor = row.getNotificationHeader().getOriginalNotificationColor();
+                int notificationColor
+                        = row.getVisibleNotificationHeader().getOriginalNotificationColor();
                 shelfColor = NotificationUtils.interpolateColors(notificationColor, shelfColor,
                         iconState.iconAppearAmount);
             }
diff --git a/media/java/android/media/MediaDescrambler.aidl b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InflationException.java
similarity index 66%
copy from media/java/android/media/MediaDescrambler.aidl
copy to packages/SystemUI/src/com/android/systemui/statusbar/notification/InflationException.java
index e789244..b484138 100644
--- a/media/java/android/media/MediaDescrambler.aidl
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InflationException.java
@@ -11,10 +11,16 @@
  * 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.
+ * limitations under the License
  */
 
-package android.media;
+package com.android.systemui.statusbar.notification;
 
-/** @hide */
-parcelable MediaDescrambler.DescrambleInfo cpp_header "media/MediaCasDefs.h";
\ No newline at end of file
+/**
+ * An exception that something went wrong during the inflation
+ */
+public class InflationException extends Exception {
+    public InflationException(String error) {
+        super(error);
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
index 78b967a..7a34b6e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigPictureTemplateViewWrapper.java
@@ -36,9 +36,9 @@
     }
 
     @Override
-    public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
-        super.notifyContentUpdated(notification, isLowPriority);
-        updateImageTag(notification);
+    public void notifyContentUpdated(ExpandableNotificationRow row) {
+        super.notifyContentUpdated(row);
+        updateImageTag(row.getStatusBarNotification());
     }
 
     private void updateImageTag(StatusBarNotification notification) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
index 39db243..9476eed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationBigTextTemplateViewWrapper.java
@@ -41,11 +41,11 @@
     }
 
     @Override
-    public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+    public void notifyContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
-        resolveViews(notification);
-        super.notifyContentUpdated(notification, isLowPriority);
+        resolveViews(row.getStatusBarNotification());
+        super.notifyContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index e5f32df..3efa29f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -19,13 +19,8 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
-import android.graphics.Color;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
-import android.graphics.drawable.ColorDrawable;
-import android.graphics.drawable.Drawable;
-import android.service.notification.StatusBarNotification;
-import android.support.v4.graphics.ColorUtils;
 import android.view.View;
 
 import com.android.systemui.R;
@@ -40,7 +35,7 @@
 
     private final ViewInvertHelper mInvertHelper;
     private final Paint mGreyPaint = new Paint();
-    private boolean mShowingLegacyBackground;
+    private boolean mIsLegacy;
     private int mLegacyColor;
 
     protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) {
@@ -55,7 +50,7 @@
             return;
         }
         super.setDark(dark, fade, delay);
-        if (!mShowingLegacyBackground && mShouldInvertDark) {
+        if (!mIsLegacy && mShouldInvertDark) {
             if (fade) {
                 mInvertHelper.fade(dark, delay);
             } else {
@@ -112,15 +107,14 @@
     @Override
     public int getCustomBackgroundColor() {
         int customBackgroundColor = super.getCustomBackgroundColor();
-        if (customBackgroundColor == 0 && mShowingLegacyBackground) {
+        if (customBackgroundColor == 0 && mIsLegacy) {
             return mLegacyColor;
         }
         return customBackgroundColor;
     }
 
-    @Override
-    public void setShowingLegacyBackground(boolean showing) {
-        super.setShowingLegacyBackground(showing);
-        mShowingLegacyBackground = showing;
+    public void setLegacy(boolean legacy) {
+        super.setLegacy(legacy);
+        mIsLegacy = legacy;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index 8eab2e9..38e4ec1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.app.Notification;
 import android.content.Context;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -26,7 +27,6 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.Drawable;
-import android.service.notification.StatusBarNotification;
 import android.util.ArraySet;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -71,6 +71,7 @@
     private TextView mHeaderText;
     private ImageView mWorkProfileImage;
     private boolean mIsLowPriority;
+    private boolean mTransformLowPriorityTitle;
 
     protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         super(view, row);
@@ -100,7 +101,7 @@
 
                     @Override
                     protected boolean hasCustomTransformation() {
-                        return mIsLowPriority;
+                        return mIsLowPriority && mTransformLowPriorityTitle;
                     }
                 }, TRANSFORMING_VIEW_TITLE);
         resolveHeaderViews();
@@ -128,9 +129,10 @@
     }
 
     @Override
-    public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
-        super.notifyContentUpdated(notification, isLowPriority);
-        mIsLowPriority = isLowPriority;
+    public void notifyContentUpdated(ExpandableNotificationRow row) {
+        super.notifyContentUpdated(row);
+        mIsLowPriority = row.isLowPriority();
+        mTransformLowPriorityTitle = !row.isChildInGroup() && !row.isSummaryWithChildren();
         ArraySet<View> previousViews = mTransformationHelper.getAllTransformingViews();
 
         // Reinspect the notification.
@@ -139,11 +141,11 @@
         updateTransformedTypes();
         addRemainingTransformTypes();
         updateCropToPaddingForImageViews();
-        mIcon.setTag(ImageTransformState.ICON_TAG, notification.getNotification().getSmallIcon());
+        Notification notification = row.getStatusBarNotification().getNotification();
+        mIcon.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
         // The work profile image is always the same lets just set the icon tag for it not to
         // animate
-        mWorkProfileImage.setTag(ImageTransformState.ICON_TAG,
-                notification.getNotification().getSmallIcon());
+        mWorkProfileImage.setTag(ImageTransformState.ICON_TAG, notification.getSmallIcon());
 
         // We need to reset all views that are no longer transforming in case a view was previously
         // transformed, but now we decided to transform its container instead.
@@ -361,6 +363,12 @@
     }
 
     @Override
+    public void setIsChildInGroup(boolean isChildInGroup) {
+        super.setIsChildInGroup(isChildInGroup);
+        mTransformLowPriorityTitle = !isChildInGroup;
+    }
+
+    @Override
     public void setVisible(boolean visible) {
         super.setVisible(visible);
         mTransformationHelper.setVisible(visible);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
new file mode 100644
index 0000000..66703ee
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
@@ -0,0 +1,278 @@
+/*
+ * 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.systemui.statusbar.notification;
+
+import android.app.Notification;
+import android.content.Context;
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+import android.view.View;
+import android.widget.RemoteViews;
+
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationContentView;
+import com.android.systemui.statusbar.NotificationData;
+import com.android.systemui.statusbar.phone.StatusBar;
+
+import java.util.Objects;
+
+/**
+ * A utility that inflates the right kind of contentView based on the state
+ */
+public class NotificationInflater {
+
+    private static final int FLAG_REINFLATE_ALL = ~0;
+    private static final int FLAG_REINFLATE_CONTENT_VIEW = 1<<0;
+    private static final int FLAG_REINFLATE_EXPANDED_VIEW = 1<<1;
+    private static final int FLAG_REINFLATE_HEADS_UP_VIEW = 1<<2;
+    private static final int FLAG_REINFLATE_PUBLIC_VIEW = 1<<3;
+    private static final int FLAG_REINFLATE_AMBIENT_VIEW = 1<<4;
+
+    private final ExpandableNotificationRow mRow;
+    private boolean mIsLowPriority;
+    private boolean mUsesIncreasedHeight;
+    private boolean mUsesIncreasedHeadsUpHeight;
+    private RemoteViews.OnClickHandler mRemoteViewClickHandler;
+    private boolean mIsChildInGroup;
+    private InflationExceptionHandler mInflateExceptionHandler;
+
+    public NotificationInflater(ExpandableNotificationRow row) {
+        mRow = row;
+    }
+
+    public void setIsLowPriority(boolean isLowPriority) {
+        mIsLowPriority = isLowPriority;
+    }
+
+    /**
+     * Set whether the notification is a child in a group
+     *
+     * @return whether the view was re-inflated
+     */
+    public boolean setIsChildInGroup(boolean childInGroup) {
+        if (childInGroup != mIsChildInGroup) {
+            mIsChildInGroup = childInGroup;
+            if (mIsLowPriority) {
+                try {
+                    int flags = FLAG_REINFLATE_CONTENT_VIEW | FLAG_REINFLATE_EXPANDED_VIEW;
+                    inflateNotificationViews(flags);
+                } catch (InflationException e) {
+                    mInflateExceptionHandler.handleInflationException(
+                            mRow.getStatusBarNotification(), e);
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public void setUsesIncreasedHeight(boolean usesIncreasedHeight) {
+        mUsesIncreasedHeight = usesIncreasedHeight;
+    }
+
+    public void setUsesIncreasedHeadsUpHeight(boolean usesIncreasedHeight) {
+        mUsesIncreasedHeadsUpHeight = usesIncreasedHeight;
+    }
+
+    public void setRemoteViewClickHandler(RemoteViews.OnClickHandler remoteViewClickHandler) {
+        mRemoteViewClickHandler = remoteViewClickHandler;
+    }
+
+    public void inflateNotificationViews() throws InflationException {
+        inflateNotificationViews(FLAG_REINFLATE_ALL);
+    }
+
+    /**
+     * reinflate all views for the specified flags
+     * @param reInflateFlags flags which views should be reinflated. Use {@link #FLAG_REINFLATE_ALL}
+     *                       to reinflate all of views.
+     * @throws InflationException
+     */
+    private void inflateNotificationViews(int reInflateFlags)
+            throws InflationException {
+        NotificationData.Entry entry = mRow.getEntry();
+        StatusBarNotification sbn = entry.notification;
+        Context context = mRow.getContext();
+        NotificationContentView privateLayout = mRow.getPrivateLayout();
+        try {
+            final Notification.Builder recoveredBuilder
+                    = Notification.Builder.recoverBuilder(context, sbn.getNotification());
+            boolean isLowPriority = mIsLowPriority && !mIsChildInGroup;
+            if ((reInflateFlags & FLAG_REINFLATE_CONTENT_VIEW) != 0) {
+                final RemoteViews newContentView = createContentView(recoveredBuilder,
+                        isLowPriority, mUsesIncreasedHeadsUpHeight);
+                if (!compareRemoteViews(newContentView,
+                        entry.cachedContentView)) {
+                    View contentViewLocal = newContentView.apply(
+                            sbn.getPackageContext(context),
+                            privateLayout,
+                            mRemoteViewClickHandler);
+                    contentViewLocal.setIsRootNamespace(true);
+                    privateLayout.setContractedChild(contentViewLocal);
+                } else {
+                    newContentView.reapply(sbn.getPackageContext(context),
+                            privateLayout.getContractedChild(),
+                            mRemoteViewClickHandler);
+                }
+                entry.cachedContentView = newContentView;
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_EXPANDED_VIEW) != 0) {
+                final RemoteViews newBigContentView = createBigContentView(
+                        recoveredBuilder, isLowPriority);
+                if (newBigContentView != null) {
+                    if (!compareRemoteViews(newBigContentView, entry.cachedBigContentView)) {
+                        View bigContentViewLocal = newBigContentView.apply(
+                                sbn.getPackageContext(context),
+                                privateLayout,
+                                mRemoteViewClickHandler);
+                        bigContentViewLocal.setIsRootNamespace(true);
+                        privateLayout.setExpandedChild(bigContentViewLocal);
+                    } else {
+                        newBigContentView.reapply(sbn.getPackageContext(context),
+                                privateLayout.getExpandedChild(),
+                                mRemoteViewClickHandler);
+                    }
+                } else if (entry.cachedBigContentView != null) {
+                    privateLayout.setExpandedChild(null);
+                }
+                entry.cachedBigContentView = newBigContentView;
+                mRow.setExpandable(newBigContentView != null);
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_HEADS_UP_VIEW) != 0) {
+                final RemoteViews newHeadsUpContentView =
+                        recoveredBuilder.createHeadsUpContentView(mUsesIncreasedHeight);
+                if (newHeadsUpContentView != null) {
+                    if (!compareRemoteViews(newHeadsUpContentView,
+                            entry.cachedHeadsUpContentView)) {
+                        View headsUpContentViewLocal = newHeadsUpContentView.apply(
+                                sbn.getPackageContext(context),
+                                privateLayout,
+                                mRemoteViewClickHandler);
+                        headsUpContentViewLocal.setIsRootNamespace(true);
+                        privateLayout.setHeadsUpChild(headsUpContentViewLocal);
+                    } else {
+                        newHeadsUpContentView.reapply(sbn.getPackageContext(context),
+                                privateLayout.getHeadsUpChild(),
+                                mRemoteViewClickHandler);
+                    }
+                } else if (entry.cachedHeadsUpContentView != null) {
+                    privateLayout.setHeadsUpChild(null);
+                }
+                entry.cachedHeadsUpContentView = newHeadsUpContentView;
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_PUBLIC_VIEW) != 0) {
+                NotificationContentView publicLayout = mRow.getPublicLayout();
+                final RemoteViews newPublicNotification
+                        = recoveredBuilder.makePublicContentView();
+                if (!compareRemoteViews(newPublicNotification, entry.cachedPublicContentView)) {
+                    View publicContentView = newPublicNotification.apply(
+                            sbn.getPackageContext(context),
+                            publicLayout,
+                            mRemoteViewClickHandler);
+                    publicContentView.setIsRootNamespace(true);
+                    publicLayout.setContractedChild(publicContentView);
+                } else {
+                    newPublicNotification.reapply(sbn.getPackageContext(context),
+                            publicLayout.getContractedChild(),
+                            mRemoteViewClickHandler);
+                }
+                entry.cachedPublicContentView = newPublicNotification;
+            }
+
+            if ((reInflateFlags & FLAG_REINFLATE_AMBIENT_VIEW) != 0) {
+                final RemoteViews newAmbientNotification
+                        = recoveredBuilder.makeAmbientNotification();
+                if (!compareRemoteViews(newAmbientNotification, entry.cachedAmbientContentView)) {
+                    View ambientContentView = newAmbientNotification.apply(
+                            sbn.getPackageContext(context),
+                            privateLayout,
+                            mRemoteViewClickHandler);
+                    ambientContentView.setIsRootNamespace(true);
+                    privateLayout.setAmbientChild(ambientContentView);
+                } else {
+                    newAmbientNotification.reapply(sbn.getPackageContext(context),
+                            privateLayout.getAmbientChild(),
+                            mRemoteViewClickHandler);
+                }
+                entry.cachedAmbientContentView = newAmbientNotification;
+            }
+
+        } catch (RuntimeException e) {
+            final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
+            Log.e(StatusBar.TAG, "couldn't inflate view for notification " + ident, e);
+            throw new InflationException("Couldn't inflate contentViews");
+        }
+    }
+
+    private RemoteViews createBigContentView(Notification.Builder builder,
+            boolean isLowPriority) {
+        RemoteViews bigContentView = builder.createBigContentView();
+        if (bigContentView != null) {
+            return bigContentView;
+        }
+        if (isLowPriority) {
+            RemoteViews contentView = builder.createContentView();
+            Notification.Builder.makeHeaderExpanded(contentView);
+            return contentView;
+        }
+        return null;
+    }
+
+    private RemoteViews createContentView(Notification.Builder builder,
+            boolean isLowPriority, boolean useLarge) {
+        if (isLowPriority) {
+            return builder.makeLowPriorityContentView(false /* useRegularSubtext */);
+        }
+        return builder.createContentView(useLarge);
+    }
+
+    // Returns true if the RemoteViews are the same.
+    private boolean compareRemoteViews(final RemoteViews a, final RemoteViews b) {
+        return (a == null && b == null) ||
+                (a != null && b != null
+                        && b.getPackage() != null
+                        && a.getPackage() != null
+                        && a.getPackage().equals(b.getPackage())
+                        && a.getLayoutId() == b.getLayoutId());
+    }
+
+    public void setInflateExceptionHandler(InflationExceptionHandler inflateExceptionHandler) {
+        mInflateExceptionHandler = inflateExceptionHandler;
+    }
+
+    public interface InflationExceptionHandler {
+        void handleInflationException(StatusBarNotification notification, InflationException e);
+    }
+    public void onDensityOrFontScaleChanged() {
+        NotificationData.Entry entry = mRow.getEntry();
+        entry.cachedAmbientContentView = null;
+        entry.cachedBigContentView = null;
+        entry.cachedContentView = null;
+        entry.cachedHeadsUpContentView = null;
+        entry.cachedPublicContentView = null;
+        try {
+            inflateNotificationViews();
+        } catch (InflationException e) {
+            mInflateExceptionHandler.handleInflationException(
+                    mRow.getStatusBarNotification(), e);
+        }
+    }
+
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
index 04ee6aa..ef5a25c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMediaTemplateViewWrapper.java
@@ -35,16 +35,16 @@
 
     View mActions;
 
-    private void resolveViews(StatusBarNotification notification) {
+    private void resolveViews() {
         mActions = mView.findViewById(com.android.internal.R.id.media_actions);
     }
 
     @Override
-    public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+    public void notifyContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
-        resolveViews(notification);
-        super.notifyContentUpdated(notification, isLowPriority);
+        resolveViews();
+        super.notifyContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
index defeab2..9631556 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationMessagingTemplateViewWrapper.java
@@ -21,7 +21,6 @@
 import com.android.systemui.statusbar.TransformableView;
 
 import android.content.Context;
-import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
 import android.view.View;
 import android.widget.TextView;
@@ -71,11 +70,11 @@
     }
 
     @Override
-    public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+    public void notifyContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
         resolveViews();
-        super.notifyContentUpdated(notification, isLowPriority);
+        super.notifyContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
index e9956ff..846d03a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -133,11 +133,11 @@
     }
 
     @Override
-    public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+    public void notifyContentUpdated(ExpandableNotificationRow row) {
         // Reinspect the notification. Before the super call, because the super call also updates
         // the transformation types and we need to have our values set by then.
-        resolveTemplateViews(notification);
-        super.notifyContentUpdated(notification, isLowPriority);
+        resolveTemplateViews(row.getStatusBarNotification());
+        super.notifyContentUpdated(row);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
index 5f5e1e4..c85e8d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -48,6 +48,7 @@
     private int mBackgroundColor = 0;
     protected boolean mShouldInvertDark;
     protected boolean mDarkInitialized = false;
+    private boolean mForcedInvisible;
 
     public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
         if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
@@ -87,10 +88,9 @@
 
     /**
      * Notifies this wrapper that the content of the view might have changed.
-     * @param notification the notification this is wrapped around
-     * @param isLowPriority is this notification low priority
+     * @param row the row this wrapper is attached to
      */
-    public void notifyContentUpdated(StatusBarNotification notification, boolean isLowPriority) {
+    public void notifyContentUpdated(ExpandableNotificationRow row) {
         mDarkInitialized = false;
         Drawable background = mView.getBackground();
         if (shouldClearBackgroundOnReapply()) {
@@ -185,7 +185,7 @@
         return mRow.isSummaryWithChildren() ? 0 : mBackgroundColor;
     }
 
-    public void setShowingLegacyBackground(boolean showing) {
+    public void setLegacy(boolean legacy) {
     }
 
     public void setContentHeight(int contentHeight, int minHeightHint) {
@@ -193,4 +193,7 @@
 
     public void setRemoteInputVisible(boolean visible) {
     }
+
+    public void setIsChildInGroup(boolean isChildInGroup) {
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 31cfa66..cd9a49d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -19,6 +19,8 @@
 import android.os.Looper;
 import android.provider.Settings.Secure;
 
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.NightDisplayController;
 import com.android.systemui.Dependency;
 import com.android.systemui.Prefs;
 import com.android.systemui.Prefs.Key;
@@ -64,6 +66,11 @@
         if (!Prefs.getBoolean(context, Key.QS_WORK_ADDED, false)) {
             Dependency.get(ManagedProfileController.class).addCallback(mProfileCallback);
         }
+
+        if (!Prefs.getBoolean(context, Key.QS_NIGHTDISPLAY_ADDED, false)
+                && NightDisplayController.isAvailable(mContext)) {
+            Dependency.get(NightDisplayController.class).setListener(mNightDisplayCallback);
+        }
     }
 
     public void destroy() {
@@ -71,6 +78,7 @@
         Dependency.get(HotspotController.class).removeCallback(mHotspotCallback);
         Dependency.get(DataSaverController.class).removeCallback(mDataSaverListener);
         Dependency.get(ManagedProfileController.class).removeCallback(mProfileCallback);
+        Dependency.get(NightDisplayController.class).setListener(null);
     }
 
     private final ManagedProfileController.Callback mProfileCallback =
@@ -115,4 +123,30 @@
             }
         }
     };
+
+    @VisibleForTesting
+    final NightDisplayController.Callback mNightDisplayCallback =
+            new NightDisplayController.Callback() {
+        @Override
+        public void onActivated(boolean activated) {
+            if (activated) {
+                addNightTile();
+            }
+        }
+
+        @Override
+        public void onAutoModeChanged(int autoMode) {
+            if (autoMode == NightDisplayController.AUTO_MODE_CUSTOM
+                    || autoMode == NightDisplayController.AUTO_MODE_TWILIGHT) {
+                addNightTile();
+            }
+        }
+
+        private void addNightTile() {
+            mHost.addTile("night");
+            Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, true);
+            mHandler.post(() -> Dependency.get(NightDisplayController.class)
+                    .setListener(null));
+        }
+    };
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 2538bdd..9a49d67 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -36,7 +36,6 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.content.res.AssetFileDescriptor.AutoCloseOutputStream;
 import android.content.res.Configuration;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
@@ -64,7 +63,6 @@
 import com.android.internal.widget.LockPatternUtils;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.Dependency;
 import com.android.systemui.Interpolators;
@@ -75,7 +73,7 @@
 import com.android.systemui.plugins.IntentButtonProvider.IntentButton.IconState;
 import com.android.systemui.plugins.PluginListener;
 import com.android.systemui.plugins.PluginManager;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.KeyguardAffordanceView;
 import com.android.systemui.statusbar.KeyguardIndicationController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
index 3cbac17..8cad85c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/MultiUserSwitch.java
@@ -31,7 +31,7 @@
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.QSPanel;
 import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index dc5f98c..3706dc8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -227,6 +227,7 @@
             ViewState iconState = mIconStates.get(view);
             iconState.initFrom(view);
             iconState.alpha = 1.0f;
+            iconState.hidden = false;
         }
     }
 
@@ -524,11 +525,5 @@
                 iconColor = ((StatusBarIconView) view).getStaticDrawableColor();
             }
         }
-
-        protected void onYTranslationAnimationFinished(View view) {
-            if (hidden) {
-                view.setVisibility(INVISIBLE);
-            }
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index a1022c4..de00237 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -37,7 +37,7 @@
 import com.android.systemui.qs.external.TileLifecycleManager;
 import com.android.systemui.qs.external.TileServices;
 import com.android.systemui.qs.tiles.AirplaneModeTile;
-import com.android.systemui.qs.tiles.BatteryTile;
+import com.android.systemui.qs.tiles.BatterySaverTile;
 import com.android.systemui.qs.tiles.BluetoothTile;
 import com.android.systemui.qs.tiles.CastTile;
 import com.android.systemui.qs.tiles.CellularTile;
@@ -273,7 +273,7 @@
         else if (tileSpec.equals("cast")) return new CastTile(this);
         else if (tileSpec.equals("hotspot")) return new HotspotTile(this);
         else if (tileSpec.equals("user")) return new UserTile(this);
-        else if (tileSpec.equals("battery")) return new BatteryTile(this);
+        else if (tileSpec.equals("battery")) return new BatterySaverTile(this);
         else if (tileSpec.equals("saver")) return new DataSaverTile(this);
         else if (tileSpec.equals("night")) return new NightDisplayTile(this);
         else if (tileSpec.equals("nfc")) return new NfcTile(this);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index c070869..a5590f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -43,7 +43,7 @@
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.keyguard.KeyguardStatusView;
 import com.android.settingslib.Utils;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.BatteryMeterView;
 import com.android.systemui.Dependency;
 import com.android.systemui.FontSizeUtils;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index a6b145e..53d2d73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -23,6 +23,7 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 
+import static com.android.systemui.statusbar.notification.NotificationInflater.InflationExceptionHandler;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT;
 import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
@@ -124,7 +125,6 @@
 import com.android.systemui.ActivityStarterDelegate;
 import com.android.systemui.DemoMode;
 import com.android.systemui.Dependency;
-import com.android.systemui.EventLogConstants;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.Interpolators;
 import com.android.systemui.Prefs;
@@ -139,7 +139,7 @@
 import com.android.systemui.fragments.PluginFragmentListener;
 import com.android.systemui.keyguard.KeyguardViewMediator;
 import com.android.systemui.plugins.qs.QS;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.plugins.qs.QS.BaseStatusBarHeader;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeListener;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowProvider.SnoozeOption;
@@ -161,7 +161,6 @@
 import com.android.systemui.statusbar.GestureRecorder;
 import com.android.systemui.statusbar.KeyboardShortcuts;
 import com.android.systemui.statusbar.KeyguardIndicationController;
-import com.android.systemui.statusbar.NotificationContentView;
 import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationData.Entry;
 import com.android.systemui.statusbar.NotificationGuts;
@@ -172,6 +171,8 @@
 import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.InflationException;
+import com.android.systemui.statusbar.notification.NotificationInflater;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
@@ -299,7 +300,7 @@
             "com.android.systemui.statusbar.banner_action_setup";
     private static final String NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION
             = "com.android.systemui.statusbar.work_challenge_unlocked_notification_action";
-    static final String TAG = "StatusBar";
+    public static final String TAG = "StatusBar";
     public static final boolean DEBUG = false;
     public static final boolean SPEW = false;
     public static final boolean DUMPTRUCK = true; // extra dumpsys info
@@ -717,6 +718,7 @@
     private LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
     private NotificationIconAreaController mNotificationIconAreaController;
     private ConfigurationListener mDensityChangeListener;
+    private InflationExceptionHandler mInflationExceptionHandler = this::handleInflationException;
 
     private void recycleAllVisibilityObjects(ArraySet<NotificationVisibility> array) {
         final int N = array.size();
@@ -1276,12 +1278,11 @@
             Entry entry = activeNotifications.get(i);
             boolean exposedGuts = mNotificationGutsExposed != null
                     && entry.row.getGuts() == mNotificationGutsExposed;
-            entry.row.reInflateViews();
+            entry.row.onDensityOrFontScaleChanged();
             if (exposedGuts) {
                 mNotificationGutsExposed = entry.row.getGuts();
                 bindGuts(entry.row, mGutsMenuItem);
             }
-            inflateViews(entry, mStackScroller);
         }
         // end old BaseStatusBar.onDensityOrFontScaleChanged().
         mScrimController.onDensityOrFontScaleChanged();
@@ -1550,14 +1551,11 @@
     }
 
     public void addNotification(StatusBarNotification notification, RankingMap ranking,
-            Entry oldEntry) {
+            Entry oldEntry) throws InflationException {
         if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
 
         mNotificationData.updateRanking(ranking);
         Entry shadeEntry = createNotificationViews(notification);
-        if (shadeEntry == null) {
-            return;
-        }
         boolean isHeadsUped = shouldPeek(shadeEntry);
         if (isHeadsUped) {
             mHeadsUpManager.showNotification(shadeEntry);
@@ -1599,6 +1597,10 @@
         setAreThereNotifications();
     }
 
+    public void handleInflationException(StatusBarNotification notification, InflationException e) {
+        handleNotificationError(notification, e.getMessage());
+    }
+
     private boolean shouldSuppressFullScreenIntent(String key) {
         if (isDeviceInVrMode()) {
             return true;
@@ -1663,10 +1665,17 @@
                     sbn.getOpPkg(),
                     sbn.getId(), sbn.getTag(), sbn.getUid(), sbn.getInitialPid(),
                     newNotification, sbn.getUser(), sbn.getOverrideGroupKey(), sbn.getPostTime());
-
-            updateNotification(newSbn, null);
-            mKeysKeptForRemoteInput.add(entry.key);
-            return;
+            boolean updated = false;
+            try {
+                updateNotification(newSbn, null);
+                updated = true;
+            } catch (InflationException e) {
+                deferRemoval = false;
+            }
+            if (updated) {
+                mKeysKeptForRemoteInput.add(entry.key);
+                return;
+            }
         }
         if (deferRemoval) {
             mLatestRankingMap = ranking;
@@ -1808,15 +1817,6 @@
                 updatePublicContentView(ent, ent.notification);
             }
             ent.row.setSensitive(sensitive, deviceSensitive);
-            if (ent.autoRedacted && ent.legacy) {
-                // TODO: Also fade this? Or, maybe easier (and better), provide a dark redacted form
-                // for legacy auto redacted notifications.
-                if (showingPublic) {
-                    ent.row.setShowingLegacyBackground(false);
-                } else {
-                    ent.row.setShowingLegacyBackground(true);
-                }
-            }
             if (mGroupManager.isChildInGroupWithSummary(ent.row.getStatusBarNotification())) {
                 ExpandableNotificationRow summary = mGroupManager.getGroupSummary(
                         ent.row.getStatusBarNotification());
@@ -5513,7 +5513,11 @@
                 @Override
                 public void run() {
                     for (StatusBarNotification sbn : notifications) {
-                        addNotification(sbn, currentRanking, null /* oldEntry */);
+                        try {
+                            addNotification(sbn, currentRanking, null /* oldEntry */);
+                        } catch (InflationException e) {
+                            handleInflationException(sbn, e);
+                        }
                     }
                 }
             });
@@ -5549,10 +5553,14 @@
                             }
                             return;
                         }
-                        if (isUpdate) {
-                            updateNotification(sbn, rankingMap);
-                        } else {
-                            addNotification(sbn, rankingMap, null /* oldEntry */);
+                        try {
+                            if (isUpdate) {
+                                updateNotification(sbn, rankingMap);
+                            } else {
+                                addNotification(sbn, rankingMap, null /* oldEntry */);
+                            }
+                        } catch (InflationException e) {
+                            handleInflationException(sbn, e);
                         }
                     }
                 });
@@ -5682,26 +5690,6 @@
         return mGroupManager;
     }
 
-    protected void bindDismissRunnable(final ExpandableNotificationRow row) {
-        row.setOnDismissRunnable(() -> performRemoveNotification(row.getStatusBarNotification()));
-    }
-
-    protected void applyColorsAndBackgrounds(StatusBarNotification sbn,
-            NotificationData.Entry entry) {
-
-        if (entry.getContentView().getId()
-                != com.android.internal.R.id.status_bar_latest_event_content) {
-            // Using custom RemoteViews
-            if (entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
-                    && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP) {
-                entry.row.setShowingLegacyBackground(true);
-                entry.legacy = true;
-            }
-        }
-
-        entry.setIconTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
-    }
-
     public boolean isMediaNotification(NotificationData.Entry entry) {
         // TODO: confirm that there's a valid media key
         return entry.getExpandedContentView() != null &&
@@ -6083,55 +6071,16 @@
         }
     }
 
-    protected boolean inflateViews(Entry entry, ViewGroup parent) {
+    protected void inflateViews(Entry entry, ViewGroup parent) throws
+            InflationException {
         PackageManager pmUser = getPackageManagerForUser(mContext,
                 entry.notification.getUser().getIdentifier());
 
         final StatusBarNotification sbn = entry.notification;
-        boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
-        boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(sbn,
-                mNotificationData.getImportance(sbn.getKey()));
-        boolean useIncreasedHeadsUp = useIncreasedCollapsedHeight && mPanelExpanded;
-        try {
-            entry.cacheContentViews(mContext, null, isLowPriority, useIncreasedCollapsedHeight,
-                    useIncreasedHeadsUp);
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Unable to get notification remote views", e);
-            return false;
-        }
-
-        final RemoteViews contentView = entry.cachedContentView;
-        final RemoteViews bigContentView = entry.cachedBigContentView;
-        final RemoteViews headsUpContentView = entry.cachedHeadsUpContentView;
-        final RemoteViews publicContentView = entry.cachedPublicContentView;
-        final RemoteViews ambientContentView = entry.cachedAmbientContentView;
-
-        if (contentView == null) {
-            Log.v(TAG, "no contentView for: " + sbn.getNotification());
-            return false;
-        }
-
-        if (DEBUG) {
-            Log.v(TAG, "publicContentView: " + publicContentView);
-        }
-
         ExpandableNotificationRow row;
-
-        // Stash away previous user expansion state so we can restore it at
-        // the end.
-        boolean hasUserChangedExpansion = false;
-        boolean userExpanded = false;
-        boolean userLocked = false;
-
         if (entry.row != null) {
             row = entry.row;
-            hasUserChangedExpansion = row.hasUserChangedExpansion();
-            userExpanded = row.isUserExpanded();
-            userLocked = row.isUserLocked();
             entry.reset();
-            if (hasUserChangedExpansion) {
-                row.setUserExpanded(userExpanded);
-            }
         } else {
             // create the row view
             LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
@@ -6143,6 +6092,8 @@
             row.setHeadsUpManager(mHeadsUpManager);
             row.setRemoteInputController(mRemoteInputController);
             row.setOnExpandClickListener(this);
+            row.setRemoteViewClickHandler(mOnClickHandler);
+            row.setInflateExceptionHandler(mInflationExceptionHandler);
 
             // Get the app name.
             // Note that Notification.Builder#bindHeaderAppName has similar logic
@@ -6162,86 +6113,19 @@
                 // Do nothing
             }
             row.setAppName(appname);
+            row.setOnDismissRunnable(() ->
+                    performRemoveNotification(row.getStatusBarNotification()));
+            row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+            if (ENABLE_REMOTE_INPUT) {
+                row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+            }
         }
 
-        bindDismissRunnable(row);
+        boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
         row.setIsLowPriority(isLowPriority);
-
-        // NB: the large icon is now handled entirely by the template
-
         // bind the click event to the content area
-        NotificationContentView contentContainer = row.getPrivateLayout();
-        NotificationContentView contentContainerPublic = row.getPublicLayout();
-
-        row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
-        if (ENABLE_REMOTE_INPUT) {
-            row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
-        }
-
         mNotificationClicker.register(row, sbn);
 
-        // set up the adaptive layout
-        View contentViewLocal = null;
-        View bigContentViewLocal = null;
-        View headsUpContentViewLocal = null;
-        View publicViewLocal = null;
-        View ambientViewLocal = null;
-        try {
-            contentViewLocal = contentView.apply(
-                    sbn.getPackageContext(mContext),
-                    contentContainer,
-                    mOnClickHandler);
-            if (bigContentView != null) {
-                bigContentViewLocal = bigContentView.apply(
-                        sbn.getPackageContext(mContext),
-                        contentContainer,
-                        mOnClickHandler);
-            }
-            if (headsUpContentView != null) {
-                headsUpContentViewLocal = headsUpContentView.apply(
-                        sbn.getPackageContext(mContext),
-                        contentContainer,
-                        mOnClickHandler);
-            }
-            if (publicContentView != null) {
-                publicViewLocal = publicContentView.apply(
-                        sbn.getPackageContext(mContext),
-                        contentContainerPublic, mOnClickHandler);
-            }
-            if (ambientContentView != null) {
-                ambientViewLocal = ambientContentView.apply(
-                        sbn.getPackageContext(mContext),
-                        contentContainer, mOnClickHandler);
-            }
-
-            if (contentViewLocal != null) {
-                contentViewLocal.setIsRootNamespace(true);
-                contentContainer.setContractedChild(contentViewLocal);
-            }
-            if (bigContentViewLocal != null) {
-                bigContentViewLocal.setIsRootNamespace(true);
-                contentContainer.setExpandedChild(bigContentViewLocal);
-            }
-            if (headsUpContentViewLocal != null) {
-                headsUpContentViewLocal.setIsRootNamespace(true);
-                contentContainer.setHeadsUpChild(headsUpContentViewLocal);
-            }
-            if (publicViewLocal != null) {
-                publicViewLocal.setIsRootNamespace(true);
-                contentContainerPublic.setContractedChild(publicViewLocal);
-            }
-
-            if (ambientViewLocal != null) {
-                ambientViewLocal.setIsRootNamespace(true);
-                contentContainer.setAmbientChild(ambientViewLocal);
-            }
-        }
-        catch (RuntimeException e) {
-            final String ident = sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId());
-            Log.e(TAG, "couldn't inflate view for notification " + ident, e);
-            return false;
-        }
-
         // Extract target SDK version.
         try {
             ApplicationInfo info = pmUser.getApplicationInfo(sbn.getPackageName(), 0);
@@ -6249,25 +6133,20 @@
         } catch (NameNotFoundException ex) {
             Log.e(TAG, "Failed looking up ApplicationInfo for " + sbn.getPackageName(), ex);
         }
+        row.setLegacy(entry.targetSdk >= Build.VERSION_CODES.GINGERBREAD
+                && entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
+        entry.setIconTag(R.id.icon_is_pre_L, entry.targetSdk < Build.VERSION_CODES.LOLLIPOP);
         entry.autoRedacted = entry.notification.getNotification().publicVersion == null;
 
         entry.row = row;
         entry.row.setOnActivatedListener(this);
-        entry.row.setExpandable(bigContentViewLocal != null);
 
-        applyColorsAndBackgrounds(sbn, entry);
-
-        // Restore previous flags.
-        if (hasUserChangedExpansion) {
-            // Note: setUserExpanded() conveniently ignores calls with
-            //       userExpanded=true if !isExpandable().
-            row.setUserExpanded(userExpanded);
-        }
-        row.setUserLocked(userLocked);
+        boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(sbn,
+                mNotificationData.getImportance(sbn.getKey()));
+        boolean useIncreasedHeadsUp = useIncreasedCollapsedHeight && mPanelExpanded;
         row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
         row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
-        row.onNotificationUpdated(entry);
-        return true;
+        row.updateNotification(entry);
     }
 
     /**
@@ -6605,23 +6484,17 @@
         return entry.notification;
     }
 
-    protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn) {
+    protected NotificationData.Entry createNotificationViews(StatusBarNotification sbn)
+            throws InflationException {
         if (DEBUG) {
             Log.d(TAG, "createNotificationViews(notification=" + sbn);
         }
         NotificationData.Entry entry = new NotificationData.Entry(sbn);
         Dependency.get(LeakDetector.class).trackInstance(entry);
-        try {
-            entry.createIcons(mContext, sbn);
-        } catch (NotificationData.IconException exception) {
-            handleNotificationError(sbn, exception.getMessage());
-        }
+        entry.createIcons(mContext, sbn);
 
         // Construct the expanded view.
-        if (!inflateViews(entry, mStackScroller)) {
-            handleNotificationError(sbn, "Couldn't expand RemoteViews for: " + sbn);
-            return null;
-        }
+        inflateViews(entry, mStackScroller);
         return entry;
     }
 
@@ -6742,7 +6615,8 @@
         }
     }
 
-    public void updateNotification(StatusBarNotification notification, RankingMap ranking) {
+    public void updateNotification(StatusBarNotification notification, RankingMap ranking)
+            throws InflationException {
         if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
 
         final String key = notification.getKey();
@@ -6757,56 +6631,16 @@
         Notification n = notification.getNotification();
         mNotificationData.updateRanking(ranking);
 
-        boolean useIncreasedCollapsedHeight = mMessagingUtil.isImportantMessaging(notification,
-                mNotificationData.getImportance(notification.getKey()));
-        entry.row.setUseIncreasedCollapsedHeight(useIncreasedCollapsedHeight);
-        boolean useIncreasedHeadsUp = useIncreasedCollapsedHeight && mPanelExpanded;
-        entry.row.setUseIncreasedHeadsUpHeight(useIncreasedHeadsUp);
-        boolean applyInPlace;
-        try {
-            applyInPlace = entry.cacheContentViews(mContext, notification.getNotification(),
-                    mNotificationData.isAmbient(key), useIncreasedCollapsedHeight,
-                    useIncreasedHeadsUp);
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Unable to get notification remote views", e);
-            applyInPlace = false;
-        }
-        boolean shouldPeek = shouldPeek(entry, notification);
-        boolean alertAgain = alertAgain(entry, n);
-        if (DEBUG) {
-            Log.d(TAG, "applyInPlace=" + applyInPlace
-                    + " shouldPeek=" + shouldPeek
-                    + " alertAgain=" + alertAgain);
-        }
-
         final StatusBarNotification oldNotification = entry.notification;
         entry.notification = notification;
         mGroupManager.onEntryUpdated(entry, oldNotification);
 
-        boolean updateSuccessful = false;
-        try {
-            if (applyInPlace) {
-                if (DEBUG) Log.d(TAG, "reusing notification for key: " + key);
-                try {
-                    entry.updateIcons(mContext, n);
-                    updateNotificationViews(entry, notification);
-                    updateSuccessful = true;
-                } catch (RuntimeException e) {
-                    // It failed to apply cleanly.
-                    Log.w(TAG, "Couldn't reapply views for package " +
-                            notification.getPackageName(), e);
-                }
-            }
-            if (!updateSuccessful) {
-                entry.updateIcons(mContext, n);
-                if (!inflateViews(entry, mStackScroller)) {
-                    handleNotificationError(notification, "Couldn't update remote views for: "
-                            + notification);
-                }
-            }
-        } catch (NotificationData.IconException e) {
-            handleNotificationError(notification, e.getMessage());
-        }
+        entry.updateIcons(mContext, n);
+        inflateViews(entry, mStackScroller);
+
+        boolean shouldPeek = shouldPeek(entry, notification);
+        boolean alertAgain = alertAgain(entry, n);
+
         updateHeadsUp(key, entry, shouldPeek, alertAgain);
         updateNotifications();
 
@@ -6821,44 +6655,9 @@
             boolean isForCurrentUser = isNotificationForCurrentProfiles(notification);
             Log.d(TAG, "notification is " + (isForCurrentUser ? "" : "not ") + "for you");
         }
-
         setAreThereNotifications();
     }
 
-    private void updateNotificationViews(Entry entry, StatusBarNotification sbn) {
-        final RemoteViews contentView = entry.cachedContentView;
-        final RemoteViews bigContentView = entry.cachedBigContentView;
-        final RemoteViews headsUpContentView = entry.cachedHeadsUpContentView;
-        final RemoteViews publicContentView = entry.cachedPublicContentView;
-        final RemoteViews ambientContentView = entry.cachedAmbientContentView;
-
-        // Reapply the RemoteViews
-        contentView.reapply(mContext, entry.getContentView(), mOnClickHandler);
-        if (bigContentView != null && entry.getExpandedContentView() != null) {
-            bigContentView.reapply(sbn.getPackageContext(mContext),
-                    entry.getExpandedContentView(),
-                    mOnClickHandler);
-        }
-        View headsUpChild = entry.getHeadsUpContentView();
-        if (headsUpContentView != null && headsUpChild != null) {
-            headsUpContentView.reapply(sbn.getPackageContext(mContext),
-                    headsUpChild, mOnClickHandler);
-        }
-        if (publicContentView != null && entry.getPublicContentView() != null) {
-            publicContentView.reapply(sbn.getPackageContext(mContext),
-                    entry.getPublicContentView(), mOnClickHandler);
-        }
-        if (ambientContentView != null && entry.getAmbientContentView() != null) {
-            ambientContentView.reapply(sbn.getPackageContext(mContext),
-                    entry.getAmbientContentView(), mOnClickHandler);
-        }
-        // update the contentIntent
-        mNotificationClicker.register(entry.row, sbn);
-
-        entry.row.onNotificationUpdated(entry);
-        entry.row.resetHeight();
-    }
-
     protected void updatePublicContentView(Entry entry,
             StatusBarNotification sbn) {
         final RemoteViews publicContentView = entry.cachedPublicContentView;
@@ -6872,10 +6671,7 @@
             TextView titleView = (TextView) inflatedView.findViewById(android.R.id.title);
             if (titleView != null
                     && !titleView.getText().toString().equals(notificationHiddenText)) {
-                publicContentView.setTextViewText(android.R.id.title, notificationHiddenText);
-                publicContentView.reapply(sbn.getPackageContext(mContext),
-                        inflatedView, mOnClickHandler);
-                entry.row.onNotificationUpdated(entry);
+                titleView.setText(notificationHiddenText);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
index 821e635..a87b50a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
@@ -116,19 +116,20 @@
     }
 
     private void notifyKeyguardChanged() {
-        mCallbacks.forEach(Callback::onKeyguardShowingChanged);
+        // Copy the list to allow removal during callback.
+        new ArrayList<Callback>(mCallbacks).forEach(Callback::onKeyguardShowingChanged);
     }
 
     public void notifyKeyguardFadingAway(long delay, long fadeoutDuration) {
         mKeyguardFadingAway = true;
         mKeyguardFadingAwayDelay = delay;
         mKeyguardFadingAwayDuration = fadeoutDuration;
-        mCallbacks.forEach(Callback::onKeyguardShowingChanged);
+        notifyKeyguardChanged();
     }
 
     public void notifyKeyguardDoneFading() {
         mKeyguardFadingAway = false;
-        mCallbacks.forEach(Callback::onKeyguardShowingChanged);
+        notifyKeyguardChanged();
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 51d931e..bc3eec9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -39,6 +39,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.MathUtils;
+import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneConstants;
@@ -78,6 +79,7 @@
     private static final int EMERGENCY_FIRST_CONTROLLER = 100;
     private static final int EMERGENCY_VOICE_CONTROLLER = 200;
     private static final int EMERGENCY_NO_SUB = 300;
+    private static final int EMERGENCY_ASSUMED_VOICE_CONTROLLER = 400;
 
     private final Context mContext;
     private final TelephonyManager mPhone;
@@ -99,8 +101,7 @@
     final EthernetSignalController mEthernetSignalController;
 
     @VisibleForTesting
-    final Map<Integer, MobileSignalController> mMobileSignalControllers =
-            new HashMap<Integer, MobileSignalController>();
+    final SparseArray<MobileSignalController> mMobileSignalControllers = new SparseArray<>();
     // When no SIMs are around at setup, and one is added later, it seems to default to the first
     // SIM for most actions.  This may be null if there aren't any SIMs around.
     private MobileSignalController mDefaultSignalController;
@@ -232,7 +233,8 @@
     }
 
     private void registerListeners() {
-        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.registerListener();
         }
         if (mSubscriptionListener == null) {
@@ -261,7 +263,8 @@
 
     private void unregisterListeners() {
         mListening = false;
-        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.unregisterListener();
         }
         mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
@@ -305,7 +308,7 @@
             if (DEBUG) Log.e(TAG, "No data sim selected");
             return mDefaultSignalController;
         }
-        if (mMobileSignalControllers.containsKey(dataSubId)) {
+        if (mMobileSignalControllers.indexOfKey(dataSubId) >= 0) {
             return mMobileSignalControllers.get(dataSubId);
         }
         if (DEBUG) Log.e(TAG, "Cannot find controller for data sub: " + dataSubId);
@@ -326,8 +329,8 @@
         }
         int voiceSubId = mSubDefaults.getDefaultVoiceSubId();
         if (!SubscriptionManager.isValidSubscriptionId(voiceSubId)) {
-            for (MobileSignalController mobileSignalController :
-                                            mMobileSignalControllers.values()) {
+            for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
                 if (!mobileSignalController.getState().isEmergency) {
                     mEmergencySource = EMERGENCY_FIRST_CONTROLLER
                             + mobileSignalController.mSubscriptionInfo.getSubscriptionId();
@@ -336,11 +339,20 @@
                 }
             }
         }
-        if (mMobileSignalControllers.containsKey(voiceSubId)) {
+        if (mMobileSignalControllers.indexOfKey(voiceSubId) >= 0) {
             mEmergencySource = EMERGENCY_VOICE_CONTROLLER + voiceSubId;
             if (DEBUG) Log.d(TAG, "Getting emergency from " + voiceSubId);
             return mMobileSignalControllers.get(voiceSubId).getState().isEmergency;
         }
+        // If we have the wrong subId but there is only one sim anyway, assume it should be the
+        // default.
+        if (mMobileSignalControllers.size() == 1) {
+            mEmergencySource = EMERGENCY_ASSUMED_VOICE_CONTROLLER
+                    + mMobileSignalControllers.keyAt(0);
+            if (DEBUG) Log.d(TAG, "Getting assumed emergency from "
+                    + mMobileSignalControllers.keyAt(0));
+            return mMobileSignalControllers.valueAt(0).getState().isEmergency;
+        }
         if (DEBUG) Log.e(TAG, "Cannot find controller for voice sub: " + voiceSubId);
         mEmergencySource = EMERGENCY_NO_SUB + voiceSubId;
         // Something is wrong, better assume we can't make calls...
@@ -363,7 +375,8 @@
         cb.setNoSims(mHasNoSims);
         mWifiSignalController.notifyListeners(cb);
         mEthernetSignalController.notifyListeners(cb);
-        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.notifyListeners(cb);
         }
         mCallbackHandler.setListening(cb, true);
@@ -416,7 +429,8 @@
         } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
             // Notify every MobileSignalController so they can know whether they are the
             // data sim or not.
-            for (MobileSignalController controller : mMobileSignalControllers.values()) {
+            for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                MobileSignalController controller = mMobileSignalControllers.valueAt(i);
                 controller.handleBroadcast(intent);
             }
         } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) {
@@ -433,7 +447,7 @@
             int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                     SubscriptionManager.INVALID_SUBSCRIPTION_ID);
             if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                if (mMobileSignalControllers.containsKey(subId)) {
+                if (mMobileSignalControllers.indexOfKey(subId) >= 0) {
                     mMobileSignalControllers.get(subId).handleBroadcast(intent);
                 } else {
                     // Can't find this subscription...  We must be out of date.
@@ -458,8 +472,9 @@
 
     @VisibleForTesting
     void handleConfigurationChanged() {
-        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
-            mobileSignalController.setConfiguration(mConfig);
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController controller = mMobileSignalControllers.valueAt(i);
+            controller.setConfiguration(mConfig);
         }
         refreshLocale();
     }
@@ -511,15 +526,20 @@
         });
         mCurrentSubscriptions = subscriptions;
 
-        HashMap<Integer, MobileSignalController> cachedControllers =
-                new HashMap<Integer, MobileSignalController>(mMobileSignalControllers);
+        SparseArray<MobileSignalController> cachedControllers =
+                new SparseArray<MobileSignalController>();
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            cachedControllers.put(mMobileSignalControllers.keyAt(i),
+                    mMobileSignalControllers.valueAt(i));
+        }
         mMobileSignalControllers.clear();
         final int num = subscriptions.size();
         for (int i = 0; i < num; i++) {
             int subId = subscriptions.get(i).getSubscriptionId();
             // If we have a copy of this controller already reuse it, otherwise make a new one.
-            if (cachedControllers.containsKey(subId)) {
-                mMobileSignalControllers.put(subId, cachedControllers.remove(subId));
+            if (cachedControllers.indexOfKey(subId) >= 0) {
+                mMobileSignalControllers.put(subId, cachedControllers.get(subId));
+                cachedControllers.remove(subId);
             } else {
                 MobileSignalController controller = new MobileSignalController(mContext, mConfig,
                         mHasMobileDataFeature, mPhone, mCallbackHandler,
@@ -535,7 +555,8 @@
             }
         }
         if (mListening) {
-            for (Integer key : cachedControllers.keySet()) {
+            for (int i = 0; i < cachedControllers.size(); i++) {
+                int key = cachedControllers.keyAt(i);
                 if (cachedControllers.get(key) == mDefaultSignalController) {
                     mDefaultSignalController = null;
                 }
@@ -557,7 +578,8 @@
 
     private void handleSetUserSetupComplete(boolean userSetup) {
         mUserSetup = userSetup;
-        for (MobileSignalController controller : mMobileSignalControllers.values()) {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController controller = mMobileSignalControllers.valueAt(i);
             controller.setUserSetupComplete(mUserSetup);
         }
     }
@@ -568,7 +590,7 @@
             return false;
         }
         for (SubscriptionInfo info : allSubscriptions) {
-            if (!mMobileSignalControllers.containsKey(info.getSubscriptionId())) {
+            if (mMobileSignalControllers.indexOfKey(info.getSubscriptionId()) < 0) {
                 return false;
             }
         }
@@ -580,7 +602,8 @@
                 Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
         if (airplaneMode != mAirplaneMode || force) {
             mAirplaneMode = airplaneMode;
-            for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+            for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
                 mobileSignalController.setAirplaneMode(mAirplaneMode);
             }
             notifyListeners();
@@ -601,7 +624,8 @@
      */
     private void notifyAllListeners() {
         notifyListeners();
-        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.notifyListeners();
         }
         mWifiSignalController.notifyListeners();
@@ -650,7 +674,8 @@
      */
     private void pushConnectivityToSignals() {
         // We want to update all the icons, all at once, for any condition change
-        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
         }
         mWifiSignalController.updateConnectivity(mConnectedTransports, mValidatedTransports);
@@ -682,7 +707,8 @@
         pw.print("  mEmergencySource=");
         pw.println(emergencyToString(mEmergencySource));
 
-        for (MobileSignalController mobileSignalController : mMobileSignalControllers.values()) {
+        for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+            MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);
             mobileSignalController.dump(pw);
         }
         mWifiSignalController.dump(pw);
@@ -694,6 +720,9 @@
 
     private static final String emergencyToString(int emergencySource) {
         if (emergencySource > EMERGENCY_NO_SUB) {
+            return "ASSUMED_VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER)
+                    + ")";
+        } else if (emergencySource > EMERGENCY_NO_SUB) {
             return "NO_SUB(" + (emergencySource - EMERGENCY_NO_SUB) + ")";
         } else if (emergencySource > EMERGENCY_VOICE_CONTROLLER) {
             return "VOICE_CONTROLLER(" + (emergencySource - EMERGENCY_VOICE_CONTROLLER) + ")";
@@ -724,7 +753,8 @@
             // Update what MobileSignalControllers, because they may change
             // to set the number of sim slots.
             updateMobileControllers();
-            for (MobileSignalController controller : mMobileSignalControllers.values()) {
+            for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                MobileSignalController controller = mMobileSignalControllers.valueAt(i);
                 controller.resetLastState();
             }
             mWifiSignalController.resetLastState();
@@ -747,7 +777,8 @@
                     connected.set(mWifiSignalController.mTransportType);
                 }
                 mWifiSignalController.updateConnectivity(connected, connected);
-                for (MobileSignalController controller : mMobileSignalControllers.values()) {
+                for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                    MobileSignalController controller = mMobileSignalControllers.valueAt(i);
                     if (mDemoInetCondition) {
                         connected.set(controller.mTransportType);
                     }
@@ -820,8 +851,7 @@
                     mCallbackHandler.setSubs(subs);
                 }
                 // Hack to index linearly for easy use.
-                MobileSignalController controller = mMobileSignalControllers
-                        .values().toArray(new MobileSignalController[0])[slot];
+                MobileSignalController controller = mMobileSignalControllers.valueAt(slot);
                 controller.getState().dataSim = datatype != null;
                 controller.getState().isDefault = datatype != null;
                 controller.getState().dataConnected = datatype != null;
@@ -875,7 +905,8 @@
             String carrierNetworkChange = args.getString("carriernetworkchange");
             if (carrierNetworkChange != null) {
                 boolean show = carrierNetworkChange.equals("show");
-                for (MobileSignalController controller : mMobileSignalControllers.values()) {
+                for (int i = 0; i < mMobileSignalControllers.size(); i++) {
+                    MobileSignalController controller = mMobileSignalControllers.valueAt(i);
                     controller.setCarrierNetworkChangeMode(show);
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 6df4a21..a776e99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -59,7 +59,7 @@
 import com.android.systemui.SystemUISecondaryUserService;
 import com.android.systemui.plugins.qs.QS.DetailAdapter;
 import com.android.systemui.qs.tiles.UserDetailView;
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.phone.SystemUIDialog;
 import com.android.systemui.util.NotificationChannels;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index e6a3add..83cbd72 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -52,6 +52,14 @@
     private static final int NUMBER_OF_CHILDREN_WHEN_COLLAPSED = 2;
     private static final int NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED = 5;
     private static final int NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED = 8;
+    private static final AnimationProperties ALPHA_FADE_IN = new AnimationProperties() {
+        private AnimationFilter mAnimationFilter = new AnimationFilter().animateAlpha();
+
+        @Override
+        public AnimationFilter getAnimationFilter() {
+            return mAnimationFilter;
+        }
+    }.setDuration(200);
 
     private final List<View> mDividers = new ArrayList<>();
     private final List<ExpandableNotificationRow> mChildren = new ArrayList<>();
@@ -64,7 +72,7 @@
     private float mCollapsedBottompadding;
     private ViewInvertHelper mOverflowInvertHelper;
     private boolean mChildrenExpanded;
-    private ExpandableNotificationRow mNotificationParent;
+    private ExpandableNotificationRow mContainingNotification;
     private TextView mOverflowNumber;
     private ViewState mGroupOverFlowState;
     private int mRealHeight;
@@ -75,10 +83,15 @@
 
     private NotificationHeaderView mNotificationHeader;
     private NotificationViewWrapper mNotificationHeaderWrapper;
+    private NotificationHeaderView mNotificationHeaderLowPriority;
+    private NotificationViewWrapper mNotificationHeaderWrapperLowPriority;
     private NotificationHeaderUtil mHeaderUtil;
     private ViewState mHeaderViewState;
     private int mClipBottomAmount;
     private boolean mIsLowPriority;
+    private boolean mHeaderVisible = true;
+    private OnClickListener mHeaderClickListener;
+    private boolean mShowingNormalHeader;
 
     public NotificationChildrenContainer(Context context) {
         this(context, null);
@@ -135,6 +148,11 @@
             mNotificationHeader.layout(0, 0, mNotificationHeader.getMeasuredWidth(),
                     mNotificationHeader.getMeasuredHeight());
         }
+        if (mNotificationHeaderLowPriority != null) {
+            mNotificationHeaderLowPriority.layout(0, 0,
+                    mNotificationHeaderLowPriority.getMeasuredWidth(),
+                    mNotificationHeaderLowPriority.getMeasuredHeight());
+        }
     }
 
     @Override
@@ -178,10 +196,14 @@
             height = Math.min(height, size);
         }
 
+        int headerHeightSpec = MeasureSpec.makeMeasureSpec(mHeaderHeight, MeasureSpec.EXACTLY);
         if (mNotificationHeader != null) {
-            int headerHeightSpec = MeasureSpec.makeMeasureSpec(mHeaderHeight, MeasureSpec.EXACTLY);
             mNotificationHeader.measure(widthMeasureSpec, headerHeightSpec);
         }
+        if (mNotificationHeaderLowPriority != null) {
+            headerHeightSpec = MeasureSpec.makeMeasureSpec(mHeaderHeight, MeasureSpec.EXACTLY);
+            mNotificationHeaderLowPriority.measure(widthMeasureSpec, headerHeightSpec);
+        }
 
         setMeasuredDimension(width, height);
     }
@@ -247,30 +269,66 @@
         return mChildren.size();
     }
 
-    public void recreateNotificationHeader(OnClickListener listener,
-            StatusBarNotification notification) {
+    public void recreateNotificationHeader(OnClickListener listener) {
+        mHeaderClickListener = listener;
+        StatusBarNotification notification = mContainingNotification.getStatusBarNotification();
         final Notification.Builder builder = Notification.Builder.recoverBuilder(getContext(),
-                mNotificationParent.getStatusBarNotification().getNotification());
-        final RemoteViews header = mIsLowPriority
-                ? builder.makeLowPriorityContentView(true /* useRegularSubtext */)
-                : builder.makeNotificationHeader();
+                notification.getNotification());
+        RemoteViews header = builder.makeNotificationHeader();
         if (mNotificationHeader == null) {
             mNotificationHeader = (NotificationHeaderView) header.apply(getContext(), this);
             final View expandButton = mNotificationHeader.findViewById(
                     com.android.internal.R.id.expand_button);
             expandButton.setVisibility(VISIBLE);
-            mNotificationHeader.setOnClickListener(listener);
+            mNotificationHeader.setOnClickListener(mHeaderClickListener);
             mNotificationHeaderWrapper = NotificationViewWrapper.wrap(getContext(),
-                    mNotificationHeader, mNotificationParent);
+                    mNotificationHeader, mContainingNotification);
             addView(mNotificationHeader, 0);
             invalidate();
         } else {
             header.reapply(getContext(), mNotificationHeader);
-            mNotificationHeaderWrapper.notifyContentUpdated(notification, mIsLowPriority);
         }
+        mNotificationHeaderWrapper.notifyContentUpdated(mContainingNotification);
+        recreateLowPriorityHeader(builder);
+        updateHeaderVisibility(false /* animate */);
         updateChildrenHeaderAppearance();
     }
 
+    /**
+     * Recreate the low-priority header.
+     *
+     * @param builder a builder to reuse. Otherwise the builder will be recovered.
+     */
+    private void recreateLowPriorityHeader(Notification.Builder builder) {
+        RemoteViews header;
+        StatusBarNotification notification = mContainingNotification.getStatusBarNotification();
+        if (mIsLowPriority) {
+            if (builder == null) {
+                builder = Notification.Builder.recoverBuilder(getContext(),
+                        notification.getNotification());
+            }
+            header = builder.makeLowPriorityContentView(true /* useRegularSubtext */);
+            if (mNotificationHeaderLowPriority == null) {
+                mNotificationHeaderLowPriority = (NotificationHeaderView) header.apply(getContext(),
+                        this);
+                final View expandButton = mNotificationHeaderLowPriority.findViewById(
+                        com.android.internal.R.id.expand_button);
+                expandButton.setVisibility(VISIBLE);
+                mNotificationHeaderLowPriority.setOnClickListener(mHeaderClickListener);
+                mNotificationHeaderWrapperLowPriority = NotificationViewWrapper.wrap(getContext(),
+                        mNotificationHeaderLowPriority, mContainingNotification);
+                addView(mNotificationHeaderLowPriority, 0);
+                invalidate();
+            } else {
+                header.reapply(getContext(), mNotificationHeaderLowPriority);
+            }
+            mNotificationHeaderWrapperLowPriority.notifyContentUpdated(mContainingNotification);
+        } else {
+            mNotificationHeaderLowPriority = null;
+            mNotificationHeaderWrapperLowPriority = null;
+        }
+    }
+
     public void updateChildrenHeaderAppearance() {
         mHeaderUtil.updateChildrenHeaderAppearance();
     }
@@ -371,9 +429,6 @@
      * @return the intrinsic size of this children container, i.e the natural fully expanded state
      */
     public int getIntrinsicHeight() {
-        if (mIsLowPriority && !mChildrenExpanded) {
-            return mNotificationHeader.getHeight();
-        }
         int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren();
         return getIntrinsicHeight(maxAllowedVisibleChildren);
     }
@@ -383,6 +438,9 @@
      *         in @param maxAllowedVisibleChildren
      */
     private int getIntrinsicHeight(float maxAllowedVisibleChildren) {
+        if (showingAsLowPriority()) {
+            return mNotificationHeaderLowPriority.getHeight();
+        }
         int intrinsicHeight = mNotificationHeaderMargin;
         int visibleChildren = 0;
         int childCount = mChildren.size();
@@ -442,24 +500,25 @@
         int lastVisibleIndex = maxAllowedVisibleChildren - 1;
         int firstOverflowIndex = lastVisibleIndex + 1;
         float expandFactor = 0;
+        boolean expandingToExpandedGroup = mUserLocked && !showingAsLowPriority();
         if (mUserLocked) {
             expandFactor = getGroupExpandFraction();
             firstOverflowIndex = getMaxAllowedVisibleChildren(true /* likeCollapsed */);
         }
 
-        boolean childrenExpanded = !mNotificationParent.isGroupExpansionChanging()
+        boolean childrenExpanded = !mContainingNotification.isGroupExpansionChanging()
                 && mChildrenExpanded;
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             if (!firstChild) {
-                if (mUserLocked) {
+                if (expandingToExpandedGroup) {
                     yPosition += NotificationUtils.interpolate(mChildPadding, mDividerHeight,
                             expandFactor);
                 } else {
                     yPosition += mChildrenExpanded ? mDividerHeight : mChildPadding;
                 }
             } else {
-                if (mUserLocked) {
+                if (expandingToExpandedGroup) {
                     yPosition += NotificationUtils.interpolate(
                             0,
                             mNotificatonTopPadding + mDividerHeight,
@@ -478,7 +537,7 @@
             // When the group is expanded, the children cast the shadows rather than the parent
             // so use the parent's elevation here.
             childState.zTranslation = childrenExpanded
-                    ? mNotificationParent.getTranslationZ()
+                    ? mContainingNotification.getTranslationZ()
                     : 0;
             childState.dimmed = parentState.dimmed;
             childState.dark = parentState.dark;
@@ -487,7 +546,7 @@
             childState.clipTopAmount = 0;
             childState.alpha = 0;
             if (i < firstOverflowIndex) {
-                childState.alpha = mIsLowPriority && !mChildrenExpanded ? expandFactor : 1.0f;
+                childState.alpha = showingAsLowPriority() ? expandFactor : 1.0f;
             } else if (expandFactor == 1.0f && i <= lastVisibleIndex) {
                 childState.alpha = (mActualHeight - childState.yTranslation) / childState.height;
                 childState.alpha = Math.max(0.0f, Math.min(1.0f, childState.alpha));
@@ -526,7 +585,7 @@
             }
             mHeaderViewState.initFrom(mNotificationHeader);
             mHeaderViewState.zTranslation = childrenExpanded
-                    ? mNotificationParent.getTranslationZ()
+                    ? mContainingNotification.getTranslationZ()
                     : 0;
         }
     }
@@ -561,11 +620,11 @@
     }
 
     private int getMaxAllowedVisibleChildren(boolean likeCollapsed) {
-        if (!likeCollapsed && (mChildrenExpanded || mNotificationParent.isUserLocked())) {
+        if (!likeCollapsed && (mChildrenExpanded || mContainingNotification.isUserLocked())) {
             return NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
         }
-        if (!mNotificationParent.isOnKeyguard()
-                && (mNotificationParent.isExpanded() || mNotificationParent.isHeadsUp())) {
+        if (mIsLowPriority || !mContainingNotification.isOnKeyguard()
+                && (mContainingNotification.isExpanded() || mContainingNotification.isHeadsUp())) {
             return NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED;
         }
         return NUMBER_OF_CHILDREN_WHEN_COLLAPSED;
@@ -578,8 +637,8 @@
         if (mUserLocked) {
             expandFraction = getGroupExpandFraction();
         }
-        final boolean dividersVisible = mUserLocked
-                || mNotificationParent.isGroupExpansionChanging();
+        final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
+                || mContainingNotification.isGroupExpansionChanging();
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
@@ -590,7 +649,7 @@
             tmpState.initFrom(divider);
             tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
             float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
-            if (mUserLocked && viewState.alpha != 0) {
+            if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
                 alpha = NotificationUtils.interpolate(0, 0.5f,
                         Math.min(viewState.alpha, expandFraction));
             }
@@ -612,7 +671,7 @@
 
     private void updateChildrenClipping() {
         int childCount = mChildren.size();
-        int layoutEnd = mNotificationParent.getActualHeight() - mClipBottomAmount;
+        int layoutEnd = mContainingNotification.getActualHeight() - mClipBottomAmount;
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
             if (child.getVisibility() == GONE) {
@@ -652,8 +711,8 @@
         int childCount = mChildren.size();
         ViewState tmpState = new ViewState();
         float expandFraction = getGroupExpandFraction();
-        final boolean dividersVisible = mUserLocked
-                || mNotificationParent.isGroupExpansionChanging();
+        final boolean dividersVisible = mUserLocked && !showingAsLowPriority()
+                || mContainingNotification.isGroupExpansionChanging();
         for (int i = childCount - 1; i >= 0; i--) {
             ExpandableNotificationRow child = mChildren.get(i);
             ExpandableViewState viewState = state.getViewStateForView(child);
@@ -664,7 +723,7 @@
             tmpState.initFrom(divider);
             tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
             float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
-            if (mUserLocked && viewState.alpha != 0) {
+            if (mUserLocked && !showingAsLowPriority() && viewState.alpha != 0) {
                 alpha = NotificationUtils.interpolate(0, 0.5f,
                         Math.min(viewState.alpha, expandFraction));
             }
@@ -718,23 +777,100 @@
         }
     }
 
-    public void setNotificationParent(ExpandableNotificationRow parent) {
-        mNotificationParent = parent;
-        mHeaderUtil = new NotificationHeaderUtil(mNotificationParent);
+    public void setContainingNotification(ExpandableNotificationRow parent) {
+        mContainingNotification = parent;
+        mHeaderUtil = new NotificationHeaderUtil(mContainingNotification);
     }
 
-    public ExpandableNotificationRow getNotificationParent() {
-        return mNotificationParent;
+    public ExpandableNotificationRow getContainingNotification() {
+        return mContainingNotification;
     }
 
     public NotificationHeaderView getHeaderView() {
         return mNotificationHeader;
     }
 
-    public void updateHeaderVisibility(int visiblity) {
-        if (mNotificationHeader != null) {
-            mNotificationHeader.setVisibility(visiblity);
+    public NotificationHeaderView getLowPriorityHeaderView() {
+        return mNotificationHeaderLowPriority;
+    }
+
+    public void setHeaderVisible(boolean visible) {
+        mHeaderVisible = visible;
+        updateHeaderVisibility(false /* animate */);
+    }
+
+    private void updateHeaderVisibility(boolean animate) {
+        NotificationHeaderView visibleHeader = mNotificationHeader;
+        NotificationHeaderView hiddenHeader = mNotificationHeaderLowPriority;
+        boolean normalHeaderVisible = true;
+        if (showingAsLowPriority()) {
+            visibleHeader = mNotificationHeaderLowPriority;
+            hiddenHeader = mNotificationHeader;
+            normalHeaderVisible = false;
         }
+        if (animate) {
+            if (mHeaderVisible && visibleHeader != null && hiddenHeader != null
+                    && mShowingNormalHeader != normalHeaderVisible) {
+                hiddenHeader.setVisibility(VISIBLE);
+                visibleHeader.setVisibility(VISIBLE);
+                NotificationViewWrapper visibleWrapper = getWrapperForView(visibleHeader);
+                NotificationViewWrapper hiddenWrapper = getWrapperForView(hiddenHeader);
+                visibleWrapper.transformFrom(hiddenWrapper);
+                hiddenWrapper.transformTo(visibleWrapper, () -> updateHeaderVisibility(false));
+                startChildAlphaAnimations(normalHeaderVisible);
+            } else {
+                animate = false;
+            }
+        }
+        if (!animate) {
+            if (visibleHeader != null) {
+                getWrapperForView(visibleHeader).setVisible(true);
+                visibleHeader.setVisibility(mHeaderVisible ? VISIBLE : INVISIBLE);
+            }
+            if (hiddenHeader != null) {
+                getWrapperForView(hiddenHeader).setVisible(false);
+                hiddenHeader.setVisibility(INVISIBLE);
+            }
+        }
+        mShowingNormalHeader = normalHeaderVisible;
+    }
+
+    private void startChildAlphaAnimations(boolean toVisible) {
+        float target = toVisible ? 1.0f : 0.0f;
+        float start = 1.0f - target;
+        int childCount = mChildren.size();
+        for (int i = 0; i < childCount; i++) {
+            if (i >= NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED) {
+                break;
+            }
+            ExpandableNotificationRow child = mChildren.get(i);
+            child.setAlpha(start);
+            ViewState viewState = new ViewState();
+            viewState.initFrom(child);
+            viewState.alpha = target;
+            ALPHA_FADE_IN.setDelay(i * 50);
+            viewState.animateTo(child, ALPHA_FADE_IN);
+        }
+    }
+
+
+    private void updateHeaderTransformation() {
+        if (mUserLocked && mHeaderVisible && showingAsLowPriority()) {
+            float fraction = getGroupExpandFraction();
+            mNotificationHeaderWrapper.transformFrom(mNotificationHeaderWrapperLowPriority,
+                    fraction);
+            mNotificationHeader.setVisibility(VISIBLE);
+            mNotificationHeaderWrapperLowPriority.transformTo(mNotificationHeaderWrapper,
+                    fraction);
+        }
+
+    }
+
+    private NotificationViewWrapper getWrapperForView(NotificationHeaderView visibleHeader) {
+        if (visibleHeader == mNotificationHeader) {
+            return mNotificationHeaderWrapper;
+        }
+        return mNotificationHeaderWrapperLowPriority;
     }
 
     /**
@@ -746,7 +882,7 @@
         if (mNotificationHeader != null) {
             if (expanded) {
                 ColorDrawable cd = new ColorDrawable();
-                cd.setColor(mNotificationParent.calculateBgColor());
+                cd.setColor(mContainingNotification.calculateBgColor());
                 mNotificationHeader.setHeaderBackgroundDrawable(cd);
             } else {
                 mNotificationHeader.setHeaderBackgroundDrawable(null);
@@ -755,6 +891,10 @@
     }
 
     public int getMaxContentHeight() {
+        if (showingAsLowPriority()) {
+            return getMinHeight(NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED, true
+                    /* likeHighPriority */);
+        }
         int maxContentHeight = mNotificationHeaderMargin + mNotificatonTopPadding;
         int visibleChildren = 0;
         int childCount = mChildren.size();
@@ -781,13 +921,21 @@
         }
         mActualHeight = actualHeight;
         float fraction = getGroupExpandFraction();
+        boolean showingLowPriority = showingAsLowPriority();
+        updateHeaderTransformation();
         int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(true /* forceCollapsed */);
         int childCount = mChildren.size();
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
-            float childHeight = child.isExpanded(true /* allowOnKeyguard */)
-                    ? child.getMaxExpandHeight()
-                    : child.getShowingLayout().getMinHeight(true /* likeGroupExpanded */);
+            float childHeight;
+            if (showingLowPriority) {
+                childHeight = child.getShowingLayout().getMinHeight(false /* likeGroupExpanded */);
+            } else if (child.isExpanded(true /* allowOnKeyguard */)) {
+                childHeight = child.getMaxExpandHeight();
+            } else {
+                childHeight = child.getShowingLayout().getMinHeight(
+                        true /* likeGroupExpanded */);
+            }
             if (i < maxAllowedVisibleChildren) {
                 float singleLineHeight = child.getShowingLayout().getMinHeight(
                         false /* likeGroupExpanded */);
@@ -800,7 +948,8 @@
     }
 
     public float getGroupExpandFraction() {
-        int visibleChildrenExpandedHeight = getVisibleChildrenExpandHeight();
+        int visibleChildrenExpandedHeight = showingAsLowPriority() ? getMaxContentHeight()
+                : getVisibleChildrenExpandHeight();
         int minExpandHeight = getCollapsedHeight();
         float factor = (mActualHeight - minExpandHeight)
                 / (float) (visibleChildrenExpandedHeight - minExpandHeight);
@@ -827,16 +976,23 @@
     }
 
     public int getMinHeight() {
-        return getMinHeight(NUMBER_OF_CHILDREN_WHEN_COLLAPSED);
+        return getMinHeight(NUMBER_OF_CHILDREN_WHEN_COLLAPSED, false /* likeHighPriority */);
     }
 
     public int getCollapsedHeight() {
-        return getMinHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */));
+        return getMinHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */),
+                false /* likeHighPriority */);
     }
 
-    private int getMinHeight(int maxAllowedVisibleChildren) {
-        if (mIsLowPriority && !mChildrenExpanded) {
-            return mNotificationHeader.getHeight();
+    /**
+     * Get the minimum Height for this group.
+     *
+     * @param maxAllowedVisibleChildren the number of children that should be visible
+     * @param likeHighPriority if the height should be calculated as if it were not low priority
+     */
+    private int getMinHeight(int maxAllowedVisibleChildren, boolean likeHighPriority) {
+        if (!likeHighPriority && showingAsLowPriority()) {
+            return mNotificationHeaderLowPriority.getHeight();
         }
         int minExpandHeight = mNotificationHeaderMargin;
         int visibleChildren = 0;
@@ -859,6 +1015,10 @@
         return minExpandHeight;
     }
 
+    public boolean showingAsLowPriority() {
+        return mIsLowPriority && !mContainingNotification.isExpanded();
+    }
+
     public void setDark(boolean dark, boolean fade, long delay) {
         if (mOverflowNumber != null) {
             mOverflowInvertHelper.setInverted(dark, fade, delay);
@@ -867,9 +1027,15 @@
     }
 
     public void reInflateViews(OnClickListener listener, StatusBarNotification notification) {
-        removeView(mNotificationHeader);
-        mNotificationHeader = null;
-        recreateNotificationHeader(listener, notification);
+        if (mNotificationHeader != null) {
+            removeView(mNotificationHeader);
+            mNotificationHeader = null;
+        }
+        if (mNotificationHeaderLowPriority != null) {
+            removeView(mNotificationHeaderLowPriority);
+            mNotificationHeaderLowPriority = null;
+        }
+        recreateNotificationHeader(listener);
         initDimens();
         for (int i = 0; i < mDividers.size(); i++) {
             View prevDivider = mDividers.get(i);
@@ -888,16 +1054,19 @@
 
     public void setUserLocked(boolean userLocked) {
         mUserLocked = userLocked;
+        if (!mUserLocked) {
+            updateHeaderVisibility(false /* animate */);
+        }
         int childCount = mChildren.size();
         for (int i = 0; i < childCount; i++) {
             ExpandableNotificationRow child = mChildren.get(i);
-            child.setUserLocked(userLocked);
+            child.setUserLocked(userLocked && !showingAsLowPriority());
         }
     }
 
     public void onNotificationUpdated() {
         mHybridGroupManager.setOverflowNumberColor(mOverflowNumber,
-                mNotificationParent.getNotificationColor());
+                mContainingNotification.getNotificationColor());
     }
 
     public int getPositionInLinearLayout(View childInGroup) {
@@ -926,6 +1095,13 @@
                 header.getIcon().setForceHidden(!iconsVisible);
             }
         }
+        if (mNotificationHeaderWrapperLowPriority != null) {
+            NotificationHeaderView header
+                    = mNotificationHeaderWrapperLowPriority.getNotificationHeader();
+            if (header != null) {
+                header.getIcon().setForceHidden(!iconsVisible);
+            }
+        }
     }
 
     public void setClipBottomAmount(int clipBottomAmount) {
@@ -935,5 +1111,36 @@
 
     public void setIsLowPriority(boolean isLowPriority) {
         mIsLowPriority = isLowPriority;
+        if (mContainingNotification != null) { /* we're not yet set up yet otherwise */
+            recreateLowPriorityHeader(null /* existingBuilder */);
+            updateHeaderVisibility(false /* animate */);
+        }
+        if (mUserLocked) {
+            setUserLocked(mUserLocked);
+        }
+    }
+
+    public NotificationHeaderView getVisibleHeader() {
+        NotificationHeaderView header = mNotificationHeader;
+        if (showingAsLowPriority()) {
+            header = mNotificationHeaderLowPriority;
+        }
+        return header;
+    }
+
+    public void onExpansionChanged() {
+        if (mIsLowPriority) {
+            if (mUserLocked) {
+                setUserLocked(mUserLocked);
+            }
+            updateHeaderVisibility(true /* animate */);
+        }
+    }
+
+    public float getIncreasedPaddingAmount() {
+        if (showingAsLowPriority()) {
+            return 0.0f;
+        }
+        return getGroupExpandFraction();
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 48dbe49..d3b336b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -3416,6 +3416,7 @@
         for (View view : mClearOverlayViewsWhenFinished) {
             StackStateAnimator.removeFromOverlay(view);
         }
+        mClearOverlayViewsWhenFinished.clear();
     }
 
     private void runAnimationFinishedRunnables() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java
index e0a6159..c8659fb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/ViewState.java
@@ -136,7 +136,7 @@
         yTranslation = view.getTranslationY();
         zTranslation = view.getTranslationZ();
         gone = view.getVisibility() == View.GONE;
-        hidden = false;
+        hidden = view.getVisibility() == View.INVISIBLE;
         scaleX = view.getScaleX();
         scaleY = view.getScaleY();
     }
@@ -594,7 +594,7 @@
     }
 
     protected void onYTranslationAnimationFinished(View view) {
-        if (hidden) {
+        if (hidden && !gone) {
             view.setVisibility(View.INVISIBLE);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index 15ad0ce..5911766 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -36,19 +36,19 @@
         nm.createNotificationChannels(Arrays.asList(
                 new NotificationChannel(
                         ALERTS,
-                        context.getString(R.string.notification_channel_alerts),
+                        R.string.notification_channel_alerts,
                         NotificationManager.IMPORTANCE_HIGH),
                 new NotificationChannel(
                         SCREENSHOTS,
-                        context.getString(R.string.notification_channel_screenshot),
+                        R.string.notification_channel_screenshot,
                         NotificationManager.IMPORTANCE_LOW),
                 new NotificationChannel(
                         GENERAL,
-                        context.getString(R.string.notification_channel_general),
+                        R.string.notification_channel_general,
                         NotificationManager.IMPORTANCE_MIN),
                 new NotificationChannel(
                         STORAGE,
-                        context.getString(R.string.notification_channel_storage),
+                        R.string.notification_channel_storage,
                         NotificationManager.IMPORTANCE_LOW)
                 ));
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
index 0a1d34f..9d0ecec 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java
@@ -25,7 +25,7 @@
 import android.os.Handler;
 import android.view.WindowManager;
 
-import com.android.systemui.ActivityStarter;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.Dependency;
 import com.android.systemui.SystemUI;
 import com.android.systemui.SystemUIFactory;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
index 09ac5a6..053e5cf2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java
@@ -76,7 +76,7 @@
     public void testOneShot() {
         Plugin mockPlugin = mock(Plugin.class);
         when(mMockPluginInstance.getPlugin()).thenReturn(new PluginInfo(null, null, mockPlugin,
-                null));
+                null, null));
         Plugin result = mPluginManager.getOneShotPlugin("myAction", TestPlugin.class);
         assertTrue(result == mockPlugin);
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
index d07cea1..f016aa1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationCustomViewWrapperTest.java
@@ -52,11 +52,11 @@
         RemoteViews views = new RemoteViews(mContext.getPackageName(), R.layout.custom_view_dark);
         View v = views.apply(mContext, null);
         NotificationViewWrapper wrap = NotificationCustomViewWrapper.wrap(mContext, v, mRow);
-        wrap.notifyContentUpdated(null, false /* isLowPriority */);
+        wrap.notifyContentUpdated(mRow);
         Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
         views.reapply(mContext, v);
-        wrap.notifyContentUpdated(null, false /* isLowPriority */);
+        wrap.notifyContentUpdated(mRow);
         Assert.assertTrue(wrap.getCustomBackgroundColor() != 0);
     }
 
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 0491fc4..9a3fabb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -19,6 +19,8 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.Matchers.anyObject;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
@@ -98,6 +100,9 @@
         mNotificationChannel = new NotificationChannel(
                 TEST_CHANNEL, TEST_CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
         when(mMockStatusBarNotification.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
+        when(mMockPackageManager.getText(eq(TEST_PACKAGE_NAME),
+                eq(R.string.notification_menu_accessibility), anyObject())).thenReturn(
+                        getContext().getString(R.string.notification_menu_accessibility));
 
         when(mMockINotificationManager.getNumNotificationChannelsForPackage(
                 eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(1);
@@ -178,6 +183,19 @@
 
     @Test
     @UiThreadTest
+    public void testBindNotification_SetsTextChannelName_resId() throws Exception {
+        NotificationChannel notificationChannelResId = new NotificationChannel(
+                TEST_CHANNEL, R.string.notification_menu_accessibility,
+                NotificationManager.IMPORTANCE_LOW);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                mMockStatusBarNotification, notificationChannelResId, null, null, null);
+        final TextView textView = mNotificationInfo.findViewById(R.id.channel_name);
+        assertEquals(getContext().getString(R.string.notification_menu_accessibility),
+                textView.getText());
+    }
+
+    @Test
+    @UiThreadTest
     public void testBindNotification_SetsOnClickListenerForSettings() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
new file mode 100644
index 0000000..9a477d2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.systemui.statusbar.phone;
+
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+import com.android.internal.app.NightDisplayController;
+import com.android.systemui.Prefs;
+import com.android.systemui.Prefs.Key;
+import com.android.systemui.SysUIRunner;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+
+@RunWith(SysUIRunner.class)
+public class AutoTileManagerTest extends SysuiTestCase {
+
+    private QSTileHost mQsTileHost;
+    private AutoTileManager mAutoTileManager;
+
+    @Before
+    public void setUp() throws Exception {
+        Prefs.putBoolean(mContext, Key.QS_NIGHTDISPLAY_ADDED, false);
+        mQsTileHost = Mockito.mock(QSTileHost.class);
+        mAutoTileManager = new AutoTileManager(mContext, mQsTileHost);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mAutoTileManager = null;
+    }
+
+    @Test
+    public void nightTileAdded_whenActivated() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onActivated(true);
+        verify(mQsTileHost).addTile("night");
+    }
+
+    @Test
+    public void nightTileNotAdded_whenDeactivated() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onActivated(false);
+        verify(mQsTileHost, never()).addTile("night");
+    }
+
+    @Test
+    public void nightTileAdded_whenNightModeTwilight() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
+                NightDisplayController.AUTO_MODE_TWILIGHT);
+        verify(mQsTileHost).addTile("night");
+    }
+
+    @Test
+    public void nightTileAdded_whenNightModeCustom() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
+                NightDisplayController.AUTO_MODE_CUSTOM);
+        verify(mQsTileHost).addTile("night");
+    }
+
+    @Test
+    public void nightTileNotAdded_whenNightModeDisabled() {
+        if (!NightDisplayController.isAvailable(mContext)) {
+            return;
+        }
+        mAutoTileManager.mNightDisplayCallback.onAutoModeChanged(
+                NightDisplayController.AUTO_MODE_DISABLED);
+        verify(mQsTileHost, never()).addTile("night");
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index ba20999..e47f750 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -12,6 +12,7 @@
 
 import com.android.settingslib.net.DataUsageController;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -106,6 +107,7 @@
                 TelephonyIcons.QS_DATA_4G);
     }
 
+    @Ignore("Flaky")
     @Test
     public void testDataDisabledIcon() {
         setupNetworkController();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 2c0f9c9..1555856 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -94,6 +94,14 @@
     }
 
     @Test
+    public void testNoEmergencyOnlyWrongSubscription() {
+        setupDefaultSignal();
+        setDefaultSubId(42);
+        mNetworkController.recalculateEmergency();
+        verifyEmergencyOnly(false);
+    }
+
+    @Test
     public void testNoEmengencyNoSubscriptions() {
         setupDefaultSignal();
         setSubscriptions();
@@ -286,12 +294,12 @@
         for (int i = 0; i < testSubscriptions.length; i++) {
             if (i == indexToSkipController) {
                 // Make sure a controller was created despite us not adding one.
-                assertTrue(mNetworkController.mMobileSignalControllers.containsKey(
-                        testSubscriptions[i]));
+                assertTrue(mNetworkController.mMobileSignalControllers.indexOfKey(
+                        testSubscriptions[i]) >= 0);
             } else if (i == indexToSkipSubscription) {
                 // Make sure the controller that did exist was removed
-                assertFalse(mNetworkController.mMobileSignalControllers.containsKey(
-                        testSubscriptions[i]));
+                assertFalse(mNetworkController.mMobileSignalControllers.indexOfKey(
+                        testSubscriptions[i]) >= 0);
             } else {
                 // If a MobileSignalController is around it needs to not be unregistered.
                 Mockito.verify(mobileSignalControllers[i], Mockito.never())
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index c1c385a..2b219e6 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2157,7 +2157,7 @@
 
     // ACTION: Settings -> Select summary tab.
     // CATEGORY: SETTINGS
-    ACTION_SELECT_SUMMARY=476;
+    ACTION_SELECT_SUMMARY = 476;
 
     // ACTION: Settings -> Select support tab.
     // CATEGORY: SETTINGS
@@ -2208,7 +2208,7 @@
     NIGHT_DISPLAY_SETTINGS = 488;
 
     // ACTION: Settings -> Storage -> Manage storage -> Click Storage Manager
-        //   SUBTYPE: false is off, true is on
+    //   SUBTYPE: false is off, true is on
     ACTION_TOGGLE_STORAGE_MANAGER = 489;
 
     // Settings launched from collapsed quick settings.
@@ -3472,6 +3472,20 @@
     // FIELD: Whether developer mode has already been enabled when clicking build number preference
     FIELD_SETTINGS_BUILD_NUMBER_DEVELOPER_MODE_ENABLED = 848;
 
+    // OPEN: Settings > Wi-Fi > Network Details (click on Access Point)
+    // CATEGORY: SETTINGS
+    // OS: O
+    WIFI_NETWORK_DETAILS = 849;
+
+    // ACTION: Settings > Battery > Menu > Usage Alerts
+    ACTION_SETTINGS_MENU_BATTERY_USAGE_ALERTS = 850;
+
+    // ACTION: Settings > Battery > Menu > Optimization
+    ACTION_SETTINGS_MENU_BATTERY_OPTIMIZATION = 851;
+
+    // ACTION: Settings > Battery > Menu > Apps Toggle
+    ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE = 852;
+
     // ---- End O Constants, all O constants go above this line ----
 
     // Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 02223c1..5ffb738 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -856,6 +856,19 @@
             mFilterStats = fs;
             mAlarmType = alarmType;
         }
+
+        @Override
+        public String toString() {
+            return "InFlight{"
+                    + "pendingIntent=" + mPendingIntent
+                    + ", workSource=" + mWorkSource
+                    + ", uid=" + mUid
+                    + ", tag=" + mTag
+                    + ", broadcastStats=" + mBroadcastStats
+                    + ", filterStats=" + mFilterStats
+                    + ", alarmType=" + mAlarmType
+                    + "}";
+        }
     }
 
     static final class FilterStats {
@@ -873,6 +886,19 @@
             mBroadcastStats = broadcastStats;
             mTag = tag;
         }
+
+        @Override
+        public String toString() {
+            return "FilterStats{"
+                    + "tag=" + mTag
+                    + ", lastTime=" + lastTime
+                    + ", aggregateTime=" + aggregateTime
+                    + ", count=" + count
+                    + ", numWakeup=" + numWakeup
+                    + ", startTime=" + startTime
+                    + ", nesting=" + nesting
+                    + "}";
+        }
     }
 
     static final class BroadcastStats {
@@ -890,6 +916,19 @@
             mUid = uid;
             mPackageName = packageName;
         }
+
+        @Override
+        public String toString() {
+            return "BroadcastStats{"
+                    + "uid=" + mUid
+                    + ", packageName=" + mPackageName
+                    + ", aggregateTime=" + aggregateTime
+                    + ", count=" + count
+                    + ", numWakeup=" + numWakeup
+                    + ", startTime=" + startTime
+                    + ", nesting=" + nesting
+                    + "}";
+        }
     }
 
     final SparseArray<ArrayMap<String, BroadcastStats>> mBroadcastStats
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index dc0e3e1..de11f36 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -167,14 +167,10 @@
         }
     }
 
-    final SparseArray<ArrayList<Callback>> mOpModeWatchers
-            = new SparseArray<ArrayList<Callback>>();
-    final ArrayMap<String, ArrayList<Callback>> mPackageModeWatchers
-            = new ArrayMap<String, ArrayList<Callback>>();
-    final ArrayMap<IBinder, Callback> mModeWatchers
-            = new ArrayMap<IBinder, Callback>();
-    final SparseArray<SparseArray<Restriction>> mAudioRestrictions
-            = new SparseArray<SparseArray<Restriction>>();
+    final SparseArray<ArraySet<Callback>> mOpModeWatchers = new SparseArray<>();
+    final ArrayMap<String, ArraySet<Callback>> mPackageModeWatchers = new ArrayMap<>();
+    final ArrayMap<IBinder, Callback> mModeWatchers = new ArrayMap<>();
+    final SparseArray<SparseArray<Restriction>> mAudioRestrictions = new SparseArray<>();
 
     public final class Callback implements DeathRecipient {
         final IAppOpsCallback mCallback;
@@ -545,11 +541,11 @@
         ArrayMap<Callback, ArraySet<String>> callbackSpecs = null;
 
         synchronized (this) {
-            ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
+            ArraySet<Callback> callbacks = mOpModeWatchers.get(code);
             if (callbacks != null) {
                 final int callbackCount = callbacks.size();
                 for (int i = 0; i < callbackCount; i++) {
-                    Callback callback = callbacks.get(i);
+                    Callback callback = callbacks.valueAt(i);
                     ArraySet<String> changedPackages = new ArraySet<>();
                     Collections.addAll(changedPackages, uidPackageNames);
                     callbackSpecs = new ArrayMap<>();
@@ -565,7 +561,7 @@
                     }
                     final int callbackCount = callbacks.size();
                     for (int i = 0; i < callbackCount; i++) {
-                        Callback callback = callbacks.get(i);
+                        Callback callback = callbacks.valueAt(i);
                         ArraySet<String> changedPackages = callbackSpecs.get(callback);
                         if (changedPackages == null) {
                             changedPackages = new ArraySet<>();
@@ -623,17 +619,17 @@
             if (op != null) {
                 if (op.mode != mode) {
                     op.mode = mode;
-                    ArrayList<Callback> cbs = mOpModeWatchers.get(code);
+                    ArraySet<Callback> cbs = mOpModeWatchers.get(code);
                     if (cbs != null) {
                         if (repCbs == null) {
-                            repCbs = new ArrayList<Callback>();
+                            repCbs = new ArrayList<>();
                         }
                         repCbs.addAll(cbs);
                     }
                     cbs = mPackageModeWatchers.get(packageName);
                     if (cbs != null) {
                         if (repCbs == null) {
-                            repCbs = new ArrayList<Callback>();
+                            repCbs = new ArrayList<>();
                         }
                         repCbs.addAll(cbs);
                     }
@@ -666,7 +662,7 @@
 
     private static HashMap<Callback, ArrayList<ChangeRec>> addCallbacks(
             HashMap<Callback, ArrayList<ChangeRec>> callbacks,
-            int op, int uid, String packageName, ArrayList<Callback> cbs) {
+            int op, int uid, String packageName, ArraySet<Callback> cbs) {
         if (cbs == null) {
             return callbacks;
         }
@@ -674,8 +670,9 @@
             callbacks = new HashMap<>();
         }
         boolean duplicate = false;
-        for (int i=0; i<cbs.size(); i++) {
-            Callback cb = cbs.get(i);
+        final int N = cbs.size();
+        for (int i=0; i<N; i++) {
+            Callback cb = cbs.valueAt(i);
             ArrayList<ChangeRec> reports = callbacks.get(cb);
             if (reports == null) {
                 reports = new ArrayList<>();
@@ -830,17 +827,17 @@
                 mModeWatchers.put(callback.asBinder(), cb);
             }
             if (op != AppOpsManager.OP_NONE) {
-                ArrayList<Callback> cbs = mOpModeWatchers.get(op);
+                ArraySet<Callback> cbs = mOpModeWatchers.get(op);
                 if (cbs == null) {
-                    cbs = new ArrayList<Callback>();
+                    cbs = new ArraySet<>();
                     mOpModeWatchers.put(op, cbs);
                 }
                 cbs.add(cb);
             }
             if (packageName != null) {
-                ArrayList<Callback> cbs = mPackageModeWatchers.get(packageName);
+                ArraySet<Callback> cbs = mPackageModeWatchers.get(packageName);
                 if (cbs == null) {
-                    cbs = new ArrayList<Callback>();
+                    cbs = new ArraySet<>();
                     mPackageModeWatchers.put(packageName, cbs);
                 }
                 cbs.add(cb);
@@ -858,14 +855,14 @@
             if (cb != null) {
                 cb.unlinkToDeath();
                 for (int i=mOpModeWatchers.size()-1; i>=0; i--) {
-                    ArrayList<Callback> cbs = mOpModeWatchers.valueAt(i);
+                    ArraySet<Callback> cbs = mOpModeWatchers.valueAt(i);
                     cbs.remove(cb);
                     if (cbs.size() <= 0) {
                         mOpModeWatchers.removeAt(i);
                     }
                 }
                 for (int i=mPackageModeWatchers.size()-1; i>=0; i--) {
-                    ArrayList<Callback> cbs = mPackageModeWatchers.valueAt(i);
+                    ArraySet<Callback> cbs = mPackageModeWatchers.valueAt(i);
                     cbs.remove(cb);
                     if (cbs.size() <= 0) {
                         mPackageModeWatchers.removeAt(i);
@@ -2066,10 +2063,10 @@
                 for (int i=0; i<mOpModeWatchers.size(); i++) {
                     pw.print("    Op "); pw.print(AppOpsManager.opToName(mOpModeWatchers.keyAt(i)));
                     pw.println(":");
-                    ArrayList<Callback> callbacks = mOpModeWatchers.valueAt(i);
+                    ArraySet<Callback> callbacks = mOpModeWatchers.valueAt(i);
                     for (int j=0; j<callbacks.size(); j++) {
                         pw.print("      #"); pw.print(j); pw.print(": ");
-                        pw.println(callbacks.get(j));
+                        pw.println(callbacks.valueAt(j));
                     }
                 }
             }
@@ -2079,10 +2076,10 @@
                 for (int i=0; i<mPackageModeWatchers.size(); i++) {
                     pw.print("    Pkg "); pw.print(mPackageModeWatchers.keyAt(i));
                     pw.println(":");
-                    ArrayList<Callback> callbacks = mPackageModeWatchers.valueAt(i);
+                    ArraySet<Callback> callbacks = mPackageModeWatchers.valueAt(i);
                     for (int j=0; j<callbacks.size(); j++) {
                         pw.print("      #"); pw.print(j); pw.print(": ");
-                        pw.println(callbacks.get(j));
+                        pw.println(callbacks.valueAt(j));
                     }
                 }
             }
@@ -2310,23 +2307,23 @@
     }
 
     private void notifyWatchersOfChange(int code) {
-        final ArrayList<Callback> clonedCallbacks;
+        final ArraySet<Callback> clonedCallbacks;
         synchronized (this) {
-            ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
+            ArraySet<Callback> callbacks = mOpModeWatchers.get(code);
             if (callbacks == null) {
                 return;
             }
-            clonedCallbacks = new ArrayList<>(callbacks);
+            clonedCallbacks = new ArraySet<>(callbacks);
         }
 
         // There are components watching for mode changes such as window manager
         // and location manager which are in our process. The callbacks in these
-        // components may require permissions our remote caller does not have.s
+        // components may require permissions our remote caller does not have.
         final long identity = Binder.clearCallingIdentity();
         try {
             final int callbackCount = clonedCallbacks.size();
             for (int i = 0; i < callbackCount; i++) {
-                Callback callback = clonedCallbacks.get(i);
+                Callback callback = clonedCallbacks.valueAt(i);
                 try {
                     callback.mCallback.opChanged(code, -1, null);
                 } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index f315553..e8df38b 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -167,7 +167,7 @@
         }
 
         public String toString() {
-            return android.text.format.DateFormat.format("MM-dd hh:mm:ss ", mTimestamp) +
+            return android.text.format.DateFormat.format("MM-dd HH:mm:ss ", mTimestamp) +
                     (mEnable ? "  Enabled " : " Disabled ") + " by " + mPackageName;
         }
 
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index b95ed08..69e481f 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -28,6 +28,7 @@
 import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem;
 import com.android.internal.inputmethod.InputMethodUtils;
 import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.os.TransferPipe;
@@ -1262,13 +1263,14 @@
 
         Bundle extras = new Bundle();
         extras.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, true);
-        mImeSwitcherNotification = new Notification.Builder(mContext)
-            .setSmallIcon(com.android.internal.R.drawable.ic_notification_ime_default)
-            .setWhen(0)
-            .setOngoing(true)
-            .addExtras(extras)
-            .setCategory(Notification.CATEGORY_SYSTEM)
-            .setColor(com.android.internal.R.color.system_notification_accent_color);
+        mImeSwitcherNotification =
+                new Notification.Builder(mContext, SystemNotificationChannels.VIRTUAL_KEYBOARD)
+                        .setSmallIcon(com.android.internal.R.drawable.ic_notification_ime_default)
+                        .setWhen(0)
+                        .setOngoing(true)
+                        .addExtras(extras)
+                        .setCategory(Notification.CATEGORY_SYSTEM)
+                        .setColor(com.android.internal.R.color.system_notification_accent_color);
 
         Intent intent = new Intent(Settings.ACTION_SHOW_INPUT_METHOD_PICKER);
         mImeSwitchPendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index f76ddc7..0a9610f 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -76,6 +76,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.ICheckCredentialProgressCallback;
 import com.android.internal.widget.ILockSettings;
@@ -442,21 +443,20 @@
         // Suppress all notifications on non-FBE devices for now
         if (!StorageManager.isFileEncryptedNativeOrEmulated()) return;
 
-        Notification notification = new Notification.Builder(mContext)
-                .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
-                .setWhen(0)
-                .setOngoing(true)
-                .setTicker(title)
-                .setDefaults(0) // please be quiet
-                .setPriority(Notification.PRIORITY_MAX)
-                .setColor(mContext.getColor(
-                        com.android.internal.R.color.system_notification_accent_color))
-                .setContentTitle(title)
-                .setContentText(message)
-                .setSubText(detail)
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setContentIntent(intent)
-                .build();
+        Notification notification =
+                new Notification.Builder(mContext, SystemNotificationChannels.SECURITY)
+                        .setSmallIcon(com.android.internal.R.drawable.ic_user_secure)
+                        .setWhen(0)
+                        .setOngoing(true)
+                        .setTicker(title)
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(message)
+                        .setSubText(detail)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setContentIntent(intent)
+                        .build();
         mNotificationManager.notifyAsUser(null, FBE_ENCRYPTED_NOTIFICATION, notification, user);
     }
 
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index d54ebaa..b83dbd6 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -663,12 +663,12 @@
     @Override
     public boolean setActiveScorer(String packageName) {
         // Only the system can set the active scorer
-        if (isCallerSystemProcess(getCallingUid()) || callerCanRequestScores()) {
-            return mNetworkScorerAppManager.setActiveScorer(packageName);
-        } else {
+        if (!isCallerSystemProcess(getCallingUid()) || !callerCanRequestScores()) {
             throw new SecurityException(
                     "Caller is neither the system process nor a score requester.");
         }
+
+        return mNetworkScorerAppManager.setActiveScorer(packageName);
     }
 
     /**
@@ -732,23 +732,23 @@
     @Override
     public List<NetworkScorerAppData> getAllValidScorers() {
         // Only the system can access this data.
-        if (isCallerSystemProcess(getCallingUid()) || callerCanRequestScores()) {
-            return mNetworkScorerAppManager.getAllValidScorers();
-        } else {
+        if (!isCallerSystemProcess(getCallingUid()) || !callerCanRequestScores()) {
             throw new SecurityException(
                     "Caller is neither the system process nor a score requester.");
         }
+
+        return mNetworkScorerAppManager.getAllValidScorers();
     }
 
     @Override
     public void disableScoring() {
         // Only the active scorer or the system should be allowed to disable scoring.
-        if (isCallerActiveScorer(getCallingUid()) || callerCanRequestScores()) {
-            // no-op for now but we could write to the setting if needed.
-        } else {
+        if (!isCallerActiveScorer(getCallingUid()) || !callerCanRequestScores()) {
             throw new SecurityException(
                     "Caller is neither the active scorer nor the scorer manager.");
         }
+
+        // no-op for now but we could write to the setting if needed.
     }
 
     /** Clear scores. Callers are responsible for checking permissions as appropriate. */
diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java
index 2f4485a..90a33a4 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -85,11 +85,12 @@
                 }
                 final ComponentName serviceComponentName =
                         new ComponentName(serviceInfo.packageName, serviceInfo.name);
+                final String serviceLabel = getRecommendationServiceLabel(serviceInfo, pm);
                 final ComponentName useOpenWifiNetworksActivity =
                         findUseOpenWifiNetworksActivity(serviceInfo);
                 appDataList.add(
                         new NetworkScorerAppData(serviceInfo.applicationInfo.uid,
-                                serviceComponentName, useOpenWifiNetworksActivity));
+                                serviceComponentName, serviceLabel, useOpenWifiNetworksActivity));
             } else {
                 if (VERBOSE) Log.v(TAG, serviceInfo.packageName
                         + " is NOT a valid scorer/recommender.");
@@ -100,6 +101,19 @@
     }
 
     @Nullable
+    private String getRecommendationServiceLabel(ServiceInfo serviceInfo, PackageManager pm) {
+        if (serviceInfo.metaData != null) {
+            final String label = serviceInfo.metaData
+                    .getString(NetworkScoreManager.RECOMMENDATION_SERVICE_LABEL_META_DATA);
+            if (!TextUtils.isEmpty(label)) {
+                return label;
+            }
+        }
+        CharSequence label = serviceInfo.loadLabel(pm);
+        return label == null ? null : label.toString();
+    }
+
+    @Nullable
     private ComponentName findUseOpenWifiNetworksActivity(ServiceInfo serviceInfo) {
         if (serviceInfo.metaData == null) {
             if (DEBUG) {
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index acacb9e..5115fde 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -58,6 +58,7 @@
 
 import com.android.internal.R;
 import com.android.internal.app.DisableCarModeActivity;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.server.power.ShutdownThread;
 import com.android.server.twilight.TwilightListener;
 import com.android.server.twilight.TwilightManager;
@@ -739,7 +740,8 @@
             if (mCarModeEnabled) {
                 Intent carModeOffIntent = new Intent(context, DisableCarModeActivity.class);
 
-                Notification.Builder n = new Notification.Builder(context)
+                Notification.Builder n =
+                        new Notification.Builder(context, SystemNotificationChannels.CAR_MODE)
                         .setSmallIcon(R.drawable.stat_notify_car_mode)
                         .setDefaults(Notification.DEFAULT_LIGHTS)
                         .setOngoing(true)
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 1b2c75d..dc73b63 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -92,6 +92,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Preconditions;
@@ -2780,16 +2781,17 @@
         }
         UserHandle user = UserHandle.of(userId);
         Context contextForUser = getContextForUser(user);
-        Notification n = new Notification.Builder(contextForUser)
-                .setSmallIcon(android.R.drawable.stat_sys_warning)
-                .setWhen(0)
-                .setColor(contextForUser.getColor(
-                        com.android.internal.R.color.system_notification_accent_color))
-                .setContentTitle(title)
-                .setContentText(subtitle)
-                .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, intent,
-                        PendingIntent.FLAG_CANCEL_CURRENT, null, user))
-                .build();
+        Notification n =
+                new Notification.Builder(contextForUser, SystemNotificationChannels.ACCOUNT)
+                    .setSmallIcon(android.R.drawable.stat_sys_warning)
+                    .setWhen(0)
+                    .setColor(contextForUser.getColor(
+                            com.android.internal.R.color.system_notification_accent_color))
+                    .setContentTitle(title)
+                    .setContentText(subtitle)
+                    .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0, intent,
+                            PendingIntent.FLAG_CANCEL_CURRENT, null, user))
+                    .build();
         installNotification(getCredentialPermissionNotificationId(
                 account, authTokenType, uid), n, packageName, user.getIdentifier());
     }
@@ -4844,7 +4846,8 @@
 
                 final String notificationTitleFormat =
                         contextForUser.getText(R.string.notification_title).toString();
-                Notification n = new Notification.Builder(contextForUser)
+                Notification n =
+                        new Notification.Builder(contextForUser, SystemNotificationChannels.ACCOUNT)
                         .setWhen(0)
                         .setSmallIcon(android.R.drawable.stat_sys_warning)
                         .setColor(contextForUser.getColor(
@@ -4864,6 +4867,7 @@
 
     private void installNotification(int notificationId, final Notification notification,
             String packageName, int userId) {
+        SystemNotificationChannels.createAccountChannelForPackage(packageName, mContext);
         final long token = clearCallingIdentity();
         try {
             INotificationManager notificationManager = mInjector.getNotificationManager();
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 2bc131f..b4f8f61 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2810,14 +2810,13 @@
     }
 
     List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, int flags,
-        int callingUid, boolean allowed) {
+        int callingUid, boolean allowed, boolean canInteractAcrossUsers) {
         ArrayList<ActivityManager.RunningServiceInfo> res
                 = new ArrayList<ActivityManager.RunningServiceInfo>();
 
         final long ident = Binder.clearCallingIdentity();
         try {
-            if (ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid)
-                == PERMISSION_GRANTED) {
+            if (canInteractAcrossUsers) {
                 int[] users = mAm.mUserController.getUsers();
                 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
                     ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(users[ui]);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d9b6fd7..88ceb6f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -47,6 +47,8 @@
 import static android.os.Process.PROC_OUT_LONG;
 import static android.os.Process.PROC_PARENS;
 import static android.os.Process.PROC_SPACE_TERM;
+import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
+import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
 import static android.provider.Settings.Global.DEBUG_APP;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
@@ -314,11 +316,13 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.internal.notification.SystemNotificationChannels;
 import com.google.android.collect.Lists;
 import com.google.android.collect.Maps;
 
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.AssistUtils;
 import com.android.internal.app.DumpHeapActivity;
 import com.android.internal.app.IAppOpsCallback;
@@ -1440,6 +1444,17 @@
 
     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
 
+    /**
+     * A global counter for generating sequence numbers.
+     * This value will be used when incrementing sequence numbers in individual uidRecords.
+     *
+     * Having a global counter ensures that seq numbers are monotonically increasing for a
+     * particular uid even when the uidRecord is re-created.
+     */
+    @GuardedBy("this")
+    @VisibleForTesting
+    long mProcStateSeqCounter = 0;
+
     static final class ProcessChangeItem {
         static final int CHANGE_ACTIVITIES = 1<<0;
         int changes;
@@ -1972,7 +1987,8 @@
                     Context context = mContext.createPackageContext(process.info.packageName, 0);
                     String text = mContext.getString(R.string.heavy_weight_notification,
                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
-                    Notification notification = new Notification.Builder(context)
+                    Notification notification =
+                            new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                             .setWhen(0)
                             .setOngoing(true)
@@ -2222,7 +2238,8 @@
                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
                 }
                 int userId = UserHandle.getUserId(uid);
-                Notification notification = new Notification.Builder(mContext)
+                Notification notification =
+                        new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                         .setWhen(0)
                         .setOngoing(true)
@@ -2603,6 +2620,33 @@
         }
     }
 
+    @VisibleForTesting
+    public ActivityManagerService() {
+        GL_ES_VERSION = 0;
+        mActivityStarter = null;
+        mAppErrors = null;
+        mAppOpsService = null;
+        mBatteryStatsService = null;
+        mCompatModePackages = null;
+        mConstants = null;
+        mGrantFile = null;
+        mHandler = null;
+        mHandlerThread = null;
+        mIntentFirewall = null;
+        mKeyguardController = null;
+        mPermissionReviewRequired = false;
+        mProcessCpuThread = null;
+        mProcessStats = null;
+        mProviderMap = null;
+        mRecentTasks = null;
+        mServices = null;
+        mStackSupervisor = null;
+        mSystemThread = null;
+        mTaskChangeNotificationController = null;
+        mUiHandler = null;
+        mUserController = null;
+    }
+
     // Note: This method is invoked on the main thread but may need to attach various
     // handlers to other threads.  So take care to be explicit about the looper.
     public ActivityManagerService(Context systemContext) {
@@ -3028,7 +3072,7 @@
                 final IVoiceInteractionSession session;
 
                 if (mLastResumedActivity.task != null
-                    && mLastResumedActivity.task.voiceSession != null) {
+                        && mLastResumedActivity.task.voiceSession != null) {
                     session = mLastResumedActivity.task.voiceSession;
                 } else {
                     session = mLastResumedActivity.voiceSession;
@@ -10711,6 +10755,7 @@
         try {
             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
+                            | PackageManager.MATCH_DISABLED_COMPONENTS
                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
                     userId);
@@ -14394,7 +14439,8 @@
         boolean dumpClient = false;
         boolean dumpCheckin = false;
         boolean dumpCheckinFormat = false;
-        boolean dumpVisibleStacks = false;
+        boolean dumpVisibleStacksOnly = false;
+        boolean dumpFocusedStackOnly = false;
         String dumpPackage = null;
 
         int opti = 0;
@@ -14409,7 +14455,9 @@
             } else if ("-c".equals(opt)) {
                 dumpClient = true;
             } else if ("-v".equals(opt)) {
-                dumpVisibleStacks = true;
+                dumpVisibleStacksOnly = true;
+            } else if ("-f".equals(opt)) {
+                dumpFocusedStackOnly = true;
             } else if ("-p".equals(opt)) {
                 if (opti < args.length) {
                     dumpPackage = args[opti];
@@ -14600,7 +14648,8 @@
                 LockGuard.dump(fd, pw, args);
             } else {
                 // Dumping a single activity?
-                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacks)) {
+                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
+                        dumpFocusedStackOnly)) {
                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
                     int res = shell.exec(this, null, fd, null, args, null,
                             new ResultReceiver(null));
@@ -15539,13 +15588,17 @@
      *  - the cmd arg isn't the flattened component name of an existing activity:
      *    dump all activity whose component contains the cmd as a substring
      *  - A hex number of the ActivityRecord object instance.
+     *
+     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
+     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
      */
     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
-            int opti, boolean dumpAll, boolean dumpVisibleStacks) {
+            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
         ArrayList<ActivityRecord> activities;
 
         synchronized (this) {
-            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacks);
+            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
+                    dumpFocusedStackOnly);
         }
 
         if (activities.size() <= 0) {
@@ -17505,12 +17558,15 @@
     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
             int flags) {
         enforceNotIsolatedCaller("getServices");
-        synchronized (this) {
-            final int callingUid = Binder.getCallingUid();
-            final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
-                callingUid);
 
-            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, allowed);
+        final int callingUid = Binder.getCallingUid();
+        final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
+            INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
+        final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
+            callingUid);
+        synchronized (this) {
+            return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
+                allowed, canInteractAcrossUsers);
         }
     }
 
@@ -18031,15 +18087,18 @@
             } else if (rl.uid != callingUid) {
                 throw new IllegalArgumentException(
                         "Receiver requested to register for uid " + callingUid
-                        + " was previously registered for uid " + rl.uid);
+                        + " was previously registered for uid " + rl.uid
+                        + " callerPackage is " + callerPackage);
             } else if (rl.pid != callingPid) {
                 throw new IllegalArgumentException(
                         "Receiver requested to register for pid " + callingPid
-                        + " was previously registered for pid " + rl.pid);
+                        + " was previously registered for pid " + rl.pid
+                        + " callerPackage is " + callerPackage);
             } else if (rl.userId != userId) {
                 throw new IllegalArgumentException(
                         "Receiver requested to register for user " + userId
-                        + " was previously registered for user " + rl.userId);
+                        + " was previously registered for user " + rl.userId
+                        + " callerPackage is " + callerPackage);
             }
             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                     permission, callingUid, userId);
@@ -18776,7 +18835,7 @@
         final boolean replacePending =
                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
 
-        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
+        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
                 + " replacePending=" + replacePending);
 
         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
@@ -19084,14 +19143,7 @@
             }
 
             if (doNext) {
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
-                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
-                      String.format("ProcessBroadcast from %s (%s) %s", r.callerPackage,
-                        r.callerApp == null ? "caller unknown" : r.callerApp.toShortString(),
-                        r.intent == null ? "" : r.intent.toString()));
-                }
                 r.queue.processNextBroadcast(false);
-                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
             }
             trimApplications();
         } finally {
@@ -19729,7 +19781,7 @@
         mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
 
         final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
-        if (isDensityChange) {
+        if (isDensityChange && displayId == DEFAULT_DISPLAY) {
             // Reset the unsupported display size dialog.
             mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
 
@@ -21742,6 +21794,10 @@
             }
         }
 
+        for (int i = mActiveUids.size() - 1; i >= 0; --i) {
+            incrementProcStateSeqIfNeeded(mActiveUids.valueAt(i));
+        }
+
         mNumServiceProcs = mNewNumServiceProcs;
 
         // Now determine the memory trimming level of background processes.
@@ -22091,6 +22147,42 @@
         }
     }
 
+    /**
+     * If {@link UidRecord#curProcStateSeq} needs to be updated, then increments the global seq
+     * counter {@link #mProcStateSeqCounter} and uses that value for {@param uidRec}.
+     */
+    @VisibleForTesting
+    void incrementProcStateSeqIfNeeded(UidRecord uidRec) {
+        if (uidRec.curProcState != uidRec.setProcState && shouldIncrementProcStateSeq(uidRec)) {
+            uidRec.curProcStateSeq = ++mProcStateSeqCounter;
+        }
+    }
+
+    /**
+     * Checks if {@link UidRecord#curProcStateSeq} needs to be incremented depending on whether
+     * the uid is coming from background to foreground state or vice versa.
+     *
+     * @return Returns true if the uid is coming from background to foreground state or vice versa,
+     *                 false otherwise.
+     */
+    @VisibleForTesting
+    boolean shouldIncrementProcStateSeq(UidRecord uidRec) {
+        final boolean isAllowedOnRestrictBackground
+                = isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
+        final boolean isAllowedOnDeviceIdleOrPowerSaveMode
+                = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState);
+
+        final boolean wasAllowedOnRestrictBackground
+                = isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
+        final boolean wasAllowedOnDeviceIdleOrPowerSaveMode
+                = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState);
+
+        // If the uid is coming from background to foreground or vice versa,
+        // then return true. Otherwise false.
+        return (wasAllowedOnDeviceIdleOrPowerSaveMode != isAllowedOnDeviceIdleOrPowerSaveMode)
+                || (wasAllowedOnRestrictBackground != isAllowedOnRestrictBackground);
+    }
+
     final void runInBackgroundDisabled(int uid) {
         synchronized (this) {
             UidRecord uidRec = mActiveUids.get(uid);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 10055c8..fa7dd28 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -2019,6 +2019,12 @@
 
         // Okay we now are going to make this activity have the new config.
         // But then we need to figure out how it needs to deal with that.
+
+        // Find changes between last reported merged configuration and the current one. This is used
+        // to decide whether to relaunch an activity or just report a configuration change.
+        final int changes = getTaskConfigurationChanges(mTmpConfig1);
+
+        // Update last reported values.
         final Configuration newGlobalConfig = service.getGlobalConfiguration();
         final Configuration newTaskMergedOverrideConfig = task.getMergedOverrideConfiguration();
         mTmpConfig1.setTo(mLastReportedConfiguration);
@@ -2026,9 +2032,6 @@
         mLastReportedConfiguration.setTo(newGlobalConfig);
         mLastReportedOverrideConfiguration.setTo(newTaskMergedOverrideConfig);
 
-        int taskChanges = getTaskConfigurationChanges(this, newTaskMergedOverrideConfig,
-                mTmpConfig2);
-        final int changes = mTmpConfig1.diff(newGlobalConfig) | taskChanges;
         if (changes == 0 && !forceNewConfig) {
             if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                     "Configuration no differences in " + this);
@@ -2043,8 +2046,7 @@
         }
 
         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
-                "Configuration changes for " + this + " ; taskChanges="
-                        + Configuration.configurationDiffToString(taskChanges) + ", allChanges="
+                "Configuration changes for " + this + ", allChanges="
                         + Configuration.configurationDiffToString(changes));
 
         // If the activity isn't currently running, just leave the new configuration and it will
@@ -2142,40 +2144,27 @@
         return (changes&(~configChanged)) != 0;
     }
 
-    private static int getTaskConfigurationChanges(ActivityRecord record, Configuration taskConfig,
-            Configuration oldTaskOverride) {
-        // If we went from full-screen to non-full-screen, make sure to use the correct
-        // configuration task diff, so the diff stays as small as possible.
-        if (Configuration.EMPTY.equals(oldTaskOverride)
-                && !Configuration.EMPTY.equals(taskConfig)) {
-            oldTaskOverride = record.task.extractOverrideConfig(record.mLastReportedConfiguration);
-        }
-
-        // Conversely, do the same when going the other direction.
-        if (Configuration.EMPTY.equals(taskConfig)
-                && !Configuration.EMPTY.equals(oldTaskOverride)) {
-            taskConfig = record.task.extractOverrideConfig(record.mLastReportedConfiguration);
-        }
-
+    private int getTaskConfigurationChanges(Configuration newTaskConfig) {
         // Determine what has changed.  May be nothing, if this is a config that has come back from
         // the app after going idle.  In that case we just want to leave the official config object
         // now in the activity and do nothing else.
-        int taskChanges = oldTaskOverride.diff(taskConfig, true /* skipUndefined */);
+        final Configuration oldTaskConfig = task.getConfiguration();
+        int taskChanges = oldTaskConfig.diff(newTaskConfig, true /* skipUndefined */);
         // We don't want to use size changes if they don't cross boundaries that are important to
         // the app.
         if ((taskChanges & CONFIG_SCREEN_SIZE) != 0) {
-            final boolean crosses = record.crossesHorizontalSizeThreshold(
-                    oldTaskOverride.screenWidthDp, taskConfig.screenWidthDp)
-                    || record.crossesVerticalSizeThreshold(
-                    oldTaskOverride.screenHeightDp, taskConfig.screenHeightDp);
+            final boolean crosses = crossesHorizontalSizeThreshold(oldTaskConfig.screenWidthDp,
+                    newTaskConfig.screenWidthDp)
+                    || crossesVerticalSizeThreshold(oldTaskConfig.screenHeightDp,
+                    newTaskConfig.screenHeightDp);
             if (!crosses) {
                 taskChanges &= ~CONFIG_SCREEN_SIZE;
             }
         }
         if ((taskChanges & CONFIG_SMALLEST_SCREEN_SIZE) != 0) {
-            final int oldSmallest = oldTaskOverride.smallestScreenWidthDp;
-            final int newSmallest = taskConfig.smallestScreenWidthDp;
-            if (!record.crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
+            final int oldSmallest = oldTaskConfig.smallestScreenWidthDp;
+            final int newSmallest = newTaskConfig.smallestScreenWidthDp;
+            if (!crossesSmallestSizeThreshold(oldSmallest, newSmallest)) {
                 taskChanges &= ~CONFIG_SMALLEST_SCREEN_SIZE;
             }
         }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 7f7caff..827a41e 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3827,7 +3827,9 @@
         r.app = null;
         r.removeWindowContainer();
         final TaskRecord task = r.task;
-        if (task != null && task.removeActivity(r)) {
+        final boolean lastActivity = task != null ? task.removeActivity(r) : false;
+
+        if (lastActivity) {
             if (DEBUG_STACK) Slog.i(TAG_STACK,
                     "removeActivityFromHistoryLocked: last activity removed from " + this);
             if (mStackSupervisor.isFocusedStack(this) && task == topTask() &&
@@ -4819,7 +4821,7 @@
     }
 
     ArrayList<ActivityRecord> getDumpActivitiesLocked(String name) {
-        ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
+        ArrayList<ActivityRecord> activities = new ArrayList<>();
 
         if ("all".equals(name)) {
             for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index ab1559d..d3ad057 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3521,22 +3521,24 @@
      * Dumps the activities matching the given {@param name} in the either the focused stack
      * or all visible stacks if {@param dumpVisibleStacks} is true.
      */
-    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name, boolean dumpVisibleStacks) {
-        if (dumpVisibleStacks) {
+    ArrayList<ActivityRecord> getDumpActivitiesLocked(String name, boolean dumpVisibleStacksOnly,
+            boolean dumpFocusedStackOnly) {
+        if (dumpFocusedStackOnly) {
+            return mFocusedStack.getDumpActivitiesLocked(name);
+        } else {
             ArrayList<ActivityRecord> activities = new ArrayList<>();
             int numDisplays = mActivityDisplays.size();
             for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
                 ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
                 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                     ActivityStack stack = stacks.get(stackNdx);
-                    if (stack.getStackVisibilityLocked(null) == STACK_VISIBLE) {
+                    if (!dumpVisibleStacksOnly ||
+                            stack.getStackVisibilityLocked(null) == STACK_VISIBLE) {
                         activities.addAll(stack.getDumpActivitiesLocked(name));
                     }
                 }
             }
             return activities;
-        } else {
-            return mFocusedStack.getDumpActivitiesLocked(name);
         }
     }
 
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index d8c5533..857241a 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -100,7 +100,6 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.AuxiliaryResolveInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
@@ -509,22 +508,23 @@
         doPendingActivityLaunchesLocked(false);
 
         return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
-            options, inTask);
+                options, inTask);
     }
 
-    /** Creates a launch intent for the given auxiliary resolution data. */
+    /**
+     * Creates a launch intent for the given auxiliary resolution data.
+     */
     private @NonNull Intent createLaunchIntent(@NonNull AuxiliaryResolveInfo auxiliaryResponse,
-        Intent originalIntent, String callingPackage,
-        String resolvedType, int userId) {
+            Intent originalIntent, String callingPackage, String resolvedType, int userId) {
         if (auxiliaryResponse.needsPhaseTwo) {
             // request phase two resolution
             mService.getPackageManagerInternalLocked().requestInstantAppResolutionPhaseTwo(
-                auxiliaryResponse, originalIntent, resolvedType, callingPackage, userId);
+                    auxiliaryResponse, originalIntent, resolvedType, callingPackage, userId);
         }
         return EphemeralResolver.buildEphemeralInstallerIntent(originalIntent,
-            callingPackage, resolvedType, userId, auxiliaryResponse.packageName,
-            auxiliaryResponse.splitName, auxiliaryResponse.versionCode,
-            auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
+                callingPackage, resolvedType, userId, auxiliaryResponse.packageName,
+                auxiliaryResponse.splitName, auxiliaryResponse.versionCode,
+                auxiliaryResponse.token, auxiliaryResponse.needsPhaseTwo);
     }
 
     void postStartActivityProcessing(
@@ -930,14 +930,13 @@
     }
 
     private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
-        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
-        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
+            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
+            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
         int result = START_CANCELED;
         try {
             mService.mWindowManager.deferSurfaceLayout();
             result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
-                startFlags,
-                doResume, options, inTask);
+                    startFlags, doResume, options, inTask);
         } finally {
             // If we are not able to proceed, disassociate the activity from the task. Leaving an
             // activity in an incomplete state can lead to issues, such as performing operations
@@ -948,8 +947,8 @@
             mService.mWindowManager.continueSurfaceLayout();
         }
 
-        postStartActivityProcessing(r, result, mSupervisor.mFocusedStack.mStackId,
-            mSourceRecord, mTargetStack);
+        postStartActivityProcessing(r, result, mSupervisor.mFocusedStack.mStackId,  mSourceRecord,
+                mTargetStack);
 
         return result;
     }
@@ -1000,11 +999,22 @@
             if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
                     || isDocumentLaunchesIntoExisting(mLaunchFlags)
                     || mLaunchSingleInstance || mLaunchSingleTask) {
+                final TaskRecord task = mReusedActivity.task;
+
                 // In this situation we want to remove all activities from the task up to the one
                 // being started. In most cases this means we are resetting the task to its initial
                 // state.
-                final ActivityRecord top = mReusedActivity.task.performClearTaskForReuseLocked(
-                        mStartActivity, mLaunchFlags);
+                final ActivityRecord top = task.performClearTaskForReuseLocked(mStartActivity,
+                        mLaunchFlags);
+
+                // The above code can remove {@code mReusedActivity} from the task, leading to the
+                // the {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The
+                // task reference is needed in the call below to
+                // {@link setTargetStackAndMoveToFrontIfNeeded}.
+                if (mReusedActivity.task == null) {
+                    mReusedActivity.task = task;
+                }
+
                 if (top != null) {
                     if (top.frontOfTask) {
                         // Activity aliases may mean we use different intents for the top activity,
@@ -1562,6 +1572,9 @@
                 // running, and the caller has asked to clear the current task to have this
                 // activity at the top.
                 mAddingToTask = true;
+
+                // We are no longer placing the activity in the task we previously thought we were.
+                mStartActivity.task = null;
                 // Now pretend like this activity is being started by the top of its task, so it
                 // is put in the right place.
                 mSourceRecord = intentActivity;
@@ -1862,7 +1875,7 @@
             final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
             try {
                 startActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null,
-                    null);
+                        null);
             } catch (Exception e) {
                 Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
                 pal.sendErrorResult(e.getMessage());
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index ee2467a..68253c7 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -16,6 +16,7 @@
 
 package com.android.server.am;
 
+import android.os.Trace;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
@@ -216,12 +217,26 @@
 
     public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
         mParallelBroadcasts.add(r);
-        r.enqueueClockTime = System.currentTimeMillis();
+        enqueueBroadcastHelper(r);
     }
 
     public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
         mOrderedBroadcasts.add(r);
+        enqueueBroadcastHelper(r);
+    }
+
+    /**
+     * Don't call this method directly; call enqueueParallelBroadcastLocked or
+     * enqueueOrderedBroadcastLocked.
+     */
+    private void enqueueBroadcastHelper(BroadcastRecord r) {
         r.enqueueClockTime = System.currentTimeMillis();
+
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
+                System.identityHashCode(r));
+        }
     }
 
     public final boolean replaceParallelBroadcastLocked(BroadcastRecord r) {
@@ -751,7 +766,7 @@
 
             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
                     + mQueueName + "]: "
-                    + mParallelBroadcasts.size() + " broadcasts, "
+                    + mParallelBroadcasts.size() + " parallel broadcasts, "
                     + mOrderedBroadcasts.size() + " ordered broadcasts");
 
             mService.updateCpuStats();
@@ -765,6 +780,16 @@
                 r = mParallelBroadcasts.remove(0);
                 r.dispatchTime = SystemClock.uptimeMillis();
                 r.dispatchClockTime = System.currentTimeMillis();
+
+                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                    Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
+                        System.identityHashCode(r));
+                    Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
+                        System.identityHashCode(r));
+                }
+
                 final int N = r.receivers.size();
                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
                         + mQueueName + "] " + r);
@@ -915,6 +940,14 @@
             if (recIdx == 0) {
                 r.dispatchTime = r.receiverTime;
                 r.dispatchClockTime = System.currentTimeMillis();
+                if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+                    Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
+                        System.identityHashCode(r));
+                    Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
+                        System.identityHashCode(r));
+                }
                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
                         + mQueueName + "] " + r);
             }
@@ -1398,6 +1431,12 @@
         }
         r.finishTime = SystemClock.uptimeMillis();
 
+        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
+            Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
+                createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
+                System.identityHashCode(r));
+        }
+
         mBroadcastHistory[mHistoryNext] = r;
         mHistoryNext = ringAdvance(mHistoryNext, 1, MAX_BROADCAST_HISTORY);
 
@@ -1456,6 +1495,14 @@
         }
     }
 
+    private String createBroadcastTraceTitle(BroadcastRecord record, int state) {
+        return String.format("Broadcast %s from %s (%s) %s",
+                state == BroadcastRecord.DELIVERY_PENDING ? "in queue" : "dispatched",
+                record.callerPackage == null ? "" : record.callerPackage,
+                record.callerApp == null ? "process unknown" : record.callerApp.toShortString(),
+                record.intent == null ? "" : record.intent.getAction());
+    }
+
     final boolean dumpLocked(FileDescriptor fd, PrintWriter pw, String[] args,
             int opti, boolean dumpAll, String dumpPackage, boolean needSep) {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
diff --git a/services/core/java/com/android/server/am/PreBootBroadcaster.java b/services/core/java/com/android/server/am/PreBootBroadcaster.java
index f4f6b66..e0d3abd 100644
--- a/services/core/java/com/android/server/am/PreBootBroadcaster.java
+++ b/services/core/java/com/android/server/am/PreBootBroadcaster.java
@@ -35,6 +35,7 @@
 import android.util.Slog;
 
 import com.android.internal.R;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.ProgressReporter;
 import com.android.server.UiThread;
 
@@ -144,13 +145,13 @@
                         contentIntent = null;
                     }
 
-                    final Notification notif = new Notification.Builder(mService.mContext)
+                    final Notification notif =
+                            new Notification.Builder(mService.mContext,
+                                    SystemNotificationChannels.UPDATES)
                             .setSmallIcon(R.drawable.stat_sys_adb)
                             .setWhen(0)
                             .setOngoing(true)
                             .setTicker(title)
-                            .setDefaults(0)
-                            .setPriority(Notification.PRIORITY_MAX)
                             .setColor(context.getColor(
                                     com.android.internal.R.color.system_notification_accent_color))
                             .setContentTitle(title)
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 82b00da..dfbe59f 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -115,7 +115,7 @@
     long destroyTime;       // time at which destory was initiated.
 
     String stringName;      // caching of toString
-    
+
     private int lastStartId;    // identifier of most recent start request.
 
     static class StartItem {
@@ -203,7 +203,7 @@
             }
         }
     }
-    
+
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("intent={");
                 pw.print(intent.getIntent().toShortString(false, true, false, true));
@@ -413,7 +413,7 @@
         restartDelay = 0;
         restartTime = 0;
     }
-    
+
     public StartItem findDeliveredStart(int id, boolean remove) {
         final int N = deliveredStarts.size();
         for (int i=0; i<N; i++) {
@@ -423,10 +423,10 @@
                 return si;
             }
         }
-        
+
         return null;
     }
-    
+
     public int getLastStartId() {
         return lastStartId;
     }
@@ -478,7 +478,8 @@
                                 ctx = ams.mContext.createPackageContextAsUser(
                                         appInfo.packageName, 0, new UserHandle(userId));
 
-                                Notification.Builder notiBuilder = new Notification.Builder(ctx);
+                                Notification.Builder notiBuilder = new Notification.Builder(ctx,
+                                        localForegroundNoti.getChannel());
 
                                 // it's ugly, but it clearly identifies the app
                                 notiBuilder.setSmallIcon(appInfo.icon);
@@ -486,9 +487,6 @@
                                 // mark as foreground
                                 notiBuilder.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true);
 
-                                // we are doing the app a kindness here
-                                notiBuilder.setPriority(Notification.PRIORITY_MIN);
-
                                 Intent runningIntent = new Intent(
                                         Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                 runningIntent.setData(Uri.fromParts("package",
@@ -541,7 +539,7 @@
             });
         }
     }
-    
+
     public void cancelNotification() {
         // Do asynchronous communication with notification manager to
         // avoid deadlocks.
@@ -588,7 +586,7 @@
             }
         });
     }
-    
+
     public void clearDeliveredStartsLocked() {
         for (int i=deliveredStarts.size()-1; i>=0; i--) {
             deliveredStarts.get(i).removeUriPermissionsLocked();
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index b051304..2410424 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1081,11 +1081,13 @@
         r.onOverrideConfigurationSent();
     }
 
-    /** @return true if this was the last activity in the task */
+    /**
+     * @return true if this was the last activity in the task
+     */
     boolean removeActivity(ActivityRecord r) {
         if (r.task != this) {
             throw new IllegalArgumentException(
-                "Activity=" + r + " does not belong to task=" + this);
+                    "Activity=" + r + " does not belong to task=" + this);
         }
 
         r.task = null;
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 302f628..f15543a 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -34,6 +34,12 @@
     boolean setWhitelist;
     boolean idle;
     int numProcs;
+    /**
+     * Sequence number associated with the {@link #curProcState}. This is incremented using
+     * {@link ActivityManagerService#mProcStateSeqCounter}
+     * when {@link #curProcState} changes from background to foreground or vice versa.
+     */
+    long curProcStateSeq;
 
     static final int CHANGE_PROCSTATE = 0;
     static final int CHANGE_GONE = 1;
@@ -83,6 +89,8 @@
         }
         sb.append(" procs:");
         sb.append(numProcs);
+        sb.append(" curProcStateSeq:");
+        sb.append(curProcStateSeq);
         sb.append("}");
         return sb.toString();
     }
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index 42c31b1..6710bdc 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -16,7 +16,6 @@
 
 package com.android.server.am;
 
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
 
@@ -80,10 +79,11 @@
     }
 
     public void setState(int newState) {
-        if (DEBUG_MU) {
-            Slog.i(TAG, "User " + mHandle.getIdentifier() + " state changed from "
-                    + stateToString(state) + " to " + stateToString(newState));
+        if (newState == state) {
+            return;
         }
+        Slog.i(TAG, "User " + mHandle.getIdentifier() + " state changed from "
+                + stateToString(state) + " to " + stateToString(newState));
         lastState = state;
         state = newState;
     }
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index d648dd8..4404dcf 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -152,9 +152,11 @@
         synchronized(mPlayerLock) {
             final AudioPlaybackConfiguration apc = mPlayers.get(new Integer(piid));
             if (checkConfigurationCaller(piid, apc, binderUid)) {
-                apc.getPlayerProxy().applyVolumeShaper(
-                        DUCK_ID,
-                        TERMINATE);
+                try {
+                    apc.getPlayerProxy().applyVolumeShaper(
+                            DUCK_ID,
+                            TERMINATE);
+                } catch (Exception e) { /* silent failure, happens happens with binder failure */ }
                 mPlayers.remove(new Integer(piid));
             } else {
                 Log.e(TAG, "Error releasing player " + piid);
diff --git a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
index 68fe505..83751a9 100644
--- a/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
+++ b/services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
@@ -32,6 +32,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.internal.notification.SystemNotificationChannels;
 
 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
@@ -187,7 +188,9 @@
             return;
         }
 
-        Notification.Builder builder = new Notification.Builder(mContext)
+        final String channelId = highPriority ? SystemNotificationChannels.NETWORK_ALERTS :
+                SystemNotificationChannels.NETWORK_STATUS;
+        Notification.Builder builder = new Notification.Builder(mContext, channelId)
                 .setWhen(System.currentTimeMillis())
                 .setShowWhen(notifyType == NotificationType.NETWORK_SWITCH)
                 .setSmallIcon(icon)
@@ -198,10 +201,6 @@
                 .setContentTitle(title)
                 .setContentIntent(intent)
                 .setLocalOnly(true)
-                .setPriority(highPriority ?
-                        Notification.PRIORITY_HIGH :
-                        Notification.PRIORITY_DEFAULT)
-                .setDefaults(highPriority ? Notification.DEFAULT_ALL : 0)
                 .setOnlyAlertOnce(true);
 
         if (notifyType == NotificationType.NETWORK_SWITCH) {
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 6c608a2..39e3758 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -66,6 +66,7 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyIntents;
 import com.android.internal.util.IndentingPrintWriter;
@@ -668,7 +669,8 @@
                 tethered_notification_message);
 
         if (mTetheredNotificationBuilder == null) {
-            mTetheredNotificationBuilder = new Notification.Builder(mContext);
+            mTetheredNotificationBuilder =
+                    new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
             mTetheredNotificationBuilder.setWhen(0)
                     .setOngoing(true)
                     .setColor(mContext.getColor(
@@ -950,6 +952,8 @@
         // Events from NetworkCallbacks that we process on the master state
         // machine thread on behalf of the UpstreamNetworkMonitor.
         static final int EVENT_UPSTREAM_CALLBACK                = BASE_MASTER + 5;
+        // we treated the error and want now to clear it
+        static final int CMD_CLEAR_ERROR                        = BASE_MASTER + 6;
 
         private State mInitialState;
         private State mTetherModeAliveState;
@@ -1491,6 +1495,10 @@
                         TetherInterfaceStateMachine who = (TetherInterfaceStateMachine)message.obj;
                         who.sendMessage(mErrorNotification);
                         break;
+                    case CMD_CLEAR_ERROR:
+                        mErrorNotification = ConnectivityManager.TETHER_ERROR_NO_ERROR;
+                        transitionTo(mInitialState);
+                        break;
                     default:
                        retValue = false;
                 }
@@ -1635,6 +1643,12 @@
             // Not really very much we can do here.
         }
 
+        // If TetherMasterSM is in ErrorState, TetherMasterSM stays there.
+        // Thus we give a chance for TetherMasterSM to recover to InitialState
+        // by sending CMD_CLEAR_ERROR
+        if (error == ConnectivityManager.TETHER_ERROR_MASTER_ERROR) {
+            mTetherMasterSM.sendMessage(TetherMasterSM.CMD_CLEAR_ERROR, who);
+        }
         switch (state) {
             case IControlsTethering.STATE_UNAVAILABLE:
             case IControlsTethering.STATE_AVAILABLE:
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index b963555..9fc2fc7 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -85,6 +85,7 @@
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnInfo;
 import com.android.internal.net.VpnProfile;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.server.DeviceIdleController;
 import com.android.server.LocalServices;
 import com.android.server.net.BaseNetworkObserver;
@@ -1293,17 +1294,16 @@
                     mContext, /* request */ 0, intent,
                     PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
                     null, user);
-            final Notification.Builder builder = new Notification.Builder(mContext)
-                    .setDefaults(0)
-                    .setSmallIcon(R.drawable.vpn_connected)
-                    .setContentTitle(mContext.getString(R.string.vpn_lockdown_disconnected))
-                    .setContentText(mContext.getString(R.string.vpn_lockdown_config))
-                    .setContentIntent(configIntent)
-                    .setCategory(Notification.CATEGORY_SYSTEM)
-                    .setPriority(Notification.PRIORITY_LOW)
-                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                    .setOngoing(true)
-                    .setColor(mContext.getColor(R.color.system_notification_accent_color));
+            final Notification.Builder builder =
+                    new Notification.Builder(mContext, SystemNotificationChannels.VPN)
+                            .setSmallIcon(R.drawable.vpn_connected)
+                            .setContentTitle(mContext.getString(R.string.vpn_lockdown_disconnected))
+                            .setContentText(mContext.getString(R.string.vpn_lockdown_config))
+                            .setContentIntent(configIntent)
+                            .setCategory(Notification.CATEGORY_SYSTEM)
+                            .setVisibility(Notification.VISIBILITY_PUBLIC)
+                            .setOngoing(true)
+                            .setColor(mContext.getColor(R.color.system_notification_accent_color));
             notificationManager.notifyAsUser(TAG, 0, builder.build(), user);
         } finally {
             Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 5e51579..710ab33 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -167,7 +167,8 @@
     private void maybeLogMessage(State state, int what) {
         if (DBG) {
             Log.d(TAG, state.getName() + " got " +
-                    sMagicDecoderRing.get(what, Integer.toString(what)));
+                    sMagicDecoderRing.get(what, Integer.toString(what)) + ", Iface = " +
+                    mIfaceName);
         }
     }
 
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 4b34eba56..f47a9079 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -297,7 +297,7 @@
         final int pid = Binder.getCallingPid();
 
         userHandle = handleIncomingUser(uri, pid, uid,
-                Intent.FLAG_GRANT_READ_URI_PERMISSION, userHandle);
+                Intent.FLAG_GRANT_READ_URI_PERMISSION, true, userHandle);
 
         final String msg = LocalServices.getService(ActivityManagerInternal.class)
                 .checkContentProviderAccess(uri.getAuthority(), userHandle);
@@ -364,7 +364,7 @@
         final int callingUserHandle = UserHandle.getCallingUserId();
 
         userHandle = handleIncomingUser(uri, pid, uid,
-                Intent.FLAG_GRANT_WRITE_URI_PERMISSION, userHandle);
+                Intent.FLAG_GRANT_WRITE_URI_PERMISSION, true, userHandle);
 
         final String msg = LocalServices.getService(ActivityManagerInternal.class)
                 .checkContentProviderAccess(uri.getAuthority(), userHandle);
@@ -1144,7 +1144,8 @@
         }
     }
 
-    private int handleIncomingUser(Uri uri, int pid, int uid, int modeFlags, int userId) {
+    private int handleIncomingUser(Uri uri, int pid, int uid, int modeFlags, boolean allowNonFull,
+            int userId) {
         if (userId == UserHandle.USER_CURRENT) {
             userId = ActivityManager.getCurrentUser();
         }
@@ -1157,8 +1158,24 @@
         } else if (userId != UserHandle.getCallingUserId()) {
             if (checkUriPermission(uri, pid, uid, modeFlags,
                     userId) != PackageManager.PERMISSION_GRANTED) {
-                mContext.enforceCallingOrSelfPermission(
-                        Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
+                boolean allow = false;
+                if (mContext.checkCallingOrSelfPermission(
+                        Manifest.permission.INTERACT_ACROSS_USERS_FULL)
+                                == PackageManager.PERMISSION_GRANTED) {
+                    allow = true;
+                } else if (allowNonFull && mContext.checkCallingOrSelfPermission(
+                        Manifest.permission.INTERACT_ACROSS_USERS)
+                                == PackageManager.PERMISSION_GRANTED) {
+                    allow = true;
+                }
+                if (!allow) {
+                    final String permissions = allowNonFull
+                            ? (Manifest.permission.INTERACT_ACROSS_USERS_FULL + " or " +
+                                    Manifest.permission.INTERACT_ACROSS_USERS)
+                            : Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+                    throw new SecurityException(TAG + "Neither user " + uid
+                            + " nor current process has " + permissions);
+                }
             }
         }
 
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 5b539ff..bbad493 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -81,6 +81,7 @@
 import android.util.Pair;
 import android.util.Slog;
 
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
 import com.android.server.job.JobSchedulerInternal;
@@ -3250,7 +3251,8 @@
                     R.string.contentServiceTooManyDeletesNotificationDesc);
 
             Context contextForUser = getContextForUser(user);
-            Notification notification = new Notification.Builder(contextForUser)
+            Notification notification =
+                    new Notification.Builder(contextForUser, SystemNotificationChannels.ACCOUNT)
                     .setSmallIcon(R.drawable.stat_notify_sync_error)
                     .setTicker(mContext.getString(R.string.contentServiceSync))
                     .setWhen(System.currentTimeMillis())
@@ -3460,4 +3462,4 @@
             return mContext;
         }
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/fingerprint/ClientMonitor.java b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
index 5a1e445..43bb21d 100644
--- a/services/core/java/com/android/server/fingerprint/ClientMonitor.java
+++ b/services/core/java/com/android/server/fingerprint/ClientMonitor.java
@@ -68,7 +68,9 @@
         mIsRestricted = restricted;
         mOwner = owner;
         try {
-            token.linkToDeath(this, 0);
+            if (token != null) {
+                token.linkToDeath(this, 0);
+            }
         } catch (RemoteException e) {
             Slog.w(TAG, "caught remote exception in linkToDeath: ", e);
         }
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 3793b91..297d5bd 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -23,6 +23,7 @@
 import android.util.Log;
 import android.view.Display;
 import com.android.internal.inputmethod.InputMethodSubtypeHandle;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.R;
 import com.android.internal.util.Preconditions;
@@ -973,17 +974,17 @@
                     intent, 0, null, UserHandle.CURRENT);
 
             Resources r = mContext.getResources();
-            Notification notification = new Notification.Builder(mContext)
-                    .setContentTitle(r.getString(
-                            R.string.select_keyboard_layout_notification_title))
-                    .setContentText(r.getString(
-                            R.string.select_keyboard_layout_notification_message))
-                    .setContentIntent(keyboardLayoutIntent)
-                    .setSmallIcon(R.drawable.ic_settings_language)
-                    .setPriority(Notification.PRIORITY_LOW)
-                    .setColor(mContext.getColor(
-                            com.android.internal.R.color.system_notification_accent_color))
-                    .build();
+            Notification notification =
+                    new Notification.Builder(mContext, SystemNotificationChannels.PHYSICAL_KEYBOARD)
+                            .setContentTitle(r.getString(
+                                    R.string.select_keyboard_layout_notification_title))
+                            .setContentText(r.getString(
+                                    R.string.select_keyboard_layout_notification_message))
+                            .setContentIntent(keyboardLayoutIntent)
+                            .setSmallIcon(R.drawable.ic_settings_language)
+                            .setColor(mContext.getColor(
+                                    com.android.internal.R.color.system_notification_accent_color))
+                            .build();
             mNotificationManager.notifyAsUser(null,
                     R.string.select_keyboard_layout_notification_title,
                     notification, UserHandle.ALL);
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 36f3287..6349f21 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -37,6 +37,7 @@
 import android.media.IAudioService;
 import android.media.IRemoteVolumeController;
 import android.media.session.IActiveSessionsListener;
+import android.media.session.ICallback;
 import android.media.session.IOnMediaKeyListener;
 import android.media.session.IOnVolumeKeyLongPressListener;
 import android.media.session.ISession;
@@ -107,6 +108,7 @@
     private AudioManagerInternal mAudioManagerInternal;
     private ContentResolver mContentResolver;
     private SettingsObserver mSettingsObserver;
+    private ICallback mCallback;
 
     // List of user IDs running in the foreground.
     // Multiple users can be in the foreground if the work profile is on.
@@ -486,6 +488,7 @@
             if (size > 0 && records.get(0).isPlaybackActive(false)) {
                 rememberMediaButtonReceiverLocked(records.get(0));
             }
+            pushAddressedPlayerChangedLocked();
             ArrayList<MediaSession.Token> tokens = new ArrayList<MediaSession.Token>();
             for (int i = 0; i < size; i++) {
                 tokens.add(new MediaSession.Token(records.get(i).getControllerBinder()));
@@ -517,6 +520,52 @@
         }
     }
 
+    private MediaSessionRecord getMediaButtonSessionLocked() {
+        // If we don't have a media button receiver to fall back on
+        // include non-playing sessions for dispatching.
+        boolean useNotPlayingSessions = true;
+        for (int userId : mCurrentUserIdList) {
+            UserRecord ur = mUserRecords.get(userId);
+            if (ur.mLastMediaButtonReceiver != null
+                    || ur.mRestoredMediaButtonReceiver != null) {
+                useNotPlayingSessions = false;
+                break;
+            }
+        }
+        return mPriorityStack.getDefaultMediaButtonSession(
+                mCurrentUserIdList, useNotPlayingSessions);
+    }
+
+    private void pushAddressedPlayerChangedLocked() {
+        if (mCallback == null) {
+            return;
+        }
+        try {
+            MediaSessionRecord mediaButtonSession = getMediaButtonSessionLocked();
+            if (mediaButtonSession != null) {
+                mCallback.onAddressedPlayerChangedToMediaSession(
+                        new MediaSession.Token(mediaButtonSession.getControllerBinder()));
+            } else {
+                for (int userId : mCurrentUserIdList) {
+                    UserRecord user = mUserRecords.get(userId);
+                    if (user.mLastMediaButtonReceiver == null
+                            && user.mRestoredMediaButtonReceiver == null) {
+                        continue;
+                    }
+                    ComponentName componentName = user.mLastMediaButtonReceiver != null
+                            ? user.mLastMediaButtonReceiver.getIntent().getComponent()
+                            : user.mRestoredMediaButtonReceiver;
+                    mCallback.onAddressedPlayerChangedToMediaButtonReceiver(componentName);
+                    return;
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Failed to pushAddressedPlayerChangedLocked", e);
+        }
+    }
+
+    // Remember media button receiver and keep it in the persistent storage.
+    // This should be called whenever there's no media session to receive media button event.
     private void rememberMediaButtonReceiverLocked(MediaSessionRecord record) {
         PendingIntent receiver = record.getMediaButtonReceiver();
         UserRecord user = mUserRecords.get(record.getUserId());
@@ -801,19 +850,74 @@
                             + "setup is in progress.");
                     return;
                 }
-                if (isGlobalPriorityActive() && uid != Process.SYSTEM_UID) {
-                    // Prevent dispatching key event through reflection while the global priority
-                    // session is active.
-                    Slog.i(TAG, "Only the system can dispatch media key event "
-                            + "to the global priority session.");
-                    return;
-                }
 
                 synchronized (mLock) {
-                    if (!isGlobalPriorityActive() && isVoiceKey(keyEvent.getKeyCode())) {
+                    boolean isGlobalPriorityActive = mPriorityStack.isGlobalPriorityActive();
+                    if (isGlobalPriorityActive && uid != Process.SYSTEM_UID) {
+                        // Prevent dispatching key event through reflection while the global
+                        // priority session is active.
+                        Slog.i(TAG, "Only the system can dispatch media key event "
+                                + "to the global priority session.");
+                        return;
+                    }
+                    if (!isGlobalPriorityActive) {
+                        // Only consider full user.
+                        UserRecord user = mUserRecords.get(mCurrentUserIdList.get(0));
+                        if (user.mOnMediaKeyListener != null) {
+                            if (DEBUG_KEY_EVENT) {
+                                Log.d(TAG, "Send " + keyEvent + " to media key listener");
+                            }
+                            try {
+                                user.mOnMediaKeyListener.onMediaKey(keyEvent,
+                                        new MediaKeyListenerResultReceiver(keyEvent, needWakeLock));
+                                return;
+                            } catch (RemoteException e) {
+                                Log.w(TAG, "Failed to send " + keyEvent + " to media key listener");
+                            }
+                        }
+                    }
+                    if (!isGlobalPriorityActive && isVoiceKey(keyEvent.getKeyCode())) {
                         handleVoiceKeyEventLocked(keyEvent, needWakeLock);
                     } else {
-                        dispatchMediaKeyEventLocked(keyEvent, needWakeLock, true);
+                        dispatchMediaKeyEventLocked(keyEvent, needWakeLock);
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void setCallback(ICallback callback) {
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                if (uid != Process.BLUETOOTH_UID) {
+                    throw new SecurityException("Only Bluetooth service processes can set"
+                            + " Callback");
+                }
+                synchronized (mLock) {
+                    Log.d(TAG, "Callback + " + mCallback
+                            + " is set by " + getCallingPackageName(uid));
+                    mCallback = callback;
+                    if (mCallback == null) {
+                        return;
+                    }
+                    try {
+                        mCallback.asBinder().linkToDeath(
+                                new IBinder.DeathRecipient() {
+                                    @Override
+                                    public void binderDied() {
+                                        synchronized (mLock) {
+                                            mCallback = null;
+                                        }
+                                    }
+                                }, 0);
+                        pushAddressedPlayerChangedLocked();
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Failed to set callback", e);
+                        mCallback = null;
                     }
                 }
             } finally {
@@ -1080,7 +1184,9 @@
 
         @Override
         public boolean isGlobalPriorityActive() {
-            return mPriorityStack.isGlobalPriorityActive();
+            synchronized (mLock) {
+                return mPriorityStack.isGlobalPriorityActive();
+            }
         }
 
         @Override
@@ -1190,52 +1296,15 @@
                     if (!mVoiceButtonHandled && !keyEvent.isCanceled()) {
                         // Resend the down then send this event through
                         KeyEvent downEvent = KeyEvent.changeAction(keyEvent, KeyEvent.ACTION_DOWN);
-                        dispatchMediaKeyEventLocked(downEvent, needWakeLock, true);
-                        dispatchMediaKeyEventLocked(keyEvent, needWakeLock, true);
+                        dispatchMediaKeyEventLocked(downEvent, needWakeLock);
+                        dispatchMediaKeyEventLocked(keyEvent, needWakeLock);
                     }
                 }
             }
         }
 
-        private void dispatchMediaKeyEventLocked(KeyEvent keyEvent, boolean needWakeLock,
-                boolean checkMediaKeyListener) {
-            // If we don't have a media button receiver to fall back on
-            // include non-playing sessions for dispatching.
-            boolean useNotPlayingSessions = true;
-            for (int userId : mCurrentUserIdList) {
-                UserRecord ur = mUserRecords.get(userId);
-                if (ur.mLastMediaButtonReceiver != null
-                        || ur.mRestoredMediaButtonReceiver != null) {
-                    useNotPlayingSessions = false;
-                    break;
-                }
-            }
-            if (DEBUG) {
-                Log.d(TAG, "dispatchMediaKeyEvent, useNotPlayingSessions="
-                        + useNotPlayingSessions);
-            }
-
-            MediaSessionRecord session = mPriorityStack.getDefaultMediaButtonSession(
-                    mCurrentUserIdList, useNotPlayingSessions);
-
-            if ((session == null
-                    || !session.hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY))
-                    && checkMediaKeyListener) {
-                // Only consider full user.
-                UserRecord user = mUserRecords.get(mCurrentUserIdList.get(0));
-                if (user.mOnMediaKeyListener != null) {
-                    if (DEBUG_KEY_EVENT) {
-                        Log.d(TAG, "Send " + keyEvent + " to media key listener");
-                    }
-                    try {
-                        user.mOnMediaKeyListener.onMediaKey(keyEvent,
-                                new MediaKeyListenerResultReceiver(keyEvent, needWakeLock));
-                        return;
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "Failed to send " + keyEvent + " to media key listener");
-                    }
-                }
-            }
+        private void dispatchMediaKeyEventLocked(KeyEvent keyEvent, boolean needWakeLock) {
+            MediaSessionRecord session = getMediaButtonSessionLocked();
             if (session != null) {
                 if (DEBUG_KEY_EVENT) {
                     Log.d(TAG, "Sending " + keyEvent + " to " + session);
@@ -1248,6 +1317,14 @@
                         needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
                         mKeyEventReceiver, Process.SYSTEM_UID,
                         getContext().getPackageName());
+                if (mCallback != null) {
+                    try {
+                        mCallback.onMediaKeyEventDispatchedToMediaSession(keyEvent,
+                                new MediaSession.Token(session.getControllerBinder()));
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Failed to send callback", e);
+                    }
+                }
             } else {
                 // Launch the last PendingIntent we had with priority
                 for (int userId : mCurrentUserIdList) {
@@ -1264,26 +1341,41 @@
                     mediaButtonIntent.putExtra(Intent.EXTRA_KEY_EVENT, keyEvent);
                     try {
                         if (user.mLastMediaButtonReceiver != null) {
+                            PendingIntent receiver = user.mLastMediaButtonReceiver;
                             if (DEBUG_KEY_EVENT) {
                                 Log.d(TAG, "Sending " + keyEvent
-                                        + " to the last known pendingIntent "
-                                        + user.mLastMediaButtonReceiver);
+                                        + " to the last known pendingIntent " + receiver);
                             }
-                            user.mLastMediaButtonReceiver.send(getContext(),
+                            receiver.send(getContext(),
                                     needWakeLock ? mKeyEventReceiver.mLastTimeoutId : -1,
                                     mediaButtonIntent, mKeyEventReceiver, mHandler);
+                            if (mCallback != null) {
+                                ComponentName componentName =
+                                        user.mLastMediaButtonReceiver.getIntent().getComponent();
+                                if (componentName != null) {
+                                    mCallback.onMediaKeyEventDispatchedToMediaButtonReceiver(
+                                            keyEvent, componentName);
+                                }
+                            }
                         } else {
+                            ComponentName receiver = user.mRestoredMediaButtonReceiver;
                             if (DEBUG_KEY_EVENT) {
                                 Log.d(TAG, "Sending " + keyEvent + " to the restored intent "
-                                        + user.mRestoredMediaButtonReceiver);
+                                        + receiver);
                             }
-                            mediaButtonIntent.setComponent(user.mRestoredMediaButtonReceiver);
+                            mediaButtonIntent.setComponent(receiver);
                             getContext().sendBroadcastAsUser(mediaButtonIntent,
                                     UserHandle.of(userId));
+                            if (mCallback != null) {
+                                mCallback.onMediaKeyEventDispatchedToMediaButtonReceiver(
+                                        keyEvent, receiver);
+                            }
                         }
                     } catch (CanceledException e) {
                         Log.i(TAG, "Error sending key event to media button receiver "
                                 + user.mLastMediaButtonReceiver, e);
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "Failed to send callback", e);
                     }
                     return;
                 }
@@ -1394,7 +1486,12 @@
                 mHandled = true;
                 mHandler.removeCallbacks(this);
                 synchronized (mLock) {
-                    dispatchMediaKeyEventLocked(mKeyEvent, mNeedWakeLock, false);
+                    if (!mPriorityStack.isGlobalPriorityActive()
+                            && isVoiceKey(mKeyEvent.getKeyCode())) {
+                        handleVoiceKeyEventLocked(mKeyEvent, mNeedWakeLock);
+                    } else {
+                        dispatchMediaKeyEventLocked(mKeyEvent, mNeedWakeLock);
+                    }
                 }
             }
         }
diff --git a/services/core/java/com/android/server/net/LockdownVpnTracker.java b/services/core/java/com/android/server/net/LockdownVpnTracker.java
index 4a8539a..a5e7d7c 100644
--- a/services/core/java/com/android/server/net/LockdownVpnTracker.java
+++ b/services/core/java/com/android/server/net/LockdownVpnTracker.java
@@ -47,6 +47,7 @@
 import com.android.internal.R;
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnProfile;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.Preconditions;
 import com.android.server.ConnectivityService;
 import com.android.server.EventLogTags;
@@ -330,18 +331,18 @@
     }
 
     private void showNotification(int titleRes, int iconRes) {
-        final Notification.Builder builder = new Notification.Builder(mContext)
-                .setWhen(0)
-                .setSmallIcon(iconRes)
-                .setContentTitle(mContext.getString(titleRes))
-                .setContentText(mContext.getString(R.string.vpn_lockdown_config))
-                .setContentIntent(mConfigIntent)
-                .setPriority(Notification.PRIORITY_LOW)
-                .setOngoing(true)
-                .addAction(R.drawable.ic_menu_refresh, mContext.getString(R.string.reset),
-                        mResetIntent)
-                .setColor(mContext.getColor(
-                        com.android.internal.R.color.system_notification_accent_color));
+        final Notification.Builder builder =
+                new Notification.Builder(mContext, SystemNotificationChannels.VPN)
+                        .setWhen(0)
+                        .setSmallIcon(iconRes)
+                        .setContentTitle(mContext.getString(titleRes))
+                        .setContentText(mContext.getString(R.string.vpn_lockdown_config))
+                        .setContentIntent(mConfigIntent)
+                        .setOngoing(true)
+                        .addAction(R.drawable.ic_menu_refresh, mContext.getString(R.string.reset),
+                                mResetIntent)
+                        .setColor(mContext.getColor(
+                                com.android.internal.R.color.system_notification_accent_color));
 
         NotificationManager.from(mContext).notify(TAG, 0, builder.build());
     }
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index ac3a025..5078998 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -58,6 +58,8 @@
 import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
 import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
 import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
+import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
+import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
 import static android.net.NetworkPolicyManager.uidPoliciesToString;
 import static android.net.NetworkPolicyManager.uidRulesToString;
 import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
@@ -169,6 +171,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.IndentingPrintWriter;
@@ -1067,7 +1070,8 @@
      */
     private void enqueueNotification(NetworkPolicy policy, int type, long totalBytes) {
         final String tag = buildNotificationTag(policy, type);
-        final Notification.Builder builder = new Notification.Builder(mContext);
+        final Notification.Builder builder =
+                new Notification.Builder(mContext, SystemNotificationChannels.NETWORK_STATUS);
         builder.setOnlyAlertOnce(true);
         builder.setWhen(0L);
         builder.setColor(mContext.getColor(
@@ -1085,7 +1089,7 @@
                 builder.setContentTitle(title);
                 builder.setContentText(body);
                 builder.setDefaults(Notification.DEFAULT_ALL);
-                builder.setPriority(Notification.PRIORITY_HIGH);
+                builder.setChannel(SystemNotificationChannels.NETWORK_ALERTS);
 
                 final Intent snoozeIntent = buildSnoozeWarningIntent(policy.template);
                 builder.setDeleteIntent(PendingIntent.getBroadcast(
@@ -2527,14 +2531,6 @@
         }
     }
 
-    static boolean isProcStateAllowedWhileIdleOrPowerSaveMode(int procState) {
-        return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
-    }
-
-    static boolean isProcStateAllowedWhileOnRestrictBackground(int procState) {
-        return procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
-    }
-
     void updateRulesForPowerSaveUL() {
         Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "updateRulesForPowerSaveUL");
         try {
@@ -2608,8 +2604,7 @@
     // (mPowerSaveTempWhitelistAppIds) for whitelisting, we can reuse their logic in this method.
     private void updateRulesForWhitelistedPowerSaveUL(int uid, boolean enabled, int chain) {
         if (enabled) {
-            if (isWhitelistedBatterySaverUL(uid)
-                    || isProcStateAllowedWhileIdleOrPowerSaveMode(mUidState.get(uid))) {
+            if (isWhitelistedBatterySaverUL(uid) || isUidForegroundOnRestrictPowerUL(uid)) {
                 setUidFirewallRule(chain, uid, FIREWALL_RULE_ALLOW);
             } else {
                 setUidFirewallRule(chain, uid, FIREWALL_RULE_DEFAULT);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 45ff20b..0e767da 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2736,9 +2736,10 @@
                                Notification.EXTRA_BUILDER_APPLICATION_INFO);
                 final Bundle extras = new Bundle();
                 extras.putParcelable(Notification.EXTRA_BUILDER_APPLICATION_INFO, appInfo);
+                final String channelId = notificationRecord.getChannel().getId();
                 final Notification summaryNotification =
-                        new Notification.Builder(getContext()).setSmallIcon(
-                                adjustedSbn.getNotification().getSmallIcon())
+                        new Notification.Builder(getContext(), channelId)
+                                .setSmallIcon(adjustedSbn.getNotification().getSmallIcon())
                                 .setGroupSummary(true)
                                 .setGroup(GroupHelper.AUTOGROUP_KEY)
                                 .setFlag(Notification.FLAG_AUTOGROUP_SUMMARY, true)
@@ -3049,6 +3050,10 @@
             throw new IllegalArgumentException("null not allowed: pkg=" + pkg
                     + " id=" + id + " notification=" + notification);
         }
+
+        // The system can post notifications for any package, let us resolve that.
+        final int notificationUid = resolveNotificationUid(opPkg, callingUid, userId);
+
         // Fix the notification as best we can.
         try {
             final ApplicationInfo ai = mPackageManagerClient.getApplicationInfoAsUser(
@@ -3068,13 +3073,13 @@
             channelId = (new Notification.TvExtender(notification)).getChannel();
         }
         final NotificationChannel channel =  mRankingHelper.getNotificationChannelWithFallback(pkg,
-                callingUid, channelId, false /* includeDeleted */);
+                notificationUid, channelId, false /* includeDeleted */);
         final StatusBarNotification n = new StatusBarNotification(
-                pkg, opPkg, id, tag, callingUid, callingPid, notification,
+                pkg, opPkg, id, tag, notificationUid, callingPid, notification,
                 user, null, System.currentTimeMillis());
         final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
 
-        if (!checkDisqualifyingFeatures(userId, callingUid, id,tag, r)) {
+        if (!checkDisqualifyingFeatures(userId, notificationUid, id,tag, r)) {
             return;
         }
 
@@ -3100,6 +3105,19 @@
         idOut[0] = id;
     }
 
+    private int resolveNotificationUid(String opPackageName, int callingUid, int userId) {
+        // The system can post notifications on behalf of any package it wants
+        if (isCallerSystem() && opPackageName != null && !"android".equals(opPackageName)) {
+            try {
+                return getContext().getPackageManager()
+                        .getPackageUidAsUser(opPackageName, userId);
+            } catch (NameNotFoundException e) {
+                /* ignore */
+            }
+        }
+        return callingUid;
+    }
+
     /**
      * Checks if a notification can be posted. checks rate limiter, snooze helper, and blocking.
      *
diff --git a/services/core/java/com/android/server/notification/RankingHelper.java b/services/core/java/com/android/server/notification/RankingHelper.java
index 867af9a..e72f7ff 100644
--- a/services/core/java/com/android/server/notification/RankingHelper.java
+++ b/services/core/java/com/android/server/notification/RankingHelper.java
@@ -66,6 +66,7 @@
 
     private static final String ATT_VERSION = "version";
     private static final String ATT_NAME = "name";
+    private static final String ATT_NAME_RES_ID = "name_res_id";
     private static final String ATT_UID = "uid";
     private static final String ATT_ID = "id";
     private static final String ATT_PRIORITY = "priority";
@@ -201,12 +202,19 @@
                             if (TAG_CHANNEL.equals(tagName)) {
                                 String id = parser.getAttributeValue(null, ATT_ID);
                                 CharSequence channelName = parser.getAttributeValue(null, ATT_NAME);
+                                int channelNameRes = safeInt(parser, ATT_NAME_RES_ID, -1);
                                 int channelImportance =
                                         safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
 
                                 if (!TextUtils.isEmpty(id)) {
-                                    final NotificationChannel channel = new NotificationChannel(id,
-                                            channelName, channelImportance);
+                                    NotificationChannel channel;
+                                    if (channelName != null) {
+                                        channel = new NotificationChannel(id, channelName,
+                                                channelImportance);
+                                    } else {
+                                        channel = new NotificationChannel(id, channelNameRes,
+                                                channelImportance);
+                                    }
                                     channel.populateFromXml(parser);
                                     r.channels.put(id, channel);
                                 }
@@ -286,7 +294,7 @@
             NotificationChannel channel;
             channel = new NotificationChannel(
                     NotificationChannel.DEFAULT_CHANNEL_ID,
-                    mContext.getString(R.string.default_notification_channel_label),
+                    R.string.default_notification_channel_label,
                     r.importance);
             channel.setBypassDnd(r.priority == Notification.PRIORITY_MAX);
             channel.setLockscreenVisibility(r.visibility);
@@ -480,7 +488,8 @@
         Preconditions.checkNotNull(pkg);
         Preconditions.checkNotNull(channel);
         Preconditions.checkNotNull(channel.getId());
-        Preconditions.checkNotNull(channel.getName());
+        Preconditions.checkArgument(!TextUtils.isEmpty(channel.getName())
+                || channel.getNameResId() != 0);
         Record r = getOrCreateRecord(pkg, uid);
         if (r == null) {
             throw new IllegalArgumentException("Invalid package");
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index 55a5f72..0ae5f31 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -438,6 +438,7 @@
             bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(),
                     icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
             Canvas canvas = new Canvas(bitmap);
+            icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
             icon.draw(canvas);
         }
 
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index bbd227e..aac04da 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -314,7 +314,8 @@
         optimizer.performDexOpt(pkg, libraryDependencies,
                 null /* ISAs */, false /* checkProfiles */,
                 getCompilerFilterForReason(compilationReason),
-                null /* CompilerStats.PackageStats */);
+                null /* CompilerStats.PackageStats */,
+                mPackageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName));
 
         return commands;
     }
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index b589057..d9ea728 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -104,7 +104,7 @@
      */
     int performDexOpt(PackageParser.Package pkg, String[] sharedLibraries,
             String[] instructionSets, boolean checkProfiles, String targetCompilationFilter,
-            CompilerStats.PackageStats packageStats) {
+            CompilerStats.PackageStats packageStats, boolean isUsedByOtherApps) {
         if (!canOptimizePackage(pkg)) {
             return DEX_OPT_SKIPPED;
         }
@@ -119,7 +119,7 @@
             }
             try {
                 return performDexOptLI(pkg, sharedLibraries, instructionSets, checkProfiles,
-                        targetCompilationFilter, packageStats);
+                        targetCompilationFilter, packageStats, isUsedByOtherApps);
             } finally {
                 if (useLock) {
                     mDexoptWakeLock.release();
@@ -135,7 +135,8 @@
     @GuardedBy("mInstallLock")
     private int performDexOptLI(PackageParser.Package pkg, String[] sharedLibraries,
             String[] targetInstructionSets, boolean checkForProfileUpdates,
-            String targetCompilerFilter, CompilerStats.PackageStats packageStats) {
+            String targetCompilerFilter, CompilerStats.PackageStats packageStats,
+            boolean isUsedByOtherApps) {
         final String[] instructionSets = targetInstructionSets != null ?
                 targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
         final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
@@ -143,7 +144,7 @@
         final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
 
         final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
-                targetCompilerFilter, isUsedByOtherApps(pkg));
+                targetCompilerFilter, isUsedByOtherApps);
         final boolean profileUpdated = checkForProfileUpdates &&
                 isProfileUpdated(pkg, sharedGid, compilerFilter);
 
@@ -477,40 +478,6 @@
         mSystemReady = true;
     }
 
-    /**
-     * Returns true if the profiling data collected for the given app indicate
-     * that the apps's APK has been loaded by another app.
-     * Note that this returns false for all forward-locked apps and apps without
-     * any collected profiling data.
-     */
-    public static boolean isUsedByOtherApps(PackageParser.Package pkg) {
-        if (pkg.isForwardLocked()) {
-            // Skip the check for forward locked packages since they don't share their code.
-            return false;
-        }
-
-        for (String apkPath : pkg.getAllCodePathsExcludingResourceOnly()) {
-            try {
-                apkPath = PackageManagerServiceUtils.realpath(new File(apkPath));
-            } catch (IOException e) {
-                // Log an error but continue without it.
-                Slog.w(TAG, "Failed to get canonical path", e);
-                continue;
-            }
-            String useMarker = apkPath.replace('/', '@');
-            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
-            for (int i = 0; i < currentUserIds.length; i++) {
-                File profileDir =
-                        Environment.getDataProfilesDeForeignDexDirectory(currentUserIds[i]);
-                File foreignUseMark = new File(profileDir, useMarker);
-                if (foreignUseMark.exists()) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     private String printDexoptFlags(int flags) {
         ArrayList<String> flagsList = new ArrayList<>();
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index a7a1683..37f78b4 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -88,6 +88,7 @@
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.content.PackageHelper;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.ImageUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -1103,7 +1104,7 @@
                 context.getResources().getDimensionPixelSize(
                         android.R.dimen.notification_large_icon_height));
         CharSequence packageLabel = packageInfo.applicationInfo.loadLabel(pm);
-        return new Notification.Builder(context)
+        return new Notification.Builder(context, SystemNotificationChannels.DEVICE_ADMIN)
                 .setSmallIcon(R.drawable.ic_check_circle_24px)
                 .setColor(context.getResources().getColor(
                         R.color.system_notification_accent_color))
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 1c5675a..fd731c3 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -29,6 +29,7 @@
 import static com.android.server.pm.PackageInstallerService.prepareStageDir;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentSender;
@@ -45,6 +46,7 @@
 import android.content.pm.PackageParser.PackageLite;
 import android.content.pm.PackageParser.PackageParserException;
 import android.content.pm.Signature;
+import android.content.pm.UserInfo;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.FileBridge;
@@ -295,6 +297,7 @@
             info.active = mActiveCount.get() > 0;
 
             info.mode = params.mode;
+            info.installReason = params.installReason;
             info.sizeBytes = params.sizeBytes;
             info.appPackageName = params.appPackageName;
             info.appIcon = params.appIcon;
@@ -1139,6 +1142,25 @@
         }
 
         final boolean success = (returnCode == PackageManager.INSTALL_SUCCEEDED);
+
+        // Send broadcast to default launcher only if it's a new install
+        final boolean isNewInstall = extras == null || !extras.getBoolean(Intent.EXTRA_REPLACING);
+        if (success && isNewInstall) {
+            UserManagerService ums = UserManagerService.getInstance();
+            if (ums != null) {
+                final UserInfo parent = ums.getProfileParent(userId);
+                final int launcherUid = (parent != null) ? parent.id : userId;
+                final ComponentName launcherComponent = mPm.getDefaultHomeActivity(launcherUid);
+                if (launcherComponent != null) {
+                    Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
+                            .putExtra(PackageInstaller.EXTRA_SESSION, generateInfo())
+                            .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
+                            .setPackage(launcherComponent.getPackageName());
+                    mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
+                }
+            }
+        }
+
         mCallback.onSessionFinished(this, success);
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 116c0a3..caacc46 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -582,7 +582,8 @@
             Manifest.permission.RECEIVE_MMS,
             Manifest.permission.READ_EXTERNAL_STORAGE,
             Manifest.permission.WRITE_EXTERNAL_STORAGE,
-            Manifest.permission.READ_PHONE_NUMBER);
+            Manifest.permission.READ_PHONE_NUMBER,
+            Manifest.permission.ANSWER_PHONE_CALLS);
 
 
     /**
@@ -745,6 +746,12 @@
     @GuardedBy("mPackages")
     final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
 
+    final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
+        @Override public boolean hasFeature(String feature) {
+            return PackageManagerService.this.hasSystemFeature(feature, 0);
+        }
+    };
+
     public static final class SharedLibraryEntry {
         public final String path;
         public final String apk;
@@ -6317,6 +6324,7 @@
                 ephemeralInstaller.filter = new IntentFilter(intent.getAction());
                 ephemeralInstaller.filter.addDataPath(
                         intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
+                ephemeralInstaller.instantAppAvailable = true;
                 result.add(ephemeralInstaller);
             }
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -7310,12 +7318,17 @@
             return false;
         }
 
-        if (!isCallerSameApp(packageName)) {
-            return false;
-        }
         synchronized (mPackages) {
             final PackageSetting ps = mSettings.mPackages.get(packageName);
-            if (ps != null) {
+            final boolean returnAllowed =
+                    ps != null
+                    && (isCallerSameApp(packageName)
+                            || mContext.checkCallingOrSelfPermission(
+                                    android.Manifest.permission.ACCESS_INSTANT_APPS)
+                                            == PERMISSION_GRANTED
+                            || mInstantAppRegistry.isInstantAccessGranted(
+                                    userId, UserHandle.getAppId(Binder.getCallingUid()), ps.appId));
+            if (returnAllowed) {
                 return ps.getInstantApp(userId);
             }
         }
@@ -7577,7 +7590,7 @@
                     + " flags=0x" + Integer.toHexString(parseFlags));
         }
         ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
-                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir);
+                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
 
         // Submit files for parsing in parallel
         int fileCount = 0;
@@ -7746,6 +7759,7 @@
         pp.setSeparateProcesses(mSeparateProcesses);
         pp.setOnlyCoreApps(mOnlyCore);
         pp.setDisplayMetrics(mMetrics);
+        pp.setCallback(mPackageParserCallback);
 
         if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
             parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
@@ -8427,11 +8441,13 @@
                 pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
                         false /* checkProfiles */,
                         getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
-                        getOrCreateCompilerPackageStats(depPackage));
+                        getOrCreateCompilerPackageStats(depPackage),
+                        mDexManager.isUsedByOtherApps(p.packageName));
             }
         }
         return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
-                targetCompilerFilter, getOrCreateCompilerPackageStats(p));
+                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
+                mDexManager.isUsedByOtherApps(p.packageName));
     }
 
     // Performs dexopt on the used secondary dex files belonging to the given package.
@@ -8703,6 +8719,7 @@
             } catch (InstallerException e) {
                 Slog.w(TAG, String.valueOf(e));
             }
+            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
         }
     }
 
@@ -9609,7 +9626,7 @@
 
     /**
      * Asserts the parsed package is valid according to the given policy. If the
-     * package is invalid, for whatever reason, throws {@link PackgeManagerException}.
+     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
      * <p>
      * Implementation detail: This method must NOT have any side effects. It would
      * ideally be static, but, it requires locks to read system state.
@@ -12334,6 +12351,7 @@
             }
             res.iconResourceId = info.icon;
             res.system = res.activityInfo.applicationInfo.isSystemApp();
+            res.instantAppAvailable = userState.instantApp;
             return res;
         }
 
@@ -12806,7 +12824,7 @@
          * By having a field variable, we're able to track filter ordering as soon as
          * a non-zero order is defined. Otherwise, multiple loops across the result set
          * would be needed to apply ordering. If the intent resolver becomes re-entrant,
-         * this needs to be contained entirely within {@link #filterResults()}.
+         * this needs to be contained entirely within {@link #filterResults}.
          */
         final ArrayMap<String, Pair<Integer, EphemeralResolveInfo>> mOrderResult = new ArrayMap<>();
 
@@ -16117,6 +16135,8 @@
                 setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
                 prepareAppDataAfterInstallLIF(newPackage);
                 addedPkg = true;
+                mDexManager.notifyPackageUpdated(newPackage.packageName,
+                        newPackage.baseCodePath, newPackage.splitCodePaths);
             } catch (PackageManagerException e) {
                 res.setError("Package couldn't be installed in " + pkg.codePath, e);
             }
@@ -16266,6 +16286,9 @@
                 updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
                         installReason);
                 prepareAppDataAfterInstallLIF(newPackage);
+
+                mDexManager.notifyPackageUpdated(newPackage.packageName,
+                            newPackage.baseCodePath, newPackage.splitCodePaths);
             }
         } catch (PackageManagerException e) {
             res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
@@ -16628,6 +16651,7 @@
         PackageParser pp = new PackageParser();
         pp.setSeparateProcesses(mSeparateProcesses);
         pp.setDisplayMetrics(mMetrics);
+        pp.setCallback(mPackageParserCallback);
 
         Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
         final PackageParser.Package pkg;
@@ -16640,13 +16664,19 @@
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
         }
 
-//        // Ephemeral apps must have target SDK >= O.
-//        // TODO: Update conditional and error message when O gets locked down
-//        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
-//            res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID,
-//                    "Ephemeral apps must have target SDK version of at least O");
-//            return;
-//        }
+        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
+        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
+            Slog.w(TAG, "Instant app package " + pkg.packageName
+                    + " does not target O, this will be a fatal error.");
+            // STOPSHIP: Make this a fatal error
+            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
+        }
+        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
+            Slog.w(TAG, "Instant app package " + pkg.packageName
+                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
+            // STOPSHIP: Make this a fatal error
+            pkg.applicationInfo.targetSandboxVersion = 2;
+        }
 
         if (pkg.applicationInfo.isStaticSharedLibrary()) {
             // Static shared libraries have synthetic package names
@@ -16824,11 +16854,20 @@
                 res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
             }
 
-            // Check whether the newly-scanned package wants to define an already-defined perm
             int N = pkg.permissions.size();
             for (int i = N-1; i >= 0; i--) {
                 PackageParser.Permission perm = pkg.permissions.get(i);
                 BasePermission bp = mSettings.mPermissions.get(perm.info.name);
+
+                // Don't allow anyone but the platform to define ephemeral permissions.
+                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
+                        && !PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
+                    Slog.w(TAG, "Package " + pkg.packageName
+                            + " attempting to delcare ephemeral permission "
+                            + perm.info.name + "; Removing ephemeral.");
+                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
+                }
+                // Check whether the newly-scanned package wants to define an already-defined perm
                 if (bp != null) {
                     // If the defining package is signed with our cert, it's okay.  This
                     // also includes the "updating the same package" case, of course.
@@ -16934,7 +16973,8 @@
             mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
                     null /* instructionSets */, false /* checkProfiles */,
                     getCompilerFilterForReason(REASON_INSTALL),
-                    getOrCreateCompilerPackageStats(pkg));
+                    getOrCreateCompilerPackageStats(pkg),
+                    mDexManager.isUsedByOtherApps(pkg.packageName));
             Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
             // Notify BackgroundDexOptJobService that the package has been changed.
@@ -19636,6 +19676,35 @@
         return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
     }
 
+    /**
+     * Report the 'Home' activity which is currently set as "always use this one". If non is set
+     * then reports the most likely home activity or null if there are more than one.
+     */
+    public ComponentName getDefaultHomeActivity(int userId) {
+        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
+        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
+        if (cn != null) {
+            return cn;
+        }
+
+        // Find the launcher with the highest priority and return that component if there are no
+        // other home activity with the same priority.
+        int lastPriority = Integer.MIN_VALUE;
+        ComponentName lastComponent = null;
+        final int size = allHomeCandidates.size();
+        for (int i = 0; i < size; i++) {
+            final ResolveInfo ri = allHomeCandidates.get(i);
+            if (ri.priority > lastPriority) {
+                lastComponent = ri.activityInfo.getComponentName();
+                lastPriority = ri.priority;
+            } else if (ri.priority == lastPriority) {
+                // Two components found with same priority.
+                lastComponent = null;
+            }
+        }
+        return lastComponent;
+    }
+
     private Intent getHomeIntent() {
         Intent intent = new Intent(Intent.ACTION_MAIN);
         intent.addCategory(Intent.CATEGORY_HOME);
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 9c9a671..0634dac 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -80,9 +80,7 @@
             try {
                 // Check that the system property name is legal.
                 String sysPropName = getSystemPropertyName(reason);
-                if (sysPropName == null ||
-                        sysPropName.isEmpty() ||
-                        sysPropName.length() > SystemProperties.PROP_NAME_MAX) {
+                if (sysPropName == null || sysPropName.isEmpty()) {
                     throw new IllegalStateException("Reason system property name \"" +
                             sysPropName +"\" for reason " + REASON_STRINGS[reason]);
                 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 45887e1..9feee8c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -133,7 +133,8 @@
                 sortTemp, packageManagerService);
 
         // Give priority to apps used by other apps.
-        applyPackageFilter((pkg) -> PackageDexOptimizer.isUsedByOtherApps(pkg), result,
+        applyPackageFilter((pkg) ->
+                packageManagerService.getDexManager().isUsedByOtherApps(pkg.packageName), result,
                 remainingPkgs, sortTemp, packageManagerService);
 
         // Filter out packages that aren't recently used, add all remaining apps.
diff --git a/services/core/java/com/android/server/pm/ParallelPackageParser.java b/services/core/java/com/android/server/pm/ParallelPackageParser.java
index 6033855..4ff3e12 100644
--- a/services/core/java/com/android/server/pm/ParallelPackageParser.java
+++ b/services/core/java/com/android/server/pm/ParallelPackageParser.java
@@ -46,6 +46,7 @@
     private final boolean mOnlyCore;
     private final DisplayMetrics mMetrics;
     private final File mCacheDir;
+    private final PackageParser.Callback mPackageParserCallback;
     private volatile String mInterruptedInThread;
 
     private final BlockingQueue<ParseResult> mQueue = new ArrayBlockingQueue<>(QUEUE_CAPACITY);
@@ -54,11 +55,12 @@
             "package-parsing-thread", Process.THREAD_PRIORITY_FOREGROUND);
 
     ParallelPackageParser(String[] separateProcesses, boolean onlyCoreApps,
-            DisplayMetrics metrics, File cacheDir) {
+            DisplayMetrics metrics, File cacheDir, PackageParser.Callback callback) {
         mSeparateProcesses = separateProcesses;
         mOnlyCore = onlyCoreApps;
         mMetrics = metrics;
         mCacheDir = cacheDir;
+        mPackageParserCallback = callback;
     }
 
     static class ParseResult {
@@ -110,6 +112,7 @@
                 pp.setOnlyCoreApps(mOnlyCore);
                 pp.setDisplayMetrics(mMetrics);
                 pp.setCacheDir(mCacheDir);
+                pp.setCallback(mPackageParserCallback);
                 pr.scanFile = scanFile;
                 pr.pkg = parsePackage(pp, scanFile, parseFlags);
             } catch (Throwable e) {
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index ac98ab9..7885748 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -1635,10 +1635,10 @@
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
                         + " still has an icon");
             }
-            if (si.hasMaskableBitmap() && !si.hasIconFile()) {
+            if (si.hasAdaptiveBitmap() && !si.hasIconFile()) {
                 failed = true;
                 Log.e(TAG_VERIFY, "Package " + getPackageName() + ": shortcut " + si.getId()
-                    + " has maskable bitmap but was not saved to a file.");
+                    + " has adaptive bitmap but was not saved to a file.");
             }
             if (si.hasIconFile() && si.hasIconResource()) {
                 failed = true;
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 74eb340..43288cd 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -46,7 +46,6 @@
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutManager;
 import android.content.pm.ShortcutServiceInternal;
 import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
 import android.content.pm.UserInfo;
@@ -1219,7 +1218,7 @@
         shortcut.setIconResourceId(0);
         shortcut.setIconResName(null);
         shortcut.clearFlags(ShortcutInfo.FLAG_HAS_ICON_FILE |
-            ShortcutInfo.FLAG_MASKABLE_BITMAP | ShortcutInfo.FLAG_HAS_ICON_RES);
+            ShortcutInfo.FLAG_ADAPTIVE_BITMAP | ShortcutInfo.FLAG_HAS_ICON_RES);
     }
 
     public void cleanupBitmapsForPackage(@UserIdInt int userId, String packageName) {
@@ -1355,7 +1354,7 @@
                         return;
                     }
                     case Icon.TYPE_BITMAP:
-                    case Icon.TYPE_BITMAP_MASKABLE: {
+                    case Icon.TYPE_ADAPTIVE_BITMAP: {
                         bitmap = icon.getBitmap(); // Don't recycle in this case.
                         break;
                     }
@@ -1386,8 +1385,8 @@
 
                         shortcut.setBitmapPath(out.getFile().getAbsolutePath());
                         shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_FILE);
-                        if (icon.getType() == Icon.TYPE_BITMAP_MASKABLE) {
-                            shortcut.addFlags(ShortcutInfo.FLAG_MASKABLE_BITMAP);
+                        if (icon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
+                            shortcut.addFlags(ShortcutInfo.FLAG_ADAPTIVE_BITMAP);
                         }
                     } finally {
                         IoUtils.closeQuietly(out);
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 00f3711..755c486 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -22,6 +22,7 @@
 import android.content.pm.PackageParser;
 import android.os.RemoteException;
 import android.os.storage.StorageManager;
+import android.os.UserHandle;
 
 import android.util.Slog;
 
@@ -179,17 +180,64 @@
         }
     }
 
-    public void notifyPackageInstalled(PackageInfo info, int userId) {
-        cachePackageCodeLocation(info, userId);
+    /**
+     * Notifies that a new package was installed for {@code userId}.
+     * {@code userId} must not be {@code UserHandle.USER_ALL}.
+     *
+     * @throws IllegalArgumentException if {@code userId} is {@code UserHandle.USER_ALL}.
+     */
+    public void notifyPackageInstalled(PackageInfo pi, int userId) {
+        if (userId == UserHandle.USER_ALL) {
+            throw new IllegalArgumentException(
+                "notifyPackageInstalled called with USER_ALL");
+        }
+        cachePackageCodeLocation(pi.packageName, pi.applicationInfo.sourceDir,
+                pi.applicationInfo.splitSourceDirs, pi.applicationInfo.dataDir, userId);
     }
 
-    private void cachePackageCodeLocation(PackageInfo info, int userId) {
-        PackageCodeLocations pcl = mPackageCodeLocationsCache.get(info.packageName);
-        if (pcl != null) {
-            pcl.mergeAppDataDirs(info.applicationInfo, userId);
-        } else {
-            mPackageCodeLocationsCache.put(info.packageName,
-                new PackageCodeLocations(info.applicationInfo, userId));
+    /**
+     * Notifies that package {@code packageName} was updated.
+     * This will clear the UsedByOtherApps mark if it exists.
+     */
+    public void notifyPackageUpdated(String packageName, String baseCodePath,
+            String[] splitCodePaths) {
+        cachePackageCodeLocation(packageName, baseCodePath, splitCodePaths, null, /*userId*/ -1);
+        // In case there was an update, write the package use info to disk async.
+        // Note that we do the writing here and not in PackageDexUsage in order to be
+        // consistent with other methods in DexManager (e.g. reconcileSecondaryDexFiles performs
+        // multiple updates in PackaeDexUsage before writing it).
+        if (mPackageDexUsage.clearUsedByOtherApps(packageName)) {
+            mPackageDexUsage.maybeWriteAsync();
+        }
+    }
+
+    /**
+     * Notifies that the user {@code userId} data for package {@code packageName}
+     * was destroyed. This will remove all usage info associated with the package
+     * for the given user.
+     * {@code userId} is allowed to be {@code UserHandle.USER_ALL} in which case
+     * all usage information for the package will be removed.
+     */
+    public void notifyPackageDataDestroyed(String packageName, int userId) {
+        boolean updated = userId == UserHandle.USER_ALL
+            ? mPackageDexUsage.removePackage(packageName)
+            : mPackageDexUsage.removeUserPackage(packageName, userId);
+        // In case there was an update, write the package use info to disk async.
+        // Note that we do the writing here and not in PackageDexUsage in order to be
+        // consistent with other methods in DexManager (e.g. reconcileSecondaryDexFiles performs
+        // multiple updates in PackaeDexUsage before writing it).
+        if (updated) {
+            mPackageDexUsage.maybeWriteAsync();
+        }
+    }
+
+    public void cachePackageCodeLocation(String packageName, String baseCodePath,
+            String[] splitCodePaths, String dataDir, int userId) {
+        PackageCodeLocations pcl = putIfAbsent(mPackageCodeLocationsCache, packageName,
+                new PackageCodeLocations(packageName, baseCodePath, splitCodePaths));
+        pcl.updateCodeLocation(baseCodePath, splitCodePaths);
+        if (dataDir != null) {
+            pcl.mergeAppDataDirs(dataDir, userId);
         }
     }
 
@@ -202,7 +250,8 @@
             int userId = entry.getKey();
             for (PackageInfo pi : packageInfoList) {
                 // Cache the code locations.
-                cachePackageCodeLocation(pi, userId);
+                cachePackageCodeLocation(pi.packageName, pi.applicationInfo.sourceDir,
+                        pi.applicationInfo.splitSourceDirs, pi.applicationInfo.dataDir, userId);
 
                 // Cache a map from package name to the set of user ids who installed the package.
                 // We will use it to sync the data and remove obsolete entries from
@@ -359,6 +408,23 @@
     }
 
     /**
+     * Return true if the profiling data collected for the given app indicate
+     * that the apps's APK has been loaded by another app.
+     * Note that this returns false for all apps without any collected profiling data.
+    */
+    public boolean isUsedByOtherApps(String packageName) {
+        PackageUseInfo useInfo = getPackageUseInfo(packageName);
+        if (useInfo == null) {
+            // No use info, means the package was not used or it was used but not by other apps.
+            // Note that right now we might prune packages which are not used by other apps.
+            // TODO(calin): maybe we should not (prune) so we can have an accurate view when we try
+            // to access the package use.
+            return false;
+        }
+        return useInfo.isUsedByOtherApps();
+    }
+
+    /**
      * Retrieves the package which owns the given dexPath.
      */
     private DexSearchResult getDexPackage(
@@ -408,27 +474,36 @@
      */
     private static class PackageCodeLocations {
         private final String mPackageName;
-        private final String mBaseCodePath;
+        private String mBaseCodePath;
         private final Set<String> mSplitCodePaths;
         // Maps user id to the application private directory.
         private final Map<Integer, Set<String>> mAppDataDirs;
 
         public PackageCodeLocations(ApplicationInfo ai, int userId) {
-            mPackageName = ai.packageName;
-            mBaseCodePath = ai.sourceDir;
+            this(ai.packageName, ai.sourceDir, ai.splitSourceDirs);
+            mergeAppDataDirs(ai.dataDir, userId);
+        }
+        public PackageCodeLocations(String packageName, String baseCodePath,
+                String[] splitCodePaths) {
+            mPackageName = packageName;
             mSplitCodePaths = new HashSet<>();
-            if (ai.splitSourceDirs != null) {
-                for (String split : ai.splitSourceDirs) {
+            mAppDataDirs = new HashMap<>();
+            updateCodeLocation(baseCodePath, splitCodePaths);
+        }
+
+        public void updateCodeLocation(String baseCodePath, String[] splitCodePaths) {
+            mBaseCodePath = baseCodePath;
+            mSplitCodePaths.clear();
+            if (splitCodePaths != null) {
+                for (String split : splitCodePaths) {
                     mSplitCodePaths.add(split);
                 }
             }
-            mAppDataDirs = new HashMap<>();
-            mergeAppDataDirs(ai, userId);
         }
 
-        public void mergeAppDataDirs(ApplicationInfo ai, int userId) {
+        public void mergeAppDataDirs(String dataDir, int userId) {
             Set<String> dataDirs = putIfAbsent(mAppDataDirs, userId, new HashSet<>());
-            dataDirs.add(ai.dataDir);
+            dataDirs.add(dataDir);
         }
 
         public int searchDex(String dexPath, int userId) {
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index 3693bce0..8a66f12 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -377,7 +377,34 @@
     }
 
     /**
+     * Clears the {@code usesByOtherApps} marker for the package {@code packageName}.
+     * @return true if the package usage info was updated.
+     */
+    public boolean clearUsedByOtherApps(String packageName) {
+        synchronized (mPackageUseInfoMap) {
+            PackageUseInfo packageUseInfo = mPackageUseInfoMap.get(packageName);
+            if (packageUseInfo == null || !packageUseInfo.mIsUsedByOtherApps) {
+                return false;
+            }
+            packageUseInfo.mIsUsedByOtherApps = false;
+            return true;
+        }
+    }
+
+    /**
+     * Remove the usage data associated with package {@code packageName}.
+     * @return true if the package usage was found and removed successfully.
+     */
+    public boolean removePackage(String packageName) {
+        synchronized (mPackageUseInfoMap) {
+            return mPackageUseInfoMap.remove(packageName) != null;
+        }
+    }
+
+    /**
      * Remove all the records about package {@code packageName} belonging to user {@code userId}.
+     * If the package is left with no records of secondary dex usage and is not used by other
+     * apps it will be removed as well.
      * @return true if the record was found and actually deleted,
      *         false if the record doesn't exist
      */
@@ -397,6 +424,12 @@
                     updated = true;
                 }
             }
+            // If no secondary dex info is left and the package is not used by other apps
+            // remove the data since it is now useless.
+            if (packageUseInfo.mDexUseInfoMap.isEmpty() && !packageUseInfo.mIsUsedByOtherApps) {
+                mPackageUseInfoMap.remove(packageName);
+                updated = true;
+            }
             return updated;
         }
     }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0d6cd80..4f1754a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2398,8 +2398,8 @@
              * permission to add alert windows that aren't
              * {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}.
              */
-            return (mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED)
-                    ? ADD_OKAY : ADD_PERMISSION_DENIED;
+            return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
+                    == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
         }
 
         // check if user has enabled this operation. SecurityException will be thrown if this app
@@ -2420,8 +2420,8 @@
             default:
                 // in the default mode, we will make a decision here based on
                 // checkCallingPermission()
-                return (mContext.checkCallingPermission(SYSTEM_ALERT_WINDOW) == PERMISSION_GRANTED)
-                        ? ADD_OKAY : ADD_PERMISSION_DENIED;
+                return (mContext.checkCallingOrSelfPermission(SYSTEM_ALERT_WINDOW)
+                        == PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
         }
     }
 
diff --git a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
index afdec9f..12836db 100644
--- a/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
+++ b/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
@@ -17,6 +17,7 @@
 package com.android.server.storage;
 
 import android.app.NotificationChannel;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.server.EventLogTags;
 import com.android.server.SystemService;
 import com.android.server.pm.InstructionSets;
@@ -141,7 +142,7 @@
      */
     static final String SERVICE = "devicestoragemonitor";
 
-    private static final String NOTIFICATION_CHANNEL_ID = SERVICE;
+    private static final String TV_NOTIFICATION_CHANNEL_ID = "devicestoragemonitor.tv";
 
     /**
     * Handler that checks the amount of disk space on the device and sends a
@@ -388,14 +389,13 @@
         PackageManager packageManager = context.getPackageManager();
         boolean isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
 
-        int importance = isTv
-            ? NotificationManager.IMPORTANCE_HIGH   // Do not change: this is TV-specific
-            : NotificationManager.IMPORTANCE_LOW;
-        notificationMgr.createNotificationChannel(
-            new NotificationChannel(NOTIFICATION_CHANNEL_ID,
-                context.getString(
-                    com.android.internal.R.string.device_storage_monitor_notification_channel),
-                importance));
+        if (isTv) {
+            notificationMgr.createNotificationChannel(new NotificationChannel(
+                    TV_NOTIFICATION_CHANNEL_ID,
+                    context.getString(
+                        com.android.internal.R.string.device_storage_monitor_notification_channel),
+                    NotificationManager.IMPORTANCE_HIGH));
+        }
 
         publishBinderService(SERVICE, mRemoteService);
         publishLocalService(DeviceStorageMonitorInternal.class, mLocalService);
@@ -495,21 +495,22 @@
                 : com.android.internal.R.string.low_internal_storage_view_text_no_boot);
         PendingIntent intent = PendingIntent.getActivityAsUser(context, 0,  lowMemIntent, 0,
                 null, UserHandle.CURRENT);
-        Notification notification = new Notification.Builder(context)
-                .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full)
-                .setTicker(title)
-                .setColor(context.getColor(
-                    com.android.internal.R.color.system_notification_accent_color))
-                .setContentTitle(title)
-                .setContentText(details)
-                .setContentIntent(intent)
-                .setStyle(new Notification.BigTextStyle()
-                      .bigText(details))
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setCategory(Notification.CATEGORY_SYSTEM)
-                .setChannel(NOTIFICATION_CHANNEL_ID)
-                .extend(new Notification.TvExtender())
-                .build();
+        Notification notification =
+                new Notification.Builder(context, SystemNotificationChannels.ALERTS)
+                        .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full)
+                        .setTicker(title)
+                        .setColor(context.getColor(
+                            com.android.internal.R.color.system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(details)
+                        .setContentIntent(intent)
+                        .setStyle(new Notification.BigTextStyle()
+                              .bigText(details))
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setCategory(Notification.CATEGORY_SYSTEM)
+                        .extend(new Notification.TvExtender()
+                                .setChannel(TV_NOTIFICATION_CHANNEL_ID))
+                        .build();
         notification.flags |= Notification.FLAG_NO_CLEAR;
         notificationMgr.notifyAsUser(null, LOW_MEMORY_NOTIFICATION_ID, notification,
                 UserHandle.ALL);
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index 0d282ef..b7b419b 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.app.Notification.VISIBILITY_PRIVATE;
 import static android.app.NotificationManager.IMPORTANCE_MIN;
 import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
 import static android.content.Context.NOTIFICATION_SERVICE;
@@ -34,8 +33,10 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+
 import com.android.internal.R;
+import com.android.server.policy.IconUtilities;
 
 /** Displays an ongoing notification for a process displaying an alert window */
 class AlertWindowNotification {
@@ -50,6 +51,7 @@
     private final String mPackageName;
     private final int mUid;
     private boolean mCancelled;
+    private IconUtilities mIconUtilities;
 
     AlertWindowNotification(WindowManagerService service, String packageName, int uid) {
         mService = service;
@@ -59,20 +61,33 @@
                 (NotificationManager) mService.mContext.getSystemService(NOTIFICATION_SERVICE);
         mNotificationTag = CHANNEL_PREFIX + mPackageName;
         mRequestCode = sNextRequestCode++;
+        mIconUtilities = new IconUtilities(mService.mContext);
 
         // 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::postNotification);
+        mService.mH.post(this::onPostNotification);
     }
 
     /** Cancels the notification */
     void cancel() {
+        // We can't call into NotificationManager with WM lock held since it might call into AM.
+        // So, we post a message to do it later.
+        mService.mH.post(this::onCancelNotification);
+    }
+
+    /** Don't call with the window manager lock held! */
+    private void onCancelNotification() {
         mNotificationManager.cancel(mNotificationTag, NOTIFICATION_ID);
         mCancelled = true;
     }
 
     /** Don't call with the window manager lock held! */
-    private void postNotification() {
+    private void onPostNotification() {
+        if (mCancelled) {
+            // Notification was cancelled, so nothing more to do...
+            return;
+        }
+
         final Context context = mService.mContext;
         final PackageManager pm = context.getPackageManager();
         final ApplicationInfo aInfo = getApplicationInfo(pm, mPackageName);
@@ -94,17 +109,14 @@
                 .addAction(getTurnOffAction(context, mPackageName, mUid));
 
         if (aInfo != null) {
-            final Bitmap bitmap = ((BitmapDrawable) pm.getApplicationIcon(aInfo)).getBitmap();
-            builder.setLargeIcon(bitmap);
+            final Drawable drawable = pm.getApplicationIcon(aInfo);
+            if (drawable != null) {
+                final Bitmap bitmap = mIconUtilities.createIconBitmap(drawable);
+                builder.setLargeIcon(bitmap);
+            }
         }
 
-        synchronized (mService.mWindowMap) {
-            if (mCancelled) {
-                // Notification was cancelled, so nothing more to do...
-                return;
-            }
-            mNotificationManager.notify(mNotificationTag, NOTIFICATION_ID, builder.build());
-        }
+        mNotificationManager.notify(mNotificationTag, NOTIFICATION_ID, builder.build());
     }
 
     private Notification.Action getTurnOffAction(Context context, String packageName, int uid) {
diff --git a/services/core/java/com/android/server/wm/AppWindowAnimator.java b/services/core/java/com/android/server/wm/AppWindowAnimator.java
index c42647e..e3941b9 100644
--- a/services/core/java/com/android/server/wm/AppWindowAnimator.java
+++ b/services/core/java/com/android/server/wm/AppWindowAnimator.java
@@ -248,8 +248,9 @@
         }
     }
 
-    void updateLayers() {
-        thumbnailLayer = mAppToken.adjustAnimLayer(animLayerAdjustment);
+    private void updateLayers() {
+        mAppToken.getDisplayContent().assignWindowLayers(false /* relayoutNeeded */);
+        thumbnailLayer = mAppToken.getHighestAnimLayer();
     }
 
     private void stepThumbnailAnimation(long currentTime) {
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 3a86874..266ab4c 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -525,7 +525,8 @@
 
     private boolean createSnapshot() {
         final TaskSnapshot snapshot = mService.mTaskSnapshotController.getSnapshot(
-                mContainer.mTask.mTaskId, mContainer.mTask.mUserId, false /* restoreFromDisk */);
+                mContainer.getTask().mTaskId, mContainer.getTask().mUserId,
+            false /* restoreFromDisk */);
 
         if (snapshot == null) {
             return false;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 2263042..994f38d 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -85,13 +85,17 @@
     final boolean mVoiceInteraction;
 
     // TODO: Use getParent instead?
-    Task mTask;
+    private Task mTask;
     /** @see WindowContainer#fillsParent() */
     private boolean mFillsParent;
     boolean layoutConfigChanges;
     boolean mShowForAllUsers;
     int mTargetSdk;
 
+    // Flag set while reparenting to prevent actions normally triggered by an individual parent
+    // change.
+    private boolean mReparenting;
+
     // The input dispatching timeout for this application token in nanoseconds.
     long mInputDispatchingTimeoutNanos;
 
@@ -426,10 +430,7 @@
     void removeIfPossible() {
         mIsExiting = false;
         removeAllWindowsIfPossible();
-        if (mTask != null) {
-            mTask.mStack.mExitingAppTokens.remove(this);
-            removeImmediately();
-        }
+        removeImmediately();
     }
 
     @Override
@@ -483,6 +484,7 @@
 
         removed = true;
         stopFreezingScreen(true, true);
+
         if (mService.mFocusedApp == this) {
             if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this);
             mService.mFocusedApp = null;
@@ -664,6 +666,37 @@
         allDrawnExcludingSaved = false;
     }
 
+    Task getTask() {
+        return mTask;
+    }
+
+    /**
+     * Sets the associated task, cleaning up dependencies when unset.
+     */
+    void setTask(Task task) {
+        // Note: the following code assumes that the previous task's stack is the same as the
+        // new task's stack.
+        if (!mReparenting && mTask != null && mTask.mStack != null) {
+            mTask.mStack.mExitingAppTokens.remove(this);
+        }
+
+        mTask = task;
+    }
+
+    @Override
+    void onParentSet() {
+        super.onParentSet();
+
+        // When the associated task is {@code null}, the {@link AppWindowToken} can no longer
+        // access visual elements like the {@link DisplayContent}. We must remove any associations
+        // such as animations.
+        if (!mReparenting && mTask == null) {
+            // It is possible we have been marked as a closing app earlier. We must remove ourselves
+            // from this list so we do not participate in any future animations.
+            mService.mClosingApps.remove(this);
+        }
+    }
+
     void postWindowRemoveStartingWindowCleanup(WindowState win) {
         // TODO: Something smells about the code below...Is there a better way?
         if (startingWindow == win) {
@@ -762,6 +795,16 @@
         if (canFreezeBounds()) {
             freezeBounds();
         }
+
+        // In the process of tearing down before relaunching, the app will
+        // try and clean up it's child surfaces. We need to prevent this from
+        // happening, so we sever the children, transfering their ownership
+        // from the client it-self to the parent surface (owned by us).
+        for (int i = mChildren.size() - 1; i >= 0; i--) {
+            final WindowState w = mChildren.get(i);
+            w.mWinAnimator.detachChildren();
+        }
+
         mPendingRelaunchCount++;
     }
 
@@ -856,13 +899,24 @@
             throw new IllegalArgumentException(
                     "window token=" + this + " already child of task=" + mTask);
         }
+
+        if (mTask.mStack != task.mStack) {
+            throw new IllegalArgumentException(
+                    "window token=" + this + " current task=" + mTask
+                        + " belongs to a different stack than " + task);
+        }
+
         if (DEBUG_ADD_REMOVE) Slog.i(TAG, "reParentWindowToken: removing window token=" + this
                 + " from task=" + mTask);
         final DisplayContent prevDisplayContent = getDisplayContent();
 
+        mReparenting = true;
+
         getParent().removeChild(this);
         task.addChild(this, position);
 
+        mReparenting = false;
+
         // Relayout display(s).
         final DisplayContent displayContent = task.getDisplayContent();
         displayContent.setLayoutNeeded();
@@ -1409,6 +1463,11 @@
     }
 
     @Override
+    int getAnimLayerAdjustment() {
+        return mAppAnimator.animLayerAdjustment;
+    }
+
+    @Override
     void dump(PrintWriter pw, String prefix) {
         super.dump(pw, prefix);
         if (appToken != null) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2c315445..461c3fa 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -341,9 +341,6 @@
         }
     };
 
-    private final Consumer<WindowState> mSetInputMethodAnimLayerAdjustment =
-            w -> w.adjustAnimLayer(mInputMethodAnimLayerAdjustment);
-
     private final Consumer<WindowState> mScheduleToastTimeout = w -> {
         final int lostFocusUid = mTmpWindow.mOwnerUid;
         final Handler handler = mService.mH;
@@ -1281,8 +1278,7 @@
     void setInputMethodAnimLayerAdjustment(int adj) {
         if (DEBUG_LAYERS) Slog.v(TAG_WM, "Setting im layer adj to " + adj);
         mInputMethodAnimLayerAdjustment = adj;
-        mImeWindowsContainers.forAllWindows(mSetInputMethodAnimLayerAdjustment,
-                true /* traverseTopToBottom */);
+        assignWindowLayers(false /* relayoutNeeded */);
     }
 
     /**
@@ -1588,9 +1584,24 @@
         // TODO(multidisplay): Needs some serious rethought when the target and IME are not on the
         // same display. Or even when the current IME/target are not on the same screen as the next
         // IME/target. For now only look for input windows on the main screen.
-        mUpdateImeTarget = updateImeTarget;
-        WindowState target = getWindow(mComputeImeTargetPredicate);
 
+        // The target candidate provided by the IME tells us which window token, but not which
+        // window within the token (e.g. child windows...). So, we use the token to look-up the
+        // best target window.
+        // TODO: Have the input method service report the right window with the token vs. just the
+        // base window of the token.
+        final WindowState baseWin = mService.getWindow(mService.mInputMethodTargetCandidate);
+        final WindowToken targetToken = baseWin != null ? baseWin.mToken : null;
+        WindowState target = targetToken != null ?
+                targetToken.getWindow(mComputeImeTargetPredicate) : null;
+        // If there isn't a better candidate in the token (maybe because they are not visible), then
+        // fall back to targeting the base window of the token, so the IME can still maintain the
+        // right z-order based on the last person that set it vs. changing its z-order to the very
+        // up since there if target is null.
+        // TODO: Consider z-ordering IME to bottom instead of top if there is no visible target.
+        // Also, consider tying the visible the visibility of the IME to the current target. I.e if
+        // target isn't visible, then IME shouldn't be visible.
+        target = target == null ? baseWin : target;
 
         // Yet more tricksyness!  If this window is a "starting" window, we do actually want
         // to be on top of it, but it is not -really- where input will go. So look down below
@@ -1673,7 +1684,7 @@
             if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "Moving IM target from " + curTarget + " to "
                     + target + (SHOW_STACK_CRAWLS ? " Callers=" + Debug.getCallers(4) : ""));
             setInputMethodTarget(target, false, target.mAppToken != null
-                    ? target.mAppToken.mAppAnimator.animLayerAdjustment : 0);
+                    ? target.mAppToken.getAnimLayerAdjustment() : 0);
         }
 
         return target;
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 75a79fd..aa8e377 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -588,7 +588,7 @@
     private boolean containsAppInDockedStack(ArraySet<AppWindowToken> apps) {
         for (int i = apps.size() - 1; i >= 0; i--) {
             final AppWindowToken token = apps.valueAt(i);
-            if (token.mTask != null && token.mTask.mStack.mStackId == DOCKED_STACK_ID) {
+            if (token.getTask() != null && token.getTask().mStack.mStackId == DOCKED_STACK_ID) {
                 return true;
             }
         }
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 5f41187..2a20a70 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -230,32 +230,37 @@
     }
 
     /**
-     * @param preChangeTargetBounds The final bounds of the stack if it is currently animating
-     * @return the repositioned PIP bounds given it's pre-change bounds, and the new display
-     *         content.
+     * Updates the display info, calculating and returning the new stack and movement bounds in the
+     * new orientation of the device if necessary.
      */
-    Rect onDisplayChanged(Rect preChangeStackBounds, Rect preChangeTargetBounds,
-            DisplayContent displayContent) {
-        final Rect postChangeStackBounds = new Rect(preChangeTargetBounds);
-        final DisplayInfo displayInfo = displayContent.getDisplayInfo();
-        if (!mDisplayInfo.equals(displayInfo)) {
-            // Calculate the snap fraction of the current stack along the old movement bounds, and
-            // then update the stack bounds to the same fraction along the rotated movement bounds.
-            final Rect preChangeMovementBounds = getMovementBounds(preChangeStackBounds);
-            final float snapFraction = mSnapAlgorithm.getSnapFraction(preChangeStackBounds,
-                    preChangeMovementBounds);
-            mDisplayInfo.copyFrom(displayInfo);
-
-            final Rect postChangeMovementBounds = getMovementBounds(preChangeStackBounds,
-                    false /* adjustForIme */);
-            mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
-                    snapFraction);
-            if (mIsMinimized) {
-                applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
-            }
-            notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+    void onTaskStackBoundsChanged(Rect targetBounds, Rect outBounds) {
+        final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
+        if (mDisplayInfo.equals(displayInfo)) {
+            return;
         }
-        return postChangeStackBounds;
+
+        mTmpRect.set(targetBounds);
+        final Rect postChangeStackBounds = mTmpRect;
+
+        // Calculate the snap fraction of the current stack along the old movement bounds
+        final Rect preChangeMovementBounds = getMovementBounds(postChangeStackBounds);
+        final float snapFraction = mSnapAlgorithm.getSnapFraction(postChangeStackBounds,
+                preChangeMovementBounds);
+        mDisplayInfo.copyFrom(displayInfo);
+
+        // Calculate the stack bounds in the new orientation to the same same fraction along the
+        // rotated movement bounds.
+        final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
+                false /* adjustForIme */);
+        mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
+                snapFraction);
+        if (mIsMinimized) {
+            applyMinimizedOffset(postChangeStackBounds, postChangeMovementBounds);
+        }
+
+        notifyMovementBoundsChanged(false /* fromImeAdjustment */);
+
+        outBounds.set(postChangeStackBounds);
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 5355f31..720a454 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -93,7 +93,7 @@
         mUid = Binder.getCallingUid();
         mPid = Binder.getCallingPid();
         mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
-        mCanAddInternalSystemWindow = service.mContext.checkCallingPermission(
+        mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission(
                 INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
         StringBuilder sb = new StringBuilder();
         sb.append("Session{");
@@ -664,6 +664,7 @@
 
     void dump(PrintWriter pw, String prefix) {
         pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
+                pw.print(" mCanAddInternalSystemWindow="); pw.print(mCanAddInternalSystemWindow);
                 pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces);
                 pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
                 pw.print(" mClientDead="); pw.print(mClientDead);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index da5fcf3..07eb88d 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -133,7 +133,7 @@
     void addChild(AppWindowToken wtoken, int position) {
         position = getAdjustedAddPosition(position);
         super.addChild(wtoken, position);
-        wtoken.mTask = this;
+        wtoken.setTask(this);
         mDeferRemoval = false;
     }
 
@@ -244,7 +244,8 @@
                 removeIfPossible();
             }
         }
-        token.mTask = null;
+
+        token.setTask(null /*task*/);
     }
 
     void setSendingToBottom(boolean toBottom) {
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotCache.java b/services/core/java/com/android/server/wm/TaskSnapshotCache.java
index 601bf28..4028336 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotCache.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotCache.java
@@ -106,8 +106,8 @@
         if (taskId != null) {
             removeRunningEntry(taskId);
         }
-        if (wtoken.mTask != null) {
-            mRetrievalCache.remove(wtoken.mTask.mTaskId);
+        if (wtoken.getTask() != null) {
+            mRetrievalCache.remove(wtoken.getTask().mTaskId);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 5041138..5995bba 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -141,11 +141,12 @@
         outClosingTasks.clear();
         for (int i = closingApps.size() - 1; i >= 0; i--) {
             final AppWindowToken atoken = closingApps.valueAt(i);
+            final Task task = atoken.getTask();
 
             // If the task of the app is not visible anymore, it means no other app in that task
             // is opening. Thus, the task is closing.
-            if (atoken.mTask != null && !atoken.mTask.isVisible()) {
-                outClosingTasks.add(closingApps.valueAt(i).mTask);
+            if (task != null && !task.isVisible()) {
+                outClosingTasks.add(task);
             }
         }
     }
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 9f52412..9f34bd7 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -96,9 +96,11 @@
             // TODO: Inherit behavior whether to draw behind status bar/nav bar.
             layoutParams.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                     | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
-            layoutParams.setTitle(String.format(TITLE_FORMAT, token.mTask.mTaskId));
-            if (token.mTask != null) {
-                final TaskDescription taskDescription = token.mTask.getTaskDescription();
+            final Task task = token.getTask();
+            if (task != null) {
+                layoutParams.setTitle(String.format(TITLE_FORMAT,task.mTaskId));
+
+                final TaskDescription taskDescription = task.getTaskDescription();
                 if (taskDescription != null) {
                     fillBackgroundColor = taskDescription.getBackgroundColor();
                 }
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index c7532ac..6cc2efb 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -262,6 +262,12 @@
 
         if (mDisplayContent != null) {
             mDisplayContent.mDimLayerController.updateDimLayer(this);
+            if (mStackId == PINNED_STACK_ID) {
+                // Update the bounds based on any changes to the display info
+                getAnimatingBounds(mTmpRect2);
+                mDisplayContent.mPinnedStackControllerLocked.onTaskStackBoundsChanged(mTmpRect2,
+                        bounds);
+            }
             mAnimationBackgroundSurface.setBounds(bounds);
         }
 
@@ -391,15 +397,18 @@
             return false;
         }
 
+        if (StackId.tasksAreFloating(mStackId)) {
+            // Update stack bounds again since the display info has changed since updateDisplayInfo,
+            // however, for floating tasks, we don't need to apply the new rotation to the bounds,
+            // we can just update and return them here
+            setBounds(mBounds);
+            mBoundsAfterRotation.set(mBounds);
+            return true;
+        }
+
         mTmpRect2.set(mBounds);
         mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
         switch (mStackId) {
-            case PINNED_STACK_ID:
-                Rect targetBounds = new Rect();
-                getAnimatingBounds(targetBounds);
-                mTmpRect2 = mDisplayContent.getPinnedStackController().onDisplayChanged(mBounds,
-                        targetBounds, mDisplayContent);
-                break;
             case DOCKED_STACK_ID:
                 repositionDockedStackAfterRotation(mTmpRect2);
                 snapDockedStackAfterRotation(mTmpRect2);
@@ -635,7 +644,7 @@
         }
         for (int appNdx = mExitingAppTokens.size() - 1; appNdx >= 0; --appNdx) {
             final AppWindowToken wtoken = mExitingAppTokens.get(appNdx);
-            if (wtoken.mTask == task) {
+            if (wtoken.getTask() == task) {
                 wtoken.mIsExiting = false;
                 mExitingAppTokens.remove(appNdx);
             }
@@ -651,7 +660,6 @@
         mAnimationBackgroundSurface = new DimLayer(mService, this, mDisplayContent.getDisplayId(),
                 "animation background stackId=" + mStackId);
 
-        final Rect oldBounds = new Rect(mBounds);
         Rect bounds = null;
         final TaskStack dockedStack = dc.getDockedStackIgnoringVisibility();
         if (mStackId == DOCKED_STACK_ID
@@ -675,15 +683,6 @@
         }
 
         updateDisplayInfo(bounds);
-
-        // Update the pinned stack controller after the display info is updated
-        if (mStackId == PINNED_STACK_ID) {
-            Rect targetBounds = new Rect();
-            getAnimatingBounds(targetBounds);
-            mDisplayContent.getPinnedStackController().onDisplayChanged(oldBounds, targetBounds,
-                    mDisplayContent);
-        }
-
         super.onDisplayChanged(dc);
     }
 
@@ -1426,16 +1425,6 @@
     }
 
     public boolean setPinnedStackSize(Rect bounds, Rect tempTaskBounds) {
-        synchronized (mService.mWindowMap) {
-            if (mDisplayContent == null) {
-                return false;
-            }
-            if (mStackId != PINNED_STACK_ID) {
-                Slog.w(TAG_WM, "Attempt to use pinned stack resize animation helper on"
-                        + "non pinned stack");
-                return false;
-            }
-        }
         try {
             mService.mActivityManager.resizePinnedStack(bounds, tempTaskBounds);
         } catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index c32e689..7213c95 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -547,6 +547,7 @@
         for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
             final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
             token.updateWallpaperWindows(visible, mWallpaperAnimLayerAdjustment);
+            token.getDisplayContent().assignWindowLayers(false);
         }
     }
 
@@ -568,7 +569,7 @@
             // Only do this if we are not transferring between two wallpaper targets.
             mWallpaperAnimLayerAdjustment =
                     (mPrevWallpaperTarget == null && mWallpaperTarget.mAppToken != null)
-                            ? mWallpaperTarget.mAppToken.mAppAnimator.animLayerAdjustment : 0;
+                            ? mWallpaperTarget.mAppToken.getAnimLayerAdjustment() : 0;
 
             if (mWallpaperTarget.mWallpaperX >= 0) {
                 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
diff --git a/services/core/java/com/android/server/wm/WallpaperWindowToken.java b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
index 28aebbb..a12c0e5 100644
--- a/services/core/java/com/android/server/wm/WallpaperWindowToken.java
+++ b/services/core/java/com/android/server/wm/WallpaperWindowToken.java
@@ -142,7 +142,6 @@
 
             // First, make sure the client has the current visibility state.
             wallpaper.dispatchWallpaperVisibility(visible);
-            wallpaper.adjustAnimLayer(animLayerAdj);
 
             if (DEBUG_LAYERS || DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "adjustWallpaper win "
                     + wallpaper + " anim layer: " + wallpaper.mWinAnimator.mAnimLayer);
diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java
index 1cd2b53d..172ec48 100644
--- a/services/core/java/com/android/server/wm/WindowLayersController.java
+++ b/services/core/java/com/android/server/wm/WindowLayersController.java
@@ -129,7 +129,7 @@
             final WindowStateAnimator winAnimator = w.mWinAnimator;
             Slog.v(TAG_WM, "Assign layer " + w + ": " + "mBase=" + w.mBaseLayer
                     + " mLayer=" + w.mLayer + (w.mAppToken == null
-                    ? "" : " mAppLayer=" + w.mAppToken.mAppAnimator.animLayerAdjustment)
+                    ? "" : " mAppLayer=" + w.mAppToken.getAnimLayerAdjustment())
                     + " =mAnimLayer=" + winAnimator.mAnimLayer);
         }, false /* traverseTopToBottom */);
     }
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 2f1aab6..eb3a2d1 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -16,7 +16,6 @@
 
 package com.android.server.wm;
 
-import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
 import static android.Manifest.permission.MANAGE_APP_TOKENS;
 import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
@@ -30,7 +29,6 @@
 import static android.content.Intent.EXTRA_UID;
 import static android.content.Intent.EXTRA_USER_HANDLE;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.UserHandle.USER_NULL;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.WindowManager.DOCKED_INVALID;
@@ -69,8 +67,6 @@
 import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
 import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
-import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
-import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
 import static com.android.server.wm.KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
@@ -112,7 +108,6 @@
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
-import android.app.admin.DevicePolicyManager;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -626,9 +621,14 @@
     WindowState mCurrentFocus = null;
     WindowState mLastFocus = null;
 
-    /** This just indicates the window the input method is on top of, not
-     * necessarily the window its input is going to. */
+    // TODO: All the IME window tracking should be moved to DisplayContent and tracked per display.
+    // This just indicates the window the input method is on top of, not necessarily the window its
+    // input is going to.
     WindowState mInputMethodTarget = null;
+    // The binder token currently using the IME as determined by the input method service.
+    // Window manager uses this to determine the final input method target
+    // (almost always this candidate) for z-ordering.
+    IBinder mInputMethodTargetCandidate = null;
 
     /** If true hold off on modifying the animation layer of mInputMethodTarget */
     boolean mInputMethodTargetWaitingAnim;
@@ -1445,9 +1445,9 @@
             if (displayContent.isDefaultDisplay) {
                 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
                 final Rect taskBounds;
-                if (atoken != null && atoken.mTask != null) {
+                if (atoken != null && atoken.getTask() != null) {
                     taskBounds = mTmpRect;
-                    atoken.mTask.getBounds(mTmpRect);
+                    atoken.getTask().getBounds(mTmpRect);
                 } else {
                     taskBounds = null;
                 }
@@ -2199,6 +2199,15 @@
         if (mAccessibilityController != null && win.getDisplayId() == DEFAULT_DISPLAY) {
             mAccessibilityController.onWindowTransitionLocked(win, transit);
         }
+
+        // When we start the exit animation we take the Surface from the client
+        // so it will stop perturbing it. We need to likewise takeaway the SurfaceFlinger
+        // side child surfaces, so they will remain preserved in their current state
+        // (rather than be cleaned up immediately by the app code).
+        SurfaceControl.openTransaction();
+        winAnimator.detachChildren();
+        SurfaceControl.closeTransaction();
+
         return focusMayChange;
     }
 
@@ -2283,7 +2292,7 @@
         // is running.
         Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "WM#applyAnimationLocked");
         if (okToDisplay()) {
-            final DisplayContent displayContent = atoken.mTask.getDisplayContent();
+            final DisplayContent displayContent = atoken.getTask().getDisplayContent();
             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
             final int width = displayInfo.appWidth;
             final int height = displayInfo.appHeight;
@@ -2324,7 +2333,7 @@
             final Configuration displayConfig = displayContent.getConfiguration();
             Animation a = mAppTransition.loadAnimation(lp, transit, enter, displayConfig.uiMode,
                     displayConfig.orientation, frame, displayFrame, insets, surfaceInsets,
-                    isVoiceInteraction, freeform, atoken.mTask.mTaskId);
+                    isVoiceInteraction, freeform, atoken.getTask().mTaskId);
             if (a != null) {
                 if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + atoken);
                 final int containingWidth = frame.width();
@@ -2544,8 +2553,8 @@
     }
 
     void setFocusTaskRegionLocked(AppWindowToken previousFocus) {
-        final Task focusedTask = mFocusedApp != null ? mFocusedApp.mTask : null;
-        final Task previousTask = previousFocus != null ? previousFocus.mTask : null;
+        final Task focusedTask = mFocusedApp != null ? mFocusedApp.getTask() : null;
+        final Task previousTask = previousFocus != null ? previousFocus.getTask() : null;
         final DisplayContent focusedDisplayContent =
                 focusedTask != null ? focusedTask.getDisplayContent() : null;
         final DisplayContent previousDisplayContent =
@@ -5076,8 +5085,8 @@
         // Also don't use mInputMethodTarget's stack, because some window with FLAG_NOT_FOCUSABLE
         // and FLAG_ALT_FOCUSABLE_IM flags both set might be set to IME target so they're moved
         // to make room for IME, but the window is not the focused window that's taking input.
-        return (mFocusedApp != null && mFocusedApp.mTask != null) ?
-                mFocusedApp.mTask.mStack : null;
+        return (mFocusedApp != null && mFocusedApp.getTask() != null) ?
+                mFocusedApp.getTask().mStack : null;
     }
 
     public boolean detectSafeMode() {
@@ -6951,8 +6960,9 @@
             pw.print("  mLastFocus="); pw.println(mLastFocus);
         }
         pw.print("  mFocusedApp="); pw.println(mFocusedApp);
-        if (mInputMethodTarget != null) {
-            pw.print("  mInputMethodTarget="); pw.println(mInputMethodTarget);
+        if (mInputMethodTarget != null || mInputMethodTargetCandidate != null) {
+            pw.println("  mInputMethodTarget=" + mInputMethodTarget
+                    + " mInputMethodTargetCandidate=" + getWindow(mInputMethodTargetCandidate));
         }
         pw.print("  mInTouchMode="); pw.print(mInTouchMode);
                 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
@@ -7819,11 +7829,28 @@
         @Override
         public void updateInputMethodWindowStatus(@NonNull IBinder imeToken,
                 boolean imeWindowVisible, @Nullable IBinder targetWindowToken) {
-            // TODO (b/34628091): Use this method to address the window animation issue.
-            if (DEBUG_INPUT_METHOD) {
-                Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken=" + imeToken
-                        + " imeWindowVisible=" + imeWindowVisible
-                        + " targetWindowToken=" + targetWindowToken);
+            synchronized (mWindowMap) {
+                final WindowState newTargetWin = getWindow(targetWindowToken);
+                final WindowState currentTargetWin = getWindow(mInputMethodTargetCandidate);
+
+                if (DEBUG_INPUT_METHOD) Slog.w(TAG_WM, "updateInputMethodWindowStatus: imeToken="
+                        + imeToken + " imeWindowVisible=" + imeWindowVisible
+                        + " targetWindowToken=" + targetWindowToken
+                        + " newTargetWin=" + newTargetWin
+                        + " currentTargetWin=" + currentTargetWin);
+
+                if (newTargetWin == currentTargetWin) {
+                    return;
+                }
+
+                final DisplayContent dc = newTargetWin != null
+                        ? newTargetWin.getDisplayContent() : currentTargetWin.getDisplayContent();
+
+                // It is possible the window for the target candidate isn't added yet, so we
+                // remember the token instead and use it to look-up the window each time we compute
+                // the ime target.
+                mInputMethodTargetCandidate = targetWindowToken;
+                dc.computeImeTarget(true /* updateImeTarget */);
             }
         }
 
@@ -7869,6 +7896,10 @@
         }
     }
 
+    WindowState getWindow(IBinder binder) {
+        return binder == null ? null : mWindowMap.get(binder);
+    }
+
     void registerAppFreezeListener(AppFreezeListener listener) {
         if (!mAppFreezeListeners.contains(listener)) {
             mAppFreezeListeners.add(listener);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 945a349..4806068 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -844,20 +844,24 @@
         // Make sure the content and visible frames are inside of the
         // final window frame.
         if (windowsAreFloating && !mFrame.isEmpty()) {
+            // For pinned workspace the frame isn't limited in any particular
+            // way since SystemUI controls the bounds. For freeform however
+            // we want to keep things inside the content frame.
+            final Rect limitFrame = task.inPinnedWorkspace() ? mFrame : mContentFrame;
             // Keep the frame out of the blocked system area, limit it in size to the content area
             // and make sure that there is always a minimum visible so that the user can drag it
             // into a usable area..
-            final int height = Math.min(mFrame.height(), mContentFrame.height());
-            final int width = Math.min(mContentFrame.width(), mFrame.width());
+            final int height = Math.min(mFrame.height(), limitFrame.height());
+            final int width = Math.min(limitFrame.width(), mFrame.width());
             final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
             final int minVisibleHeight = Math.min(height, WindowManagerService.dipToPixel(
                     MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics));
             final int minVisibleWidth = Math.min(width, WindowManagerService.dipToPixel(
                     MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics));
-            final int top = Math.max(mContentFrame.top,
-                    Math.min(mFrame.top, mContentFrame.bottom - minVisibleHeight));
-            final int left = Math.max(mContentFrame.left + minVisibleWidth - width,
-                    Math.min(mFrame.left, mContentFrame.right - minVisibleWidth));
+            final int top = Math.max(limitFrame.top,
+                    Math.min(mFrame.top, limitFrame.bottom - minVisibleHeight));
+            final int left = Math.max(limitFrame.left + minVisibleWidth - width,
+                    Math.min(mFrame.left, limitFrame.right - minVisibleWidth));
             mFrame.set(left, top, left + width, top + height);
             mContentFrame.set(mFrame);
             mVisibleFrame.set(mContentFrame);
@@ -1202,7 +1206,7 @@
     }
 
     Task getTask() {
-        return mAppToken != null ? mAppToken.mTask : null;
+        return mAppToken != null ? mAppToken.getTask() : null;
     }
 
     TaskStack getStack() {
@@ -1528,6 +1532,13 @@
             return changed;
         }
 
+        // Next up we will notify the client that it's visibility has changed.
+        // We need to prevent it from destroying child surfaces until
+        // the animation has finished.
+        if (!visible && isVisibleNow()) {
+            mWinAnimator.detachChildren();
+        }
+
         if (visible != isVisibleNow()) {
             if (!runningAppAnimation) {
                 final AccessibilityController accessibilityController =
@@ -1923,16 +1934,11 @@
         if (mIsImWindow && mService.mInputMethodTarget != null) {
             final AppWindowToken appToken = mService.mInputMethodTarget.mAppToken;
             if (appToken != null) {
-                return appToken.mAppAnimator.animLayerAdjustment;
+                return appToken.getAnimLayerAdjustment();
             }
         }
 
-        if (mAppToken != null) {
-            return mAppToken.mAppAnimator.animLayerAdjustment;
-        }
-
-        // Nothing is animating, so there is no animation adjustment.
-        return 0;
+        return mToken.getAnimLayerAdjustment();
     }
 
     int getSpecialWindowAnimLayerAdjustment() {
@@ -2383,8 +2389,8 @@
 
     /** @return true if this window desires touch events. */
     boolean canReceiveTouchInput() {
-        return mAppToken != null && mAppToken.mTask != null
-                && mAppToken.mTask.mStack.shouldIgnoreInput();
+        return mAppToken != null && mAppToken.getTask() != null
+                && mAppToken.getTask().mStack.shouldIgnoreInput();
     }
 
     @Override
@@ -2717,29 +2723,32 @@
             destroyedSomething |= c.destroySurface(cleanupOnResume, appStopped);
         }
 
-        if (appStopped || mWindowRemovalAllowed || cleanupOnResume) {
-
-            mWinAnimator.destroyPreservedSurfaceLocked();
-
-            if (mDestroying) {
-                if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + this
-                        + " destroySurfaces: appStopped=" + appStopped
-                        + " win.mWindowRemovalAllowed=" + mWindowRemovalAllowed
-                        + " win.mRemoveOnExit=" + mRemoveOnExit);
-
-                if (!cleanupOnResume || mRemoveOnExit) {
-                    destroyOrSaveSurface();
-                }
-                if (mRemoveOnExit) {
-                    removeImmediately();
-                }
-                if (cleanupOnResume) {
-                    requestUpdateWallpaperIfNeeded();
-                }
-                mDestroying = false;
-                destroyedSomething = true;
-            }
+        if (!(appStopped || mWindowRemovalAllowed || cleanupOnResume)) {
+            return destroyedSomething;
         }
+
+        if (appStopped || mWindowRemovalAllowed) {
+            mWinAnimator.destroyPreservedSurfaceLocked();
+        }
+
+        if (mDestroying) {
+            if (DEBUG_ADD_REMOVE) Slog.e(TAG_WM, "win=" + this
+                    + " destroySurfaces: appStopped=" + appStopped
+                    + " win.mWindowRemovalAllowed=" + mWindowRemovalAllowed
+                    + " win.mRemoveOnExit=" + mRemoveOnExit);
+            if (!cleanupOnResume || mRemoveOnExit) {
+                destroyOrSaveSurface();
+            }
+            if (mRemoveOnExit) {
+                removeImmediately();
+            }
+            if (cleanupOnResume) {
+                requestUpdateWallpaperIfNeeded();
+            }
+            mDestroying = false;
+            destroyedSomething = true;
+        }
+
         return destroyedSomething;
     }
 
@@ -3860,20 +3869,6 @@
         return highest;
     }
 
-    int adjustAnimLayer(int adj) {
-        int highestAnimLayer = mWinAnimator.mAnimLayer = mLayer + adj;
-        if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG_WM,
-                "adjustAnimLayer win=" + this + " anim layer: " + mWinAnimator.mAnimLayer);
-        for (int i = mChildren.size() - 1; i >= 0; i--) {
-            final WindowState childWindow = mChildren.get(i);
-            childWindow.adjustAnimLayer(adj);
-            if (childWindow.mWinAnimator.mAnimLayer > highestAnimLayer) {
-                highestAnimLayer = childWindow.mWinAnimator.mAnimLayer;
-            }
-        }
-        return highestAnimLayer;
-    }
-
     @Override
     boolean forAllWindows(ToBooleanFunction<WindowState> callback, boolean traverseTopToBottom) {
         if (mChildren.isEmpty()) {
@@ -4397,7 +4392,8 @@
             // will keep their surface and its size may change over time.
             if (mHasSurface && !isChildWindow()) {
                 mWinAnimator.preserveSurfaceLocked();
-                result |= RELAYOUT_RES_FIRST_TIME;
+                result |= RELAYOUT_RES_SURFACE_CHANGED |
+                    RELAYOUT_RES_FIRST_TIME;
             }
         }
         final boolean freeformResizing = isDragResizing()
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 98598e1..4b71338 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -566,6 +566,20 @@
         if (!mDestroyPreservedSurfaceUponRedraw) {
             return;
         }
+        if (mSurfaceController != null) {
+            if (mPendingDestroySurface != null) {
+                // If we are preserving a surface but we aren't relaunching that means
+                // we are just doing an in-place switch. In that case any SurfaceFlinger side
+                // child layers need to be reparented to the new surface to make this
+                // transparent to the app.
+                if (mWin.mAppToken == null || mWin.mAppToken.isRelaunching() == false) {
+                    SurfaceControl.openTransaction();
+                    mPendingDestroySurface.reparentChildrenInTransaction(mSurfaceController);
+                    SurfaceControl.closeTransaction();
+                }
+            }
+        }
+
         destroyDeferredSurfaceLocked();
         mDestroyPreservedSurfaceUponRedraw = false;
     }
@@ -1965,4 +1979,10 @@
         }
         return mForceScaleUntilResize;
     }
+
+    void detachChildren() {
+        if (mSurfaceController != null) {
+            mSurfaceController.detachChildren();
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index f8e7428..f7d3343 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -135,6 +135,20 @@
         }
     }
 
+    void reparentChildrenInTransaction(WindowSurfaceController other) {
+        if (SHOW_TRANSACTIONS) Slog.i(TAG, "REPARENT from: " + this + " to: " + other);
+        if ((mSurfaceControl != null) && (other.mSurfaceControl != null)) {
+            mSurfaceControl.reparentChildren(other.getHandle());
+        }
+    }
+
+    void detachChildren() {
+        if (SHOW_TRANSACTIONS) Slog.i(TAG, "SEVER CHILDREN");
+        if (mSurfaceControl != null) {
+            mSurfaceControl.detachChildren();
+        }
+    }
+
     void hideInTransaction(String reason) {
         if (SHOW_TRANSACTIONS) logSurface("HIDE ( " + reason + " )", null);
         mHiddenForOtherReasons = true;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index 897d5b86..f247ebe 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -651,7 +651,7 @@
         if (openingAppAnimator == null || openingAppAnimator.animation == null) {
             return;
         }
-        final int taskId = appToken.mTask.mTaskId;
+        final int taskId = appToken.getTask().mTaskId;
         Bitmap thumbnailHeader = mService.mAppTransition.getAppTransitionThumbnailHeader(taskId);
         if (thumbnailHeader == null || thumbnailHeader.getConfig() == Bitmap.Config.ALPHA_8) {
             if (DEBUG_APP_TRANSITIONS) Slog.d(TAG, "No thumbnail header bitmap for: " + taskId);
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index 8beb87d..fab59d6 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -151,21 +151,6 @@
         }
     }
 
-    int adjustAnimLayer(int adj) {
-        int highestAnimLayer = -1;
-        for (int j = mChildren.size() - 1; j >= 0; j--) {
-            final WindowState w = mChildren.get(j);
-            final int winHighestAnimLayer = w.adjustAnimLayer(adj);
-            if (winHighestAnimLayer > highestAnimLayer) {
-                highestAnimLayer = winHighestAnimLayer;
-            }
-            if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
-                mDisplayContent.setInputMethodAnimLayerAdjustment(adj);
-            }
-        }
-        return highestAnimLayer;
-    }
-
     /**
      * Returns true if the new window is considered greater than the existing window in terms of
      * z-order.
@@ -197,6 +182,11 @@
         return mChildren.isEmpty();
     }
 
+    // Used by AppWindowToken.
+    int getAnimLayerAdjustment() {
+        return 0;
+    }
+
     WindowState getReplacingWindow() {
         for (int i = mChildren.size() - 1; i >= 0; i--) {
             final WindowState win = mChildren.get(i);
diff --git a/services/core/jni/com_android_server_lights_LightsService.cpp b/services/core/jni/com_android_server_lights_LightsService.cpp
index 74af639..813dcf5 100644
--- a/services/core/jni/com_android_server_lights_LightsService.cpp
+++ b/services/core/jni/com_android_server_lights_LightsService.cpp
@@ -43,28 +43,86 @@
 static bool validate(jint light, jint flash, jint brightness) {
     bool valid = true;
 
-    if (light < 0 || light >= static_cast<int>(Type::COUNT)) {
+    if (light < 0 || light >= static_cast<jint>(Type::COUNT)) {
         ALOGE("Invalid light parameter %d.", light);
         valid = false;
     }
 
-    if (flash != static_cast<int>(Flash::NONE) &&
-        flash != static_cast<int>(Flash::TIMED) &&
-        flash != static_cast<int>(Flash::HARDWARE)) {
+    if (flash != static_cast<jint>(Flash::NONE) &&
+        flash != static_cast<jint>(Flash::TIMED) &&
+        flash != static_cast<jint>(Flash::HARDWARE)) {
         ALOGE("Invalid flash parameter %d.", flash);
         valid = false;
     }
 
-    if (brightness != static_cast<int>(Brightness::USER) &&
-        brightness != static_cast<int>(Brightness::SENSOR) &&
-        brightness != static_cast<int>(Brightness::LOW_PERSISTENCE)) {
+    if (brightness != static_cast<jint>(Brightness::USER) &&
+        brightness != static_cast<jint>(Brightness::SENSOR) &&
+        brightness != static_cast<jint>(Brightness::LOW_PERSISTENCE)) {
         ALOGE("Invalid brightness parameter %d.", brightness);
         valid = false;
     }
 
+    if (brightness == static_cast<jint>(Brightness::LOW_PERSISTENCE) &&
+        light != static_cast<jint>(Type::BACKLIGHT)) {
+        ALOGE("Cannot set low-persistence mode for non-backlight device.");
+        valid = false;
+    }
+
     return valid;
 }
 
+static LightState constructState(
+        jint colorARGB,
+        jint flashMode,
+        jint onMS,
+        jint offMS,
+        jint brightnessMode){
+    Flash flash = static_cast<Flash>(flashMode);
+    Brightness brightness = static_cast<Brightness>(brightnessMode);
+
+    LightState state{};
+
+    if (brightness == Brightness::LOW_PERSISTENCE) {
+        state.flashMode = Flash::NONE;
+    } else {
+        // Only set non-brightness settings when not in low-persistence mode
+        state.flashMode = flash;
+        state.flashOnMs = onMS;
+        state.flashOffMs = offMS;
+    }
+
+    state.color = colorARGB;
+    state.brightnessMode = brightness;
+
+    return state;
+}
+
+static void processReturn(
+        const Return<Status> &ret,
+        Type type,
+        const LightState &state) {
+    if (!ret.isOk()) {
+        ALOGE("Failed to issue set light command.");
+        gLight = nullptr;
+        return;
+    }
+
+    switch (static_cast<Status>(ret)) {
+        case Status::SUCCESS:
+            break;
+        case Status::LIGHT_NOT_SUPPORTED:
+            ALOGE("Light requested not available on this device. %d", type);
+            break;
+        case Status::BRIGHTNESS_NOT_SUPPORTED:
+            ALOGE("Brightness parameter not supported on this device: %d",
+                state.brightnessMode);
+            break;
+        case Status::UNKNOWN:
+        default:
+            ALOGE("Unknown error setting light.");
+    }
+}
+
 static void setLight_native(
         JNIEnv* /* env */,
         jobject /* clazz */,
@@ -79,63 +137,23 @@
         return;
     }
 
-    // TODO(b/31632518)
-    if (gLight == nullptr) {
+    if (gLight == nullptr || !gLight->ping().isOk()) {
         gLight = ILight::getService();
     }
 
     if (gLight == nullptr) {
-        ALOGE("LightService unable to get ILight interface.");
+        ALOGE("Unable to get ILight interface.");
         return;
     }
 
     Type type = static_cast<Type>(light);
-    Flash flash = static_cast<Flash>(flashMode);
-    Brightness brightness = static_cast<Brightness>(brightnessMode);
+    LightState state = constructState(
+        colorARGB, flashMode, onMS, offMS, brightnessMode);
 
-    LightState state{};
-
-    if (brightnessMode == static_cast<int>(Brightness::LOW_PERSISTENCE)) {
-        if (light != static_cast<int>(Type::BACKLIGHT)) {
-            ALOGE("Cannot set low-persistence mode for non-backlight device.");
-            return;
-        }
-        state.flashMode = Flash::NONE;
-    } else {
-        // Only set non-brightness settings when not in low-persistence mode
-        state.flashMode = flash;
-        state.flashOnMs = onMS;
-        state.flashOffMs = offMS;
-    }
-
-    state.color = colorARGB;
-    state.brightnessMode = brightness;
-
-    Status status;
     {
         ALOGD_IF_SLOW(50, "Excessive delay setting light");
         Return<Status> ret = gLight->setLight(type, state);
-
-        if (!ret.isOk()) {
-            ALOGE("Failed to issue set light command.");
-            return;
-        }
-
-        status = static_cast<Status>(ret); // hal status
-    }
-
-    switch (status) {
-        case Status::SUCCESS:
-            break;
-        case Status::LIGHT_NOT_SUPPORTED:
-            ALOGE("Light requested not availale on this device.");
-            break;
-        case Status::BRIGHTNESS_NOT_SUPPORTED:
-            ALOGE("Brightness parameter not supported on this device.");
-            break;
-        case Status::UNKNOWN:
-        default:
-            ALOGE("Unknown error setting light.");
+        processReturn(ret, type, state);
     }
 }
 
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 20b70a6..36ae94b 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1144,7 +1144,7 @@
     }
 
     auto result = gnssHal->setCallback(gnssCbIface);
-    if ((!result) || (!result.isOk())) {
+    if (!result.isOk() || !result) {
         ALOGE("SetCallback for Gnss Interface fails\n");
         return JNI_FALSE;
     }
@@ -1154,7 +1154,7 @@
         ALOGE("Unable to initialize GNSS Xtra interface\n");
     } else {
         result = gnssXtraIface->setCallback(gnssXtraCbIface);
-        if ((!result) || (!result.isOk())) {
+        if (!result.isOk() || !result) {
             gnssXtraIface = nullptr;
             ALOGE("SetCallback for Gnss Xtra Interface fails\n");
         }
@@ -1344,7 +1344,7 @@
         jlong time, jlong timeReference, jint uncertainty) {
     if (gnssHal != nullptr) {
         auto result = gnssHal->injectTime(time, timeReference, uncertainty);
-        if (!result || !result.isOk()) {
+        if (!result.isOk() || !result) {
             ALOGE("%s: Gnss injectTime() failed", __func__);
         }
     }
@@ -1354,7 +1354,7 @@
         jobject /* obj */, jdouble latitude, jdouble longitude, jfloat accuracy) {
     if (gnssHal != nullptr) {
         auto result = gnssHal->injectLocation(latitude, longitude, accuracy);
-        if (!result || !result.isOk()) {
+        if (!result.isOk() || !result) {
             ALOGE("%s: Gnss injectLocation() failed", __func__);
         }
     }
@@ -1391,7 +1391,7 @@
     const char *apnStr = env->GetStringUTFChars(apn, NULL);
 
     auto result = agnssIface->dataConnOpen(apnStr, static_cast<IAGnss::ApnIpType>(apnIpType));
-    if ((!result) || (!result.isOk())) {
+    if (!result.isOk() || !result){
         ALOGE("%s: Failed to set APN and its IP type", __func__);
     }
     env->ReleaseStringUTFChars(apn, apnStr);
@@ -1405,7 +1405,7 @@
     }
 
     auto result = agnssIface->dataConnClosed();
-    if ((!result) || (!result.isOk())) {
+    if (!result.isOk() || !result) {
         ALOGE("%s: Failed to close AGnss data connection", __func__);
     }
 }
@@ -1418,7 +1418,7 @@
     }
 
     auto result = agnssIface->dataConnFailed();
-    if ((!result) || (!result.isOk())) {
+    if (!result.isOk() || !result) {
         ALOGE("%s: Failed to notify unavailability of AGnss data connection", __func__);
     }
 }
@@ -1434,7 +1434,7 @@
     auto result = agnssIface->setServer(static_cast<IAGnssCallback::AGnssType>(type),
                                        c_hostname,
                                        port);
-    if ((!result) || (!result.isOk())) {
+    if (!result.isOk() || !result) {
         ALOGE("%s: Failed to set AGnss host name and port", __func__);
     }
 
@@ -1512,13 +1512,13 @@
         auto result = agnssRilIface->updateNetworkState(connected,
                                                        static_cast<IAGnssRil::NetworkType>(type),
                                                        roaming);
-        if ((!result) || (!result.isOk())) {
+        if (!result.isOk() || !result) {
             ALOGE("updateNetworkState failed");
         }
 
         const char *c_apn = env->GetStringUTFChars(apn, NULL);
         result = agnssRilIface->updateNetworkAvailability(available, c_apn);
-        if ((!result) || (!result.isOk())) {
+        if (!result.isOk() || !result) {
             ALOGE("updateNetworkAvailability failed");
         }
 
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 17e6bba..8b94ca0 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -165,10 +165,10 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.JournaledFile;
-import com.android.internal.util.ParcelableString;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.XmlUtils;
 import com.android.internal.widget.LockPatternUtils;
@@ -4863,6 +4863,28 @@
     }
 
     /**
+     * Determine whether DPMS should check if a delegate package is already installed before
+     * granting it new delegations via {@link #setDelegatedScopes}.
+     */
+    private static boolean shouldCheckIfDelegatePackageIsInstalled(String delegatePackage,
+            int targetSdk, List<String> scopes) {
+        // 1) Never skip is installed check from N.
+        if (targetSdk >= Build.VERSION_CODES.N) {
+            return true;
+        }
+        // 2) Skip if DELEGATION_CERT_INSTALL is the only scope being given.
+        if (scopes.size() == 1 && scopes.get(0).equals(DELEGATION_CERT_INSTALL)) {
+            return false;
+        }
+        // 3) Skip if all previously granted scopes are being cleared.
+        if (scopes.isEmpty()) {
+            return false;
+        }
+        // Otherwise it should check that delegatePackage is installed.
+        return true;
+    }
+
+    /**
      * Set the scopes of a device owner or profile owner delegate.
      *
      * @param who the device owner or profile owner.
@@ -4888,8 +4910,8 @@
             // Ensure calling process is device/profile owner.
             getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
             // Ensure the delegate is installed (skip this for DELEGATION_CERT_INSTALL in pre-N).
-            if (scopes.size() == 1 && scopes.get(0).equals(DELEGATION_CERT_INSTALL) ||
-                    getTargetSdk(who.getPackageName(), userId) >= Build.VERSION_CODES.N) {
+            if (shouldCheckIfDelegatePackageIsInstalled(delegatePackage,
+                        getTargetSdk(who.getPackageName(), userId), scopes)) {
                 // Throw when the delegate package is not installed.
                 if (!isPackageInstalledForUser(delegatePackage, userId)) {
                     throw new IllegalArgumentException("Package " + delegatePackage
@@ -5107,8 +5129,10 @@
                 final String currentPackage = policy.mDelegationMap.keyAt(i);
                 final List<String> currentScopes = policy.mDelegationMap.valueAt(i);
 
-                if (!currentPackage.equals(delegatePackage) && currentScopes.remove(scope)) {
-                    setDelegatedScopes(who, currentPackage, currentScopes);
+                if (!currentPackage.equals(delegatePackage) && currentScopes.contains(scope)) {
+                    final List<String> newScopes = new ArrayList(currentScopes);
+                    newScopes.remove(scope);
+                    setDelegatedScopes(who, currentPackage, newScopes);
                 }
             }
         }
@@ -5269,13 +5293,14 @@
 
     private void sendWipeProfileNotification() {
         String contentText = mContext.getString(R.string.work_profile_deleted_description_dpm_wipe);
-        Notification notification = new Notification.Builder(mContext)
-                .setSmallIcon(android.R.drawable.stat_sys_warning)
-                .setContentTitle(mContext.getString(R.string.work_profile_deleted))
-                .setContentText(contentText)
-                .setColor(mContext.getColor(R.color.system_notification_accent_color))
-                .setStyle(new Notification.BigTextStyle().bigText(contentText))
-                .build();
+        Notification notification =
+                new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN)
+                        .setSmallIcon(android.R.drawable.stat_sys_warning)
+                        .setContentTitle(mContext.getString(R.string.work_profile_deleted))
+                        .setContentText(contentText)
+                        .setColor(mContext.getColor(R.color.system_notification_accent_color))
+                        .setStyle(new Notification.BigTextStyle().bigText(contentText))
+                        .build();
         mInjector.getNotificationManager().notify(PROFILE_WIPED_NOTIFICATION_ID, notification);
     }
 
@@ -10695,7 +10720,8 @@
         intent.setPackage("com.android.systemui");
         final PendingIntent pendingIntent = PendingIntent.getBroadcastAsUser(mContext, 0, intent, 0,
                 UserHandle.CURRENT);
-        Notification notification = new Notification.Builder(mContext)
+        Notification notification =
+                new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN)
                 .setSmallIcon(R.drawable.ic_qs_network_logging)
                 .setContentTitle(mContext.getString(R.string.network_logging_notification_title))
                 .setContentText(mContext.getString(R.string.network_logging_notification_text))
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/MonitoringCertNotificationTask.java b/services/devicepolicy/java/com/android/server/devicepolicy/MonitoringCertNotificationTask.java
index 03c137a..1933fe7 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/MonitoringCertNotificationTask.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/MonitoringCertNotificationTask.java
@@ -34,8 +34,8 @@
 import android.security.KeyChain.KeyChainConnection;
 import android.util.Log;
 
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.R;
-import com.android.internal.util.ParcelableString;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -132,16 +132,16 @@
                 dialogIntent, PendingIntent.FLAG_UPDATE_CURRENT, null,
                 UserHandle.of(parentUserId));
 
-        final Notification noti = new Notification.Builder(userContext)
-            .setSmallIcon(smallIconId)
-            .setContentTitle(resources.getQuantityText(R.plurals.ssl_ca_cert_warning,
-                    pendingCertificateCount))
-            .setContentText(contentText)
-            .setContentIntent(notifyIntent)
-            .setPriority(Notification.PRIORITY_HIGH)
-            .setShowWhen(false)
-            .setColor(R.color.system_notification_accent_color)
-            .build();
+        final Notification noti =
+                new Notification.Builder(userContext, SystemNotificationChannels.SECURITY)
+                        .setSmallIcon(smallIconId)
+                        .setContentTitle(resources.getQuantityText(R.plurals.ssl_ca_cert_warning,
+                                pendingCertificateCount))
+                        .setContentText(contentText)
+                        .setContentIntent(notifyIntent)
+                        .setShowWhen(false)
+                        .setColor(R.color.system_notification_accent_color)
+                        .build();
 
         mInjector.getNotificationManager().notifyAsUser(
                 LOG_TAG, MONITORING_CERT_NOTIFICATION_ID, noti, userHandle);
@@ -150,12 +150,7 @@
     private List<String> getInstalledCaCertificates(UserHandle userHandle)
             throws RemoteException, RuntimeException {
         try (KeyChainConnection conn = mInjector.keyChainBindAsUser(userHandle)) {
-            List<ParcelableString> aliases = conn.getService().getUserCaAliases().getList();
-            List<String> result = new ArrayList<>(aliases.size());
-            for (int i = 0; i < aliases.size(); i++) {
-                result.add(aliases.get(i).string);
-            }
-            return result;
+            return conn.getService().getUserCaAliases().getList();
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
             return null;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
index 6d42dc9..969c89e 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/RemoteBugreportUtils.java
@@ -28,6 +28,7 @@
 import android.text.format.DateUtils;
 
 import com.android.internal.R;
+import com.android.internal.notification.SystemNotificationChannels;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -62,14 +63,14 @@
         PendingIntent pendingDialogIntent = PendingIntent.getActivityAsUser(context, type,
                 dialogIntent, 0, null, UserHandle.CURRENT);
 
-        Notification.Builder builder = new Notification.Builder(context)
-                .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
-                .setOngoing(true)
-                .setLocalOnly(true)
-                .setPriority(Notification.PRIORITY_HIGH)
-                .setContentIntent(pendingDialogIntent)
-                .setColor(context.getColor(
-                        com.android.internal.R.color.system_notification_accent_color));
+        Notification.Builder builder =
+                new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
+                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
+                        .setOngoing(true)
+                        .setLocalOnly(true)
+                        .setContentIntent(pendingDialogIntent)
+                        .setColor(context.getColor(
+                                com.android.internal.R.color.system_notification_accent_color));
 
         if (type == DevicePolicyManager.NOTIFICATION_BUGREPORT_ACCEPTED_NOT_FINISHED) {
             builder.setContentTitle(context.getString(
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index e586482..1a0aff7 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -53,6 +53,7 @@
 import com.android.internal.R;
 import com.android.internal.app.NightDisplayController;
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.BinderInternal;
 import com.android.internal.os.SamplingProfilerIntegration;
 import com.android.internal.policy.EmergencyAffordanceManager;
@@ -1118,6 +1119,7 @@
 
             traceBeginAndSlog("StartNotificationManager");
             mSystemServiceManager.startService(NotificationManagerService.class);
+            SystemNotificationChannels.createAll(context);
             notification = INotificationManager.Stub.asInterface(
                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
             networkPolicy.bindNotificationManager(notification);
diff --git a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
index f943ee2c..472f984 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/RetailDemoModeService.java
@@ -61,6 +61,7 @@
 import android.text.TextUtils;
 import android.util.KeyValueListParser;
 import android.util.Slog;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.BackgroundThread;
 import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
@@ -818,7 +819,7 @@
         }
 
         Notification createResetNotification() {
-            return new Notification.Builder(getContext())
+            return new Notification.Builder(getContext(), SystemNotificationChannels.RETAIL_MODE)
                     .setContentTitle(getContext().getString(R.string.reset_retail_demo_mode_title))
                     .setContentText(getContext().getString(R.string.reset_retail_demo_mode_text))
                     .setOngoing(true)
diff --git a/services/tests/notification/AndroidManifest.xml b/services/tests/notification/AndroidManifest.xml
index 92f155f..cf050a8 100644
--- a/services/tests/notification/AndroidManifest.xml
+++ b/services/tests/notification/AndroidManifest.xml
@@ -23,6 +23,7 @@
     <uses-permission android:name="android.permission.MANAGE_USERS" />
     <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <uses-permission android:name="android.permission.ACCESS_NOTIFICATIONS" />
+    <uses-permission android:name="android.permission.READ_CONTACTS" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java b/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
index 936531b..05c33a4 100644
--- a/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/GroupHelperTest.java
@@ -64,7 +64,7 @@
 
     private StatusBarNotification getSbn(String pkg, int id, String tag,
             UserHandle user, String groupKey) {
-        Notification.Builder nb = new Notification.Builder(getContext())
+        Notification.Builder nb = new Notification.Builder(getContext(), "test_channel_id")
                 .setContentTitle("A")
                 .setWhen(1205);
         if (groupKey != null) {
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
index 064ab0a..176342b 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationComparatorTest.java
@@ -63,6 +63,7 @@
     private final int smsUid = 11;
     private final String pkg2 = "pkg2";
     private final int uid2 = 1111111;
+    private static final String TEST_CHANNEL_ID = "test_channel_id";
 
     private NotificationRecord mRecordMinCall;
     private NotificationRecord mRecordHighCall;
@@ -100,7 +101,7 @@
         smsPkg = Settings.Secure.getString(mContext.getContentResolver(),
                 Settings.Secure.SMS_DEFAULT_APPLICATION);
 
-        Notification n1 = new Notification.Builder(mContext)
+        Notification n1 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setCategory(Notification.CATEGORY_CALL)
                 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
                 .build();
@@ -109,7 +110,7 @@
                 new UserHandle(userId), "", 2000), getDefaultChannel());
         mRecordMinCall.setUserImportance(NotificationManager.IMPORTANCE_MIN);
 
-        Notification n2 = new Notification.Builder(mContext)
+        Notification n2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setCategory(Notification.CATEGORY_CALL)
                 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
                 .setColorized(true /* colorized */)
@@ -119,7 +120,7 @@
                 new UserHandle(userId), "", 1999), getDefaultChannel());
         mRecordHighCall.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
 
-        Notification n3 = new Notification.Builder(mContext)
+        Notification n3 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setStyle(new Notification.MediaStyle()
                         .setMediaSession(new MediaSession.Token(null)))
                 .setFlag(Notification.FLAG_FOREGROUND_SERVICE, true)
@@ -129,7 +130,7 @@
                 "", 1499), getDefaultChannel());
         mRecordDefaultMedia.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
-        Notification n4 = new Notification.Builder(mContext)
+        Notification n4 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setStyle(new Notification.MessagingStyle("sender!")).build();
         mRecordInlineReply = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "inlinereply", uid2, uid2, n4, new UserHandle(userId),
@@ -137,34 +138,34 @@
         mRecordInlineReply.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
         mRecordInlineReply.setPackagePriority(Notification.PRIORITY_MAX);
 
-        Notification n5 = new Notification.Builder(mContext)
+        Notification n5 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setCategory(Notification.CATEGORY_MESSAGE).build();
         mRecordSms = new NotificationRecord(mContext, new StatusBarNotification(smsPkg,
                 smsPkg, 1, "sms", smsUid, smsUid, n5, new UserHandle(userId),
                 "", 1299), getDefaultChannel());
         mRecordSms.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
-        Notification n6 = new Notification.Builder(mContext).build();
+        Notification n6 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
         mRecordStarredContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "starred", uid2, uid2, n6, new UserHandle(userId),
                 "", 1259), getDefaultChannel());
         mRecordStarredContact.setContactAffinity(ValidateNotificationPeople.STARRED_CONTACT);
         mRecordStarredContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
-        Notification n7 = new Notification.Builder(mContext).build();
+        Notification n7 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
         mRecordContact = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "contact", uid2, uid2, n7, new UserHandle(userId),
                 "", 1259), getDefaultChannel());
         mRecordContact.setContactAffinity(ValidateNotificationPeople.VALID_CONTACT);
         mRecordContact.setUserImportance(NotificationManager.IMPORTANCE_DEFAULT);
 
-        Notification n8 = new Notification.Builder(mContext).build();
+        Notification n8 = new Notification.Builder(mContext, TEST_CHANNEL_ID).build();
         mRecordUrgent = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "urgent", uid2, uid2, n8, new UserHandle(userId),
                 "", 1258), getDefaultChannel());
         mRecordUrgent.setUserImportance(NotificationManager.IMPORTANCE_HIGH);
 
-        Notification n9 = new Notification.Builder(mContext)
+        Notification n9 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setCategory(Notification.CATEGORY_MESSAGE)
                 .setFlag(Notification.FLAG_ONGOING_EVENT
                         |Notification.FLAG_FOREGROUND_SERVICE, true)
@@ -174,7 +175,7 @@
                 "", 9258), getDefaultChannel());
         mRecordCheater.setUserImportance(NotificationManager.IMPORTANCE_LOW);
 
-        Notification n10 = new Notification.Builder(mContext)
+        Notification n10 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                 .setStyle(new Notification.InboxStyle().setSummaryText("message!")).build();
         mRecordEmail = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
                 pkg2, 1, "email", uid2, uid2, n10, new UserHandle(userId),
diff --git a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
index 88f1a53..b7b3617 100644
--- a/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/notification/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -129,11 +129,9 @@
         if (channel == null) {
             channel = new NotificationChannel("id", "name", NotificationManager.IMPORTANCE_DEFAULT);
         }
-        Notification.Builder nb = new Notification.Builder(mContext)
+        Notification.Builder nb = new Notification.Builder(mContext, channel.getId())
                 .setContentTitle("foo")
-                .setSmallIcon(android.R.drawable.sym_def_app_icon)
-                .setChannel(channel.getId())
-                .setPriority(Notification.PRIORITY_HIGH);
+                .setSmallIcon(android.R.drawable.sym_def_app_icon);
         if (extender != null) {
             nb.extend(extender);
         }
diff --git a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
index 8210072..ffb0a9e 100644
--- a/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/RankingHelperTest.java
@@ -93,6 +93,7 @@
     private final int uid = 0;
     private final String pkg2 = "pkg2";
     private final int uid2 = 1111111;
+    private static final String TEST_CHANNEL_ID = "test_channel_id";
     private AudioAttributes mAudioAttributes;
 
     private Context getContext() {
@@ -107,7 +108,7 @@
         mHelper = new RankingHelper(getContext(), mPm, handler, mUsageStats,
                 new String[]{ImportanceExtractor.class.getName()});
 
-        mNotiGroupGSortA = new Notification.Builder(getContext())
+        mNotiGroupGSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("A")
                 .setGroup("G")
                 .setSortKey("A")
@@ -117,7 +118,7 @@
                 "package", "package", 1, null, 0, 0, mNotiGroupGSortA, user,
                 null, System.currentTimeMillis()), getDefaultChannel());
 
-        mNotiGroupGSortB = new Notification.Builder(getContext())
+        mNotiGroupGSortB = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("B")
                 .setGroup("G")
                 .setSortKey("B")
@@ -127,7 +128,7 @@
                 "package", "package", 1, null, 0, 0, mNotiGroupGSortB, user,
                 null, System.currentTimeMillis()), getDefaultChannel());
 
-        mNotiNoGroup = new Notification.Builder(getContext())
+        mNotiNoGroup = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("C")
                 .setWhen(1201)
                 .build();
@@ -135,7 +136,7 @@
                 "package", "package", 1, null, 0, 0, mNotiNoGroup, user,
                 null, System.currentTimeMillis()), getDefaultChannel());
 
-        mNotiNoGroup2 = new Notification.Builder(getContext())
+        mNotiNoGroup2 = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("D")
                 .setWhen(1202)
                 .build();
@@ -143,7 +144,7 @@
                 "package", "package", 1, null, 0, 0, mNotiNoGroup2, user,
                 null, System.currentTimeMillis()), getDefaultChannel());
 
-        mNotiNoGroupSortA = new Notification.Builder(getContext())
+        mNotiNoGroupSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("E")
                 .setWhen(1201)
                 .setSortKey("A")
@@ -195,6 +196,7 @@
     private void compareChannels(NotificationChannel expected, NotificationChannel actual) {
         assertEquals(expected.getId(), actual.getId());
         assertEquals(expected.getName(), actual.getName());
+        assertEquals(expected.getNameResId(), actual.getNameResId());
         assertEquals(expected.shouldVibrate(), actual.shouldVibrate());
         assertEquals(expected.shouldShowLights(), actual.shouldShowLights());
         assertEquals(expected.getImportance(), actual.getImportance());
@@ -259,11 +261,13 @@
 
     @Test
     public void testChannelXml() throws Exception {
+        int nameResId = 924896;
+
         NotificationChannelGroup ncg = new NotificationChannelGroup("1", "2");
         NotificationChannel channel1 =
                 new NotificationChannel("id1", "name1", NotificationManager.IMPORTANCE_HIGH);
         NotificationChannel channel2 =
-                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
+                new NotificationChannel("id2", nameResId, IMPORTANCE_LOW);
         channel2.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
         channel2.enableLights(true);
         channel2.setBypassDnd(true);
diff --git a/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
index c5abba8..9575d32 100644
--- a/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
+++ b/services/tests/notification/src/com/android/server/notification/SnoozeHelperTest.java
@@ -51,6 +51,8 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class SnoozeHelperTest {
+    private static final String TEST_CHANNEL_ID = "test_channel_id";
+
     @Mock SnoozeHelper.Callback mCallback;
     @Mock AlarmManager mAm;
     @Mock ManagedServices.UserProfiles mUserProfiles;
@@ -77,7 +79,7 @@
         verify(mAm, times(1)).setExactAndAllowWhileIdle(
                 anyInt(), captor.capture(), any(PendingIntent.class));
         long actualSnoozedUntilDuration = captor.getValue() - SystemClock.elapsedRealtime();
-        assertTrue(Math.abs(actualSnoozedUntilDuration - 1000) < 2);
+        assertTrue(Math.abs(actualSnoozedUntilDuration - 1000) < 25);
         assertTrue(mSnoozeHelper.isSnoozed(
                 UserHandle.USER_SYSTEM, r.sbn.getPackageName(), r.getKey()));
     }
@@ -232,20 +234,16 @@
 
     private NotificationRecord getNotificationRecord(String pkg, int id, String tag,
             UserHandle user) {
-        Notification n = new Notification.Builder(getContext())
+        Notification n = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
                 .setContentTitle("A")
                 .setGroup("G")
                 .setSortKey("A")
                 .setWhen(1205)
                 .build();
+        final NotificationChannel notificationChannel = new NotificationChannel(
+                TEST_CHANNEL_ID, "name", NotificationManager.IMPORTANCE_LOW);
         return new NotificationRecord(getContext(), new StatusBarNotification(
                 pkg, pkg, id, tag, 0, 0, n, user, null,
-                System.currentTimeMillis()), getDefaultChannel());
+                System.currentTimeMillis()), notificationChannel);
     }
-
-    private NotificationChannel getDefaultChannel() {
-        return new NotificationChannel(NotificationChannel.DEFAULT_CHANNEL_ID, "name",
-                NotificationManager.IMPORTANCE_LOW);
-    }
-
 }
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 4141f2f..38c6b0d 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -119,6 +119,7 @@
     private static final String INVALID_BSSID = "invalid_bssid";
     private static final ComponentName RECOMMENDATION_SERVICE_COMP =
             new ComponentName("newPackageName", "newScoringServiceClass");
+    private static final String RECOMMENDATION_SERVICE_LABEL = "Test Recommendation Service";
     private static final ComponentName USE_WIFI_ENABLE_ACTIVITY_COMP =
             new ComponentName("useWifiPackageName", "enableUseWifiActivityClass");
     private static final ScoredNetwork SCORED_NETWORK =
@@ -128,7 +129,8 @@
             new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID_2), "00:00:00:00:00:00")),
                     null /* rssiCurve*/);
     private static final NetworkScorerAppData NEW_SCORER = new NetworkScorerAppData(
-            1, RECOMMENDATION_SERVICE_COMP, USE_WIFI_ENABLE_ACTIVITY_COMP);
+            1, RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
+            USE_WIFI_ENABLE_ACTIVITY_COMP);
 
     @Mock private NetworkScorerAppManager mNetworkScorerAppManager;
     @Mock private Context mContext;
@@ -924,7 +926,8 @@
         when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES))
                 .thenReturn(PackageManager.PERMISSION_GRANTED);
         NetworkScorerAppData expectedAppData = new NetworkScorerAppData(Binder.getCallingUid(),
-                RECOMMENDATION_SERVICE_COMP, USE_WIFI_ENABLE_ACTIVITY_COMP);
+                RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
+                USE_WIFI_ENABLE_ACTIVITY_COMP);
         bindToScorer(expectedAppData);
         assertEquals(expectedAppData, mNetworkScoreService.getActiveScorer());
     }
@@ -965,7 +968,8 @@
     private void bindToScorer(boolean callerIsScorer) {
         final int callingUid = callerIsScorer ? Binder.getCallingUid() : Binder.getCallingUid() + 1;
         NetworkScorerAppData appData = new NetworkScorerAppData(callingUid,
-                RECOMMENDATION_SERVICE_COMP, USE_WIFI_ENABLE_ACTIVITY_COMP);
+                RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL,
+                USE_WIFI_ENABLE_ACTIVITY_COMP);
         bindToScorer(appData);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
index e9a2d34..502bf06 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
@@ -59,6 +59,9 @@
 
 @RunWith(AndroidJUnit4.class)
 public class NetworkScorerAppManagerTest {
+    private static String MOCK_SERVICE_LABEL = "Mock Service";
+    private static String MOCK_OVERRIDEN_SERVICE_LABEL = "Mock Service Label Override";
+
     @Mock private Context mMockContext;
     @Mock private PackageManager mMockPm;
     @Mock private Resources mResources;
@@ -94,6 +97,22 @@
         assertNotNull(activeScorer);
         assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
         assertEquals(924, activeScorer.packageUid);
+        assertEquals(MOCK_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel());
+    }
+
+    @Test
+    public void testGetActiveScorer_providerAvailable_serviceLabelOverride() throws Exception {
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        setNetworkRecoPackageSetting(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+                null /* enableUseOpenWifiPackageActivityPackage*/, true /* serviceLabelOverride */);
+
+        final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
+        assertNotNull(activeScorer);
+        assertEquals(recoComponent, activeScorer.getRecommendationServiceComponent());
+        assertEquals(924, activeScorer.packageUid);
+        assertEquals(MOCK_OVERRIDEN_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel());
     }
 
     @Test
@@ -269,11 +288,17 @@
     }
 
     private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid) {
-        mockRecommendationServiceAvailable(compName, packageUid, null);
+        mockRecommendationServiceAvailable(compName, packageUid, null, false);
     }
 
     private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid,
             String enableUseOpenWifiActivityPackage) {
+        mockRecommendationServiceAvailable(
+                compName, packageUid, enableUseOpenWifiActivityPackage, false);
+    }
+
+    private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid,
+            String enableUseOpenWifiActivityPackage, boolean serviceLabelOverride) {
         final ResolveInfo serviceInfo = new ResolveInfo();
         serviceInfo.serviceInfo = new ServiceInfo();
         serviceInfo.serviceInfo.name = compName.getClassName();
@@ -286,6 +311,16 @@
                     NetworkScoreManager.USE_OPEN_WIFI_PACKAGE_META_DATA,
                     enableUseOpenWifiActivityPackage);
         }
+        if (serviceLabelOverride) {
+            if (serviceInfo.serviceInfo.metaData == null) {
+                serviceInfo.serviceInfo.metaData = new Bundle();
+            }
+            serviceInfo.serviceInfo.metaData.putString(
+                    NetworkScoreManager.RECOMMENDATION_SERVICE_LABEL_META_DATA,
+                    MOCK_OVERRIDEN_SERVICE_LABEL);
+        } else {
+            serviceInfo.serviceInfo.nonLocalizedLabel = MOCK_SERVICE_LABEL;
+        }
 
         final int flags = PackageManager.GET_META_DATA;
         when(mMockPm.resolveService(
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
new file mode 100644
index 0000000..cc2f7d5
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.am;
+
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
+import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
+import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
+import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
+import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
+import static android.app.ActivityManager.PROCESS_STATE_RECEIVER;
+import static android.app.ActivityManager.PROCESS_STATE_SERVICE;
+import static android.app.ActivityManager.PROCESS_STATE_TOP;
+import static android.util.DebugUtils.valueToString;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.app.ActivityManager;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.function.Function;
+
+/**
+ * Test class for {@link ActivityManagerService}.
+ *
+ * To run the tests, use
+ *
+ * runtest -c com.android.server.am.ActivityManagerServiceTest frameworks-services
+ *
+ * or the following steps:
+ *
+ * Build: m FrameworksServicesTests
+ * Install: adb install -r \
+ *     ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
+ * Run: adb shell am instrument -e class com.android.server.am.ActivityManagerServiceTest -w \
+ *     com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ActivityManagerServiceTest {
+    private static final int TEST_UID = 111;
+
+    @Test
+    public void testIncrementProcStateSeqIfNeeded() {
+        final ActivityManagerService ams = new ActivityManagerService();
+        final UidRecord uidRec = new UidRecord(TEST_UID);
+
+        assertEquals("Initially global seq counter should be 0", 0, ams.mProcStateSeqCounter);
+        assertEquals("Initially seq counter in uidRecord should be 0", 0, uidRec.curProcStateSeq);
+
+        // Uid state is not moving from background to foreground or vice versa.
+        uidRec.setProcState = PROCESS_STATE_TOP;
+        uidRec.curProcState = PROCESS_STATE_TOP;
+        ams.incrementProcStateSeqIfNeeded(uidRec);
+        assertEquals(0, ams.mProcStateSeqCounter);
+        assertEquals(0, uidRec.curProcStateSeq);
+
+        // Uid state is moving from foreground to background.
+        uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+        uidRec.setProcState = PROCESS_STATE_SERVICE;
+        ams.incrementProcStateSeqIfNeeded(uidRec);
+        assertEquals(1, ams.mProcStateSeqCounter);
+        assertEquals(1, uidRec.curProcStateSeq);
+
+        // Explicitly setting the seq counter for more verification.
+        ams.mProcStateSeqCounter = 42;
+
+        // Uid state is not moving from background to foreground or vice versa.
+        uidRec.setProcState = PROCESS_STATE_IMPORTANT_BACKGROUND;
+        uidRec.curProcState = PROCESS_STATE_IMPORTANT_FOREGROUND;
+        ams.incrementProcStateSeqIfNeeded(uidRec);
+        assertEquals(42, ams.mProcStateSeqCounter);
+        assertEquals(1, uidRec.curProcStateSeq);
+
+        // Uid state is moving from background to foreground.
+        uidRec.setProcState = PROCESS_STATE_LAST_ACTIVITY;
+        uidRec.curProcState = PROCESS_STATE_TOP;
+        ams.incrementProcStateSeqIfNeeded(uidRec);
+        assertEquals(43, ams.mProcStateSeqCounter);
+        assertEquals(43, uidRec.curProcStateSeq);
+    }
+
+    @Test
+    public void testShouldIncrementProcStateSeq() {
+        final ActivityManagerService ams = new ActivityManagerService();
+        final UidRecord uidRec = new UidRecord(TEST_UID);
+
+        final String error1 = "Seq should be incremented: prevState: %s, curState: %s";
+        final String error2 = "Seq should not be incremented: prevState: %s, curState: %s";
+        Function<String, String> errorMsg = errorTemplate -> {
+            return String.format(errorTemplate,
+                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.setProcState),
+                    valueToString(ActivityManager.class, "PROCESS_STATE_", uidRec.curProcState));
+        };
+
+        // No change in uid state
+        uidRec.setProcState = PROCESS_STATE_RECEIVER;
+        uidRec.curProcState = PROCESS_STATE_RECEIVER;
+        assertFalse(errorMsg.apply(error2), ams.shouldIncrementProcStateSeq(uidRec));
+
+        // Foreground to foreground
+        uidRec.setProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+        uidRec.curProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
+        assertFalse(errorMsg.apply(error2), ams.shouldIncrementProcStateSeq(uidRec));
+
+        // Background to background
+        uidRec.setProcState = PROCESS_STATE_CACHED_ACTIVITY;
+        uidRec.curProcState = PROCESS_STATE_CACHED_EMPTY;
+        assertFalse(errorMsg.apply(error2), ams.shouldIncrementProcStateSeq(uidRec));
+
+        // Background to background
+        uidRec.setProcState = PROCESS_STATE_NONEXISTENT;
+        uidRec.curProcState = PROCESS_STATE_CACHED_ACTIVITY;
+        assertFalse(errorMsg.apply(error2), ams.shouldIncrementProcStateSeq(uidRec));
+
+        // Background to foreground
+        uidRec.setProcState = PROCESS_STATE_SERVICE;
+        uidRec.curProcState = PROCESS_STATE_FOREGROUND_SERVICE;
+        assertTrue(errorMsg.apply(error1), ams.shouldIncrementProcStateSeq(uidRec));
+
+        // Foreground to background
+        uidRec.setProcState = PROCESS_STATE_TOP;
+        uidRec.curProcState = PROCESS_STATE_LAST_ACTIVITY;
+        assertTrue(errorMsg.apply(error1), ams.shouldIncrementProcStateSeq(uidRec));
+    }
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index d65a9bf..756514b 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -34,7 +34,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ParceledListSlice;
+import android.content.pm.StringParceledListSlice;
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.net.IIpConnectivityMetrics;
@@ -56,7 +56,6 @@
 import android.util.Pair;
 
 import com.android.internal.R;
-import com.android.internal.util.ParcelableString;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -1220,8 +1219,8 @@
         mContext.userContexts.put(user, mContext);
         when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
 
-        ParceledListSlice<ParcelableString> oneCert = asSlice(new String[] {"1"});
-        ParceledListSlice<ParcelableString> fourCerts = asSlice(new String[] {"1", "2", "3", "4"});
+        StringParceledListSlice oneCert = asSlice(new String[] {"1"});
+        StringParceledListSlice fourCerts = asSlice(new String[] {"1", "2", "3", "4"});
 
         final String TEST_STRING = "Test for exactly 2 certs out of 4";
         doReturn(TEST_STRING).when(mContext.resources).getQuantityText(anyInt(), eq(2));
@@ -1229,7 +1228,7 @@
         // Given that we have exactly one certificate installed,
         when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert);
         // when that certificate is approved,
-        dpms.approveCaCert(oneCert.getList().get(0).string, userId, true);
+        dpms.approveCaCert(oneCert.getList().get(0), userId, true);
         // a notification should not be shown.
         verify(mContext.notificationManager, timeout(1000))
                 .cancelAsUser(anyString(), anyInt(), eq(user));
@@ -1237,8 +1236,8 @@
         // Given that we have four certificates installed,
         when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
         // when two of them are approved (one of them approved twice hence no action),
-        dpms.approveCaCert(fourCerts.getList().get(0).string, userId, true);
-        dpms.approveCaCert(fourCerts.getList().get(1).string, userId, true);
+        dpms.approveCaCert(fourCerts.getList().get(0), userId, true);
+        dpms.approveCaCert(fourCerts.getList().get(1), userId, true);
         // a notification should be shown saying that there are two certificates left to approve.
         verify(mContext.notificationManager, timeout(1000))
                 .notifyAsUser(anyString(), anyInt(), argThat(
@@ -3974,18 +3973,9 @@
     }
 
     /**
-     * Convert String[] to ParceledListSlice&lt;ParcelableString&gt;.
-     * <p>
-     * TODO: This shouldn't be necessary. If ParcelableString does need to exist, it also needs
-     * a real constructor.
+     * Convert String[] to StringParceledListSlice.
      */
-    private static ParceledListSlice<ParcelableString> asSlice(String[] s) {
-        List<ParcelableString> list = new ArrayList<>(s.length);
-        for (int i = 0; i < s.length; i++) {
-            ParcelableString item = new ParcelableString();
-            item.string = s[i];
-            list.add(i, item);
-        }
-        return new ParceledListSlice<ParcelableString>(list);
+    private static StringParceledListSlice asSlice(String[] s) {
+        return new StringParceledListSlice(Arrays.asList(s));
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java
index 6c6eb7e..d665094 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java
@@ -69,7 +69,7 @@
     class TestParallelPackageParser extends ParallelPackageParser {
 
         TestParallelPackageParser() {
-            super(null, false, null, null);
+            super(null, false, null, null, null);
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 94ff07f..4b3c2f8 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -247,7 +247,7 @@
         final Icon icon1 = Icon.createWithResource(getTestContext(), R.drawable.icon1);
         final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.icon2));
-        final Icon icon3 = Icon.createWithMaskableBitmap(BitmapFactory.decodeResource(
+        final Icon icon3 = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
             getTestContext().getResources(), R.drawable.icon2));
 
         final ShortcutInfo si1 = makeShortcut(
@@ -567,7 +567,7 @@
 
         final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.black_32x32));
-        final Icon bmp64x64_maskable = Icon.createWithMaskableBitmap(BitmapFactory.decodeResource(
+        final Icon bmp64x64_maskable = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.black_64x64));
         final Icon bmp512x512 = Icon.createWithBitmap(BitmapFactory.decodeResource(
                 getTestContext().getResources(), R.drawable.black_512x512));
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index c54fa02..900da09 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -46,7 +46,6 @@
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.frameworks.servicestests.R;
-import com.android.server.pm.ShortcutService.ConfigConstants;
 import com.android.server.pm.ShortcutUser.PackageWithUser;
 
 import java.io.File;
@@ -993,7 +992,7 @@
 
         setCaller(CALLING_PACKAGE_1, USER_10);
 
-        final Icon bmp32x32 = Icon.createWithMaskableBitmap(BitmapFactory.decodeResource(
+        final Icon bmp32x32 = Icon.createWithAdaptiveBitmap(BitmapFactory.decodeResource(
             getTestContext().getResources(), R.drawable.black_32x32));
 
         PersistableBundle pb = new PersistableBundle();
@@ -1047,7 +1046,7 @@
         assertEquals(1, si.getExtras().getInt("k"));
 
         assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE
-            | ShortcutInfo.FLAG_STRINGS_RESOLVED | ShortcutInfo.FLAG_MASKABLE_BITMAP,
+            | ShortcutInfo.FLAG_STRINGS_RESOLVED | ShortcutInfo.FLAG_ADAPTIVE_BITMAP,
             si.getFlags());
         assertNotNull(si.getBitmapPath()); // Something should be set.
         assertEquals(0, si.getIconResourceId());
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 90a2ec0..fa0bd39 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -16,9 +16,10 @@
 
 package com.android.server.pm.dex;
 
-import android.os.Build;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.os.Build;
+import android.os.UserHandle;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
@@ -57,6 +58,7 @@
 
     private int mUser0;
     private int mUser1;
+
     @Before
     public void setup() {
 
@@ -243,6 +245,113 @@
         assertSecondaryUse(newPackage, pui, newSecondaries, /*isUsedByOtherApps*/false, mUser0);
     }
 
+    @Test
+    public void testNotifyPackageUpdated() {
+        // Foo loads Bar main apks.
+        notifyDexLoad(mFooUser0, mBarUser0.getBaseAndSplitDexPaths(), mUser0);
+
+        // Bar is used by others now and should be in our records.
+        PackageUseInfo pui = getPackageUseInfo(mBarUser0);
+        assertNotNull(pui);
+        assertTrue(pui.isUsedByOtherApps());
+        assertTrue(pui.getDexUseInfoMap().isEmpty());
+
+        // Notify that bar is updated.
+        mDexManager.notifyPackageUpdated(mBarUser0.getPackageName(),
+                mBarUser0.mPackageInfo.applicationInfo.sourceDir,
+                mBarUser0.mPackageInfo.applicationInfo.splitSourceDirs);
+
+        // The usedByOtherApps flag should be clear now.
+        pui = getPackageUseInfo(mBarUser0);
+        assertNotNull(pui);
+        assertFalse(pui.isUsedByOtherApps());
+    }
+
+    @Test
+    public void testNotifyPackageUpdatedCodeLocations() {
+        // Simulate a split update.
+        String newSplit = mBarUser0.replaceLastSplit();
+        List<String> newSplits = new ArrayList<>();
+        newSplits.add(newSplit);
+
+        // We shouldn't find yet the new split as we didn't notify the package update.
+        notifyDexLoad(mFooUser0, newSplits, mUser0);
+        PackageUseInfo pui = getPackageUseInfo(mBarUser0);
+        assertNull(pui);
+
+        // Notify that bar is updated. splitSourceDirs will contain the updated path.
+        mDexManager.notifyPackageUpdated(mBarUser0.getPackageName(),
+                mBarUser0.mPackageInfo.applicationInfo.sourceDir,
+                mBarUser0.mPackageInfo.applicationInfo.splitSourceDirs);
+
+        // Now, when the split is loaded we will find it and we should mark Bar as usedByOthers.
+        notifyDexLoad(mFooUser0, newSplits, mUser0);
+        pui = getPackageUseInfo(mBarUser0);
+        assertNotNull(pui);
+        assertTrue(pui.isUsedByOtherApps());
+    }
+
+    @Test
+    public void testNotifyPackageDataDestroyForOne() {
+        // Bar loads its own secondary files.
+        notifyDexLoad(mBarUser0, mBarUser0.getSecondaryDexPaths(), mUser0);
+        notifyDexLoad(mBarUser1, mBarUser1.getSecondaryDexPaths(), mUser1);
+
+        mDexManager.notifyPackageDataDestroyed(mBarUser0.getPackageName(), mUser0);
+
+        // Bar should not be around since it was removed for all users.
+        PackageUseInfo pui = getPackageUseInfo(mBarUser1);
+        assertNotNull(pui);
+        assertSecondaryUse(mBarUser1, pui, mBarUser1.getSecondaryDexPaths(),
+                /*isUsedByOtherApps*/false, mUser1);
+    }
+
+    @Test
+    public void testNotifyPackageDataDestroyForeignUse() {
+        // Foo loads its own secondary files.
+        List<String> fooSecondaries = mFooUser0.getSecondaryDexPaths();
+        notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
+
+        // Bar loads Foo main apks.
+        notifyDexLoad(mBarUser0, mFooUser0.getBaseAndSplitDexPaths(), mUser0);
+
+        mDexManager.notifyPackageDataDestroyed(mFooUser0.getPackageName(), mUser0);
+
+        // Foo should still be around since it's used by other apps but with no
+        // secondary dex info.
+        PackageUseInfo pui = getPackageUseInfo(mFooUser0);
+        assertNotNull(pui);
+        assertTrue(pui.isUsedByOtherApps());
+        assertTrue(pui.getDexUseInfoMap().isEmpty());
+    }
+
+    @Test
+    public void testNotifyPackageDataDestroyComplete() {
+        // Foo loads its own secondary files.
+        List<String> fooSecondaries = mFooUser0.getSecondaryDexPaths();
+        notifyDexLoad(mFooUser0, fooSecondaries, mUser0);
+
+        mDexManager.notifyPackageDataDestroyed(mFooUser0.getPackageName(), mUser0);
+
+        // Foo should not be around since all its secondary dex info were deleted
+        // and it is not used by other apps.
+        PackageUseInfo pui = getPackageUseInfo(mFooUser0);
+        assertNull(pui);
+    }
+
+    @Test
+    public void testNotifyPackageDataDestroyForAll() {
+        // Foo loads its own secondary files.
+        notifyDexLoad(mBarUser0, mBarUser0.getSecondaryDexPaths(), mUser0);
+        notifyDexLoad(mBarUser1, mBarUser1.getSecondaryDexPaths(), mUser1);
+
+        mDexManager.notifyPackageDataDestroyed(mBarUser0.getPackageName(), UserHandle.USER_ALL);
+
+        // Bar should not be around since it was removed for all users.
+        PackageUseInfo pui = getPackageUseInfo(mBarUser0);
+        assertNull(pui);
+    }
+
     private void assertSecondaryUse(TestData testData, PackageUseInfo pui,
             List<String> secondaries, boolean isUsedByOtherApps, int ownerUserId) {
         for (String dex : secondaries) {
@@ -317,5 +426,12 @@
             }
             return paths;
         }
+
+        String replaceLastSplit() {
+            int length = mPackageInfo.applicationInfo.splitSourceDirs.length;
+            // Add an extra bogus dex extension to simulate a new split name.
+            mPackageInfo.applicationInfo.splitSourceDirs[length - 1] += ".dex";
+            return mPackageInfo.applicationInfo.splitSourceDirs[length - 1];
+        }
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
index 19e0bcf..2e99433 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
@@ -257,6 +257,30 @@
     }
 
     @Test
+    public void testRemovePackage() {
+        // Record Bar secondaries for two different users.
+        assertTrue(record(mBarSecondary1User0));
+        assertTrue(record(mBarSecondary2User1));
+
+        // Remove the package.
+        assertTrue(mPackageDexUsage.removePackage(mBarSecondary1User0.mPackageName));
+        // Assert that we can't find the package anymore.
+        assertNull(mPackageDexUsage.getPackageUseInfo(mBarSecondary1User0.mPackageName));
+    }
+
+    @Test
+    public void testRemoveNonexistentPackage() {
+        // Record Bar secondaries for two different users.
+        assertTrue(record(mBarSecondary1User0));
+
+        // Remove the package.
+        assertTrue(mPackageDexUsage.removePackage(mBarSecondary1User0.mPackageName));
+        // Remove the package again. It should return false because the package no longer
+        // has a record in the use info.
+        assertFalse(mPackageDexUsage.removePackage(mBarSecondary1User0.mPackageName));
+    }
+
+    @Test
     public void testRemoveUserPackage() {
         // Record Bar secondaries for two different users.
         assertTrue(record(mBarSecondary1User0));
@@ -282,6 +306,32 @@
         assertPackageDexUsage(null, mBarSecondary2User1);
     }
 
+    @Test
+    public void testClearUsedByOtherApps() {
+        // Write a package which is used by other apps.
+        assertTrue(record(mFooSplit2UsedByOtherApps0));
+        assertTrue(mPackageDexUsage.clearUsedByOtherApps(mFooSplit2UsedByOtherApps0.mPackageName));
+
+        // Check that the package is no longer used by other apps.
+        TestData noLongerUsedByOtherApps = new TestData(
+            mFooSplit2UsedByOtherApps0.mPackageName,
+            mFooSplit2UsedByOtherApps0.mDexFile,
+            mFooSplit2UsedByOtherApps0.mOwnerUserId,
+            mFooSplit2UsedByOtherApps0.mLoaderIsa,
+            /*mIsUsedByOtherApps*/false,
+            mFooSplit2UsedByOtherApps0.mPrimaryOrSplit);
+        assertPackageDexUsage(noLongerUsedByOtherApps);
+    }
+
+    @Test
+    public void testClearUsedByOtherAppsNonexistent() {
+        // Write a package which is used by other apps.
+        assertTrue(record(mFooSplit2UsedByOtherApps0));
+        assertTrue(mPackageDexUsage.clearUsedByOtherApps(mFooSplit2UsedByOtherApps0.mPackageName));
+        // Clearing again should return false as there should be no update on the use info.
+        assertFalse(mPackageDexUsage.clearUsedByOtherApps(mFooSplit2UsedByOtherApps0.mPackageName));
+    }
+
     private void assertPackageDexUsage(TestData primary, TestData... secondaries) {
         String packageName = primary == null ? secondaries[0].mPackageName : primary.mPackageName;
         boolean primaryUsedByOtherApps = primary == null ? false : primary.mUsedByOtherApps;
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 04e5583..2ccaefc 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -138,19 +138,18 @@
 
     @Test
     public void testReparent() throws Exception {
+        final StackWindowController stackController =
+            createStackControllerOnDisplay(sDisplayContent);
         final TestTaskWindowContainerController taskController1 =
-                new TestTaskWindowContainerController(
-                        createStackControllerOnDisplay(sDisplayContent));
+                new TestTaskWindowContainerController(stackController);
         final TestAppWindowContainerController appWindowController1 = createAppWindowController(
                 taskController1);
         final TestTaskWindowContainerController taskController2 =
-                new TestTaskWindowContainerController(
-                        createStackControllerOnDisplay(sDisplayContent));
+                new TestTaskWindowContainerController(stackController);
         final TestAppWindowContainerController appWindowController2 = createAppWindowController(
                 taskController2);
         final TestTaskWindowContainerController taskController3 =
-                new TestTaskWindowContainerController(
-                        createStackControllerOnDisplay(sDisplayContent));
+                new TestTaskWindowContainerController(stackController);
 
         try {
             appWindowController1.reparent(taskController1, 0);
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index bd3271b..e589bc7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -22,6 +22,7 @@
 import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 import org.junit.Test;
@@ -53,7 +54,7 @@
                 sDisplayContent, "exiting app");
         final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
         exitingAppToken.mIsExiting = true;
-        exitingAppToken.mTask.mStack.mExitingAppTokens.add(exitingAppToken);
+        exitingAppToken.getTask().mStack.mExitingAppTokens.add(exitingAppToken);
 
         assertForAllWindowsOrder(Arrays.asList(
                 sWallpaperWindow,
@@ -146,6 +147,7 @@
         final WindowState appWin = createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin");
         appWin.setHasSurface(true);
         assertTrue(appWin.canBeImeTarget());
+        sWm.mInputMethodTargetCandidate = appWin.mClient.asBinder();
         WindowState imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
         assertEquals(appWin, imeTarget);
 
@@ -156,6 +158,20 @@
         assertTrue(childWin.canBeImeTarget());
         imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
         assertEquals(childWin, imeTarget);
+
+        final WindowState appWin2 =
+                createWindow(null, TYPE_APPLICATION, sDisplayContent, "appWin2");
+        appWin2.setHasSurface(true);
+        assertTrue(appWin2.canBeImeTarget());
+        // Verify that the IME target isn't adjusted since mInputMethodTargetCandidate didn't change
+        // to the new app.
+        imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
+        assertNotEquals(appWin2, imeTarget);
+
+        sWm.mInputMethodTargetCandidate = appWin2.mClient.asBinder();
+        // Verify app is not IME target since its token is set as a candidate.
+        imeTarget = sDisplayContent.computeImeTarget(false /* updateImeTarget */);
+        assertEquals(appWin2, imeTarget);
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 5dff997..58d277b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -49,7 +49,7 @@
         final ArraySet<Task> closingTasks = new ArraySet<>();
         sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
         assertEquals(1, closingTasks.size());
-        assertEquals(closingWindow.mAppToken.mTask, closingTasks.valueAt(0));
+        assertEquals(closingWindow.mAppToken.getTask(), closingTasks.valueAt(0));
     }
 
     @Test
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 52e10a5..440362d 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -69,7 +69,6 @@
 class WindowTestsBase {
     static WindowManagerService sWm = null;
     static TestWindowManagerPolicy sPolicy = null;
-    private final static IWindow sIWindow = new TestIWindow();
     private final static Session sMockSession = mock(Session.class);
     private static int sNextDisplayId = Display.DEFAULT_DISPLAY + 1;
     static int sNextStackId = FIRST_DYNAMIC_STACK_ID;
@@ -148,6 +147,7 @@
         }
 
         sWm.mInputMethodTarget = null;
+        sWm.mInputMethodTargetCandidate = null;
     }
 
     private static WindowState createCommonWindow(WindowState parent, int type, String name) {
@@ -167,7 +167,7 @@
         final TestTaskWindowContainerController taskController =
                 new TestTaskWindowContainerController(stackController);
         TestAppWindowToken appWinToken = new TestAppWindowToken(sDisplayContent);
-        appWinToken.mTask = taskController.mContainer;
+        appWinToken.setTask(taskController.mContainer);
         final WindowState win = createWindow(null, TYPE_BASE_APPLICATION, name);
         win.mAppToken = appWinToken;
         return win;
@@ -237,11 +237,12 @@
         final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(type);
         attrs.setTitle(name);
 
-        final WindowState w = new WindowState(sWm, sMockSession, sIWindow, token, parent, OP_NONE,
-                0, attrs, 0, 0, ownerCanAddInternalSystemWindow);
+        final WindowState w = new WindowState(sWm, sMockSession, new TestIWindow(), token, parent,
+                OP_NONE, 0, attrs, 0, 0, ownerCanAddInternalSystemWindow);
         // TODO: Probably better to make this call in the WindowState ctor to avoid errors with
         // adding it to the token...
         token.addWindow(w);
+        sWm.mWindowMap.put(w.mClient.asBinder(), w);
         return w;
     }
 
@@ -279,6 +280,7 @@
 
     /* Used so we can gain access to some protected members of the {@link WindowToken} class */
     static class TestWindowToken extends WindowToken {
+        int adj = 0;
 
         TestWindowToken(int type, DisplayContent dc) {
             this(type, dc, false /* persistOnEmpty */);
@@ -296,6 +298,11 @@
         boolean hasWindow(WindowState w) {
             return mChildren.contains(w);
         }
+
+        @Override
+        int getAnimLayerAdjustment() {
+            return adj;
+        }
     }
 
     /** Used so we can gain access to some protected members of the {@link AppWindowToken} class. */
@@ -463,8 +470,9 @@
         boolean resizeReported;
 
         TestWindowState(WindowManager.LayoutParams attrs, WindowToken token) {
-            super(sWm, sMockSession, sIWindow, token, null, OP_NONE, 0, attrs, 0, 0,
+            super(sWm, sMockSession, new TestIWindow(), token, null, OP_NONE, 0, attrs, 0, 0,
                     false /* ownerCanAddInternalSystemWindow */);
+            sWm.mWindowMap.put(mClient.asBinder(), this);
         }
 
         @Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index 0c053b9..babb6d9 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -102,14 +102,28 @@
         final WindowState window2 = createWindow(null, TYPE_APPLICATION, token, "window2");
         final WindowState window3 = createWindow(null, TYPE_APPLICATION, token, "window3");
 
-        final int adj = 50;
-        final int window2StartLayer = window2.mLayer = 100;
-        final int window3StartLayer = window3.mLayer = 200;
-        final int highestLayer = token.adjustAnimLayer(adj);
+        window2.mLayer = 100;
+        window3.mLayer = 200;
 
-        assertEquals(adj, window1.mWinAnimator.mAnimLayer);
-        assertEquals(adj, window11.mWinAnimator.mAnimLayer);
-        assertEquals(adj, window12.mWinAnimator.mAnimLayer);
+        // We assign layers once, to get the base values computed by
+        // the controller.
+        sLayersController.assignWindowLayers(sDisplayContent);
+
+        final int window1StartLayer = window1.mWinAnimator.mAnimLayer;
+        final int window11StartLayer = window11.mWinAnimator.mAnimLayer;
+        final int window12StartLayer = window12.mWinAnimator.mAnimLayer;
+        final int window2StartLayer = window2.mWinAnimator.mAnimLayer;
+        final int window3StartLayer = window3.mWinAnimator.mAnimLayer;
+
+        // Then we set an adjustment, and assign them again, they should
+        // be offset.
+        int adj = token.adj = 50;
+        sLayersController.assignWindowLayers(sDisplayContent);
+        final int highestLayer = token.getHighestAnimLayer();
+
+        assertEquals(window1StartLayer + adj, window1.mWinAnimator.mAnimLayer);
+        assertEquals(window11StartLayer + adj, window11.mWinAnimator.mAnimLayer);
+        assertEquals(window12StartLayer + adj, window12.mWinAnimator.mAnimLayer);
         assertEquals(window2StartLayer + adj, window2.mWinAnimator.mAnimLayer);
         assertEquals(window3StartLayer + adj, window3.mWinAnimator.mAnimLayer);
         assertEquals(window3StartLayer + adj, highestLayer);
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 469a8f1..ab988b2 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -60,6 +60,7 @@
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -96,6 +97,8 @@
         UserUsageStatsService.StatsUpdatedListener {
 
     static final String TAG = "UsageStatsService";
+    public static final boolean ENABLE_TIME_CHANGE_CORRECTION
+            = SystemProperties.getBoolean("debug.time_change_correction", true);
 
     static final boolean DEBUG = false; // Never submit with true
     static final boolean COMPRESS_TIME = false;
@@ -658,7 +661,8 @@
         final long actualRealtime = SystemClock.elapsedRealtime();
         final long expectedSystemTime = (actualRealtime - mRealTimeSnapshot) + mSystemTimeSnapshot;
         final long diffSystemTime = actualSystemTime - expectedSystemTime;
-        if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS) {
+        if (Math.abs(diffSystemTime) > TIME_CHANGE_THRESHOLD_MILLIS
+                && ENABLE_TIME_CHANGE_CORRECTION) {
             // The time has changed.
             Slog.i(TAG, "Time changed in UsageStats by " + (diffSystemTime / 1000) + " seconds");
             final int userCount = mUserState.size();
diff --git a/services/usb/java/com/android/server/usb/MtpNotificationManager.java b/services/usb/java/com/android/server/usb/MtpNotificationManager.java
index 5c46222..db7b385 100644
--- a/services/usb/java/com/android/server/usb/MtpNotificationManager.java
+++ b/services/usb/java/com/android/server/usb/MtpNotificationManager.java
@@ -20,7 +20,6 @@
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -32,6 +31,8 @@
 import android.hardware.usb.UsbManager;
 import android.os.UserHandle;
 
+import com.android.internal.notification.SystemNotificationChannels;
+
 /**
  * Manager for MTP storage notification.
  */
@@ -77,11 +78,12 @@
                 device.getProductName());
         final String description = resources.getString(
                 com.android.internal.R.string.usb_mtp_launch_notification_description);
-        final Notification.Builder builder = new Notification.Builder(mContext)
-                .setContentTitle(title)
-                .setContentText(description)
-                .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
-                .setCategory(Notification.CATEGORY_SYSTEM);
+        final Notification.Builder builder =
+                new Notification.Builder(mContext, SystemNotificationChannels.USB)
+                        .setContentTitle(title)
+                        .setContentText(description)
+                        .setSmallIcon(com.android.internal.R.drawable.stat_sys_data_usb)
+                        .setCategory(Notification.CATEGORY_SYSTEM);
 
         final Intent intent = new Intent(ACTION_OPEN_IN_APPS);
         intent.putExtra(UsbManager.EXTRA_DEVICE, device);
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 07b4ca1..b1df0af 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -50,6 +50,7 @@
 import android.util.Slog;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.notification.SystemNotificationChannels;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.FgThread;
@@ -912,13 +913,13 @@
                     PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                             intent, 0, null, UserHandle.CURRENT);
 
-                    Notification notification = new Notification.Builder(mContext)
+                    Notification notification =
+                            new Notification.Builder(mContext, SystemNotificationChannels.USB)
                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                             .setWhen(0)
                             .setOngoing(true)
                             .setTicker(title)
                             .setDefaults(0)  // please be quiet
-                            .setPriority(Notification.PRIORITY_MIN)
                             .setColor(mContext.getColor(
                                     com.android.internal.R.color.system_notification_accent_color))
                             .setContentTitle(title)
@@ -951,13 +952,13 @@
                     PendingIntent pi = PendingIntent.getActivityAsUser(mContext, 0,
                             intent, 0, null, UserHandle.CURRENT);
 
-                    Notification notification = new Notification.Builder(mContext)
+                    Notification notification =
+                            new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
                             .setWhen(0)
                             .setOngoing(true)
                             .setTicker(title)
                             .setDefaults(0)  // please be quiet
-                            .setPriority(Notification.PRIORITY_DEFAULT)
                             .setColor(mContext.getColor(
                                     com.android.internal.R.color.system_notification_accent_color))
                             .setContentTitle(title)
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index 4b8e4c8..a923fc3 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -117,7 +117,7 @@
     public UsbPortManager(Context context) {
         mContext = context;
         try {
-            boolean ret = IServiceManager.getService("manager")
+            boolean ret = IServiceManager.getService()
                     .registerForNotifications("android.hardware.usb@1.0::IUsb",
                     "", mServiceNotification);
             if (!ret) {
@@ -455,9 +455,9 @@
 
         public void notifyRoleSwitchStatus(String portName, PortRole role, int retval) {
             if (retval == Status.SUCCESS) {
-                logAndPrint(Log.INFO, pw, portName + "role switch successful");
+                logAndPrint(Log.INFO, pw, portName + " role switch successful");
             } else {
-                logAndPrint(Log.ERROR, pw, portName + "role switch failed");
+                logAndPrint(Log.ERROR, pw, portName + " role switch failed");
             }
         }
     };
@@ -498,11 +498,12 @@
                 mProxy.setCallback(mHALCallback);
                 mProxy.queryPortStatus();
             } catch (NoSuchElementException e) {
-                logAndPrint(Log.ERROR, pw, sSERVICENAME + "not found."
-                        + " Did the service failed to start ?");
+                logAndPrint(Log.ERROR, pw, sSERVICENAME + " not found."
+                        + " Did the service fail to start?");
                 Thread.dumpStack();
             } catch (RemoteException e) {
-                logAndPrint(Log.ERROR, pw, sSERVICENAME + "connectToProxy: Service not responding");
+                logAndPrint(Log.ERROR, pw, sSERVICENAME
+                        + " connectToProxy: Service not responding");
                 Thread.dumpStack();
             }
         }
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 4295d40..5bb479f 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -328,8 +328,15 @@
          */
         public static final int PROPERTY_HAS_CDMA_VOICE_PRIVACY = 0x00000080;
 
+        /**
+         * Indicates that the call is from a self-managed {@link ConnectionService}.
+         * <p>
+         * See also {@link Connection#PROPERTY_SELF_MANAGED}
+         */
+        public static final int PROPERTY_SELF_MANAGED = 0x00000100;
+
         //******************************************************************************************
-        // Next PROPERTY value: 0x00000100
+        // Next PROPERTY value: 0x00000200
         //******************************************************************************************
 
         private final String mTelecomCallId;
@@ -878,6 +885,7 @@
      * party, if it is active.
      */
     public static final class RttCall {
+        /** @hide */
         @Retention(RetentionPolicy.SOURCE)
         @IntDef({RTT_MODE_INVALID, RTT_MODE_FULL, RTT_MODE_HCO, RTT_MODE_VCO})
         public @interface RttAudioMode {}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index 6807ef4..359dcb1 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -373,6 +373,24 @@
             "android.telecom.INCLUDE_EXTERNAL_CALLS";
 
     /**
+     * A boolean meta-data value indicating whether an {@link InCallService} wants to be informed of
+     * calls which have the {@link Call.Details#PROPERTY_SELF_MANAGED} property.  A self-managed
+     * call is one which originates from a self-managed {@link ConnectionService} which has chosen
+     * to implement its own call user interface.  An {@link InCallService} implementation which
+     * would like to be informed of external calls should set this meta-data to {@code true} in the
+     * manifest registration of their {@link InCallService}.  By default, the {@link InCallService}
+     * will NOT be informed about self-managed calls.
+     * <p>
+     * An {@link InCallService} which receives self-managed calls is free to view and control the
+     * state of calls in the self-managed {@link ConnectionService}.  An example use-case is
+     * exposing these calls to a wearable or automotive device via its companion app.
+     * <p>
+     * See also {@link Connection#PROPERTY_SELF_MANAGED}.
+     */
+    public static final String METADATA_INCLUDE_SELF_MANAGED_CALLS =
+            "android.telecom.INCLUDE_SELF_MANAGED_CALLS";
+
+    /**
      * The dual tone multi-frequency signaling character sent to indicate the dialing system should
      * pause for a predefined period.
      */
@@ -1051,10 +1069,12 @@
 
     /**
      * Returns whether there is an ongoing phone call (can be in dialing, ringing, active or holding
-     * states).
+     * states) originating from either a manager or self-managed {@link ConnectionService}.
      * <p>
      * Requires permission: {@link android.Manifest.permission#READ_PHONE_STATE}
-     * </p>
+     *
+     * @return {@code true} if there is an ongoing call in either a managed or self-managed
+     *      {@link ConnectionService}, {@code false} otherwise.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     public boolean isInCall() {
@@ -1069,6 +1089,31 @@
     }
 
     /**
+     * Returns whether there is an ongoing call originating from a managed
+     * {@link ConnectionService}.  An ongoing call can be in dialing, ringing, active or holding
+     * states.
+     * <p>
+     * If you also need to know if there are ongoing self-managed calls, use {@link #isInCall()}
+     * instead.
+     * <p>
+     * Requires permission: {@link android.Manifest.permission#READ_PHONE_STATE}
+     *
+     * @return {@code true} if there is an ongoing call in a managed {@link ConnectionService},
+     *      {@code false} otherwise.
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    public boolean isInManagedCall() {
+        try {
+            if (isServiceConnected()) {
+                return getTelecomService().isInManagedCall(mContext.getOpPackageName());
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException calling isInManagedCall().", e);
+        }
+        return false;
+    }
+
+    /**
      * Returns one of the following constants that represents the current state of Telecom:
      *
      * {@link TelephonyManager#CALL_STATE_RINGING}
@@ -1079,6 +1124,9 @@
      * {@link android.Manifest.permission#READ_PHONE_STATE} permission. This is intentional, to
      * preserve the behavior of {@link TelephonyManager#getCallState()}, which also did not require
      * the permission.
+     *
+     * Takes into consideration both managed and self-managed calls.
+     *
      * @hide
      */
     @SystemApi
@@ -1096,6 +1144,7 @@
     /**
      * Returns whether there currently exists is a ringing incoming-call.
      *
+     * @return {@code true} if there is a managed or self-managed ringing call.
      * @hide
      */
     @SystemApi
@@ -1130,18 +1179,22 @@
 
     /**
      * If there is a ringing incoming call, this method accepts the call on behalf of the user.
-     * TODO: L-release - need to convert all invocation of ITelecmmService#answerRingingCall to use
-     * this method (clockwork & gearhead).
+     *
      * If the incoming call is a video call, the call will be answered with the same video state as
      * the incoming call requests.  This means, for example, that an incoming call requesting
      * {@link VideoProfile#STATE_BIDIRECTIONAL} will be answered, accepting that state.
-     * @hide
+     *
+     * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or
+     * {@link android.Manifest.permission#ANSWER_PHONE_CALLS}
      */
-    @SystemApi
+    //TODO: L-release - need to convert all invocation of ITelecmmService#answerRingingCall to use
+    // this method (clockwork & gearhead).
+    @RequiresPermission(anyOf =
+            {Manifest.permission.ANSWER_PHONE_CALLS, Manifest.permission.MODIFY_PHONE_STATE})
     public void acceptRingingCall() {
         try {
             if (isServiceConnected()) {
-                getTelecomService().acceptRingingCall();
+                getTelecomService().acceptRingingCall(mContext.getPackageName());
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelecomService#acceptRingingCall", e);
@@ -1152,14 +1205,18 @@
      * If there is a ringing incoming call, this method accepts the call on behalf of the user,
      * with the specified video state.
      *
+     * Requires permission: {@link android.Manifest.permission#MODIFY_PHONE_STATE} or
+     * {@link android.Manifest.permission#ANSWER_PHONE_CALLS}
+     *
      * @param videoState The desired video state to answer the call with.
-     * @hide
      */
-    @SystemApi
+    @RequiresPermission(anyOf =
+            {Manifest.permission.ANSWER_PHONE_CALLS, Manifest.permission.MODIFY_PHONE_STATE})
     public void acceptRingingCall(int videoState) {
         try {
             if (isServiceConnected()) {
-                getTelecomService().acceptRingingCallWithVideoState(videoState);
+                getTelecomService().acceptRingingCallWithVideoState(
+                        mContext.getPackageName(), videoState);
             }
         } catch (RemoteException e) {
             Log.e(TAG, "Error calling ITelecomService#acceptRingingCallWithVideoState", e);
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index d9465dc..8740224 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -165,6 +165,11 @@
     boolean isInCall(String callingPackage);
 
     /**
+     * @see TelecomServiceImpl#isInManagedCall
+     */
+    boolean isInManagedCall(String callingPackage);
+
+    /**
      * @see TelecomServiceImpl#isRinging
      */
     boolean isRinging(String callingPackage);
@@ -182,12 +187,12 @@
     /**
      * @see TelecomServiceImpl#acceptRingingCall
      */
-    void acceptRingingCall();
+    void acceptRingingCall(String callingPackage);
 
     /**
      * @see TelecomServiceImpl#acceptRingingCallWithVideoState(int)
      */
-    void acceptRingingCallWithVideoState(int videoState);
+    void acceptRingingCallWithVideoState(String callingPackage, int videoState);
 
     /**
      * @see TelecomServiceImpl#cancelMissedCallsNotification
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7bb58dd4..632a1d6 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1282,6 +1282,14 @@
         "support_3gpp_call_forwarding_while_roaming_bool";
 
     /**
+     * When {@code true}, the user will be notified when they attempt to place an international call
+     * when the call is placed using wifi calling.
+     * @hide
+     */
+    public static final String KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL =
+            "notify_international_call_on_wfc_bool";
+
+    /**
      * Determine whether user edited tether APN (type dun) has effect
      * {@code false} - Default. APN with dun type in telephony database has no effect.
      *
@@ -1529,6 +1537,7 @@
         sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null);
         sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1);
         sDefaults.putBoolean(KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL, true);
+        sDefaults.putBoolean(KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL, false);
         sDefaults.putBoolean(KEY_EDITABLE_TETHER_APN_BOOL, false);
         sDefaults.putStringArray(KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY,
                 null);
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index cc21b5e..a3e11c8 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1440,6 +1440,30 @@
     }
 
     /**
+     * Determines if a {@param phoneNumber} is international if dialed from
+     * {@param defaultCountryIso}.
+     *
+     * @param phoneNumber The phone number.
+     * @param defaultCountryIso The current country ISO.
+     * @return {@code true} if the number is international, {@code false} otherwise.
+     * @hide
+     */
+    public static boolean isInternationalNumber(String phoneNumber, String defaultCountryIso) {
+        // If it starts with # or * its not international.
+        if (phoneNumber.startsWith("#") || phoneNumber.startsWith("*")) {
+            return false;
+        }
+
+        PhoneNumberUtil util = PhoneNumberUtil.getInstance();
+        try {
+            PhoneNumber pn = util.parseAndKeepRawInput(phoneNumber, defaultCountryIso);
+            return pn.getCountryCode() != util.getCountryCodeForRegion(defaultCountryIso);
+        } catch (NumberParseException e) {
+            return false;
+        }
+    }
+
+    /**
      * Format a phone number.
      * <p>
      * If the given number doesn't have the country code, the phone will be
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index f5974cd..932c276 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -819,6 +819,21 @@
     public static final String EVENT_DOWNGRADE_DATA_DISABLED =
             "android.telephony.event.EVENT_DOWNGRADE_DATA_DISABLED";
 
+    /**
+     * {@link android.telecom.Connection} event used to indicate that the InCall UI should notify
+     * the user when an international call is placed while on WFC only.
+     * <p>
+     * Used when the carrier config value
+     * {@link CarrierConfigManager#KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL} is true, the device
+     * is on WFC (VoLTE not available) and an international number is dialed.
+     * <p>
+     * Sent via {@link android.telecom.Connection#sendConnectionEvent(String, Bundle)}.
+     * The {@link Bundle} parameter is expected to be null when this connection event is used.
+     * @hide
+     */
+    public static final String EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC =
+            "android.telephony.event.EVENT_NOTIFY_INTERNATIONAL_CALL_ON_WFC";
+
     /* Visual voicemail protocols */
 
     /**
@@ -4026,9 +4041,8 @@
             }
         }
 
-        if (property.length() > SystemProperties.PROP_NAME_MAX
-                || propVal.length() > SystemProperties.PROP_VALUE_MAX) {
-            Rlog.d(TAG, "setTelephonyProperty: property to long phoneId=" + phoneId +
+        if (propVal.length() > SystemProperties.PROP_VALUE_MAX) {
+            Rlog.d(TAG, "setTelephonyProperty: property too long phoneId=" + phoneId +
                     " property=" + property + " value: " + value + " propVal=" + propVal);
             return;
         }
@@ -4285,6 +4299,45 @@
     }
 
     /**
+     * Returns an array of Forbidden PLMNs from the USIM App
+     * Returns null if the query fails.
+     *
+     *
+     * <p>Requires that the caller has READ_PRIVILEGED_PHONE_STATE
+     *
+     * @return an array of forbidden PLMNs or null if not available
+     */
+    public String[] getForbiddenPlmns() {
+      return getForbiddenPlmns(getSubId(), APPTYPE_USIM);
+    }
+
+    /**
+     * Returns an array of Forbidden PLMNs from the specified SIM App
+     * Returns null if the query fails.
+     *
+     *
+     * <p>Requires that the calling app has READ_PRIVILEGED_PHONE_STATE
+     *
+     * @param subId subscription ID used for authentication
+     * @param appType the icc application type, like {@link #APPTYPE_USIM}
+     * @return fplmns an array of forbidden PLMNs
+     * @hide
+     */
+    public String[] getForbiddenPlmns(int subId, int appType) {
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony == null)
+                return null;
+            return telephony.getForbiddenPlmns(subId, appType);
+        } catch (RemoteException ex) {
+            return null;
+        } catch (NullPointerException ex) {
+            // This could happen before phone starts
+            return null;
+        }
+    }
+
+    /**
      * Get P-CSCF address from PCO after data connection is established or modified.
      * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
      * @return array of P-CSCF address
diff --git a/telephony/java/android/telephony/ims/ImsService.java b/telephony/java/android/telephony/ims/ImsService.java
index fe8dbfb..f1f683c 100644
--- a/telephony/java/android/telephony/ims/ImsService.java
+++ b/telephony/java/android/telephony/ims/ImsService.java
@@ -18,6 +18,7 @@
 
 import android.app.PendingIntent;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
@@ -41,6 +42,10 @@
 import com.android.ims.internal.IImsUt;
 import com.android.internal.annotations.VisibleForTesting;
 
+import static android.Manifest.permission.MODIFY_PHONE_STATE;
+import static android.Manifest.permission.READ_PHONE_STATE;
+import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
+
 /**
  * Main ImsService implementation, which binds via the Telephony ImsResolver. Services that extend
  * ImsService must register the service in their AndroidManifest to be detected by the framework.
@@ -94,6 +99,7 @@
         public void createImsFeature(int slotId, int feature, IImsFeatureStatusCallback c)
                 throws RemoteException {
             synchronized (mFeatures) {
+                enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "createImsFeature");
                 onCreateImsFeatureInternal(slotId, feature, c);
             }
         }
@@ -101,6 +107,7 @@
         @Override
         public void removeImsFeature(int slotId, int feature) throws RemoteException {
             synchronized (mFeatures) {
+                enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "removeImsFeature");
                 onRemoveImsFeatureInternal(slotId, feature);
             }
         }
@@ -108,6 +115,7 @@
         @Override
         public int startSession(int slotId, int featureType, PendingIntent incomingCallIntent,
                 IImsRegistrationListener listener) throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "startSession");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -120,6 +128,7 @@
         @Override
         public void endSession(int slotId, int featureType, int sessionId) throws RemoteException {
             synchronized (mFeatures) {
+                enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "endSession");
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
                     feature.endSession(sessionId);
@@ -130,6 +139,7 @@
         @Override
         public boolean isConnected(int slotId, int featureType, int callSessionType, int callType)
                 throws RemoteException {
+            enforceReadPhoneStatePermission("isConnected");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -141,6 +151,7 @@
 
         @Override
         public boolean isOpened(int slotId, int featureType) throws RemoteException {
+            enforceReadPhoneStatePermission("isOpened");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -152,6 +163,7 @@
 
         @Override
         public int getFeatureStatus(int slotId, int featureType) throws RemoteException {
+            enforceReadPhoneStatePermission("getFeatureStatus");
             int status = ImsFeature.STATE_NOT_AVAILABLE;
             synchronized (mFeatures) {
                 SparseArray<ImsFeature> featureMap = mFeatures.get(slotId);
@@ -168,6 +180,7 @@
         @Override
         public void addRegistrationListener(int slotId, int featureType,
                 IImsRegistrationListener listener) throws RemoteException {
+            enforceReadPhoneStatePermission("addRegistrationListener");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -179,6 +192,7 @@
         @Override
         public void removeRegistrationListener(int slotId, int featureType,
                 IImsRegistrationListener listener) throws RemoteException {
+            enforceReadPhoneStatePermission("removeRegistrationListener");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -190,6 +204,7 @@
         @Override
         public ImsCallProfile createCallProfile(int slotId, int featureType, int sessionId,
                 int callSessionType, int callType) throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "createCallProfile");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -202,6 +217,7 @@
         @Override
         public IImsCallSession createCallSession(int slotId, int featureType, int sessionId,
                 ImsCallProfile profile, IImsCallSessionListener listener) throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "createCallSession");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -214,6 +230,7 @@
         @Override
         public IImsCallSession getPendingCallSession(int slotId, int featureType, int sessionId,
                 String callId) throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getPendingCallSession");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -226,6 +243,7 @@
         @Override
         public IImsUt getUtInterface(int slotId, int featureType)
                 throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getUtInterface");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -238,6 +256,7 @@
         @Override
         public IImsConfig getConfigInterface(int slotId, int featureType)
                 throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getConfigInterface");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -249,6 +268,7 @@
 
         @Override
         public void turnOnIms(int slotId, int featureType) throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "turnOnIms");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -259,6 +279,7 @@
 
         @Override
         public void turnOffIms(int slotId, int featureType) throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "turnOffIms");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -270,6 +291,7 @@
         @Override
         public IImsEcbm getEcbmInterface(int slotId, int featureType)
                 throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getEcbmInterface");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -282,6 +304,7 @@
         @Override
         public void setUiTTYMode(int slotId, int featureType, int uiTtyMode, Message onComplete)
                 throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "setUiTTYMode");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -293,6 +316,7 @@
         @Override
         public IImsMultiEndpoint getMultiEndpointInterface(int slotId, int featureType)
                 throws RemoteException {
+            enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, "getMultiEndpointInterface");
             synchronized (mFeatures) {
                 MMTelFeature feature = resolveMMTelFeature(slotId, featureType);
                 if (feature != null) {
@@ -329,6 +353,8 @@
         }
         ImsFeature f = makeImsFeature(slotId, featureType);
         if (f != null) {
+            f.setContext(this);
+            f.setSlotId(slotId);
             f.setImsFeatureStatusCallback(c);
             featureMap.put(featureType, f);
         }
@@ -412,6 +438,17 @@
     }
 
     /**
+     * Check for both READ_PHONE_STATE and READ_PRIVILEGED_PHONE_STATE. READ_PHONE_STATE is a
+     * public permission and READ_PRIVILEGED_PHONE_STATE is only granted to system apps.
+     */
+    private void enforceReadPhoneStatePermission(String fn) {
+        if (checkCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE)
+                != PackageManager.PERMISSION_GRANTED) {
+            enforceCallingOrSelfPermission(READ_PHONE_STATE, fn);
+        }
+    }
+
+    /**
      * @return An implementation of MMTelFeature that will be used by the system for MMTel
      * functionality. Must be able to handle emergency calls at any time as well.
      */
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 8d7d260..988dd58 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -17,7 +17,10 @@
 package android.telephony.ims.feature;
 
 import android.annotation.IntDef;
+import android.content.Context;
+import android.content.Intent;
 import android.os.RemoteException;
+import android.telephony.SubscriptionManager;
 import android.util.Log;
 
 import com.android.ims.internal.IImsFeatureStatusCallback;
@@ -35,6 +38,32 @@
 
     private static final String LOG_TAG = "ImsFeature";
 
+    /**
+     * Action to broadcast when ImsService is up.
+     * Internal use only.
+     * Only defined here separately compatibility purposes with the old ImsService.
+     * @hide
+     */
+    public static final String ACTION_IMS_SERVICE_UP =
+            "com.android.ims.IMS_SERVICE_UP";
+
+    /**
+     * Action to broadcast when ImsService is down.
+     * Internal use only.
+     * Only defined here separately for compatibility purposes with the old ImsService.
+     * @hide
+     */
+    public static final String ACTION_IMS_SERVICE_DOWN =
+            "com.android.ims.IMS_SERVICE_DOWN";
+
+    /**
+     * Part of the ACTION_IMS_SERVICE_UP or _DOWN intents.
+     * A long value; the phone ID corresponding to the IMS service coming up or down.
+     * Only defined here separately for compatibility purposes with the old ImsService.
+     * @hide
+     */
+    public static final String EXTRA_PHONE_ID = "android:phone_id";
+
     // Invalid feature value
     public static final int INVALID = -1;
     // ImsFeatures that are defined in the Manifests. Ensure that these values match the previously
@@ -61,11 +90,21 @@
     private List<INotifyFeatureRemoved> mRemovedListeners = new ArrayList<>();
     private IImsFeatureStatusCallback mStatusCallback;
     private @ImsState int mState = STATE_NOT_AVAILABLE;
+    private int mSlotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
+    private Context mContext;
 
     public interface INotifyFeatureRemoved {
         void onFeatureRemoved(int slotId);
     }
 
+    public void setContext(Context context) {
+        mContext = context;
+    }
+
+    public void setSlotId(int slotId) {
+        mSlotId = slotId;
+    }
+
     public void addFeatureRemovedListener(INotifyFeatureRemoved listener) {
         synchronized (mRemovedListeners) {
             mRemovedListeners.add(listener);
@@ -118,6 +157,30 @@
                 Log.w(LOG_TAG, "Couldn't notify feature state: " + e.getMessage());
             }
         }
+        sendImsServiceIntent(state);
+    }
+
+    /**
+     * Provide backwards compatibility using deprecated service UP/DOWN intents.
+     */
+    private void sendImsServiceIntent(@ImsState int state) {
+        if(mContext == null || mSlotId == SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
+            return;
+        }
+        Intent intent;
+        switch (state) {
+            case ImsFeature.STATE_NOT_AVAILABLE:
+            case ImsFeature.STATE_INITIALIZING:
+                intent = new Intent(ACTION_IMS_SERVICE_DOWN);
+                break;
+            case ImsFeature.STATE_READY:
+                intent = new Intent(ACTION_IMS_SERVICE_UP);
+                break;
+            default:
+                intent = new Intent(ACTION_IMS_SERVICE_DOWN);
+        }
+        intent.putExtra(EXTRA_PHONE_ID, mSlotId);
+        mContext.sendBroadcast(intent);
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 88daf64..e3816b6 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1278,7 +1278,6 @@
      */
     void setPolicyDataEnabled(boolean enabled, int subId);
 
-
     /**
      * Get Client request stats which will contain statistical information
      * on each request made by client.
@@ -1295,4 +1294,16 @@
      * @hide
      * */
     void setSimPowerStateForSlot(int slotId, boolean powerUp);
+
+    /**
+     * Returns a list of Forbidden PLMNs from the specified SIM App
+     * Returns null if the query fails.
+     *
+     *
+     * <p>Requires that the calling app has READ_PRIVILEGED_PHONE_STATE
+     *
+     * @param subId subscription ID used for authentication
+     * @param appType the icc application type, like {@link #APPTYPE_USIM}
+     */
+    String[] getForbiddenPlmns(int subId, int appType);
 }
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index c3b740e..eafa6b7 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -411,6 +411,8 @@
     int RIL_REQUEST_GET_ACTIVITY_INFO = 135;
     int RIL_REQUEST_SET_ALLOWED_CARRIERS = 136;
     int RIL_REQUEST_GET_ALLOWED_CARRIERS = 137;
+    int RIL_REQUEST_SEND_DEVICE_STATE = 138;
+    int RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER = 139;
     int RIL_REQUEST_SET_SIM_CARD_POWER = 140;
 
     int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java
index d51d75e..29ba776 100644
--- a/test-runner/src/android/test/mock/MockPackageManager.java
+++ b/test-runner/src/android/test/mock/MockPackageManager.java
@@ -365,6 +365,12 @@
 
     /** @hide */
     @Override
+    public boolean isInstantApp(String packageName) {
+        throw new UnsupportedOperationException();
+    }
+
+    /** @hide */
+    @Override
     public int getInstantAppCookieMaxSize() {
         throw new UnsupportedOperationException();
     }
diff --git a/tests/net/java/android/net/ConnectivityManagerTest.java b/tests/net/java/android/net/ConnectivityManagerTest.java
index b984bbf..684a101 100644
--- a/tests/net/java/android/net/ConnectivityManagerTest.java
+++ b/tests/net/java/android/net/ConnectivityManagerTest.java
@@ -36,21 +36,36 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.when;
 
-import android.net.ConnectivityManager;
-import android.net.NetworkCapabilities;
-
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.Build.VERSION_CODES;
+import android.net.ConnectivityManager.NetworkCallback;
 import android.support.test.filters.SmallTest;
 import android.support.test.runner.AndroidJUnit4;
 
-import org.junit.runner.RunWith;
+import org.junit.Before;
 import org.junit.Test;
-
-
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class ConnectivityManagerTest {
+
+    @Mock Context mCtx;
+    @Mock IConnectivityManager mService;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
     static NetworkCapabilities verifyNetworkCapabilities(
             int legacyType, int transportType, int... capabilities) {
         final NetworkCapabilities nc = ConnectivityManager.networkCapabilitiesForType(legacyType);
@@ -173,4 +188,34 @@
         verifyUnrestrictedNetworkCapabilities(
                 ConnectivityManager.TYPE_ETHERNET, TRANSPORT_ETHERNET);
     }
+
+    @Test
+    public void testNoDoubleCallbackRegistration() throws Exception {
+        ConnectivityManager manager = new ConnectivityManager(mCtx, mService);
+        NetworkRequest request = new NetworkRequest.Builder().clearCapabilities().build();
+        NetworkCallback callback = new ConnectivityManager.NetworkCallback();
+        ApplicationInfo info = new ApplicationInfo();
+        info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
+
+        when(mCtx.getApplicationInfo()).thenReturn(info);
+        when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt())).thenReturn(request);
+
+        manager.requestNetwork(request, callback);
+
+        // Callback is already registered, reregistration should fail.
+        Class<IllegalArgumentException> wantException = IllegalArgumentException.class;
+        expectThrowable(() -> manager.requestNetwork(request, callback), wantException);
+    }
+
+    static void expectThrowable(Runnable block, Class<? extends Throwable> throwableType) {
+        try {
+            block.run();
+        } catch (Throwable t) {
+            if (t.getClass().equals(throwableType)) {
+                return;
+            }
+            fail("expected exception of type " + throwableType + ", but was " + t.getClass());
+        }
+        fail("expected exception of type " + throwableType);
+    }
 }
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index eeaf26f..c05045e 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -369,6 +369,11 @@
             connect(false);
         }
 
+        public void suspend() {
+            mNetworkInfo.setDetailedState(DetailedState.SUSPENDED, null, null);
+            mNetworkAgent.sendNetworkInfo(mNetworkInfo);
+        }
+
         public void disconnect() {
             mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
             mNetworkAgent.sendNetworkInfo(mNetworkInfo);
@@ -1054,6 +1059,7 @@
         AVAILABLE,
         NETWORK_CAPABILITIES,
         LINK_PROPERTIES,
+        SUSPENDED,
         LOSING,
         LOST,
         UNAVAILABLE
@@ -1067,7 +1073,7 @@
             state = s; network = n; arg = o;
         }
         public String toString() {
-            return String.format("%s (%s)", state, network);
+            return String.format("%s (%s) (%s)", state, network, arg);
         }
         @Override
         public boolean equals(Object o) {
@@ -1105,11 +1111,26 @@
         }
 
         @Override
+        public void onCapabilitiesChanged(Network network, NetworkCapabilities netCap) {
+            setLastCallback(CallbackState.NETWORK_CAPABILITIES, network, netCap);
+        }
+
+        @Override
+        public void onLinkPropertiesChanged(Network network, LinkProperties linkProp) {
+            setLastCallback(CallbackState.LINK_PROPERTIES, network, linkProp);
+        }
+
+        @Override
         public void onUnavailable() {
             setLastCallback(CallbackState.UNAVAILABLE, null, null);
         }
 
         @Override
+        public void onNetworkSuspended(Network network) {
+            setLastCallback(CallbackState.SUSPENDED, network, null);
+        }
+
+        @Override
         public void onLosing(Network network, int maxMsToLive) {
             setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
         }
@@ -1132,11 +1153,12 @@
             return cb;
         }
 
-        void expectCallback(CallbackState state, MockNetworkAgent mockAgent, int timeoutMs) {
-            CallbackInfo expected = new CallbackInfo(
-                    state, (mockAgent != null) ? mockAgent.getNetwork() : null, 0);
+        CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent, int timeoutMs) {
+            final Network expectedNetwork = (agent != null) ? agent.getNetwork() : null;
+            CallbackInfo expected = new CallbackInfo(state, expectedNetwork, 0);
             CallbackInfo actual = nextCallback(timeoutMs);
             assertEquals("Unexpected callback:", expected, actual);
+
             if (state == CallbackState.LOSING) {
                 String msg = String.format(
                         "Invalid linger time value %d, must be between %d and %d",
@@ -1144,10 +1166,50 @@
                 int maxMsToLive = (Integer) actual.arg;
                 assertTrue(msg, 0 <= maxMsToLive && maxMsToLive <= TEST_LINGER_DELAY_MS);
             }
+
+            return actual;
         }
 
-        void expectCallback(CallbackState state, MockNetworkAgent mockAgent) {
-            expectCallback(state, mockAgent, TIMEOUT_MS);
+        CallbackInfo expectCallback(CallbackState state, MockNetworkAgent agent) {
+            return expectCallback(state, agent, TIMEOUT_MS);
+        }
+
+        void expectAvailableCallbacks(MockNetworkAgent agent, boolean expectSuspended, int timeoutMs) {
+            expectCallback(CallbackState.AVAILABLE, agent, timeoutMs);
+
+            final boolean HAS_DATASYNC_ON_AVAILABLE = false;
+            if (HAS_DATASYNC_ON_AVAILABLE) {
+                if (expectSuspended) {
+                    expectCallback(CallbackState.SUSPENDED, agent, timeoutMs);
+                }
+                expectCallback(CallbackState.NETWORK_CAPABILITIES, agent, timeoutMs);
+                expectCallback(CallbackState.LINK_PROPERTIES, agent, timeoutMs);
+            }
+        }
+
+        void expectAvailableCallbacks(MockNetworkAgent agent) {
+            expectAvailableCallbacks(agent, false, TIMEOUT_MS);
+        }
+
+        void expectAvailableAndSuspendedCallbacks(MockNetworkAgent agent) {
+            expectAvailableCallbacks(agent, true, TIMEOUT_MS);
+        }
+
+        void expectAvailableAndValidatedCallbacks(MockNetworkAgent agent) {
+            expectAvailableCallbacks(agent, true, TIMEOUT_MS);
+            expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, agent);
+        }
+
+        void expectCapabilitiesWith(int capability, MockNetworkAgent agent) {
+            CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent);
+            NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
+            assertTrue(nc.hasCapability(capability));
+        }
+
+        void expectCapabilitiesWithout(int capability, MockNetworkAgent agent) {
+            CallbackInfo cbi = expectCallback(CallbackState.NETWORK_CAPABILITIES, agent);
+            NetworkCapabilities nc = (NetworkCapabilities) cbi.arg;
+            assertFalse(nc.hasCapability(capability));
         }
 
         void assertNoCallback() {
@@ -1184,8 +1246,8 @@
         ConditionVariable cv = waitForConnectivityBroadcasts(1);
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(false);
-        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        genericNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent);
+        cellNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         waitFor(cv);
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
@@ -1199,8 +1261,8 @@
         cv = waitForConnectivityBroadcasts(2);
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        genericNetworkCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        wifiNetworkCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         waitFor(cv);
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
@@ -1223,8 +1285,8 @@
         // Test validated networks
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
-        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        genericNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
+        cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
 
@@ -1236,9 +1298,10 @@
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
-        genericNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        genericNetworkCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         genericNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
-        wifiNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        genericNetworkCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        wifiNetworkCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
         cellNetworkCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
         assertNoCallbacks(genericNetworkCallback, wifiNetworkCallback, cellNetworkCallback);
@@ -1274,28 +1337,32 @@
         mEthernetNetworkAgent.addCapability(NET_CAPABILITY_NOT_METERED);
 
         mCellNetworkAgent.connect(true);
-        callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.connect(true);
         // We get AVAILABLE on wifi when wifi connects and satisfies our unmetered request.
         // We then get LOSING when wifi validates and cell is outscored.
-        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        // TODO: Investigate sending validated before losing.
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         mEthernetNetworkAgent.connect(true);
-        callback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
+        callback.expectAvailableCallbacks(mEthernetNetworkAgent);
+        // TODO: Investigate sending validated before losing.
         callback.expectCallback(CallbackState.LOSING, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mEthernetNetworkAgent);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mEthernetNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mEthernetNetworkAgent);
         assertEquals(mEthernetNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         mEthernetNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mEthernetNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
 
         for (int i = 0; i < 4; i++) {
             MockNetworkAgent oldNetwork, newNetwork;
@@ -1312,7 +1379,7 @@
             callback.expectCallback(CallbackState.LOSING, oldNetwork);
             // TODO: should we send an AVAILABLE callback to newNetwork, to indicate that it is no
             // longer lingering?
-            defaultCallback.expectCallback(CallbackState.AVAILABLE, newNetwork);
+            defaultCallback.expectAvailableCallbacks(newNetwork);
             assertEquals(newNetwork.getNetwork(), mCm.getActiveNetwork());
         }
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
@@ -1320,17 +1387,19 @@
         // Verify that if a network no longer satisfies a request, we send LOST and not LOSING, even
         // if the network is still up.
         mWiFiNetworkAgent.removeCapability(NET_CAPABILITY_NOT_METERED);
+        // We expect a notification about the capabilities change, and nothing else.
+        defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_NOT_METERED, mWiFiNetworkAgent);
+        defaultCallback.assertNoCallback();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
 
         // Wifi no longer satisfies our listen, which is for an unmetered network.
         // But because its score is 55, it's still up (and the default network).
-        defaultCallback.assertNoCallback();
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         // Disconnect our test networks.
         mWiFiNetworkAgent.disconnect();
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         mCellNetworkAgent.disconnect();
         defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
 
@@ -1346,22 +1415,22 @@
 
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(false);   // Score: 10
-        callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        callback.expectAvailableCallbacks(mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         // Bring up wifi with a score of 20.
         // Cell stays up because it would satisfy the default request if it validated.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);   // Score: 20
-        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         // Bring up wifi with a score of 70.
@@ -1369,31 +1438,33 @@
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.adjustScore(50);
         mWiFiNetworkAgent.connect(false);   // Score: 70
-        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         // Tear down wifi.
         mWiFiNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertEquals(mCellNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         // Bring up wifi, then validate it. Previous versions would immediately tear down cell, but
         // it's arguably correct to linger it, since it was the default network before it validated.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
-        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        // TODO: Investigate sending validated before losing.
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork());
 
         mWiFiNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         mCellNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
@@ -1401,13 +1472,15 @@
         // If a network is lingering, and we add and remove a request from it, resume lingering.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
-        callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
-        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        // TODO: Investigate sending validated before losing.
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
 
         NetworkRequest cellRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_CELLULAR).build();
@@ -1423,7 +1496,7 @@
         mWiFiNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         defaultCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
 
         // Cell is now the default network. Pin it with a cell-specific request.
         noopCallback = new NetworkCallback();  // Can't reuse NetworkCallbacks. http://b/20701525
@@ -1432,8 +1505,8 @@
         // Now connect wifi, and expect it to become the default network.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
-        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
         // The default request is lingering on cell, but nothing happens to cell, and we send no
         // callbacks for it, because it's kept up by cellRequest.
         callback.assertNoCallback();
@@ -1619,7 +1692,7 @@
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.addCapability(NET_CAPABILITY_MMS);
         mCellNetworkAgent.connectWithoutInternet();
-        networkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        networkCallback.expectAvailableCallbacks(mCellNetworkAgent);
         verifyActiveNetwork(TRANSPORT_WIFI);
         // Test releasing NetworkRequest disconnects cellular with MMS
         cv = mCellNetworkAgent.getDisconnectedCV();
@@ -1645,7 +1718,7 @@
         MockNetworkAgent mmsNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mmsNetworkAgent.addCapability(NET_CAPABILITY_MMS);
         mmsNetworkAgent.connectWithoutInternet();
-        networkCallback.expectCallback(CallbackState.AVAILABLE, mmsNetworkAgent);
+        networkCallback.expectAvailableCallbacks(mmsNetworkAgent);
         verifyActiveNetwork(TRANSPORT_CELLULAR);
         // Test releasing MMS NetworkRequest does not disconnect main cellular NetworkAgent
         cv = mmsNetworkAgent.getDisconnectedCV();
@@ -1671,7 +1744,7 @@
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         String firstRedirectUrl = "http://example.com/firstPath";
         mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
-        captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        captivePortalCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
 
         // Take down network.
@@ -1684,7 +1757,7 @@
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         String secondRedirectUrl = "http://example.com/secondPath";
         mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
-        captivePortalCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        captivePortalCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl);
 
         // Make captive portal disappear then revalidate.
@@ -1694,7 +1767,9 @@
         captivePortalCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
 
         // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
-        validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        validatedCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        // TODO: Investigate only sending available callbacks.
+        validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
 
         // Break network connectivity.
         // Expect NET_CAPABILITY_VALIDATED onLost callback.
@@ -1739,7 +1814,7 @@
         mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
 
         // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
-        validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        validatedCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         // But there should be no CaptivePortal callback.
         captivePortalCallback.assertNoCallback();
     }
@@ -1792,14 +1867,14 @@
         // Bring up cell and expect CALLBACK_AVAILABLE.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
+        defaultNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
 
         // Bring up wifi and expect CALLBACK_AVAILABLE.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
         cellNetworkCallback.assertNoCallback();
-        defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultNetworkCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
 
         // Bring down cell. Expect no default network callback, since it wasn't the default.
         mCellNetworkAgent.disconnect();
@@ -1809,7 +1884,7 @@
         // Bring up cell. Expect no default network callback, since it won't be the default.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         defaultNetworkCallback.assertNoCallback();
 
         // Bring down wifi. Expect the default network callback to notified of LOST wifi
@@ -1817,28 +1892,16 @@
         mWiFiNetworkAgent.disconnect();
         cellNetworkCallback.assertNoCallback();
         defaultNetworkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        defaultNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultNetworkCallback.expectAvailableCallbacks(mCellNetworkAgent);
         mCellNetworkAgent.disconnect();
         cellNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
         defaultNetworkCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
     }
 
-    private class TestRequestUpdateCallback extends TestNetworkCallback {
-        @Override
-        public void onCapabilitiesChanged(Network network, NetworkCapabilities netCap) {
-            setLastCallback(CallbackState.NETWORK_CAPABILITIES, network, netCap);
-        }
-
-        @Override
-        public void onLinkPropertiesChanged(Network network, LinkProperties linkProp) {
-            setLastCallback(CallbackState.LINK_PROPERTIES, network, linkProp);
-        }
-    }
-
     @SmallTest
-    public void testRequestCallbackUpdates() throws Exception {
+    public void testAdditionalStateCallbacks() throws Exception {
         // File a network request for mobile.
-        final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback();
+        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
         final NetworkRequest cellRequest = new NetworkRequest.Builder()
                 .addTransportType(TRANSPORT_CELLULAR).build();
         mCm.requestNetwork(cellRequest, cellNetworkCallback);
@@ -1847,10 +1910,10 @@
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
 
-        // We should get onAvailable().
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        // We should get onCapabilitiesChanged(), when the mobile network successfully validates.
-        cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
+        // We should get onAvailable(), onCapabilitiesChanged(), and
+        // onLinkPropertiesChanged() in rapid succession. Additionally, we
+        // should get onCapabilitiesChanged() when the mobile network validates.
+        cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
 
         // Update LinkProperties.
@@ -1861,20 +1924,28 @@
         cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
 
+        // Suspend the network.
+        mCellNetworkAgent.suspend();
+        cellNetworkCallback.expectCallback(CallbackState.SUSPENDED, mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+
         // Register a garden variety default network request.
-        final TestNetworkCallback dfltNetworkCallback = new TestRequestUpdateCallback();
+        final TestNetworkCallback dfltNetworkCallback = new TestNetworkCallback();
         mCm.registerDefaultNetworkCallback(dfltNetworkCallback);
-        // Only onAvailable() is called; no other information is delivered.
-        dfltNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        // We should get onAvailable(), onCapabilitiesChanged(), onLinkPropertiesChanged(),
+        // as well as onNetworkSuspended() in rapid succession.
+        dfltNetworkCallback.expectAvailableAndSuspendedCallbacks(mCellNetworkAgent);
         dfltNetworkCallback.assertNoCallback();
 
         // Request a NetworkCapabilities update; only the requesting callback is notified.
+        // TODO: Delete this together with Connectivity{Manager,Service} code.
         mCm.requestNetworkCapabilities(dfltNetworkCallback);
         dfltNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
         dfltNetworkCallback.assertNoCallback();
 
         // Request a LinkProperties update; only the requesting callback is notified.
+        // TODO: Delete this together with Connectivity{Manager,Service} code.
         mCm.requestLinkProperties(dfltNetworkCallback);
         dfltNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
         cellNetworkCallback.assertNoCallback();
@@ -1917,18 +1988,20 @@
 
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
-        callback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        callback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
+        fgCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         assertTrue(isForegroundNetwork(mCellNetworkAgent));
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
 
         // When wifi connects, cell lingers.
-        callback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        fgCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        callback.expectAvailableCallbacks(mWiFiNetworkAgent);
         callback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        callback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
+        fgCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         fgCallback.expectCallback(CallbackState.LOSING, mCellNetworkAgent);
+        fgCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         assertTrue(isForegroundNetwork(mCellNetworkAgent));
         assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
 
@@ -1936,7 +2009,8 @@
         mService.waitForIdle();
         int timeoutMs = TEST_LINGER_DELAY_MS + TEST_LINGER_DELAY_MS / 4;
         fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent, timeoutMs);
-        callback.assertNoCallback();
+        // Expect a network capabilities update sans FOREGROUND.
+        callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
         assertFalse(isForegroundNetwork(mCellNetworkAgent));
         assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
 
@@ -1945,9 +2019,15 @@
                 .addTransportType(TRANSPORT_CELLULAR).build();
         final TestNetworkCallback cellCallback = new TestNetworkCallback();
         mCm.requestNetwork(cellRequest, cellCallback);
-        cellCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        callback.assertNoCallback();  // Because the network is already up.
+        // NOTE: This request causes the network's capabilities to change. This
+        // is currently delivered before the onAvailable() callbacks.
+        // TODO: Fix this.
+        cellCallback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
+        cellCallback.expectAvailableCallbacks(mCellNetworkAgent);
+        fgCallback.expectAvailableCallbacks(mCellNetworkAgent);
+        // Expect a network capabilities update with FOREGROUND, because the most recent
+        // request causes its state to change.
+        callback.expectCapabilitiesWith(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
         assertTrue(isForegroundNetwork(mCellNetworkAgent));
         assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
 
@@ -1955,7 +2035,8 @@
         // lingering.
         mCm.unregisterNetworkCallback(cellCallback);
         fgCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
-        callback.assertNoCallback();
+        // Expect a network capabilities update sans FOREGROUND.
+        callback.expectCapabilitiesWithout(NET_CAPABILITY_FOREGROUND, mCellNetworkAgent);
         assertFalse(isForegroundNetwork(mCellNetworkAgent));
         assertTrue(isForegroundNetwork(mWiFiNetworkAgent));
 
@@ -1963,7 +2044,7 @@
         mWiFiNetworkAgent.disconnect();
         callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
         fgCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
-        fgCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        fgCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertTrue(isForegroundNetwork(mCellNetworkAgent));
 
         mCm.unregisterNetworkCallback(callback);
@@ -2104,7 +2185,7 @@
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         testFactory.expectAddRequests(2);  // Because the cell request changes score twice.
         mCellNetworkAgent.connect(true);
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         testFactory.waitForNetworkRequests(2);
         assertFalse(testFactory.getMyStartRequested());  // Because the cell network outscores us.
 
@@ -2195,20 +2276,22 @@
         // Bring up validated cell.
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         mCellNetworkAgent.connect(true);
-        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mCellNetworkAgent);
         Network cellNetwork = mCellNetworkAgent.getNetwork();
 
         // Bring up validated wifi.
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        validatedWifiCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
+        validatedWifiCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        validatedWifiCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         Network wifiNetwork = mWiFiNetworkAgent.getNetwork();
 
         // Fail validation on wifi.
         mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
         mCm.reportNetworkConnectivity(wifiNetwork, false);
+        defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
 
         // Because avoid bad wifi is off, we don't switch to cellular.
@@ -2223,18 +2306,18 @@
         // that we switch back to cell.
         tracker.configRestrictsAvoidBadWifi = false;
         tracker.reevaluate();
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertEquals(mCm.getActiveNetwork(), cellNetwork);
 
         // Switch back to a restrictive carrier.
         tracker.configRestrictsAvoidBadWifi = true;
         tracker.reevaluate();
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         assertEquals(mCm.getActiveNetwork(), wifiNetwork);
 
         // Simulate the user selecting "switch" on the dialog, and check that we switch to cell.
         mCm.setAvoidUnvalidated(wifiNetwork);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
                 NET_CAPABILITY_VALIDATED));
         assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
@@ -2245,13 +2328,15 @@
         mWiFiNetworkAgent.disconnect();
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(true);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-        validatedWifiCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableAndValidatedCallbacks(mWiFiNetworkAgent);
+        validatedWifiCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
+        validatedWifiCallback.expectCapabilitiesWith(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         wifiNetwork = mWiFiNetworkAgent.getNetwork();
 
         // Fail validation on wifi and expect the dialog to appear.
         mWiFiNetworkAgent.getWrappedNetworkMonitor().gen204ProbeResult = 599;
         mCm.reportNetworkConnectivity(wifiNetwork, false);
+        defaultCallback.expectCapabilitiesWithout(NET_CAPABILITY_VALIDATED, mWiFiNetworkAgent);
         validatedWifiCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
 
         // Simulate the user selecting "switch" and checking the don't ask again checkbox.
@@ -2259,7 +2344,7 @@
         tracker.reevaluate();
 
         // We now switch to cell.
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertFalse(mCm.getNetworkCapabilities(wifiNetwork).hasCapability(
                 NET_CAPABILITY_VALIDATED));
         assertTrue(mCm.getNetworkCapabilities(cellNetwork).hasCapability(
@@ -2270,17 +2355,17 @@
         // We switch to wifi and then to cell.
         Settings.Global.putString(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, null);
         tracker.reevaluate();
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         assertEquals(mCm.getActiveNetwork(), wifiNetwork);
         Settings.Global.putInt(cr, Settings.Global.NETWORK_AVOID_BAD_WIFI, 1);
         tracker.reevaluate();
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mCellNetworkAgent);
         assertEquals(mCm.getActiveNetwork(), cellNetwork);
 
         // If cell goes down, we switch to wifi.
         mCellNetworkAgent.disconnect();
         defaultCallback.expectCallback(CallbackState.LOST, mCellNetworkAgent);
-        defaultCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
+        defaultCallback.expectAvailableCallbacks(mWiFiNetworkAgent);
         validatedWifiCallback.assertNoCallback();
 
         mCm.unregisterNetworkCallback(cellNetworkCallback);
@@ -2322,7 +2407,7 @@
 
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
-        networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent, timeoutMs);
+        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, timeoutMs);
 
         // pass timeout and validate that UNAVAILABLE is not called
         networkCallback.assertNoCallback();
@@ -2343,7 +2428,7 @@
         mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
         mWiFiNetworkAgent.connect(false);
         final int assertTimeoutMs = 150;
-        networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent, assertTimeoutMs);
+        networkCallback.expectAvailableCallbacks(mWiFiNetworkAgent, false, assertTimeoutMs);
         sleepFor(20);
         mWiFiNetworkAgent.disconnect();
         networkCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 0e031e7..15648bd 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -309,6 +309,8 @@
     CATEGORY_ATTR = 0x010103e8,
     BANNER_ATTR = 0x10103f2,
     ISGAME_ATTR = 0x10103f4,
+    REQUIRED_FEATURE_ATTR = 0x1010557,
+    REQUIRED_NOT_FEATURE_ATTR = 0x1010558,
 };
 
 String8 getComponentName(String8 &pkgName, String8 &componentName) {
@@ -366,11 +368,19 @@
     printf("\n");
 }
 
-static void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1) {
+static void printUsesPermission(const String8& name, bool optional=false, int maxSdkVersion=-1,
+        const String8& requiredFeature = String8::empty(),
+        const String8& requiredNotFeature = String8::empty()) {
     printf("uses-permission: name='%s'", ResTable::normalizeForOutput(name.string()).string());
     if (maxSdkVersion != -1) {
          printf(" maxSdkVersion='%d'", maxSdkVersion);
     }
+    if (requiredFeature.length() > 0) {
+         printf(" requiredFeature='%s'", requiredFeature.string());
+    }
+    if (requiredNotFeature.length() > 0) {
+         printf(" requiredNotFeature='%s'", requiredNotFeature.string());
+    }
     printf("\n");
 
     if (optional) {
@@ -1545,6 +1555,10 @@
 
                         const int32_t maxSdkVersion =
                                 AaptXml::getIntegerAttribute(tree, MAX_SDK_VERSION_ATTR, -1);
+                        const String8 requiredFeature = AaptXml::getAttribute(tree,
+                                REQUIRED_FEATURE_ATTR, &error);
+                        const String8 requiredNotFeature = AaptXml::getAttribute(tree,
+                                REQUIRED_NOT_FEATURE_ATTR, &error);
 
                         if (name == "android.permission.WRITE_EXTERNAL_STORAGE") {
                             hasWriteExternalStoragePermission = true;
@@ -1565,7 +1579,7 @@
 
                         printUsesPermission(name,
                                 AaptXml::getIntegerAttribute(tree, REQUIRED_ATTR, 1) == 0,
-                                maxSdkVersion);
+                                maxSdkVersion, requiredFeature, requiredNotFeature);
 
                     } else if (tag == "uses-permission-sdk-23" || tag == "uses-permission-sdk-m") {
                         String8 name = AaptXml::getAttribute(tree, NAME_ATTR, &error);
diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
index fad35d2..8130bc2 100644
--- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
+++ b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java
@@ -52,6 +52,8 @@
             throw new IllegalArgumentException("Outline is not a rect shadow");
         }
 
+        // TODO replacing the algorithm here to create better shadow
+
         float shadowSize = elevationToShadow(elevation);
         int saved = modifyCanvas(canvas, shadowSize);
         if (saved == -1) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index df3ce19..04fdae9 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -106,7 +106,7 @@
 import java.util.List;
 import java.util.Map;
 
-import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
+import static android.os._Original_Build.VERSION_CODES.JELLY_BEAN_MR1;
 import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_APPLICATION_PACKAGE;
 
 /**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
index 0039476..2274b90 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgePackageManager.java
@@ -321,6 +321,11 @@
     }
 
     @Override
+    public boolean isInstantApp(String packageName) {
+        return false;
+    }
+
+    @Override
     public int getInstantAppCookieMaxSize() {
         return 0;
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
index 5386b17..7f8d992 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/Config.java
@@ -16,13 +16,13 @@
 
 package com.android.layoutlib.bridge.bars;
 
-import android.os.Build.VERSION_CODES;
+import android.os._Original_Build.VERSION_CODES;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import static android.os.Build.VERSION_CODES.*;
+import static android.os._Original_Build.VERSION_CODES.*;
 
 /**
  * Various helper methods to simulate older versions of platform.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index a6e5fb8..8bb2c59 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -49,7 +49,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 
-import static android.os.Build.VERSION_CODES.LOLLIPOP;
+import static android.os._Original_Build.VERSION_CODES.LOLLIPOP;
 
 /**
  * Base "bar" class for the window decor around the the edited layout.
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
new file mode 100644
index 0000000..4f3ed60
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/shadows_test.png
Binary files differ
diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
new file mode 100644
index 0000000..59dbbec
--- /dev/null
+++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/shadows_test.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent" >
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1">
+
+        <Button
+            android:layout_marginLeft="40dp"
+            android:layout_width="48dp"
+            android:layout_height="40dp"
+            android:layout_alignParentLeft="true"
+            android:layout_centerVertical="true"
+            android:elevation="48dp"
+            android:stateListAnimator="@null"/>
+
+        <Button
+            android:layout_marginRight="40dp"
+            android:layout_width="48dp"
+            android:layout_height="40dp"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:elevation="48dp"
+            android:stateListAnimator="@null"/>
+
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1">
+
+        <Button
+            android:layout_marginLeft="40dp"
+            android:layout_width="48dp"
+            android:layout_height="40dp"
+            android:layout_alignParentLeft="true"
+            android:layout_centerVertical="true"
+            android:elevation="0dp"
+            android:stateListAnimator="@null"/>
+
+        <Button
+            android:layout_marginRight="40dp"
+            android:layout_width="48dp"
+            android:layout_height="40dp"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:elevation="100dp"
+            android:stateListAnimator="@null"/>
+
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1">
+
+        <Button
+            android:layout_marginLeft="40dp"
+            android:layout_width="48dp"
+            android:layout_height="40dp"
+            android:layout_alignParentLeft="true"
+            android:layout_centerVertical="true"
+            android:elevation="12dp"
+            android:stateListAnimator="@null"/>
+
+        <Button
+            android:layout_marginRight="40dp"
+            android:layout_width="48dp"
+            android:layout_height="40dp"
+            android:layout_alignParentRight="true"
+            android:layout_centerVertical="true"
+            android:elevation="36dp"
+            android:stateListAnimator="@null"/>
+
+    </RelativeLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
index b15ee95..c83d2e4 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java
@@ -34,7 +34,7 @@
 @SuiteClasses({
         RenderTests.class, LayoutParserWrapperTest.class,
         BridgeXmlBlockParserTest.class, BridgeXmlPullAttributesTest.class,
-        Matrix_DelegateTest.class, TestDelegates.class
+        Matrix_DelegateTest.class, TestDelegates.class, PerformanceTests.class
 })
 public class Main {
 }
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
index 9e60f0f..7199781 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/RenderTests.java
@@ -424,4 +424,9 @@
         assertNotEquals(0, outValue.data);
         assertTrue(sRenderMessages.isEmpty());
     }
+
+    @Test
+    public void testRectangleShadow() throws Exception {
+        renderAndVerify("shadows_test.xml", "shadows_test.png");
+    }
 }
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
index bed5806a..d59b419 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/AsmGenerator.java
@@ -37,6 +37,7 @@
 import java.util.jar.JarEntry;
 import java.util.jar.JarOutputStream;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Class that generates a new JAR from a list of classes, some of which are to be kept as-is
@@ -127,7 +128,10 @@
         // Create the map of classes to rename.
         mRenameClasses = new HashMap<>();
         mClassesNotRenamed = new HashSet<>();
-        String[] renameClasses = createInfo.getRenamedClasses();
+        String[] renameClasses = Stream.concat(
+                Arrays.stream(createInfo.getRenamedClasses()),
+                Arrays.stream(createInfo.getRefactoredClasses()))
+                .toArray(String[]::new);
         int n = renameClasses.length;
         for (int i = 0; i < n; i += 2) {
             assert i + 1 < n;
@@ -140,7 +144,10 @@
 
         // Create a map of classes to be refactored.
         mRefactorClasses = new HashMap<>();
-        String[] refactorClasses = createInfo.getJavaPkgClasses();
+        String[] refactorClasses = Stream.concat(
+                Arrays.stream(createInfo.getJavaPkgClasses()),
+                Arrays.stream(createInfo.getRefactoredClasses()))
+                .toArray(String[]::new);
         n = refactorClasses.length;
         for (int i = 0; i < n; i += 2) {
             assert i + 1 < n;
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index a8582c6..b0aa3c2 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -36,66 +36,42 @@
  */
 public final class CreateInfo implements ICreateInfo {
 
-    /**
-     * Returns the list of class from layoutlib_create to inject in layoutlib.
-     * The list can be empty but must not be null.
-     */
     @Override
     public Class<?>[] getInjectedClasses() {
         return INJECTED_CLASSES;
     }
 
-    /**
-     * Returns the list of methods to rewrite as delegates.
-     * The list can be empty but must not be null.
-     */
     @Override
     public String[] getDelegateMethods() {
         return DELEGATE_METHODS;
     }
 
-    /**
-     * Returns the list of classes on which to delegate all native methods.
-     * The list can be empty but must not be null.
-     */
     @Override
     public String[] getDelegateClassNatives() {
         return DELEGATE_CLASS_NATIVES;
     }
 
-    /**
-     * Returns the list of classes to rename, must be an even list: the binary FQCN
-     * of class to replace followed by the new FQCN.
-     * The list can be empty but must not be null.
-     */
     @Override
     public String[] getRenamedClasses() {
         return RENAMED_CLASSES;
     }
 
-    /**
-     * Returns the list of classes for which the methods returning them should be deleted.
-     * The array contains a list of null terminated section starting with the name of the class
-     * to rename in which the methods are deleted, followed by a list of return types identifying
-     * the methods to delete.
-     * The list can be empty but must not be null.
-     */
     @Override
     public String[] getDeleteReturns() {
         return DELETE_RETURNS;
     }
 
-    /**
-     * Returns the list of classes to refactor, must be an even list: the binary FQCN of class to
-     * replace followed by the new FQCN. All references to the old class should be updated to the
-     * new class. The list can be empty but must not be null.
-     */
     @Override
     public String[] getJavaPkgClasses() {
       return JAVA_PKG_CLASSES;
     }
 
     @Override
+    public String[] getRefactoredClasses() {
+        return REFACTOR_CLASSES;
+    }
+
+    @Override
     public Set<String> getExcludedClasses() {
         String[] refactoredClasses = getJavaPkgClasses();
         int count = refactoredClasses.length / 2 + EXCLUDED_CLASSES.length;
@@ -333,10 +309,22 @@
             "java.text.SimpleDateFormat",                      "android.icu.text.SimpleDateFormat",
         };
 
+    /**
+     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
+     * {@link #getJavaPkgClasses()}.
+     * Classes included here will be renamed and then all their references in any other classes
+     * will be also modified.
+     * FQCN of class to refactor followed by its new FQCN.
+     */
+    private final static String[] REFACTOR_CLASSES =
+            new String[] {
+                    "android.os.Build",                                "android.os._Original_Build",
+            };
+
     private final static String[] EXCLUDED_CLASSES =
         new String[] {
             "android.preference.PreferenceActivity",
-            "org.kxml2.io.KXmlParser"
+            "org.kxml2.io.KXmlParser",
         };
 
     /**
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
index 48abde4..eca1c07 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/ICreateInfo.java
@@ -52,6 +52,15 @@
     String[] getRenamedClasses();
 
     /**
+     * List of classes to refactor. This is similar to combining {@link #getRenamedClasses()} and
+     * {@link #getJavaPkgClasses()}.
+     * Classes included here will be renamed and then all their references in any other classes
+     * will be also modified.
+     * FQCN of class to refactor followed by its new FQCN.
+     */
+    String[] getRefactoredClasses();
+
+    /**
      * Returns the list of classes for which the methods returning them should be deleted.
      * The array contains a list of null terminated section starting with the name of the class
      * to rename in which the methods are deleted, followed by a list of return types identifying
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
index 4d5d5d2..e718fb9 100644
--- a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/AsmGeneratorTest.java
@@ -35,6 +35,7 @@
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashSet;
@@ -54,8 +55,6 @@
  * Unit tests for some methods of {@link AsmGenerator}.
  */
 public class AsmGeneratorTest {
-
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
     private MockLog mLog;
     private ArrayList<String> mOsJarPath;
     private String mOsDestJar;
@@ -81,6 +80,7 @@
     @After
     public void tearDown() throws Exception {
         if (mTempFile != null) {
+            //noinspection ResultOfMethodCallIgnored
             mTempFile.delete();
             mTempFile = null;
         }
@@ -89,23 +89,7 @@
     @Test
     public void testClassRenaming() throws IOException, LogAbortException {
 
-        ICreateInfo ci = new ICreateInfo() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                // classes to inject in the final JAR
-                return new Class<?>[0];
-            }
-
-            @Override
-            public String[] getDelegateMethods() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getDelegateClassNatives() {
-                return EMPTY_STRING_ARRAY;
-            }
-
+        ICreateInfo ci = new CreateInfoAdapter() {
             @Override
             public String[] getRenamedClasses() {
                 // classes to rename (so that we can replace them)
@@ -114,37 +98,6 @@
                         "not.an.actual.ClassName", "anoter.fake.NewClassName",
                 };
             }
-
-            @Override
-            public String[] getJavaPkgClasses() {
-              return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public Set<String> getExcludedClasses() {
-                return null;
-            }
-
-            @Override
-            public String[] getDeleteReturns() {
-                 // methods deleted from their return type.
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedFields() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedClasses() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-                return Collections.emptyMap();
-            }
         };
 
         AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
@@ -154,7 +107,7 @@
                 new String[] {        // include classes
                     "**"
                 },
-                Collections.<String>emptySet() /* excluded classes */,
+                Collections.emptySet() /* excluded classes */,
                 new String[]{} /* include files */);
         aa.analyze();
         agen.generate();
@@ -165,8 +118,8 @@
     }
 
     @Test
-    public void testClassRefactoring() throws IOException, LogAbortException {
-        ICreateInfo ci = new ICreateInfo() {
+    public void testJavaClassRefactoring() throws IOException, LogAbortException {
+        ICreateInfo ci = new CreateInfoAdapter() {
             @Override
             public Class<?>[] getInjectedClasses() {
                 // classes to inject in the final JAR
@@ -176,22 +129,6 @@
             }
 
             @Override
-            public String[] getDelegateMethods() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getDelegateClassNatives() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
             public String[] getJavaPkgClasses() {
              // classes to refactor (so that we can replace them)
                 return new String[] {
@@ -203,27 +140,6 @@
             public Set<String> getExcludedClasses() {
                 return Collections.singleton("java.lang.JavaClass");
             }
-
-            @Override
-            public String[] getDeleteReturns() {
-                 // methods deleted from their return type.
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedFields() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedClasses() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-                return Collections.emptyMap();
-            }
         };
 
         AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
@@ -233,7 +149,7 @@
                 new String[] {        // include classes
                     "**"
                 },
-                Collections.<String>emptySet(),
+                Collections.emptySet(),
                 new String[] {        /* include files */
                     "mock_android/data/data*"
                 });
@@ -242,47 +158,64 @@
         Map<String, ClassReader> output = new TreeMap<>();
         Map<String, InputStream> filesFound = new TreeMap<>();
         parseZip(mOsDestJar, output, filesFound);
-        boolean injectedClassFound = false;
+        RecordingClassVisitor cv = new RecordingClassVisitor();
         for (ClassReader cr: output.values()) {
-            TestClassVisitor cv = new TestClassVisitor();
             cr.accept(cv, 0);
-            injectedClassFound |= cv.mInjectedClassFound;
         }
-        assertTrue(injectedClassFound);
+        assertTrue(cv.mVisitedClasses.contains(
+                "com/android/tools/layoutlib/create/dataclass/JavaClass"));
+        assertFalse(cv.mVisitedClasses.contains(
+                JAVA_CLASS_NAME));
         assertArrayEquals(new String[] {"mock_android/data/dataFile"},
                 filesFound.keySet().toArray());
     }
 
     @Test
-    public void testClassExclusion() throws IOException, LogAbortException {
-        ICreateInfo ci = new ICreateInfo() {
+    public void testClassRefactoring() throws IOException, LogAbortException {
+        ICreateInfo ci = new CreateInfoAdapter() {
             @Override
             public Class<?>[] getInjectedClasses() {
-                return new Class<?>[0];
+                // classes to inject in the final JAR
+                return new Class<?>[] {
+                        com.android.tools.layoutlib.create.dataclass.JavaClass.class
+                };
             }
 
             @Override
-            public String[] getDelegateMethods() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getDelegateClassNatives() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getJavaPkgClasses() {
+            public String[] getRefactoredClasses() {
                 // classes to refactor (so that we can replace them)
-                return EMPTY_STRING_ARRAY;
+                return new String[] {
+                        "mock_android.view.View", "mock_android.view._Original_View",
+                };
             }
+        };
 
+        AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
+
+        AsmAnalyzer aa = new AsmAnalyzer(mLog, mOsJarPath, agen,
+                null,                 // derived from
+                new String[] {        // include classes
+                        "**"
+                },
+                Collections.emptySet(),
+                new String[] {});
+        aa.analyze();
+        agen.generate();
+        Map<String, ClassReader> output = new TreeMap<>();
+        parseZip(mOsDestJar, output, new TreeMap<>());
+        RecordingClassVisitor cv = new RecordingClassVisitor();
+        for (ClassReader cr: output.values()) {
+            cr.accept(cv, 0);
+        }
+        assertTrue(cv.mVisitedClasses.contains(
+                "mock_android/view/_Original_View"));
+        assertFalse(cv.mVisitedClasses.contains(
+                "mock_android/view/View"));
+    }
+
+    @Test
+    public void testClassExclusion() throws IOException, LogAbortException {
+        ICreateInfo ci = new CreateInfoAdapter() {
             @Override
             public Set<String> getExcludedClasses() {
                 Set<String> set = new HashSet<>(2);
@@ -290,27 +223,6 @@
                 set.add("java.lang.JavaClass");
                 return set;
             }
-
-            @Override
-            public String[] getDeleteReturns() {
-                // methods deleted from their return type.
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedFields() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedClasses() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
-                return Collections.emptyMap();
-            }
         };
 
         AsmGenerator agen = new AsmGenerator(mLog, mOsDestJar, ci);
@@ -340,55 +252,7 @@
     public void testMethodInjection() throws IOException, LogAbortException,
             ClassNotFoundException, IllegalAccessException, InstantiationException,
             NoSuchMethodException, InvocationTargetException {
-        ICreateInfo ci = new ICreateInfo() {
-            @Override
-            public Class<?>[] getInjectedClasses() {
-                return new Class<?>[0];
-            }
-
-            @Override
-            public String[] getDelegateMethods() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getDelegateClassNatives() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getRenamedClasses() {
-                // classes to rename (so that we can replace them)
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getJavaPkgClasses() {
-                // classes to refactor (so that we can replace them)
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public Set<String> getExcludedClasses() {
-                return Collections.emptySet();
-            }
-
-            @Override
-            public String[] getDeleteReturns() {
-                // methods deleted from their return type.
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedFields() {
-                return EMPTY_STRING_ARRAY;
-            }
-
-            @Override
-            public String[] getPromotedClasses() {
-                return EMPTY_STRING_ARRAY;
-            }
-
+        ICreateInfo ci = new CreateInfoAdapter() {
             @Override
             public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
                 return Collections.singletonMap("mock_android.util.EmptyArray",
@@ -474,97 +338,94 @@
         }
     }
 
-    private class TestClassVisitor extends ClassVisitor {
+    /**
+     * {@link ClassVisitor} that records every class that sees.
+     */
+    private static class RecordingClassVisitor extends ClassVisitor {
+        private Set<String> mVisitedClasses = new HashSet<>();
 
-        boolean mInjectedClassFound = false;
-
-        TestClassVisitor() {
+        private RecordingClassVisitor() {
             super(Main.ASM_VERSION);
         }
 
-        @Override
-        public void visit(int version, int access, String name, String signature,
-                String superName, String[] interfaces) {
-            assertTrue(!getBase(name).equals(JAVA_CLASS_NAME));
-            if (name.equals("com/android/tools/layoutlib/create/dataclass/JavaClass")) {
-                mInjectedClassFound = true;
+        private void addClass(String className) {
+            if (className == null) {
+                return;
             }
-            super.visit(version, access, name, signature, superName, interfaces);
+
+            int pos = className.indexOf('$');
+            if (pos > 0) {
+                // For inner classes, add also the base class
+                mVisitedClasses.add(className.substring(0, pos));
+            }
+            mVisitedClasses.add(className);
         }
 
         @Override
-        public FieldVisitor visitField(int access, String name, String desc,
-                String signature, Object value) {
-            assertTrue(testType(Type.getType(desc)));
+        public void visit(int version, int access, String name, String signature, String superName,
+                String[] interfaces) {
+            addClass(superName);
+            Arrays.stream(interfaces).forEach(this::addClass);
+        }
+
+        private void processType(Type type) {
+            switch (type.getSort()) {
+                case Type.OBJECT:
+                    addClass(type.getInternalName());
+                    break;
+                case Type.ARRAY:
+                    addClass(type.getElementType().getInternalName());
+                    break;
+                case Type.METHOD:
+                    processType(type.getReturnType());
+                    Arrays.stream(type.getArgumentTypes()).forEach(this::processType);
+                    break;
+            }
+        }
+
+        @Override
+        public FieldVisitor visitField(int access, String name, String desc, String signature,
+                Object value) {
+            processType(Type.getType(desc));
             return super.visitField(access, name, desc, signature, value);
         }
 
-        @SuppressWarnings("hiding")
         @Override
-        public MethodVisitor visitMethod(int access, String name, String desc,
-                String signature, String[] exceptions) {
+        public MethodVisitor visitMethod(int access, String name, String desc, String signature,
+                String[] exceptions) {
             MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
             return new MethodVisitor(Main.ASM_VERSION, mv) {
 
                 @Override
-                public void visitFieldInsn(int opcode, String owner, String name,
-                        String desc) {
-                    assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME));
-                    assertTrue(testType(Type.getType(desc)));
+                public void visitFieldInsn(int opcode, String owner, String name, String desc) {
+                    addClass(owner);
+                    processType(Type.getType(desc));
                     super.visitFieldInsn(opcode, owner, name, desc);
                 }
 
                 @Override
                 public void visitLdcInsn(Object cst) {
                     if (cst instanceof Type) {
-                        assertTrue(testType((Type)cst));
+                        processType((Type) cst);
                     }
                     super.visitLdcInsn(cst);
                 }
 
                 @Override
                 public void visitTypeInsn(int opcode, String type) {
-                    assertTrue(!getBase(type).equals(JAVA_CLASS_NAME));
+                    addClass(type);
                     super.visitTypeInsn(opcode, type);
                 }
 
                 @Override
-                public void visitMethodInsn(int opcode, String owner, String name,
-                        String desc, boolean itf) {
-                    assertTrue(!getBase(owner).equals(JAVA_CLASS_NAME));
-                    assertTrue(testType(Type.getType(desc)));
+                public void visitMethodInsn(int opcode, String owner, String name, String desc,
+                        boolean itf) {
+                    addClass(owner);
+                    processType(Type.getType(desc));
                     super.visitMethodInsn(opcode, owner, name, desc, itf);
                 }
 
             };
         }
-
-        private boolean testType(Type type) {
-            int sort = type.getSort();
-            if (sort == Type.OBJECT) {
-                assertTrue(!getBase(type.getInternalName()).equals(JAVA_CLASS_NAME));
-            } else if (sort == Type.ARRAY) {
-                assertTrue(!getBase(type.getElementType().getInternalName())
-                        .equals(JAVA_CLASS_NAME));
-            } else if (sort == Type.METHOD) {
-                boolean r = true;
-                for (Type t : type.getArgumentTypes()) {
-                    r &= testType(t);
-                }
-                return r & testType(type.getReturnType());
-            }
-            return true;
-        }
-
-        private String getBase(String className) {
-            if (className == null) {
-                return null;
-            }
-            int pos = className.indexOf('$');
-            if (pos > 0) {
-                return className.substring(0, pos);
-            }
-            return className;
-        }
     }
 }
diff --git a/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
new file mode 100644
index 0000000..ad7cb9a
--- /dev/null
+++ b/tools/layoutlib/create/tests/com/android/tools/layoutlib/create/CreateInfoAdapter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.tools.layoutlib.create;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+class CreateInfoAdapter implements ICreateInfo {
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    @Override
+    public Class<?>[] getInjectedClasses() {
+        return new Class<?>[0];
+    }
+
+    @Override
+    public String[] getDelegateMethods() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public String[] getDelegateClassNatives() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public String[] getRenamedClasses() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public String[] getRefactoredClasses() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public String[] getDeleteReturns() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public String[] getJavaPkgClasses() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public Set<String> getExcludedClasses() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public String[] getPromotedFields() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public String[] getPromotedClasses() {
+        return EMPTY_STRING_ARRAY;
+    }
+
+    @Override
+    public Map<String, InjectMethodRunnable> getInjectedMethodsMap() {
+        return Collections.emptyMap();
+    }
+}
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
index f790332..4268f24 100644
--- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -236,11 +236,11 @@
         public static final int TTLS    = 2;
         /** EAP-Password */
         public static final int PWD     = 3;
-        /** EAP-Subscriber Identity Module */
+        /** EAP-Subscriber Identity Module [RFC-4186] */
         public static final int SIM     = 4;
-        /** EAP-Authentication and Key Agreement */
+        /** EAP-Authentication and Key Agreement [RFC-4187] */
         public static final int AKA     = 5;
-        /** EAP-Authentication and Key Agreement Prime */
+        /** EAP-Authentication and Key Agreement Prime [RFC-5448] */
         public static final int AKA_PRIME = 6;
         /** Hotspot 2.0 r2 OSEN */
         public static final int UNAUTH_TLS = 7;
@@ -263,11 +263,11 @@
         public static final int MSCHAPV2    = 3;
         /** Generic Token Card */
         public static final int GTC         = 4;
-        /** EAP-Subscriber Identity Module */
+        /** EAP-Subscriber Identity Module [RFC-4186] */
         public static final int SIM         = 5;
-        /** EAP-Authentication and Key Agreement */
+        /** EAP-Authentication and Key Agreement [RFC-4187] */
         public static final int AKA         = 6;
-        /** EAP-Authentication and Key Agreement Prime */
+        /** EAP-Authentication and Key Agreement Prime [RFC-5448] */
         public static final int AKA_PRIME   = 7;
         private static final String AUTH_PREFIX = "auth=";
         private static final String AUTHEAP_PREFIX = "autheap=";
@@ -756,8 +756,8 @@
      * key entry when the config is saved and removing the key entry when
      * the config is removed.
 
-     * @param privateKey
-     * @param clientCertificate
+     * @param privateKey a PrivateKey instance for the end certificate.
+     * @param clientCertificate an X509Certificate representing the end certificate.
      * @throws IllegalArgumentException for an invalid key or certificate.
      */
     public void setClientKeyEntry(PrivateKey privateKey, X509Certificate clientCertificate) {
@@ -775,9 +775,11 @@
      * with this configuration.  The framework takes care of installing the
      * key entry when the config is saved and removing the key entry when
      * the config is removed.
-
-     * @param privateKey
-     * @param clientCertificateChain
+     *
+     * @param privateKey a PrivateKey instance for the end certificate.
+     * @param clientCertificateChain an array of X509Certificate instances which starts with
+     *         end certificate and continues with additional CA certificates necessary to
+     *         link the end certificate with some root certificate known by the authenticator.
      * @throws IllegalArgumentException for an invalid key or certificate.
      */
     public void setClientKeyEntryWithCertificateChain(PrivateKey privateKey,
@@ -835,7 +837,15 @@
     }
 
     /**
-     * Get the complete client certificate chain
+     * Get the complete client certificate chain in the same order as it was last supplied.
+     *
+     * <p>If the chain was last supplied by a call to
+     * {@link #setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate)}
+     * with a non-null * certificate instance, a single-element array containing the certificate
+     * will be * returned. If {@link #setClientKeyEntryWithCertificateChain(
+     * java.security.PrivateKey, java.security.cert.X509Certificate[])} was last called with a
+     * non-empty array, this array will be returned in the same order as it was supplied.
+     * Otherwise, {@code null} will be returned.
      *
      * @return X.509 client certificates
      */
diff --git a/wifi/java/android/net/wifi/aware/DiscoverySession.java b/wifi/java/android/net/wifi/aware/DiscoverySession.java
index 57b98e9..59fe1ee 100644
--- a/wifi/java/android/net/wifi/aware/DiscoverySession.java
+++ b/wifi/java/android/net/wifi/aware/DiscoverySession.java
@@ -31,7 +31,7 @@
  * {@link PublishDiscoverySession} and {@link SubscribeDiscoverySession}. This
  * class provides functionality common to both publish and subscribe discovery sessions:
  * <ul>
- *     <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])}.
+ *     <li>Sending messages: {@link #sendMessage(PeerHandle, int, byte[])} method.
  *     <li>Creating a network-specifier when requesting a Aware connection:
  *     {@link #createNetworkSpecifier(PeerHandle, byte[])}.
  * </ul>
@@ -247,8 +247,8 @@
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for a
-     * WiFi Aware connection to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
+     * unencrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
@@ -256,7 +256,58 @@
      * discovery or communication (in such scenarios the MAC address of the peer is shielded by
      * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
      * OOB (out-of-band) mechanism then use the alternative
-     * {@link WifiAwareSession#createNetworkSpecifier(int, byte[], byte[])} method - which uses the
+     * {@link WifiAwareSession#createNetworkSpecifierOpen(int, byte[])} method - which uses the
+     * peer's MAC address.
+     * <p>
+     * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
+     * and a Publisher is a RESPONDER.
+     *
+     * @param peerHandle The peer's handle obtained through
+     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle, byte[], java.util.List)}
+     *                   or
+     *                   {@link DiscoverySessionCallback#onMessageReceived(PeerHandle, byte[])}.
+     *                   On a RESPONDER this value is used to gate the acceptance of a connection
+     *                   request from only that peer. A RESPONDER may specify a null - indicating
+     *                   that it will accept connection requests from any device.
+     *
+     * @return A string to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
+     * android.net.ConnectivityManager.NetworkCallback)}
+     * [or other varieties of that API].
+     *
+     * @hide
+     */
+    public String createNetworkSpecifierOpen(@Nullable PeerHandle peerHandle) {
+        if (mTerminated) {
+            Log.w(TAG, "createNetworkSpecifierOpen: called on terminated session");
+            return null;
+        } else {
+            WifiAwareManager mgr = mMgr.get();
+            if (mgr == null) {
+                Log.w(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
+                return null;
+            }
+
+            int role = this instanceof SubscribeDiscoverySession
+                    ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
+                    : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
+
+            return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, null);
+        }
+    }
+
+    /**
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
+     * encrypted WiFi Aware connection (link) to the specified peer. The
+     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
+     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
+     * <p>
+     * This method should be used when setting up a connection with a peer discovered through Aware
+     * discovery or communication (in such scenarios the MAC address of the peer is shielded by
+     * an opaque peer ID handle). If a Aware connection is needed to a peer discovered using other
+     * OOB (out-of-band) mechanism then use the alternative
+     * {@link WifiAwareSession#createNetworkSpecifierPmk(int, byte[], byte[])} method - which uses the
      * peer's MAC address.
      * <p>
      * Note: per the Wi-Fi Aware specification the roles are fixed - a Subscriber is an INITIATOR
@@ -267,29 +318,34 @@
      * byte[], java.util.List)} or
      * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
      * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
-     *                   from only that peer. A RESPONDER may specified a null - indicating that
+     *                   from only that peer. A RESPONDER may specify a null - indicating that
      *                   it will accept connection requests from any device.
-     * @param token An arbitrary token (message) to be used to match connection initiation request
-     *              to a responder setup. A RESPONDER is set up with a {@code token} which must
-     *              be matched by the token provided by the INITIATOR. A null token is permitted
-     *              on the RESPONDER and matches any peer token. An empty ({@code ""}) token is
-     *              not the same as a null token and requires the peer token to be empty as well.
+     * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
+     *            encrypting the data-path. Use the
+     *            {@link #createNetworkSpecifierOpen(PeerHandle)} to specify an open (unencrypted)
+     *            link.
      *
      * @return A string to be used to construct
      * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
+     *
+     * @hide
      */
-    public String createNetworkSpecifier(@Nullable PeerHandle peerHandle,
-            @Nullable byte[] token) {
+    public String createNetworkSpecifierPmk(@Nullable PeerHandle peerHandle,
+            @NonNull byte[] pmk) {
+        if (pmk == null || pmk.length == 0) {
+            throw new IllegalArgumentException("PMK must not be null or empty");
+        }
+
         if (mTerminated) {
-            Log.w(TAG, "createNetworkSpecifier: called on terminated session");
+            Log.w(TAG, "createNetworkSpecifierPmk: called on terminated session");
             return null;
         } else {
             WifiAwareManager mgr = mMgr.get();
             if (mgr == null) {
-                Log.w(TAG, "createNetworkSpecifier: called post GC on WifiAwareManager");
+                Log.w(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
                 return null;
             }
 
@@ -297,7 +353,30 @@
                     ? WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                     : WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
 
-            return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, token);
+            return mgr.createNetworkSpecifier(mClientId, role, mSessionId, peerHandle, pmk);
         }
     }
+
+    /**
+     * Place-holder for {@code createNetworkSpecifierOpen(PeerHandle)}. Present to enable
+     * development of replacements CL without causing an API change. Will be removed when new
+     * APIs are exposed.
+     *
+     * @param peerHandle The peer's handle obtained through
+     * {@link DiscoverySessionCallback#onServiceDiscovered(PeerHandle,
+     * byte[], java.util.List)} or
+     * {@link DiscoverySessionCallback#onMessageReceived(PeerHandle,
+     * byte[])}. On a RESPONDER this value is used to gate the acceptance of a connection request
+     *                   from only that peer. A RESPONDER may specify a null - indicating that
+     *                   it will accept connection requests from any device.
+     * @param token Deprecated and ignored.
+     * @return A string to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
+     * android.net.ConnectivityManager.NetworkCallback)}
+     * [or other varieties of that API].
+     */
+    public String createNetworkSpecifier(@Nullable PeerHandle peerHandle, @Nullable byte[] token) {
+        return createNetworkSpecifierOpen(peerHandle);
+    }
 }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 0eb6a3d..3d784ba 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -130,55 +130,34 @@
      */
 
     /**
-     * TYPE_1A: role, client_id, session_id, peer_id, token
+     * TYPE: in band, specific peer: role, client_id, session_id, peer_id, pmk optional
      * @hide
      */
-    public static final int NETWORK_SPECIFIER_TYPE_1A = 0;
+    public static final int NETWORK_SPECIFIER_TYPE_IB = 0;
 
     /**
-     * TYPE_1B: role, client_id, session_id, peer_id [only permitted for RESPONDER]
+     * TYPE: in band, any peer: role, client_id, session_id, pmk optional
+     * [only permitted for RESPONDER]
      * @hide
      */
-    public static final int NETWORK_SPECIFIER_TYPE_1B = 1;
+    public static final int NETWORK_SPECIFIER_TYPE_IB_ANY_PEER = 1;
 
     /**
-     * TYPE_1C: role, client_id, session_id, token [only permitted for RESPONDER]
+     * TYPE: out-of-band: role, client_id, peer_mac, pmk optional
      * @hide
      */
-    public static final int NETWORK_SPECIFIER_TYPE_1C = 2;
+    public static final int NETWORK_SPECIFIER_TYPE_OOB = 2;
 
     /**
-     * TYPE_1C: role, client_id, session_id [only permitted for RESPONDER]
+     * TYPE: out-of-band, any peer: role, client_id, pmk optional
+     * [only permitted for RESPONDER]
      * @hide
      */
-    public static final int NETWORK_SPECIFIER_TYPE_1D = 3;
+    public static final int NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER = 3;
 
-    /**
-     * TYPE_2A: role, client_id, peer_mac, token
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_2A = 4;
-
-    /**
-     * TYPE_2B: role, client_id, peer_mac [only permitted for RESPONDER]
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_2B = 5;
-
-    /**
-     * TYPE_2C: role, client_id, token [only permitted for RESPONDER]
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_2C = 6;
-
-    /**
-     * TYPE_2D: role, client_id [only permitted for RESPONDER]
-     * @hide
-     */
-    public static final int NETWORK_SPECIFIER_TYPE_2D = 7;
 
     /** @hide */
-    public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_2D;
+    public static final int NETWORK_SPECIFIER_TYPE_MAX_VALID = NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER;
 
     /** @hide */
     public static final String NETWORK_SPECIFIER_KEY_TYPE = "type";
@@ -199,7 +178,7 @@
     public static final String NETWORK_SPECIFIER_KEY_PEER_MAC = "peer_mac";
 
     /** @hide */
-    public static final String NETWORK_SPECIFIER_KEY_TOKEN = "token";
+    public static final String NETWORK_SPECIFIER_KEY_PMK = "pmk";
 
     /**
      * Broadcast intent action to indicate that the state of Wi-Fi Aware availability has changed.
@@ -494,23 +473,15 @@
 
     /** @hide */
     public String createNetworkSpecifier(int clientId, int role, int sessionId,
-            PeerHandle peerHandle, byte[] token) {
+            PeerHandle peerHandle, @Nullable byte[] pmk) {
         if (VDBG) {
             Log.v(TAG, "createNetworkSpecifier: role=" + role + ", sessionId=" + sessionId
                     + ", peerHandle=" + ((peerHandle == null) ? peerHandle : peerHandle.peerId)
-                    + ", token=" + token);
+                    + ", pmk=" + ((pmk == null) ? "null" : "non-null"));
         }
 
-        int type;
-        if (token != null && peerHandle != null) {
-            type = NETWORK_SPECIFIER_TYPE_1A;
-        } else if (token == null && peerHandle != null) {
-            type = NETWORK_SPECIFIER_TYPE_1B;
-        } else if (token != null && peerHandle == null) {
-            type = NETWORK_SPECIFIER_TYPE_1C;
-        } else {
-            type = NETWORK_SPECIFIER_TYPE_1D;
-        }
+        int type = (peerHandle == null) ? NETWORK_SPECIFIER_TYPE_IB_ANY_PEER
+                : NETWORK_SPECIFIER_TYPE_IB;
 
         if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                 && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
@@ -519,10 +490,6 @@
                             + "specifier");
         }
         if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
-            if (token == null) {
-                throw new IllegalArgumentException(
-                        "createNetworkSpecifier: Invalid null token - not permitted on INITIATOR");
-            }
             if (peerHandle == null) {
                 throw new IllegalArgumentException(
                         "createNetworkSpecifier: Invalid peer handle (value of null) - not "
@@ -540,10 +507,11 @@
             if (peerHandle != null) {
                 json.put(NETWORK_SPECIFIER_KEY_PEER_ID, peerHandle.peerId);
             }
-            if (token != null) {
-                json.put(NETWORK_SPECIFIER_KEY_TOKEN,
-                        Base64.encodeToString(token, 0, token.length, Base64.DEFAULT));
+            if (pmk == null) {
+                pmk = new byte[0];
             }
+            json.put(NETWORK_SPECIFIER_KEY_PMK,
+                    Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
         } catch (JSONException e) {
             return "";
         }
@@ -553,21 +521,14 @@
 
     /** @hide */
     public String createNetworkSpecifier(int clientId, @DataPathRole int role,
-            @Nullable byte[] peer, @Nullable byte[] token) {
+            @Nullable byte[] peer, @Nullable byte[] pmk) {
         if (VDBG) {
-            Log.v(TAG, "createNetworkSpecifier: role=" + role + ", token=" + token);
+            Log.v(TAG, "createNetworkSpecifier: role=" + role
+                    + ", pmk=" + ((pmk == null) ? "null" : "non-null"));
         }
 
-        int type;
-        if (token != null && peer != null) {
-            type = NETWORK_SPECIFIER_TYPE_2A;
-        } else if (token == null && peer != null) {
-            type = NETWORK_SPECIFIER_TYPE_2B;
-        } else if (token != null && peer == null) {
-            type = NETWORK_SPECIFIER_TYPE_2C;
-        } else { // both are null
-            type = NETWORK_SPECIFIER_TYPE_2D;
-        }
+        int type = (peer == null) ?
+                NETWORK_SPECIFIER_TYPE_OOB_ANY_PEER : NETWORK_SPECIFIER_TYPE_OOB;
 
         if (role != WIFI_AWARE_DATA_PATH_ROLE_INITIATOR
                 && role != WIFI_AWARE_DATA_PATH_ROLE_RESPONDER) {
@@ -576,19 +537,13 @@
                             + "specifier");
         }
         if (role == WIFI_AWARE_DATA_PATH_ROLE_INITIATOR) {
-            if (peer == null || peer.length != 6) {
-                throw new IllegalArgumentException(
-                        "createNetworkSpecifier: Invalid peer MAC address");
+            if (peer == null) {
+                throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC "
+                        + "address - null not permitted on INITIATOR");
             }
-            if (token == null) {
-                throw new IllegalArgumentException(
-                        "createNetworkSpecifier: Invalid null token - not permitted on INITIATOR");
-            }
-        } else {
-            if (peer != null && peer.length != 6) {
-                throw new IllegalArgumentException(
-                        "createNetworkSpecifier: Invalid peer MAC address");
-            }
+        }
+        if (peer != null && peer.length != 6) {
+            throw new IllegalArgumentException("createNetworkSpecifier: Invalid peer MAC address");
         }
 
         JSONObject json;
@@ -600,10 +555,11 @@
             if (peer != null) {
                 json.put(NETWORK_SPECIFIER_KEY_PEER_MAC, new String(HexEncoding.encode(peer)));
             }
-            if (token != null) {
-                json.put(NETWORK_SPECIFIER_KEY_TOKEN,
-                        Base64.encodeToString(token, 0, token.length, Base64.DEFAULT));
+            if (pmk == null) {
+                pmk = new byte[0];
             }
+            json.put(NETWORK_SPECIFIER_KEY_PMK,
+                    Base64.encodeToString(pmk, 0, pmk.length, Base64.DEFAULT));
         } catch (JSONException e) {
             return "";
         }
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareSession.java b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
index 8696920..856066e 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareSession.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareSession.java
@@ -183,47 +183,114 @@
     }
 
     /**
-     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for a
-     * WiFi Aware connection to the specified peer. The
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
+     * unencrypted WiFi Aware connection (link) to the specified peer. The
      * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
      * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
      * <p>
      *     This API is targeted for applications which can obtain the peer MAC address using OOB
      *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
      *     when using Aware discovery use the alternative network specifier method -
-     *     {@link DiscoverySession#createNetworkSpecifier(PeerHandle,
-     *     byte[])}.
+     *     {@link DiscoverySession#createNetworkSpecifierOpen(PeerHandle)}.
      *
      * @param role  The role of this device:
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
      *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
      * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
      *              value is used to gate the acceptance of a connection request from only that
-     *              peer. A RESPONDER may specified a null - indicating that it will accept
+     *              peer. A RESPONDER may specify a null - indicating that it will accept
      *              connection requests from any device.
-     * @param token An arbitrary token (message) to be used to match connection initiation request
-     *              to a responder setup. A RESPONDER is set up with a {@code token} which must
-     *              be matched by the token provided by the INITIATOR. A null token is permitted
-     *              on the RESPONDER and matches any peer token. An empty ({@code ""}) token is
-     *              not the same as a null token and requires the peer token to be empty as well.
      *
      * @return A string to be used to construct
      * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
      * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
      * android.net.ConnectivityManager.NetworkCallback)}
      * [or other varieties of that API].
+     *
+     * @hide
+     */
+    public String createNetworkSpecifierOpen(@WifiAwareManager.DataPathRole int role,
+            @Nullable byte[] peer) {
+        WifiAwareManager mgr = mMgr.get();
+        if (mgr == null) {
+            Log.e(TAG, "createNetworkSpecifierOpen: called post GC on WifiAwareManager");
+            return "";
+        }
+        if (mTerminated) {
+            Log.e(TAG, "createNetworkSpecifierOpen: called after termination");
+            return "";
+        }
+        return mgr.createNetworkSpecifier(mClientId, role, peer, null);
+    }
+
+    /**
+     * Create a {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} for an
+     * encrypted WiFi Aware connection (link) to the specified peer. The
+     * {@link android.net.NetworkRequest.Builder#addTransportType(int)} should be set to
+     * {@link android.net.NetworkCapabilities#TRANSPORT_WIFI_AWARE}.
+     * <p>
+     *     This API is targeted for applications which can obtain the peer MAC address using OOB
+     *     (out-of-band) discovery. Aware discovery does not provide the MAC address of the peer -
+     *     when using Aware discovery use the alternative network specifier method -
+     *     {@link DiscoverySession#createNetworkSpecifierPmk(PeerHandle, byte[])}}.
+     *
+     * @param role  The role of this device:
+     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
+     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
+     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
+     *              value is used to gate the acceptance of a connection request from only that
+     *              peer. A RESPONDER may specify a null - indicating that it will accept
+     *              connection requests from any device.
+     * @param pmk A PMK (pairwise master key, see IEEE 802.11i) specifying the key to use for
+     *            encrypting the data-path. Use the {@link #createNetworkSpecifierOpen(int, byte[])}
+     *            to specify an open (unencrypted) link.
+     *
+     * @return A string to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
+     * android.net.ConnectivityManager.NetworkCallback)}
+     * [or other varieties of that API].
+     *
+     * @hide
+     */
+    public String createNetworkSpecifierPmk(@WifiAwareManager.DataPathRole int role,
+            @Nullable byte[] peer, @NonNull byte[] pmk) {
+        WifiAwareManager mgr = mMgr.get();
+        if (mgr == null) {
+            Log.e(TAG, "createNetworkSpecifierPmk: called post GC on WifiAwareManager");
+            return "";
+        }
+        if (mTerminated) {
+            Log.e(TAG, "createNetworkSpecifierPmk: called after termination");
+            return "";
+        }
+        if (pmk == null || pmk.length == 0) {
+            throw new IllegalArgumentException("PMK must not be null or empty");
+        }
+        return mgr.createNetworkSpecifier(mClientId, role, peer, pmk);
+    }
+
+    /**
+     * Place-holder for {@code #createNetworkSpecifierOpen(int, byte[])}. Present to enable
+     * development of replacements CL without causing an API change. Will be removed when new
+     * APIs are exposed.
+     *
+     * @param role  The role of this device:
+     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_INITIATOR} or
+     *              {@link WifiAwareManager#WIFI_AWARE_DATA_PATH_ROLE_RESPONDER}
+     * @param peer  The MAC address of the peer's Aware discovery interface. On a RESPONDER this
+     *              value is used to gate the acceptance of a connection request from only that
+     *              peer. A RESPONDER may specify a null - indicating that it will accept
+     *              connection requests from any device.
+     * @param token Deprecated and ignored.
+     * @return A string to be used to construct
+     * {@link android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to pass to
+     * {@link android.net.ConnectivityManager#requestNetwork(android.net.NetworkRequest,
+     * android.net.ConnectivityManager.NetworkCallback)}
+     * [or other varieties of that API].
      */
     public String createNetworkSpecifier(@WifiAwareManager.DataPathRole int role,
             @Nullable byte[] peer, @Nullable byte[] token) {
-        WifiAwareManager mgr = mMgr.get();
-        if (mgr == null) {
-            Log.e(TAG, "createNetworkSpecifier: called post GC on WifiAwareManager");
-            return "";
-        }
-        if (mTerminated) {
-            Log.e(TAG, "createNetworkSpecifier: called after termination");
-            return "";
-        }
-        return mgr.createNetworkSpecifier(mClientId, role, peer, token);
+        return createNetworkSpecifierOpen(role, peer);
     }
 }
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index 620759d..2388841 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -122,12 +122,22 @@
         private static final int MAX_PASSWORD_BYTES = 255;
 
         /**
+         * Supported authentication methods.
+         * @hide
+         */
+        public static final String AUTH_METHOD_PAP = "PAP";
+        /** @hide */
+        public static final String AUTH_METHOD_MSCHAP = "MS-CHAP";
+        /** @hide */
+        public static final String AUTH_METHOD_MSCHAPV2 = "MS-CHAP-V2";
+
+        /**
          * Supported Non-EAP inner methods.  Refer to
          * Credential/UsernamePassword/EAPMethod/InnerEAPType in Hotspot 2.0 Release 2 Technical
          * Specification Section 9.1 for more info.
          */
-        private static final Set<String> SUPPORTED_AUTH =
-                new HashSet<String>(Arrays.asList("PAP", "CHAP", "MS-CHAP", "MS-CHAP-V2"));
+        private static final Set<String> SUPPORTED_AUTH = new HashSet<String>(
+                Arrays.asList(AUTH_METHOD_PAP, AUTH_METHOD_MSCHAP, AUTH_METHOD_MSCHAPV2));
 
         /**
          * Username of the credential.
@@ -348,8 +358,9 @@
     public static final class CertificateCredential implements Parcelable {
         /**
          * Supported certificate types.
+         * @hide
          */
-        private static final String CERT_TYPE_X509V3 = "x509v3";
+        public static final String CERT_TYPE_X509V3 = "x509v3";
 
         /**
          * Certificate SHA-256 fingerprint length.
diff --git a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
index c4d2d32..d0aedba 100644
--- a/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiEnterpriseConfigTest.java
@@ -89,11 +89,29 @@
     @Test
     public void testSetClientKeyEntryWithNull() {
         mEnterpriseConfig.setClientKeyEntry(null, null);
-        assertEquals(null, mEnterpriseConfig.getClientCertificateChain());
-        assertEquals(null, mEnterpriseConfig.getClientCertificate());
+        assertNull(mEnterpriseConfig.getClientCertificateChain());
+        assertNull(mEnterpriseConfig.getClientCertificate());
         mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
-        assertEquals(null, mEnterpriseConfig.getClientCertificateChain());
-        assertEquals(null, mEnterpriseConfig.getClientCertificate());
+        assertNull(mEnterpriseConfig.getClientCertificateChain());
+        assertNull(mEnterpriseConfig.getClientCertificate());
+
+        // Setting the client certificate to null should clear the existing chain.
+        PrivateKey clientKey = FakeKeys.RSA_KEY1;
+        X509Certificate clientCert0 = FakeKeys.CLIENT_CERT;
+        X509Certificate clientCert1 = FakeKeys.CA_CERT1;
+        mEnterpriseConfig.setClientKeyEntry(clientKey, clientCert0);
+        assertNotNull(mEnterpriseConfig.getClientCertificate());
+        mEnterpriseConfig.setClientKeyEntry(null, null);
+        assertNull(mEnterpriseConfig.getClientCertificate());
+        assertNull(mEnterpriseConfig.getClientCertificateChain());
+
+        // Setting the chain to null should clear the existing chain.
+        X509Certificate[] clientChain = new X509Certificate[] {clientCert0, clientCert1};
+        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
+        assertNotNull(mEnterpriseConfig.getClientCertificateChain());
+        mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
+        assertNull(mEnterpriseConfig.getClientCertificate());
+        assertNull(mEnterpriseConfig.getClientCertificateChain());
     }
 
     @Test
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index 7f68f6f..992958b 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -973,11 +973,11 @@
         final int sessionId = 123;
         final PeerHandle peerHandle = new PeerHandle(123412);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER;
-        final String token = "Some arbitrary token string - can really be anything";
+        final byte[] pmk = "Some arbitrary byte array".getBytes();
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final PublishConfig publishConfig = new PublishConfig.Builder().build();
 
-        String tokenB64 = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);
+        String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
 
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
                 WifiAwareSession.class);
@@ -1008,9 +1008,8 @@
         mMockLooper.dispatchAll();
         inOrder.verify(mockSessionCallback).onPublishStarted(publishSession.capture());
 
-        // (3) request a network specifier from the session
-        String networkSpecifier = publishSession.getValue().createNetworkSpecifier(peerHandle,
-                token.getBytes());
+        // (3) request an open (unencrypted) network specifier from the session
+        String networkSpecifier = publishSession.getValue().createNetworkSpecifierOpen(peerHandle);
 
         // validate format
         JSONObject jsonObject = new JSONObject(networkSpecifier);
@@ -1022,8 +1021,22 @@
                 equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
         collector.checkThat("peer_id", peerHandle.peerId,
                 equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
-        collector.checkThat("token", tokenB64,
-                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_TOKEN)));
+
+        // (4) request an encrypted (PMK) network specifier from the session
+        networkSpecifier = publishSession.getValue().createNetworkSpecifierPmk(peerHandle, pmk);
+
+        // validate format
+        jsonObject = new JSONObject(networkSpecifier);
+        collector.checkThat("role", role,
+                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
+        collector.checkThat("client_id", clientId,
+                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
+        collector.checkThat("session_id", sessionId,
+                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_SESSION_ID)));
+        collector.checkThat("peer_id", peerHandle.peerId,
+                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_ID)));
+        collector.checkThat("pmk", pmkB64 ,
+                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
 
         verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                 mockPublishSession, mockRttListener);
@@ -1039,9 +1052,9 @@
         final ConfigRequest configRequest = new ConfigRequest.Builder().build();
         final byte[] someMac = HexEncoding.decode("000102030405".toCharArray(), false);
         final int role = WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_INITIATOR;
-        final String token = "Some arbitrary token string - can really be anything";
+        final byte[] pmk = "Some arbitrary pmk data".getBytes();
 
-        String tokenB64 = Base64.encodeToString(token.getBytes(), Base64.DEFAULT);
+        String pmkB64 = Base64.encodeToString(pmk, Base64.DEFAULT);
 
         ArgumentCaptor<WifiAwareSession> sessionCaptor = ArgumentCaptor.forClass(
                 WifiAwareSession.class);
@@ -1060,10 +1073,10 @@
         inOrder.verify(mockCallback).onAttached(sessionCaptor.capture());
         WifiAwareSession session = sessionCaptor.getValue();
 
-        /* (2) request a direct network specifier*/
-        String networkSpecifier = session.createNetworkSpecifier(role, someMac, token.getBytes());
+        // (2) request an open (unencrypted) direct network specifier
+        String networkSpecifier = session.createNetworkSpecifierOpen(role, someMac);
 
-        /* validate format*/
+        // validate format
         JSONObject jsonObject = new JSONObject(networkSpecifier);
         collector.checkThat("role", role,
                 equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
@@ -1072,8 +1085,21 @@
         collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
                 jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
                 false)));
-        collector.checkThat("token", tokenB64,
-                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_TOKEN)));
+
+        // (3) request an encrypted (PMK) direct network specifier
+        networkSpecifier = session.createNetworkSpecifierPmk(role, someMac, pmk);
+
+        // validate format
+        jsonObject = new JSONObject(networkSpecifier);
+        collector.checkThat("role", role,
+                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_ROLE)));
+        collector.checkThat("client_id", clientId,
+                equalTo(jsonObject.getInt(WifiAwareManager.NETWORK_SPECIFIER_KEY_CLIENT_ID)));
+        collector.checkThat("peer_mac", someMac, equalTo(HexEncoding.decode(
+                jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PEER_MAC).toCharArray(),
+                false)));
+        collector.checkThat("pmk", pmkB64,
+                equalTo(jsonObject.getString(WifiAwareManager.NETWORK_SPECIFIER_KEY_PMK)));
 
         verifyNoMoreInteractions(mockCallback, mockSessionCallback, mockAwareService,
                 mockPublishSession, mockRttListener);