Merge "Use text input for various internationalized listeners" into oc-dev
diff --git a/api/current.txt b/api/current.txt
index c99f325..15d308e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3578,7 +3578,7 @@
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public void enterPictureInPictureMode();
     method public boolean enterPictureInPictureMode(android.app.PictureInPictureArgs);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public void finish();
     method public void finishActivity(int);
     method public void finishActivityFromChild(android.app.Activity, int);
@@ -4358,7 +4358,7 @@
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public boolean dispatchTouchEvent(android.view.MotionEvent);
     method public boolean dispatchTrackballEvent(android.view.MotionEvent);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public android.app.ActionBar getActionBar();
     method public final android.content.Context getContext();
     method public android.view.View getCurrentFocus();
@@ -7044,6 +7044,7 @@
     method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
     method public android.os.Bundle getAppWidgetOptions(int);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders();
+    method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForPackage(java.lang.String, android.os.UserHandle);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForProfile(android.os.UserHandle);
     method public static android.appwidget.AppWidgetManager getInstance(android.content.Context);
     method public boolean isRequestPinAppWidgetSupported();
@@ -20913,6 +20914,7 @@
     method public int getContentType();
     method public int getFlags();
     method public int getUsage();
+    method public static deprecated int getVolumeControlStream(android.media.AudioAttributes);
     method public int getVolumeControlStream();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
@@ -24555,85 +24557,6 @@
     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 int ASPECT_RATIO_16_9 = 0; // 0x0
-    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
-    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
-    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
-    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
-    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
-    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
-    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_INTENT_URI = "intent_uri";
-    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 int INTERACTION_TYPE_FANS = 3; // 0x3
-    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
-    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
-    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
-    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
-    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
-    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
-    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
-    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
-    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
-    field public static final int TYPE_ALBUM = 8; // 0x8
-    field public static final int TYPE_ARTIST = 9; // 0x9
-    field public static final int TYPE_CHANNEL = 6; // 0x6
-    field public static final int TYPE_CLIP = 4; // 0x4
-    field public static final int TYPE_EVENT = 5; // 0x5
-    field public static final int TYPE_MOVIE = 0; // 0x0
-    field public static final int TYPE_PLAYLIST = 10; // 0xa
-    field public static final int TYPE_STATION = 11; // 0xb
-    field public static final int TYPE_TRACK = 7; // 0x7
-    field public static final int TYPE_TV_EPISODE = 3; // 0x3
-    field public static final int TYPE_TV_SEASON = 2; // 0x2
-    field public static final int TYPE_TV_SERIES = 1; // 0x1
-  }
-
-  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_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";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
-    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
-    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
-    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
-    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
-    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
-    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
-    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
-    field public static final java.lang.String COLUMN_TITLE = "title";
-    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
-    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
-    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
-  }
-
   public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
     field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
   }
@@ -24720,22 +24643,116 @@
     field public static final java.lang.String CONTENT_DIRECTORY = "logo";
   }
 
-  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BaseTvColumns {
+    field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
+    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
+    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
+    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
+    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
+    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
+    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    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_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_ID = "content_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    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";
+    field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
+    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_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    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_LONG_DESCRIPTION = "long_description";
+    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_POSTER_ART_URI = "poster_art_uri";
+    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_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    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_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    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_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     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 int INTERACTION_TYPE_FANS = 3; // 0x3
+    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
+    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
+    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
+    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
+    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
+    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
+    field public static final int TYPE_ALBUM = 8; // 0x8
+    field public static final int TYPE_ARTIST = 9; // 0x9
+    field public static final int TYPE_CHANNEL = 6; // 0x6
+    field public static final int TYPE_CLIP = 4; // 0x4
+    field public static final int TYPE_EVENT = 5; // 0x5
+    field public static final int TYPE_MOVIE = 0; // 0x0
+    field public static final int TYPE_PLAYLIST = 10; // 0xa
+    field public static final int TYPE_STATION = 11; // 0xb
+    field public static final int TYPE_TRACK = 7; // 0x7
+    field public static final int TYPE_TV_EPISODE = 3; // 0x3
+    field public static final int TYPE_TV_SEASON = 2; // 0x2
+    field public static final int TYPE_TV_SERIES = 1; // 0x1
   }
 
-  public static final class TvContract.Programs implements android.media.tv.TvContract.BaseProgramColumns {
+  public static final class TvContract.Programs 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_BROADCAST_GENRE = "broadcast_genre";
+    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_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
+    field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
     field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
     field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
     field public static final android.net.Uri CONTENT_URI;
@@ -24764,28 +24781,122 @@
     field public static final java.lang.String TRAVEL = "TRAVEL";
   }
 
-  public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseProgramColumns {
+  public static final class TvContract.RecordedPrograms 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_BROADCAST_GENRE = "broadcast_genre";
+    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_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    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";
     field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
     field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
     field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
     field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
     field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
     field public static final android.net.Uri CONTENT_URI;
   }
 
-  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
     ctor public TvContract.WatchNextPrograms();
+    field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
+    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
+    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
+    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
+    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
+    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
+    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    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_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    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";
+    field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
+    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_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    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_ENGAGEMENT_TIME_UTC_MILLIS = "last_engagement_time_utc_millis";
+    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_LONG_DESCRIPTION = "long_description";
+    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_POSTER_ART_URI = "poster_art_uri";
+    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_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    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_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    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_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     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 int INTERACTION_TYPE_FANS = 3; // 0x3
+    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
+    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
+    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
+    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
+    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
+    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
+    field public static final int TYPE_ALBUM = 8; // 0x8
+    field public static final int TYPE_ARTIST = 9; // 0x9
+    field public static final int TYPE_CHANNEL = 6; // 0x6
+    field public static final int TYPE_CLIP = 4; // 0x4
+    field public static final int TYPE_EVENT = 5; // 0x5
+    field public static final int TYPE_MOVIE = 0; // 0x0
+    field public static final int TYPE_PLAYLIST = 10; // 0xa
+    field public static final int TYPE_STATION = 11; // 0xb
+    field public static final int TYPE_TRACK = 7; // 0x7
+    field public static final int TYPE_TV_EPISODE = 3; // 0x3
+    field public static final int TYPE_TV_SEASON = 2; // 0x2
+    field public static final int TYPE_TV_SERIES = 1; // 0x1
     field public static final int WATCH_NEXT_TYPE_CONTINUE = 0; // 0x0
     field public static final int WATCH_NEXT_TYPE_NEW = 2; // 0x2
     field public static final int WATCH_NEXT_TYPE_NEXT = 1; // 0x1
@@ -34410,14 +34521,15 @@
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
     ctor public FontsContract.Columns();
+    field public static final java.lang.String ITALIC = "font_italic";
     field public static final java.lang.String RESULT_CODE = "result_code";
     field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
     field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
     field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
     field public static final int RESULT_CODE_OK = 0; // 0x0
-    field public static final java.lang.String STYLE = "font_style";
     field public static final java.lang.String TTC_INDEX = "font_ttc_index";
     field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings";
+    field public static final java.lang.String WEIGHT = "font_weight";
   }
 
   public final deprecated class LiveFolders implements android.provider.BaseColumns {
@@ -36940,7 +37052,7 @@
     ctor public FillResponse.Builder();
     method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
     method public android.service.autofill.FillResponse build();
-    method public android.service.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender, android.widget.RemoteViews);
+    method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
     method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
     method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
   }
@@ -38639,6 +38751,7 @@
     method public java.lang.String getCallerDisplayName();
     method public int getCallerDisplayNamePresentation();
     method public final long getConnectTimeMillis();
+    method public long getCreationTimeMillis();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public android.os.Bundle getExtras();
     method public android.telecom.GatewayInfo getGatewayInfo();
@@ -41212,6 +41325,8 @@
     field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2
     field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0
     field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0
   }
 
   public static final class Layout.Alignment extends java.lang.Enum {
@@ -41413,7 +41528,7 @@
     method public android.text.StaticLayout.Builder setHyphenationFrequency(int);
     method public android.text.StaticLayout.Builder setIncludePad(boolean);
     method public android.text.StaticLayout.Builder setIndents(int[], int[]);
-    method public android.text.StaticLayout.Builder setJustify(boolean);
+    method public android.text.StaticLayout.Builder setJustificationMode(int);
     method public android.text.StaticLayout.Builder setLineSpacing(float, float);
     method public android.text.StaticLayout.Builder setMaxLines(int);
     method public android.text.StaticLayout.Builder setText(java.lang.CharSequence);
@@ -46492,7 +46607,7 @@
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public boolean getAllowEnterTransitionOverlap();
     method public boolean getAllowReturnTransitionOverlap();
     method public final android.view.WindowManager.LayoutParams getAttributes();
@@ -48617,7 +48732,7 @@
     method public abstract boolean getOffscreenPreRaster();
     method public abstract deprecated android.webkit.WebSettings.PluginState getPluginState();
     method public abstract java.lang.String getSansSerifFontFamily();
-    method public abstract boolean getSaveFormData();
+    method public abstract deprecated boolean getSaveFormData();
     method public abstract deprecated boolean getSavePassword();
     method public abstract java.lang.String getSerifFontFamily();
     method public abstract java.lang.String getStandardFontFamily();
@@ -48666,7 +48781,7 @@
     method public abstract deprecated void setPluginState(android.webkit.WebSettings.PluginState);
     method public abstract deprecated void setRenderPriority(android.webkit.WebSettings.RenderPriority);
     method public abstract void setSansSerifFontFamily(java.lang.String);
-    method public abstract void setSaveFormData(boolean);
+    method public abstract deprecated void setSaveFormData(boolean);
     method public abstract deprecated void setSavePassword(boolean);
     method public abstract void setSerifFontFamily(java.lang.String);
     method public abstract void setStandardFontFamily(java.lang.String);
@@ -48957,12 +49072,12 @@
 
   public abstract class WebViewDatabase {
     ctor public WebViewDatabase();
-    method public abstract void clearFormData();
+    method public abstract deprecated void clearFormData();
     method public abstract void clearHttpAuthUsernamePassword();
     method public abstract deprecated void clearUsernamePassword();
     method public abstract java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String);
     method public static android.webkit.WebViewDatabase getInstance(android.content.Context);
-    method public abstract boolean hasFormData();
+    method public abstract deprecated boolean hasFormData();
     method public abstract boolean hasHttpAuthUsernamePassword();
     method public abstract deprecated boolean hasUsernamePassword();
     method public abstract void setHttpAuthUsernamePassword(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
@@ -51223,7 +51338,7 @@
     method public boolean getIncludeFontPadding();
     method public android.os.Bundle getInputExtras(boolean);
     method public int getInputType();
-    method public boolean getJustify();
+    method public int getJustificationMode();
     method public final android.text.method.KeyListener getKeyListener();
     method public final android.text.Layout getLayout();
     method public float getLetterSpacing();
@@ -51336,7 +51451,7 @@
     method public void setIncludeFontPadding(boolean);
     method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public void setInputType(int);
-    method public void setJustify(boolean);
+    method public void setJustificationMode(int);
     method public void setKeyListener(android.text.method.KeyListener);
     method public void setLetterSpacing(float);
     method public void setLineSpacing(float, float);
diff --git a/api/removed.txt b/api/removed.txt
index 42b2ae6..d20c08c 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -296,6 +296,10 @@
     field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
+  public static final class FontsContract.Columns implements android.provider.BaseColumns {
+    field public static final java.lang.String STYLE = "font_style";
+  }
+
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/api/system-current.txt b/api/system-current.txt
index 222f706..f74bc3a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3702,7 +3702,7 @@
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public void enterPictureInPictureMode();
     method public boolean enterPictureInPictureMode(android.app.PictureInPictureArgs);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public void finish();
     method public void finishActivity(int);
     method public void finishActivityFromChild(android.app.Activity, int);
@@ -4509,7 +4509,7 @@
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public boolean dispatchTouchEvent(android.view.MotionEvent);
     method public boolean dispatchTrackballEvent(android.view.MotionEvent);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public android.app.ActionBar getActionBar();
     method public final android.content.Context getContext();
     method public android.view.View getCurrentFocus();
@@ -4621,6 +4621,7 @@
     method public android.database.Cursor query(android.app.DownloadManager.Query);
     method public int remove(long...);
     field public static final java.lang.String ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE";
+    field public static final java.lang.String ACTION_DOWNLOAD_COMPLETED = "android.intent.action.DOWNLOAD_COMPLETED";
     field public static final java.lang.String ACTION_NOTIFICATION_CLICKED = "android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED";
     field public static final java.lang.String ACTION_VIEW_DOWNLOADS = "android.intent.action.VIEW_DOWNLOADS";
     field public static final java.lang.String COLUMN_BYTES_DOWNLOADED_SO_FAR = "bytes_so_far";
@@ -7502,6 +7503,7 @@
     method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
     method public android.os.Bundle getAppWidgetOptions(int);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders();
+    method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForPackage(java.lang.String, android.os.UserHandle);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForProfile(android.os.UserHandle);
     method public static android.appwidget.AppWidgetManager getInstance(android.content.Context);
     method public boolean isRequestPinAppWidgetSupported();
@@ -9796,6 +9798,7 @@
     field public static final java.lang.String ACTION_DREAMING_STARTED = "android.intent.action.DREAMING_STARTED";
     field public static final java.lang.String ACTION_DREAMING_STOPPED = "android.intent.action.DREAMING_STOPPED";
     field public static final java.lang.String ACTION_EDIT = "android.intent.action.EDIT";
+    field public static final deprecated java.lang.String ACTION_EPHEMERAL_RESOLVER_SETTINGS = "android.intent.action.EPHEMERAL_RESOLVER_SETTINGS";
     field public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_AVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE";
     field public static final java.lang.String ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE = "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE";
     field public static final java.lang.String ACTION_FACTORY_RESET = "android.intent.action.FACTORY_RESET";
@@ -9808,7 +9811,10 @@
     field public static final java.lang.String ACTION_INPUT_METHOD_CHANGED = "android.intent.action.INPUT_METHOD_CHANGED";
     field public static final java.lang.String ACTION_INSERT = "android.intent.action.INSERT";
     field public static final java.lang.String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
+    field public static final deprecated java.lang.String ACTION_INSTALL_EPHEMERAL_PACKAGE = "android.intent.action.INSTALL_EPHEMERAL_PACKAGE";
+    field public static final java.lang.String ACTION_INSTALL_INSTANT_APP_PACKAGE = "android.intent.action.INSTALL_INSTANT_APP_PACKAGE";
     field public static final java.lang.String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
+    field public static final java.lang.String ACTION_INSTANT_APP_RESOLVER_SETTINGS = "android.intent.action.INSTANT_APP_RESOLVER_SETTINGS";
     field public static final java.lang.String ACTION_INTENT_FILTER_NEEDS_VERIFICATION = "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION";
     field public static final java.lang.String ACTION_LOCALE_CHANGED = "android.intent.action.LOCALE_CHANGED";
     field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED";
@@ -9867,6 +9873,8 @@
     field public static final java.lang.String ACTION_QUICK_CLOCK = "android.intent.action.QUICK_CLOCK";
     field public static final java.lang.String ACTION_QUICK_VIEW = "android.intent.action.QUICK_VIEW";
     field public static final java.lang.String ACTION_REBOOT = "android.intent.action.REBOOT";
+    field public static final deprecated java.lang.String ACTION_RESOLVE_EPHEMERAL_PACKAGE = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE";
+    field public static final java.lang.String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE";
     field public static final java.lang.String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS";
     field public static final java.lang.String ACTION_RUN = "android.intent.action.RUN";
     field public static final java.lang.String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
@@ -9876,6 +9884,7 @@
     field public static final java.lang.String ACTION_SEND = "android.intent.action.SEND";
     field public static final java.lang.String ACTION_SENDTO = "android.intent.action.SENDTO";
     field public static final java.lang.String ACTION_SEND_MULTIPLE = "android.intent.action.SEND_MULTIPLE";
+    field public static final deprecated java.lang.String ACTION_SERVICE_STATE = "android.intent.action.SERVICE_STATE";
     field public static final java.lang.String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER";
     field public static final java.lang.String ACTION_SHOW_APP_INFO = "android.intent.action.SHOW_APP_INFO";
     field public static final java.lang.String ACTION_SHUTDOWN = "android.intent.action.ACTION_SHUTDOWN";
@@ -9950,6 +9959,8 @@
     field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
     field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
     field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
+    field public static final deprecated java.lang.String EXTRA_CDMA_DEFAULT_ROAMING_INDICATOR = "cdmaDefaultRoamingIndicator";
+    field public static final deprecated java.lang.String EXTRA_CDMA_ROAMING_INDICATOR = "cdmaRoamingIndicator";
     field public static final deprecated java.lang.String EXTRA_CHANGED_COMPONENT_NAME = "android.intent.extra.changed_component_name";
     field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list";
     field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list";
@@ -9959,7 +9970,14 @@
     field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT";
     field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER";
     field public static final java.lang.String EXTRA_CONTENT_ANNOTATIONS = "android.intent.extra.CONTENT_ANNOTATIONS";
+    field public static final deprecated java.lang.String EXTRA_CSS_INDICATOR = "cssIndicator";
+    field public static final deprecated java.lang.String EXTRA_DATA_OPERATOR_ALPHA_LONG = "data-operator-alpha-long";
+    field public static final deprecated java.lang.String EXTRA_DATA_OPERATOR_ALPHA_SHORT = "data-operator-alpha-short";
+    field public static final deprecated java.lang.String EXTRA_DATA_OPERATOR_NUMERIC = "data-operator-numeric";
+    field public static final deprecated java.lang.String EXTRA_DATA_RADIO_TECH = "dataRadioTechnology";
+    field public static final deprecated java.lang.String EXTRA_DATA_REG_STATE = "dataRegState";
     field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
+    field public static final deprecated java.lang.String EXTRA_DATA_ROAMING_TYPE = "dataRoamingType";
     field public static final java.lang.String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE";
     field public static final int EXTRA_DOCK_STATE_CAR = 2; // 0x2
     field public static final int EXTRA_DOCK_STATE_DESK = 1; // 0x1
@@ -9968,6 +9986,7 @@
     field public static final int EXTRA_DOCK_STATE_UNDOCKED = 0; // 0x0
     field public static final java.lang.String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
     field public static final java.lang.String EXTRA_EMAIL = "android.intent.extra.EMAIL";
+    field public static final deprecated java.lang.String EXTRA_EMERGENCY_ONLY = "emergencyOnly";
     field public static final java.lang.String EXTRA_EXCLUDE_COMPONENTS = "android.intent.extra.EXCLUDE_COMPONENTS";
     field public static final java.lang.String EXTRA_FORCE_FACTORY_RESET = "android.intent.extra.FORCE_FACTORY_RESET";
     field public static final java.lang.String EXTRA_HTML_TEXT = "android.intent.extra.HTML_TEXT";
@@ -9975,10 +9994,18 @@
     field public static final java.lang.String EXTRA_INITIAL_INTENTS = "android.intent.extra.INITIAL_INTENTS";
     field public static final java.lang.String EXTRA_INSTALLER_PACKAGE_NAME = "android.intent.extra.INSTALLER_PACKAGE_NAME";
     field public static final java.lang.String EXTRA_INTENT = "android.intent.extra.INTENT";
+    field public static final deprecated java.lang.String EXTRA_IS_DATA_ROAMING_FROM_REGISTRATION = "isDataRoamingFromRegistration";
+    field public static final deprecated java.lang.String EXTRA_IS_USING_CARRIER_AGGREGATION = "isUsingCarrierAggregation";
     field public static final java.lang.String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
     field public static final java.lang.String EXTRA_LOCAL_ONLY = "android.intent.extra.LOCAL_ONLY";
+    field public static final deprecated java.lang.String EXTRA_LTE_EARFCN_RSRP_BOOST = "LteEarfcnRsrpBoost";
+    field public static final deprecated java.lang.String EXTRA_MANUAL = "manual";
     field public static final java.lang.String EXTRA_MIME_TYPES = "android.intent.extra.MIME_TYPES";
+    field public static final deprecated java.lang.String EXTRA_NETWORK_ID = "networkId";
     field public static final java.lang.String EXTRA_NOT_UNKNOWN_SOURCE = "android.intent.extra.NOT_UNKNOWN_SOURCE";
+    field public static final deprecated java.lang.String EXTRA_OPERATOR_ALPHA_LONG = "operator-alpha-long";
+    field public static final deprecated java.lang.String EXTRA_OPERATOR_ALPHA_SHORT = "operator-alpha-short";
+    field public static final deprecated java.lang.String EXTRA_OPERATOR_NUMERIC = "operator-numeric";
     field public static final java.lang.String EXTRA_ORIGINATING_UID = "android.intent.extra.ORIGINATING_UID";
     field public static final java.lang.String EXTRA_ORIGINATING_URI = "android.intent.extra.ORIGINATING_URI";
     field public static final java.lang.String EXTRA_PACKAGES = "android.intent.extra.PACKAGES";
@@ -10010,11 +10037,15 @@
     field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
     field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
     field public static final java.lang.String EXTRA_SUBSCRIPTION_INDEX = "android.intent.extra.SUBSCRIPTION_INDEX";
+    field public static final deprecated java.lang.String EXTRA_SYSTEM_ID = "systemId";
     field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
     field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT";
     field public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE";
     field public static final java.lang.String EXTRA_UID = "android.intent.extra.UID";
     field public static final java.lang.String EXTRA_USER = "android.intent.extra.USER";
+    field public static final deprecated java.lang.String EXTRA_VOICE_RADIO_TECH = "radioTechnology";
+    field public static final deprecated java.lang.String EXTRA_VOICE_REG_STATE = "voiceRegState";
+    field public static final deprecated java.lang.String EXTRA_VOICE_ROAMING_TYPE = "voiceRoamingType";
     field public static final int FILL_IN_ACTION = 1; // 0x1
     field public static final int FILL_IN_CATEGORIES = 4; // 0x4
     field public static final int FILL_IN_CLIP_DATA = 128; // 0x80
@@ -22653,6 +22684,7 @@
     method public int getContentType();
     method public int getFlags();
     method public int getUsage();
+    method public static deprecated int getVolumeControlStream(android.media.AudioAttributes);
     method public int getVolumeControlStream();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
@@ -26500,85 +26532,6 @@
     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 int ASPECT_RATIO_16_9 = 0; // 0x0
-    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
-    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
-    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
-    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
-    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
-    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
-    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_INTENT_URI = "intent_uri";
-    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 int INTERACTION_TYPE_FANS = 3; // 0x3
-    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
-    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
-    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
-    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
-    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
-    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
-    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
-    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
-    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
-    field public static final int TYPE_ALBUM = 8; // 0x8
-    field public static final int TYPE_ARTIST = 9; // 0x9
-    field public static final int TYPE_CHANNEL = 6; // 0x6
-    field public static final int TYPE_CLIP = 4; // 0x4
-    field public static final int TYPE_EVENT = 5; // 0x5
-    field public static final int TYPE_MOVIE = 0; // 0x0
-    field public static final int TYPE_PLAYLIST = 10; // 0xa
-    field public static final int TYPE_STATION = 11; // 0xb
-    field public static final int TYPE_TRACK = 7; // 0x7
-    field public static final int TYPE_TV_EPISODE = 3; // 0x3
-    field public static final int TYPE_TV_SEASON = 2; // 0x2
-    field public static final int TYPE_TV_SERIES = 1; // 0x1
-  }
-
-  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_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";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
-    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
-    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
-    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
-    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
-    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
-    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
-    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
-    field public static final java.lang.String COLUMN_TITLE = "title";
-    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
-    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
-    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
-  }
-
   public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
     field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
   }
@@ -26666,22 +26619,116 @@
     field public static final java.lang.String CONTENT_DIRECTORY = "logo";
   }
 
-  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BaseTvColumns {
+    field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
+    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
+    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
+    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
+    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
+    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
+    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    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_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_ID = "content_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    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";
+    field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
+    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_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    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_LONG_DESCRIPTION = "long_description";
+    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_POSTER_ART_URI = "poster_art_uri";
+    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_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    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_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    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_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     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 int INTERACTION_TYPE_FANS = 3; // 0x3
+    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
+    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
+    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
+    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
+    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
+    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
+    field public static final int TYPE_ALBUM = 8; // 0x8
+    field public static final int TYPE_ARTIST = 9; // 0x9
+    field public static final int TYPE_CHANNEL = 6; // 0x6
+    field public static final int TYPE_CLIP = 4; // 0x4
+    field public static final int TYPE_EVENT = 5; // 0x5
+    field public static final int TYPE_MOVIE = 0; // 0x0
+    field public static final int TYPE_PLAYLIST = 10; // 0xa
+    field public static final int TYPE_STATION = 11; // 0xb
+    field public static final int TYPE_TRACK = 7; // 0x7
+    field public static final int TYPE_TV_EPISODE = 3; // 0x3
+    field public static final int TYPE_TV_SEASON = 2; // 0x2
+    field public static final int TYPE_TV_SERIES = 1; // 0x1
   }
 
-  public static final class TvContract.Programs implements android.media.tv.TvContract.BaseProgramColumns {
+  public static final class TvContract.Programs 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_BROADCAST_GENRE = "broadcast_genre";
+    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_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
+    field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
     field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
     field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
     field public static final android.net.Uri CONTENT_URI;
@@ -26710,28 +26757,122 @@
     field public static final java.lang.String TRAVEL = "TRAVEL";
   }
 
-  public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseProgramColumns {
+  public static final class TvContract.RecordedPrograms 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_BROADCAST_GENRE = "broadcast_genre";
+    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_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    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";
     field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
     field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
     field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
     field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
     field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
     field public static final android.net.Uri CONTENT_URI;
   }
 
-  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
     ctor public TvContract.WatchNextPrograms();
+    field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
+    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
+    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
+    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
+    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
+    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
+    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    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_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    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";
+    field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
+    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_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    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_ENGAGEMENT_TIME_UTC_MILLIS = "last_engagement_time_utc_millis";
+    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_LONG_DESCRIPTION = "long_description";
+    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_POSTER_ART_URI = "poster_art_uri";
+    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_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    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_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    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_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     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 int INTERACTION_TYPE_FANS = 3; // 0x3
+    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
+    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
+    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
+    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
+    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
+    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
+    field public static final int TYPE_ALBUM = 8; // 0x8
+    field public static final int TYPE_ARTIST = 9; // 0x9
+    field public static final int TYPE_CHANNEL = 6; // 0x6
+    field public static final int TYPE_CLIP = 4; // 0x4
+    field public static final int TYPE_EVENT = 5; // 0x5
+    field public static final int TYPE_MOVIE = 0; // 0x0
+    field public static final int TYPE_PLAYLIST = 10; // 0xa
+    field public static final int TYPE_STATION = 11; // 0xb
+    field public static final int TYPE_TRACK = 7; // 0x7
+    field public static final int TYPE_TV_EPISODE = 3; // 0x3
+    field public static final int TYPE_TV_SEASON = 2; // 0x2
+    field public static final int TYPE_TV_SERIES = 1; // 0x1
     field public static final int WATCH_NEXT_TYPE_CONTINUE = 0; // 0x0
     field public static final int WATCH_NEXT_TYPE_NEW = 2; // 0x2
     field public static final int WATCH_NEXT_TYPE_NEXT = 1; // 0x1
@@ -37319,14 +37460,15 @@
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
     ctor public FontsContract.Columns();
+    field public static final java.lang.String ITALIC = "font_italic";
     field public static final java.lang.String RESULT_CODE = "result_code";
     field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
     field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
     field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
     field public static final int RESULT_CODE_OK = 0; // 0x0
-    field public static final java.lang.String STYLE = "font_style";
     field public static final java.lang.String TTC_INDEX = "font_ttc_index";
     field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings";
+    field public static final java.lang.String WEIGHT = "font_weight";
   }
 
   public final deprecated class LiveFolders implements android.provider.BaseColumns {
@@ -39975,7 +40117,7 @@
     ctor public FillResponse.Builder();
     method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
     method public android.service.autofill.FillResponse build();
-    method public android.service.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender, android.widget.RemoteViews);
+    method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
     method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
     method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
   }
@@ -41801,6 +41943,7 @@
     method public java.lang.String getCallerDisplayName();
     method public int getCallerDisplayNamePresentation();
     method public final long getConnectTimeMillis();
+    method public long getCreationTimeMillis();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public android.os.Bundle getExtras();
     method public android.telecom.GatewayInfo getGatewayInfo();
@@ -44674,6 +44817,8 @@
     field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2
     field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0
     field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0
   }
 
   public static final class Layout.Alignment extends java.lang.Enum {
@@ -44875,7 +45020,7 @@
     method public android.text.StaticLayout.Builder setHyphenationFrequency(int);
     method public android.text.StaticLayout.Builder setIncludePad(boolean);
     method public android.text.StaticLayout.Builder setIndents(int[], int[]);
-    method public android.text.StaticLayout.Builder setJustify(boolean);
+    method public android.text.StaticLayout.Builder setJustificationMode(int);
     method public android.text.StaticLayout.Builder setLineSpacing(float, float);
     method public android.text.StaticLayout.Builder setMaxLines(int);
     method public android.text.StaticLayout.Builder setText(java.lang.CharSequence);
@@ -49955,7 +50100,7 @@
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public boolean getAllowEnterTransitionOverlap();
     method public boolean getAllowReturnTransitionOverlap();
     method public final android.view.WindowManager.LayoutParams getAttributes();
@@ -52165,7 +52310,7 @@
     method public abstract deprecated android.webkit.WebSettings.PluginState getPluginState();
     method public abstract deprecated boolean getPluginsEnabled();
     method public abstract java.lang.String getSansSerifFontFamily();
-    method public abstract boolean getSaveFormData();
+    method public abstract deprecated boolean getSaveFormData();
     method public abstract deprecated boolean getSavePassword();
     method public abstract java.lang.String getSerifFontFamily();
     method public abstract java.lang.String getStandardFontFamily();
@@ -52220,7 +52365,7 @@
     method public abstract deprecated void setPluginsEnabled(boolean);
     method public abstract deprecated void setRenderPriority(android.webkit.WebSettings.RenderPriority);
     method public abstract void setSansSerifFontFamily(java.lang.String);
-    method public abstract void setSaveFormData(boolean);
+    method public abstract deprecated void setSaveFormData(boolean);
     method public abstract deprecated void setSavePassword(boolean);
     method public abstract void setSerifFontFamily(java.lang.String);
     method public abstract void setStandardFontFamily(java.lang.String);
@@ -52548,12 +52693,12 @@
 
   public abstract class WebViewDatabase {
     ctor public WebViewDatabase();
-    method public abstract void clearFormData();
+    method public abstract deprecated void clearFormData();
     method public abstract void clearHttpAuthUsernamePassword();
     method public abstract deprecated void clearUsernamePassword();
     method public abstract java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String);
     method public static android.webkit.WebViewDatabase getInstance(android.content.Context);
-    method public abstract boolean hasFormData();
+    method public abstract deprecated boolean hasFormData();
     method public abstract boolean hasHttpAuthUsernamePassword();
     method public abstract deprecated boolean hasUsernamePassword();
     method public abstract void setHttpAuthUsernamePassword(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
@@ -55053,7 +55198,7 @@
     method public boolean getIncludeFontPadding();
     method public android.os.Bundle getInputExtras(boolean);
     method public int getInputType();
-    method public boolean getJustify();
+    method public int getJustificationMode();
     method public final android.text.method.KeyListener getKeyListener();
     method public final android.text.Layout getLayout();
     method public float getLetterSpacing();
@@ -55166,7 +55311,7 @@
     method public void setIncludeFontPadding(boolean);
     method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public void setInputType(int);
-    method public void setJustify(boolean);
+    method public void setJustificationMode(int);
     method public void setKeyListener(android.text.method.KeyListener);
     method public void setLetterSpacing(float);
     method public void setLineSpacing(float, float);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 1bafe96..1effe9c 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -290,6 +290,10 @@
     field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
+  public static final class FontsContract.Columns implements android.provider.BaseColumns {
+    field public static final java.lang.String STYLE = "font_style";
+  }
+
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/api/test-current.txt b/api/test-current.txt
index 387d14c..b51739b 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3580,7 +3580,7 @@
     method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
     method public void enterPictureInPictureMode();
     method public boolean enterPictureInPictureMode(android.app.PictureInPictureArgs);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public void finish();
     method public void finishActivity(int);
     method public void finishActivityFromChild(android.app.Activity, int);
@@ -4370,7 +4370,7 @@
     method public boolean dispatchPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
     method public boolean dispatchTouchEvent(android.view.MotionEvent);
     method public boolean dispatchTrackballEvent(android.view.MotionEvent);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public android.app.ActionBar getActionBar();
     method public final android.content.Context getContext();
     method public android.view.View getCurrentFocus();
@@ -7074,6 +7074,7 @@
     method public android.appwidget.AppWidgetProviderInfo getAppWidgetInfo(int);
     method public android.os.Bundle getAppWidgetOptions(int);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProviders();
+    method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForPackage(java.lang.String, android.os.UserHandle);
     method public java.util.List<android.appwidget.AppWidgetProviderInfo> getInstalledProvidersForProfile(android.os.UserHandle);
     method public static android.appwidget.AppWidgetManager getInstance(android.content.Context);
     method public boolean isRequestPinAppWidgetSupported();
@@ -21026,6 +21027,7 @@
     method public int getContentType();
     method public int getFlags();
     method public int getUsage();
+    method public static deprecated int getVolumeControlStream(android.media.AudioAttributes);
     method public int getVolumeControlStream();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final int CONTENT_TYPE_MOVIE = 3; // 0x3
@@ -24668,85 +24670,6 @@
     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 int ASPECT_RATIO_16_9 = 0; // 0x0
-    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
-    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
-    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
-    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
-    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
-    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
-    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_INTENT_URI = "intent_uri";
-    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 int INTERACTION_TYPE_FANS = 3; // 0x3
-    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
-    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
-    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
-    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
-    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
-    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
-    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
-    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
-    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
-    field public static final int TYPE_ALBUM = 8; // 0x8
-    field public static final int TYPE_ARTIST = 9; // 0x9
-    field public static final int TYPE_CHANNEL = 6; // 0x6
-    field public static final int TYPE_CLIP = 4; // 0x4
-    field public static final int TYPE_EVENT = 5; // 0x5
-    field public static final int TYPE_MOVIE = 0; // 0x0
-    field public static final int TYPE_PLAYLIST = 10; // 0xa
-    field public static final int TYPE_STATION = 11; // 0xb
-    field public static final int TYPE_TRACK = 7; // 0x7
-    field public static final int TYPE_TV_EPISODE = 3; // 0x3
-    field public static final int TYPE_TV_SEASON = 2; // 0x2
-    field public static final int TYPE_TV_SERIES = 1; // 0x1
-  }
-
-  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_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";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
-    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
-    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
-    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
-    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
-    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
-    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
-    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
-    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
-    field public static final java.lang.String COLUMN_TITLE = "title";
-    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
-    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
-    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
-  }
-
   public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
     field public static final java.lang.String COLUMN_PACKAGE_NAME = "package_name";
   }
@@ -24833,22 +24756,116 @@
     field public static final java.lang.String CONTENT_DIRECTORY = "logo";
   }
 
-  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+  public static final class TvContract.PreviewPrograms implements android.media.tv.TvContract.BaseTvColumns {
+    field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
+    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
+    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
+    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
+    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
+    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
+    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    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_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_ID = "content_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    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";
+    field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
+    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_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    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_LONG_DESCRIPTION = "long_description";
+    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_POSTER_ART_URI = "poster_art_uri";
+    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_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    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_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    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_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     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 int INTERACTION_TYPE_FANS = 3; // 0x3
+    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
+    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
+    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
+    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
+    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
+    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
+    field public static final int TYPE_ALBUM = 8; // 0x8
+    field public static final int TYPE_ARTIST = 9; // 0x9
+    field public static final int TYPE_CHANNEL = 6; // 0x6
+    field public static final int TYPE_CLIP = 4; // 0x4
+    field public static final int TYPE_EVENT = 5; // 0x5
+    field public static final int TYPE_MOVIE = 0; // 0x0
+    field public static final int TYPE_PLAYLIST = 10; // 0xa
+    field public static final int TYPE_STATION = 11; // 0xb
+    field public static final int TYPE_TRACK = 7; // 0x7
+    field public static final int TYPE_TV_EPISODE = 3; // 0x3
+    field public static final int TYPE_TV_SEASON = 2; // 0x2
+    field public static final int TYPE_TV_SERIES = 1; // 0x1
   }
 
-  public static final class TvContract.Programs implements android.media.tv.TvContract.BaseProgramColumns {
+  public static final class TvContract.Programs 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_BROADCAST_GENRE = "broadcast_genre";
+    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_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    field public static final java.lang.String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
     field public static final deprecated java.lang.String COLUMN_EPISODE_NUMBER = "episode_number";
+    field public static final java.lang.String COLUMN_EPISODE_TITLE = "episode_title";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
     field public static final deprecated java.lang.String COLUMN_SEASON_NUMBER = "season_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
     field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
     field public static final android.net.Uri CONTENT_URI;
@@ -24877,28 +24894,122 @@
     field public static final java.lang.String TRAVEL = "TRAVEL";
   }
 
-  public static final class TvContract.RecordedPrograms implements android.media.tv.TvContract.BaseProgramColumns {
+  public static final class TvContract.RecordedPrograms 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_BROADCAST_GENRE = "broadcast_genre";
+    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_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+    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";
     field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
+    field public static final java.lang.String COLUMN_POSTER_ART_URI = "poster_art_uri";
     field public static final java.lang.String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
     field public static final java.lang.String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
     field public static final java.lang.String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
     field public static final java.lang.String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS = "recording_expire_time_utc_millis";
+    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
     field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+    field public static final java.lang.String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
     field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
     field public static final android.net.Uri CONTENT_URI;
   }
 
-  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BasePreviewProgramColumns {
+  public static final class TvContract.WatchNextPrograms implements android.media.tv.TvContract.BaseTvColumns {
     ctor public TvContract.WatchNextPrograms();
+    field public static final int ASPECT_RATIO_16_9 = 0; // 0x0
+    field public static final int ASPECT_RATIO_1_1 = 2; // 0x2
+    field public static final int ASPECT_RATIO_2_3 = 3; // 0x3
+    field public static final int ASPECT_RATIO_3_2 = 1; // 0x1
+    field public static final int AVAILABILITY_AVAILABLE = 0; // 0x0
+    field public static final int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1; // 0x1
+    field public static final int AVAILABILITY_PAID_CONTENT = 2; // 0x2
+    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
+    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_CANONICAL_GENRE = "canonical_genre";
+    field public static final java.lang.String COLUMN_CONTENT_ID = "content_id";
+    field public static final java.lang.String COLUMN_CONTENT_RATING = "content_rating";
+    field public static final java.lang.String COLUMN_DURATION_MILLIS = "duration_millis";
+    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";
+    field public static final java.lang.String COLUMN_INTENT_URI = "intent_uri";
+    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_DATA = "internal_provider_data";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+    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_ENGAGEMENT_TIME_UTC_MILLIS = "last_engagement_time_utc_millis";
+    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_LONG_DESCRIPTION = "long_description";
+    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_POSTER_ART_URI = "poster_art_uri";
+    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_SEARCHABLE = "searchable";
+    field public static final java.lang.String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+    field public static final java.lang.String COLUMN_SEASON_TITLE = "season_title";
+    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
+    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_THUMBNAIL_URI = "thumbnail_uri";
+    field public static final java.lang.String COLUMN_TITLE = "title";
+    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_VERSION_NUMBER = "version_number";
+    field public static final java.lang.String COLUMN_VIDEO_HEIGHT = "video_height";
+    field public static final java.lang.String COLUMN_VIDEO_WIDTH = "video_width";
     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 int INTERACTION_TYPE_FANS = 3; // 0x3
+    field public static final int INTERACTION_TYPE_FOLLOWERS = 2; // 0x2
+    field public static final int INTERACTION_TYPE_LIKES = 4; // 0x4
+    field public static final int INTERACTION_TYPE_LISTENS = 1; // 0x1
+    field public static final int INTERACTION_TYPE_THUMBS = 5; // 0x5
+    field public static final int INTERACTION_TYPE_VIEWERS = 6; // 0x6
+    field public static final int INTERACTION_TYPE_VIEWS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_PERCENTAGE = 2; // 0x2
+    field public static final int REVIEW_RATING_STYLE_STARS = 0; // 0x0
+    field public static final int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1; // 0x1
+    field public static final int TYPE_ALBUM = 8; // 0x8
+    field public static final int TYPE_ARTIST = 9; // 0x9
+    field public static final int TYPE_CHANNEL = 6; // 0x6
+    field public static final int TYPE_CLIP = 4; // 0x4
+    field public static final int TYPE_EVENT = 5; // 0x5
+    field public static final int TYPE_MOVIE = 0; // 0x0
+    field public static final int TYPE_PLAYLIST = 10; // 0xa
+    field public static final int TYPE_STATION = 11; // 0xb
+    field public static final int TYPE_TRACK = 7; // 0x7
+    field public static final int TYPE_TV_EPISODE = 3; // 0x3
+    field public static final int TYPE_TV_SEASON = 2; // 0x2
+    field public static final int TYPE_TV_SERIES = 1; // 0x1
     field public static final int WATCH_NEXT_TYPE_CONTINUE = 0; // 0x0
     field public static final int WATCH_NEXT_TYPE_NEW = 2; // 0x2
     field public static final int WATCH_NEXT_TYPE_NEXT = 1; // 0x1
@@ -34550,14 +34661,15 @@
 
   public static final class FontsContract.Columns implements android.provider.BaseColumns {
     ctor public FontsContract.Columns();
+    field public static final java.lang.String ITALIC = "font_italic";
     field public static final java.lang.String RESULT_CODE = "result_code";
     field public static final int RESULT_CODE_FONT_NOT_FOUND = 1; // 0x1
     field public static final int RESULT_CODE_FONT_UNAVAILABLE = 2; // 0x2
     field public static final int RESULT_CODE_MALFORMED_QUERY = 3; // 0x3
     field public static final int RESULT_CODE_OK = 0; // 0x0
-    field public static final java.lang.String STYLE = "font_style";
     field public static final java.lang.String TTC_INDEX = "font_ttc_index";
     field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings";
+    field public static final java.lang.String WEIGHT = "font_weight";
   }
 
   public final deprecated class LiveFolders implements android.provider.BaseColumns {
@@ -37098,7 +37210,7 @@
     ctor public FillResponse.Builder();
     method public android.service.autofill.FillResponse.Builder addDataset(android.service.autofill.Dataset);
     method public android.service.autofill.FillResponse build();
-    method public android.service.autofill.FillResponse.Builder setAuthentication(android.content.IntentSender, android.widget.RemoteViews);
+    method public android.service.autofill.FillResponse.Builder setAuthentication(android.view.autofill.AutofillId[], android.content.IntentSender, android.widget.RemoteViews);
     method public android.service.autofill.FillResponse.Builder setExtras(android.os.Bundle);
     method public android.service.autofill.FillResponse.Builder setSaveInfo(android.service.autofill.SaveInfo);
   }
@@ -38843,6 +38955,7 @@
     method public java.lang.String getCallerDisplayName();
     method public int getCallerDisplayNamePresentation();
     method public final long getConnectTimeMillis();
+    method public long getCreationTimeMillis();
     method public android.telecom.DisconnectCause getDisconnectCause();
     method public android.os.Bundle getExtras();
     method public android.telecom.GatewayInfo getGatewayInfo();
@@ -41420,6 +41533,8 @@
     field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2
     field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0
     field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1
+    field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0
   }
 
   public static final class Layout.Alignment extends java.lang.Enum {
@@ -41621,7 +41736,7 @@
     method public android.text.StaticLayout.Builder setHyphenationFrequency(int);
     method public android.text.StaticLayout.Builder setIncludePad(boolean);
     method public android.text.StaticLayout.Builder setIndents(int[], int[]);
-    method public android.text.StaticLayout.Builder setJustify(boolean);
+    method public android.text.StaticLayout.Builder setJustificationMode(int);
     method public android.text.StaticLayout.Builder setLineSpacing(float, float);
     method public android.text.StaticLayout.Builder setMaxLines(int);
     method public android.text.StaticLayout.Builder setText(java.lang.CharSequence);
@@ -46874,7 +46989,7 @@
     method public void clearFlags(int);
     method public abstract void closeAllPanels();
     method public abstract void closePanel(int);
-    method public android.view.View findViewById(int);
+    method public <T extends android.view.View> T findViewById(int);
     method public boolean getAllowEnterTransitionOverlap();
     method public boolean getAllowReturnTransitionOverlap();
     method public final android.view.WindowManager.LayoutParams getAttributes();
@@ -49001,7 +49116,7 @@
     method public abstract boolean getOffscreenPreRaster();
     method public abstract deprecated android.webkit.WebSettings.PluginState getPluginState();
     method public abstract java.lang.String getSansSerifFontFamily();
-    method public abstract boolean getSaveFormData();
+    method public abstract deprecated boolean getSaveFormData();
     method public abstract deprecated boolean getSavePassword();
     method public abstract java.lang.String getSerifFontFamily();
     method public abstract java.lang.String getStandardFontFamily();
@@ -49050,7 +49165,7 @@
     method public abstract deprecated void setPluginState(android.webkit.WebSettings.PluginState);
     method public abstract deprecated void setRenderPriority(android.webkit.WebSettings.RenderPriority);
     method public abstract void setSansSerifFontFamily(java.lang.String);
-    method public abstract void setSaveFormData(boolean);
+    method public abstract deprecated void setSaveFormData(boolean);
     method public abstract deprecated void setSavePassword(boolean);
     method public abstract void setSerifFontFamily(java.lang.String);
     method public abstract void setStandardFontFamily(java.lang.String);
@@ -49341,12 +49456,12 @@
 
   public abstract class WebViewDatabase {
     ctor public WebViewDatabase();
-    method public abstract void clearFormData();
+    method public abstract deprecated void clearFormData();
     method public abstract void clearHttpAuthUsernamePassword();
     method public abstract deprecated void clearUsernamePassword();
     method public abstract java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String);
     method public static android.webkit.WebViewDatabase getInstance(android.content.Context);
-    method public abstract boolean hasFormData();
+    method public abstract deprecated boolean hasFormData();
     method public abstract boolean hasHttpAuthUsernamePassword();
     method public abstract deprecated boolean hasUsernamePassword();
     method public abstract void setHttpAuthUsernamePassword(java.lang.String, java.lang.String, java.lang.String, java.lang.String);
@@ -51614,7 +51729,7 @@
     method public boolean getIncludeFontPadding();
     method public android.os.Bundle getInputExtras(boolean);
     method public int getInputType();
-    method public boolean getJustify();
+    method public int getJustificationMode();
     method public final android.text.method.KeyListener getKeyListener();
     method public final android.text.Layout getLayout();
     method public float getLetterSpacing();
@@ -51727,7 +51842,7 @@
     method public void setIncludeFontPadding(boolean);
     method public void setInputExtras(int) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
     method public void setInputType(int);
-    method public void setJustify(boolean);
+    method public void setJustificationMode(int);
     method public void setKeyListener(android.text.method.KeyListener);
     method public void setLetterSpacing(float);
     method public void setLineSpacing(float, float);
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 42b2ae6..d20c08c 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -296,6 +296,10 @@
     field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
   }
 
+  public static final class FontsContract.Columns implements android.provider.BaseColumns {
+    field public static final java.lang.String STYLE = "font_style";
+  }
+
   public static final class Settings.Global extends android.provider.Settings.NameValueTable {
     field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
   }
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 2435ffa..7394490 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -370,7 +370,8 @@
 
 bool BootAnimation::android()
 {
-    ALOGD("BootAnimationShownTiming start time: %" PRId64 "ms", elapsedRealtime());
+    ALOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
+            elapsedRealtime());
     initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
     initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
 
@@ -896,7 +897,8 @@
     const int animationX = (mWidth - animation.width) / 2;
     const int animationY = (mHeight - animation.height) / 2;
 
-    ALOGD("BootAnimationShownTiming start time: %" PRId64 "ms", elapsedRealtime());
+    ALOGD("%sAnimationShownTiming start time: %" PRId64 "ms", mShuttingDown ? "Shutdown" : "Boot",
+            elapsedRealtime());
     for (size_t i=0 ; i<pcount ; i++) {
         const Animation::Part& part(animation.parts[i]);
         const size_t fcount = part.frames.size();
diff --git a/core/java/android/accounts/ChooseTypeAndAccountActivity.java b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
index 35011b5..8442585 100644
--- a/core/java/android/accounts/ChooseTypeAndAccountActivity.java
+++ b/core/java/android/accounts/ChooseTypeAndAccountActivity.java
@@ -40,8 +40,8 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 
@@ -98,11 +98,10 @@
             "alwaysPromptForAccount";
 
     /**
-     * If set then this string willb e used as the description rather than
+     * If set then this string will be used as the description rather than
      * the default.
      */
-    public static final String EXTRA_DESCRIPTION_TEXT_OVERRIDE =
-            "descriptionTextOverride";
+    public static final String EXTRA_DESCRIPTION_TEXT_OVERRIDE = "descriptionTextOverride";
 
     public static final int REQUEST_NULL = 0;
     public static final int REQUEST_CHOOSE_TYPE = 1;
@@ -112,7 +111,8 @@
     private static final String KEY_INSTANCE_STATE_EXISTING_ACCOUNTS = "existingAccounts";
     private static final String KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME = "selectedAccountName";
     private static final String KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT = "selectedAddAccount";
-    private static final String KEY_INSTANCE_STATE_ACCOUNT_LIST = "accountAndVisibilityList";
+    private static final String KEY_INSTANCE_STATE_ACCOUNTS_LIST = "accountsList";
+    private static final String KEY_INSTANCE_STATE_VISIBILITY_LIST = "visibilityList";
 
     private static final int SELECTED_ITEM_NONE = -1;
 
@@ -122,7 +122,7 @@
     private boolean mSelectedAddNewAccount = false;
     private String mDescriptionOverride;
 
-    private Map<Account, Integer> mAccounts;
+    private LinkedHashMap<Account, Integer> mAccounts;
     // TODO Redesign flow to show NOT_VISIBLE accounts
     // and display a warning if they are selected.
     // Currently NOT_VISBILE accounts are not shown at all.
@@ -164,6 +164,10 @@
         // save some items we use frequently
         final Intent intent = getIntent();
 
+        mSetOfAllowableAccounts = getAllowableAccountSet(intent);
+        mSetOfRelevantAccountTypes = getReleventAccountTypes(intent);
+        mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
+
         if (savedInstanceState != null) {
             mPendingRequest = savedInstanceState.getInt(KEY_INSTANCE_STATE_PENDING_REQUEST);
             mExistingAccounts =
@@ -174,8 +178,15 @@
                     savedInstanceState.getString(KEY_INSTANCE_STATE_SELECTED_ACCOUNT_NAME);
             mSelectedAddNewAccount =
                     savedInstanceState.getBoolean(KEY_INSTANCE_STATE_SELECTED_ADD_ACCOUNT, false);
-            mAccounts = (Map<Account, Integer>) savedInstanceState
-                    .getSerializable(KEY_INSTANCE_STATE_ACCOUNT_LIST);
+            // restore mAccounts
+            Parcelable[] accounts =
+                savedInstanceState.getParcelableArray(KEY_INSTANCE_STATE_ACCOUNTS_LIST);
+            ArrayList<Integer> visibility =
+                savedInstanceState.getIntegerArrayList(KEY_INSTANCE_STATE_VISIBILITY_LIST);
+            mAccounts = new LinkedHashMap<>();
+            for (int i = 0; i < accounts.length; i++) {
+                mAccounts.put((Account) accounts[i], visibility.get(i));
+            }
         } else {
             mPendingRequest = REQUEST_NULL;
             mExistingAccounts = null;
@@ -185,20 +196,21 @@
             if (selectedAccount != null) {
                 mSelectedAccountName = selectedAccount.name;
             }
+            mAccounts = getAcceptableAccountChoices(AccountManager.get(this));
         }
 
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "selected account name is " + mSelectedAccountName);
         }
 
+        mPossiblyVisibleAccounts = new ArrayList<>(mAccounts.size());
+        for (Map.Entry<Account, Integer> entry : mAccounts.entrySet()) {
+            if (AccountManager.VISIBILITY_NOT_VISIBLE != entry.getValue()) {
+                mPossiblyVisibleAccounts.add(entry.getKey());
+            }
+        }
 
-        mSetOfAllowableAccounts = getAllowableAccountSet(intent);
-        mSetOfRelevantAccountTypes = getReleventAccountTypes(intent);
-        mDescriptionOverride = intent.getStringExtra(EXTRA_DESCRIPTION_TEXT_OVERRIDE);
-
-        mAccounts = getAcceptableAccountChoices(AccountManager.get(this));
-        if (mAccounts.isEmpty()
-                && mDisallowAddAccounts) {
+        if (mPossiblyVisibleAccounts.isEmpty() && mDisallowAddAccounts) {
             requestWindowFeature(Window.FEATURE_NO_TITLE);
             setContentView(R.layout.app_not_authorized);
             mDontShowPicker = true;
@@ -216,7 +228,7 @@
         if (mPendingRequest == REQUEST_NULL) {
             // If there are no relevant accounts and only one relevant account type go directly to
             // add account. Otherwise let the user choose.
-            if (mAccounts.isEmpty()) {
+            if (mPossiblyVisibleAccounts.isEmpty()) {
                 setNonLabelThemeAndCallSuperCreate(savedInstanceState);
                 if (mSetOfRelevantAccountTypes.size() == 1) {
                     runAddAccountForAuthenticator(mSetOfRelevantAccountTypes.iterator().next());
@@ -226,12 +238,6 @@
             }
         }
 
-        mPossiblyVisibleAccounts = new ArrayList<>(mAccounts.size());
-        for (Map.Entry<Account, Integer> entry : mAccounts.entrySet()) {
-            if (AccountManager.VISIBILITY_NOT_VISIBLE != entry.getValue()) {
-                mPossiblyVisibleAccounts.add(entry.getKey());
-            }
-        }
         String[] listItems = getListOfDisplayableOptions(mPossiblyVisibleAccounts);
         mSelectedItemIndex = getItemIndexToSelect(mPossiblyVisibleAccounts, mSelectedAccountName,
                 mSelectedAddNewAccount);
@@ -270,10 +276,16 @@
                         mPossiblyVisibleAccounts.get(mSelectedItemIndex).name);
             }
         }
-        // should be HashMap by default.
-        HashMap<Account, Integer> accountsHashMap = (mAccounts instanceof HashMap)
-                ? (HashMap) mAccounts : new HashMap<Account, Integer>(mAccounts);
-        outState.putSerializable(KEY_INSTANCE_STATE_ACCOUNT_LIST, accountsHashMap);
+        // save mAccounts
+        Parcelable[] accounts = new Parcelable[mAccounts.size()];
+        ArrayList<Integer> visibility = new ArrayList<>(mAccounts.size());
+        int i = 0;
+        for (Map.Entry<Account, Integer> e : mAccounts.entrySet()) {
+            accounts[i++] = e.getKey();
+            visibility.add(e.getValue());
+        }
+        outState.putParcelableArray(KEY_INSTANCE_STATE_ACCOUNTS_LIST, accounts);
+        outState.putIntegerArrayList(KEY_INSTANCE_STATE_VISIBILITY_LIST, visibility);
     }
 
     public void onCancelButtonClicked(View view) {
@@ -308,7 +320,7 @@
         if (resultCode == RESULT_CANCELED) {
             // if canceling out of addAccount and the original state caused us to skip this,
             // finish this activity
-            if (mAccounts.isEmpty()) {
+            if (mPossiblyVisibleAccounts.isEmpty()) {
                 setResult(Activity.RESULT_CANCELED);
                 finish();
             }
@@ -428,18 +440,20 @@
     private void setResultAndFinish(final String accountName, final String accountType) {
         // Mark account as visible since user chose it.
         Account account = new Account(accountName, accountType);
-        Integer oldVisibility = mAccounts.get(account);
-        // oldVisibility is null if new account was added
-        if (oldVisibility == null) {
-            Map<Account, Integer> accountsAndVisibility = AccountManager.get(this)
-                    .getAccountsAndVisibilityForPackage(mCallingPackage, null /* type */);
-            oldVisibility = accountsAndVisibility.get(account);
-        }
+        Integer oldVisibility =
+            AccountManager.get(this).getAccountVisibility(account, mCallingPackage);
         if (oldVisibility != null
                 && oldVisibility == AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE) {
             AccountManager.get(this).setAccountVisibility(account, mCallingPackage,
                     AccountManager.VISIBILITY_USER_MANAGED_VISIBLE);
         }
+
+        if (oldVisibility != null && oldVisibility == AccountManager.VISIBILITY_NOT_VISIBLE) {
+            // Added account is not visible to caller.
+            setResult(Activity.RESULT_CANCELED);
+            finish();
+            return;
+        }
         Bundle bundle = new Bundle();
         bundle.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, accountType);
@@ -448,6 +462,7 @@
             Log.v(TAG, "ChooseTypeAndAccountActivity.setResultAndFinish: selected account "
                     + accountName + ", " + accountType);
         }
+
         finish();
     }
 
@@ -509,22 +524,24 @@
      * that don't match the allowable types, if provided, or that don't match the allowable
      * accounts, if provided.
      */
-    private Map<Account, Integer> getAcceptableAccountChoices(AccountManager accountManager) {
-        Map<Account, Integer> accountsAndVisibility =
-                accountManager.getAccountsAndVisibilityForPackage(mCallingPackage, null /* type */);
-
-        Map<Account, Integer> accountsToPopulate =
-                new HashMap<Account, Integer>(accountsAndVisibility.size());
-        for (Map.Entry<Account, Integer> entry : accountsAndVisibility.entrySet()) {
+    private LinkedHashMap<Account, Integer> getAcceptableAccountChoices(AccountManager accountManager) {
+        Map<Account, Integer> accountsAndVisibilityForCaller =
+                accountManager.getAccountsAndVisibilityForPackage(mCallingPackage, null);
+        Account[] allAccounts = accountManager.getAccounts();
+        LinkedHashMap<Account, Integer> accountsToPopulate =
+                new LinkedHashMap<>(accountsAndVisibilityForCaller.size());
+        for (Account account : allAccounts) {
             if (mSetOfAllowableAccounts != null
-                    && !mSetOfAllowableAccounts.contains(entry.getKey())) {
+                    && !mSetOfAllowableAccounts.contains(account)) {
                 continue;
             }
             if (mSetOfRelevantAccountTypes != null
-                    && !mSetOfRelevantAccountTypes.contains(entry.getKey().type)) {
+                    && !mSetOfRelevantAccountTypes.contains(account.type)) {
                 continue;
             }
-            accountsToPopulate.put(entry.getKey(), entry.getValue());
+            if (accountsAndVisibilityForCaller.get(account) != null) {
+                accountsToPopulate.put(account, accountsAndVisibilityForCaller.get(account));
+            }
         }
         return accountsToPopulate;
     }
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d432160..c0505eb 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2443,13 +2443,20 @@
     }
 
     /**
-     * Finds a view that was identified by the id attribute from the XML that
-     * was processed in {@link #onCreate}.
+     * Finds a view that was identified by the {@code android:id} XML attribute
+     * that was processed in {@link #onCreate}.
+     * <p>
+     * <strong>Note:</strong> In most cases -- depending on compiler support --
+     * the resulting view is automatically cast to the target class type. If
+     * the target class type is unconstrained, an explicit cast may be
+     * necessary.
      *
-     * @return The view if found or null otherwise.
+     * @param id the ID to search for
+     * @return a view with given ID if found, or {@code null} otherwise
+     * @see View#findViewById(int)
      */
     @Nullable
-    public View findViewById(@IdRes int id) {
+    public <T extends View> T findViewById(@IdRes int id) {
         return getWindow().findViewById(id);
     }
 
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index d1d462c..7299d6b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -38,6 +38,7 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ParceledListSlice;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.AssetManager;
@@ -869,16 +870,20 @@
             sendMessage(H.UNBIND_SERVICE, s);
         }
 
-        public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-            int flags ,Intent args) {
-            ServiceArgsData s = new ServiceArgsData();
-            s.token = token;
-            s.taskRemoved = taskRemoved;
-            s.startId = startId;
-            s.flags = flags;
-            s.args = args;
+        public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
+            List<ServiceStartArgs> list = args.getList();
 
-            sendMessage(H.SERVICE_ARGS, s);
+            for (int i = 0; i < list.size(); i++) {
+                ServiceStartArgs ssa = list.get(i);
+                ServiceArgsData s = new ServiceArgsData();
+                s.token = token;
+                s.taskRemoved = ssa.taskRemoved;
+                s.startId = ssa.startId;
+                s.flags = ssa.flags;
+                s.args = ssa.args;
+
+                sendMessage(H.SERVICE_ARGS, s);
+            }
         }
 
         public final void scheduleStopService(IBinder token) {
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 72ccf72..943c572 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -498,14 +498,22 @@
     }
 
     /**
-     * Finds a child view with the given identifier. Returns null if the
-     * specified child view does not exist or the dialog has not yet been fully
-     * created (for example, via {@link #show()} or {@link #create()}).
+     * Finds the first descendant view with the given ID or {@code null} if the
+     * ID is invalid (< 0), there is no matching view in the hierarchy, or the
+     * dialog has not yet been fully created (for example, via {@link #show()}
+     * or {@link #create()}).
+     * <p>
+     * <strong>Note:</strong> In most cases -- depending on compiler support --
+     * the resulting view is automatically cast to the target class type. If
+     * the target class type is unconstrained, an explicit cast may be
+     * necessary.
      *
-     * @param id the identifier of the view to find
-     * @return The view with the given id or null.
+     * @param id the ID to search for
+     * @return a view with given ID if found, or {@code null} otherwise
+     * @see View#findViewById(int)
      */
-    public @Nullable View findViewById(@IdRes int id) {
+    @Nullable
+    public <T extends View> T findViewById(@IdRes int id) {
         return mWindow.findViewById(id);
     }
 
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 462f66f..b89c165 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.content.ContentResolver;
 import android.content.ContentUris;
@@ -321,6 +322,11 @@
      */
     public static final String EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS = "extra_click_download_ids";
 
+    /** {@hide} */
+    @SystemApi
+    public static final String ACTION_DOWNLOAD_COMPLETED =
+            "android.intent.action.DOWNLOAD_COMPLETED";
+
     /**
      * columns to request from DownloadProvider.
      * @hide
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index 3102a93..a3c123f 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -2608,6 +2608,12 @@
         }
     }
 
+    void noteStateNotSaved() {
+        if (mChildFragmentManager != null) {
+            mChildFragmentManager.noteStateNotSaved();
+        }
+    }
+
     @Deprecated
     void performMultiWindowModeChanged(boolean isInMultiWindowMode) {
         onMultiWindowModeChanged(isInMultiWindowMode);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 279b900..3107453 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1128,8 +1128,13 @@
             newState = Fragment.CREATED;
         }
         if (f.mRemoving && newState > f.mState) {
-            // While removing a fragment, we can't change it to a higher state.
-            newState = f.mState;
+            if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) {
+                // Allow the fragment to be created so that it can be saved later.
+                newState = Fragment.CREATED;
+            } else {
+                // While removing a fragment, we can't change it to a higher state.
+                newState = f.mState;
+            }
         }
         // Defer start if requested; don't allow it to move to STARTED or higher
         // if it's not already started.
@@ -2888,8 +2893,15 @@
 
     public void noteStateNotSaved() {
         mStateSaved = false;
+        final int addedCount = mAdded == null ? 0 : mAdded.size();
+        for (int i = 0; i < addedCount; i++) {
+            Fragment fragment = mAdded.get(i);
+            if (fragment != null) {
+                fragment.noteStateNotSaved();
+            }
+        }
     }
-    
+
     public void dispatchCreate() {
         mStateSaved = false;
         dispatchMoveToState(Fragment.CREATED);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index f4d26fd..079bbcd 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -635,6 +635,11 @@
      */
     int getLastResumedActivityUserId();
 
+    /**
+     * Add a bare uid to the background restrictions whitelist.  Only the system uid may call this.
+     */
+     void backgroundWhitelistUid(int uid);
+
     // WARNING: when these transactions are updated, check if they are any callers on the native
     // side. If so, make sure they are using the correct transaction ids and arguments.
     // If a transaction which will also be used on the native side is being inserted, add it
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index 6c43fe3..1b3c00b 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -25,6 +25,7 @@
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.ParceledListSlice;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.CompatibilityInfo;
@@ -86,8 +87,7 @@
             in Bundle coreSettings, in String buildSerial);
     void scheduleExit();
     void scheduleConfigurationChanged(in Configuration config);
-    void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
-            int flags, in Intent args);
+    void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
     void updateTimeZone();
     void processInBackground();
     void scheduleBindService(IBinder token,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 3d66135..161dd25 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3793,9 +3793,9 @@
                 // Ambient view does not have these
                 bindHeaderText(contentView);
                 bindHeaderChronometerAndTime(contentView);
-                bindExpandButton(contentView);
                 bindProfileBadge(contentView);
             }
+            bindExpandButton(contentView);
         }
 
         private void bindExpandButton(RemoteViews contentView) {
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 489a0f0..d620a81 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -945,7 +945,7 @@
                 final ResourcesKey key = mResourceImpls.keyAt(i);
                 final WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i);
                 final ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null;
-                if (impl != null && key.mResDir.equals(assetPath)) {
+                if (impl != null && Objects.equals(key.mResDir, assetPath)) {
                     if (!ArrayUtils.contains(key.mLibDirs, libAsset)) {
                         final int newLibAssetCount = 1 +
                                 (key.mLibDirs != null ? key.mLibDirs.length : 0);
diff --git a/core/java/android/service/autofill/AutoFillService.java b/core/java/android/app/ServiceStartArgs.aidl
similarity index 68%
rename from core/java/android/service/autofill/AutoFillService.java
rename to core/java/android/app/ServiceStartArgs.aidl
index c26f679..fd2cf0f 100644
--- a/core/java/android/service/autofill/AutoFillService.java
+++ b/core/java/android/app/ServiceStartArgs.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * 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.
@@ -13,12 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.service.autofill;
 
-/**
- * @hide
- * @deprecated TODO(b/35956626): remove once clients use AutofillService
- */
-@Deprecated
-public abstract class AutoFillService extends AutofillService {
-}
+package android.app;
+
+/** @hide */
+parcelable ServiceStartArgs;
diff --git a/core/java/android/app/ServiceStartArgs.java b/core/java/android/app/ServiceStartArgs.java
new file mode 100644
index 0000000..f030cba
--- /dev/null
+++ b/core/java/android/app/ServiceStartArgs.java
@@ -0,0 +1,82 @@
+/*
+ * 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.app;
+
+import android.content.Intent;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Describes a Service.onStartCommand() request from the system.
+ * @hide
+ */
+public class ServiceStartArgs implements Parcelable {
+    final public boolean taskRemoved;
+    final public int startId;
+    final public int flags;
+    final public Intent args;
+
+    public ServiceStartArgs(boolean _taskRemoved, int _startId, int _flags, Intent _args) {
+        taskRemoved = _taskRemoved;
+        startId = _startId;
+        flags = _flags;
+        args = _args;
+    }
+
+    public String toString() {
+        return "ServiceStartArgs{taskRemoved=" + taskRemoved + ", startId=" + startId
+                + ", flags=0x" + Integer.toHexString(flags) + ", args=" + args + "}";
+    }
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeInt(taskRemoved ? 1 : 0);
+        out.writeInt(startId);
+        out.writeInt(flags);
+        if (args != null) {
+            out.writeInt(1);
+            args.writeToParcel(out, 0);
+        } else {
+            out.writeInt(0);
+        }
+    }
+
+    public static final Parcelable.Creator<ServiceStartArgs> CREATOR
+            = new Parcelable.Creator<ServiceStartArgs>() {
+        public ServiceStartArgs createFromParcel(Parcel in) {
+            return new ServiceStartArgs(in);
+        }
+
+        public ServiceStartArgs[] newArray(int size) {
+            return new ServiceStartArgs[size];
+        }
+    };
+
+    public ServiceStartArgs(Parcel in) {
+        taskRemoved = in.readInt() != 0;
+        startId = in.readInt();
+        flags = in.readInt();
+        if (in.readInt() != 0) {
+            args = Intent.CREATOR.createFromParcel(in);
+        } else {
+            args = null;
+        }
+    }
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 2f0a630..82ad825 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -697,8 +697,8 @@
             "android.app.extra.PROVISIONING_ORGANIZATION_NAME";
 
     /**
-     * A String extra holding a url to the website of the device's provider. The website can be
-     * opened in a browser during provisioning.
+     * A String extra holding a url to the website of the device provider so the user can open it
+     * during provisioning. If the url is not HTTPS, an error will be shown.
      *
      * <p>Use in an intent with action {@link #ACTION_PROVISION_MANAGED_DEVICE_FROM_TRUSTED_SOURCE}
      *
@@ -2768,9 +2768,11 @@
      * or clears the lockscreen password.
      * <p>
      * <em>This token is highly sensitive and should be treated at the same level as user
-     * credentials. In particular, NEVER store this token on device in plaintext, especially in
-     * Device-Encrypted storage if the token will be used to reset password on FBE devices before
-     * user unlocks.
+     * credentials. In particular, NEVER store this token on device in plaintext. Do not store
+     * the plaintext token in device-encrypted storage if it will be needed to reset password on
+     * file-based encryption devices before user unlocks. Consider carefully how any password token
+     * will be stored on your server and who will need access to them. Tokens may be the subject of
+     * legal access requests.
      * </em>
      *
      * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index 7d2db5c..fe51633 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -27,9 +27,6 @@
 import android.view.ViewStructure.HtmlInfo.Builder;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillType;
-import android.view.autofill.AutoFillValue;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 
@@ -920,15 +917,6 @@
         }
 
         /**
-         * @hide
-         * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
-         */
-        @Deprecated
-        public AutoFillId getAutoFillId() {
-            return AutoFillId.forDaRealId(mAutofillId);
-        }
-
-        /**
          * Gets the id that can be used to autofill the view contents.
          *
          * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
@@ -939,26 +927,6 @@
         }
 
         /**
-         * @hide
-         * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype()
-         */
-        @Deprecated
-        public AutoFillType getAutoFillType() {
-            switch (getAutofillType()) {
-                case View.AUTOFILL_TYPE_TEXT:
-                    return AutoFillType.forText();
-                case View.AUTOFILL_TYPE_TOGGLE:
-                    return AutoFillType.forToggle();
-                case View.AUTOFILL_TYPE_LIST:
-                    return AutoFillType.forList();
-                case View.AUTOFILL_TYPE_DATE:
-                    return AutoFillType.forDate();
-                default:
-                    return null;
-            }
-        }
-
-        /**
          * Gets the the type of value that can be used to autofill the view contents.
          *
          * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
@@ -982,15 +950,6 @@
         }
 
         /**
-         * @hide
-         * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
-         */
-        @Deprecated
-        public AutoFillValue getAutoFillValue() {
-            return AutoFillValue.forDaRealValue(mAutofillValue);
-        }
-
-        /**
          * Gets the the value of this view.
          *
          * <p>It's only set when the {@link AssistStructure} is used for autofilling purposes, not
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
index 74a39e8..9f35e85 100644
--- a/core/java/android/appwidget/AppWidgetManager.java
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -710,9 +710,9 @@
      * user may have a corporate profile. In this case the parent user profile has a
      * child profile, the corporate one.
      *
-     * @param profile The profile for which to get providers. Passing null is equivaled
-     *         to passing only the current user handle.
-     * @return The intalled providers.
+     * @param profile The profile for which to get providers. Passing null is equivalent
+     *        to querying for only the calling user.
+     * @return The installed providers.
      *
      * @see android.os.Process#myUserHandle()
      * @see android.os.UserManager#getUserProfiles()
@@ -722,7 +722,31 @@
             return Collections.emptyList();
         }
         return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
-                profile);
+                profile, null);
+    }
+
+    /**
+     * Gets the AppWidget providers for the given package and user profile. User
+     * profile can only be the current user or a profile of the current user. For
+     * example, the current user may have a corporate profile. In this case the
+     * parent user profile has a child profile, the corporate one.
+     *
+     * @param packageName The package for which to get providers. If null, this method is
+     *        equivalent to {@link #getInstalledProvidersForProfile(UserHandle)}.
+     * @param profile The profile for which to get providers. Passing null is equivalent
+     *        to querying for only the calling user.
+     * @return The installed providers.
+     *
+     * @see android.os.Process#myUserHandle()
+     * @see android.os.UserManager#getUserProfiles()
+     */
+    public List<AppWidgetProviderInfo> getInstalledProvidersForPackage(@Nullable String packageName,
+            @Nullable UserHandle profile) {
+        if (mService == null) {
+            return Collections.emptyList();
+        }
+        return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
+                profile, packageName);
     }
 
     /**
@@ -733,7 +757,7 @@
             return Collections.emptyList();
         }
         return getInstalledProvidersForProfile(AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
-                null);
+                null, null);
     }
 
     /**
@@ -752,7 +776,7 @@
         if (mService == null) {
             return Collections.emptyList();
         }
-        return getInstalledProvidersForProfile(categoryFilter, null);
+        return getInstalledProvidersForProfile(categoryFilter, null, null);
     }
 
     /**
@@ -766,6 +790,7 @@
      * @param profile A profile of the current user which to be queried. The user
      *        is itself also a profile. If null, the providers only for the current user
      *        are returned.
+     * @param packageName If specified, will only return providers from the given package.
      * @return The intalled providers.
      *
      * @see android.os.Process#myUserHandle()
@@ -774,7 +799,7 @@
      * @hide
      */
     public List<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
-            UserHandle profile) {
+            @Nullable UserHandle profile, @Nullable String packageName) {
         if (mService == null) {
             return Collections.emptyList();
         }
@@ -785,7 +810,7 @@
 
         try {
             ParceledListSlice<AppWidgetProviderInfo> providers = mService.getInstalledProvidersForProfile(
-                    categoryFilter, profile.getIdentifier());
+                    categoryFilter, profile.getIdentifier(), packageName);
             if (providers == null) {
                 return Collections.emptyList();
             }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index da887af..5415eb5 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1505,22 +1505,38 @@
     public static final String ACTION_INSTALL_PACKAGE = "android.intent.action.INSTALL_PACKAGE";
 
     /**
-     * Activity Action: Launch ephemeral installer.
-     * <p>
-     * Input: The data must be a http: URI that the ephemeral application is registered
-     * to handle.
+     * @hide
+     * @deprecated Do not use. This will go away.
+     *     Replace with {@link #ACTION_INSTALL_INSTANT_APP_PACKAGE}.
+     */
+    @SystemApi
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_INSTALL_EPHEMERAL_PACKAGE
+            = "android.intent.action.INSTALL_EPHEMERAL_PACKAGE";
+    /**
+     * Activity Action: Launch instant application installer.
      * <p class="note">
      * This is a protected intent that can only be sent by the system.
      * </p>
      *
      * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_INSTALL_EPHEMERAL_PACKAGE
-            = "android.intent.action.INSTALL_EPHEMERAL_PACKAGE";
+    public static final String ACTION_INSTALL_INSTANT_APP_PACKAGE
+            = "android.intent.action.INSTALL_INSTANT_APP_PACKAGE";
 
     /**
-     * Service Action: Resolve ephemeral application.
+     * @hide
+     * @deprecated Do not use. This will go away.
+     *     Replace with {@link #ACTION_RESOLVE_INSTANT_APP_PACKAGE}.
+     */
+    @SystemApi
+    @SdkConstant(SdkConstantType.SERVICE_ACTION)
+    public static final String ACTION_RESOLVE_EPHEMERAL_PACKAGE
+            = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE";
+    /**
+     * Service Action: Resolve instant application.
      * <p>
      * The system will have a persistent connection to this service.
      * This is a protected intent that can only be sent by the system.
@@ -1528,12 +1544,22 @@
      *
      * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String ACTION_RESOLVE_EPHEMERAL_PACKAGE
-            = "android.intent.action.RESOLVE_EPHEMERAL_PACKAGE";
+    public static final String ACTION_RESOLVE_INSTANT_APP_PACKAGE
+            = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE";
 
     /**
-     * Activity Action: Launch ephemeral settings.
+     * @hide
+     * @deprecated Do not use. This will go away.
+     *     Replace with {@link #ACTION_INSTANT_APP_RESOLVER_SETTINGS}.
+     */
+    @SystemApi
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_EPHEMERAL_RESOLVER_SETTINGS
+            = "android.intent.action.EPHEMERAL_RESOLVER_SETTINGS";
+    /**
+     * Activity Action: Launch instant app settings.
      *
      * <p class="note">
      * This is a protected intent that can only be sent by the system.
@@ -1541,9 +1567,10 @@
      *
      * @hide
      */
+    @SystemApi
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
-    public static final String ACTION_EPHEMERAL_RESOLVER_SETTINGS
-            = "android.intent.action.EPHEMERAL_RESOLVER_SETTINGS";
+    public static final String ACTION_INSTANT_APP_RESOLVER_SETTINGS
+            = "android.intent.action.INSTANT_APP_RESOLVER_SETTINGS";
 
     /**
      * Used as a string extra field with {@link #ACTION_INSTALL_PACKAGE} to install a
@@ -3479,6 +3506,261 @@
     public static final String ACTION_SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
 
     /**
+     * Broadcast Action: indicate that the phone service state has changed.
+     * The intent will have the following extra values:</p>
+     * <p>
+     * @see #EXTRA_VOICE_REG_STATE
+     * @see #EXTRA_DATA_REG_STATE
+     * @see #EXTRA_VOICE_ROAMING_TYPE
+     * @see #EXTRA_DATA_ROAMING_TYPE
+     * @see #EXTRA_OPERATOR_ALPHA_LONG
+     * @see #EXTRA_OPERATOR_ALPHA_SHORT
+     * @see #EXTRA_OPERATOR_NUMERIC
+     * @see #EXTRA_DATA_OPERATOR_ALPHA_LONG
+     * @see #EXTRA_DATA_OPERATOR_ALPHA_SHORT
+     * @see #EXTRA_DATA_OPERATOR_NUMERIC
+     * @see #EXTRA_MANUAL
+     * @see #EXTRA_VOICE_RADIO_TECH
+     * @see #EXTRA_DATA_RADIO_TECH
+     * @see #EXTRA_CSS_INDICATOR
+     * @see #EXTRA_NETWORK_ID
+     * @see #EXTRA_SYSTEM_ID
+     * @see #EXTRA_CDMA_ROAMING_INDICATOR
+     * @see #EXTRA_CDMA_DEFAULT_ROAMING_INDICATOR
+     * @see #EXTRA_EMERGENCY_ONLY
+     * @see #EXTRA_IS_DATA_ROAMING_FROM_REGISTRATION
+     * @see #EXTRA_IS_USING_CARRIER_AGGREGATION
+     * @see #EXTRA_LTE_EARFCN_RSRP_BOOST
+     *
+     * <p class="note">
+     * Requires the READ_PHONE_STATE permission.
+     *
+     * <p class="note">This is a protected intent that can only be sent by the system.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SERVICE_STATE = "android.intent.action.SERVICE_STATE";
+
+    /**
+     * An int extra used with {@link #ACTION_SERVICE_STATE} which indicates voice registration
+     * state.
+     * @see android.telephony.ServiceState#STATE_EMERGENCY_ONLY
+     * @see android.telephony.ServiceState#STATE_IN_SERVICE
+     * @see android.telephony.ServiceState#STATE_OUT_OF_SERVICE
+     * @see android.telephony.ServiceState#STATE_POWER_OFF
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_VOICE_REG_STATE = "voiceRegState";
+
+    /**
+     * An int extra used with {@link #ACTION_SERVICE_STATE} which indicates data registration state.
+     * @see android.telephony.ServiceState#STATE_EMERGENCY_ONLY
+     * @see android.telephony.ServiceState#STATE_IN_SERVICE
+     * @see android.telephony.ServiceState#STATE_OUT_OF_SERVICE
+     * @see android.telephony.ServiceState#STATE_POWER_OFF
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_DATA_REG_STATE = "dataRegState";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} which indicates the voice roaming
+     * type.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_VOICE_ROAMING_TYPE = "voiceRoamingType";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} which indicates the data roaming
+     * type.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_DATA_ROAMING_TYPE = "dataRoamingType";
+
+    /**
+     * A string extra used with {@link #ACTION_SERVICE_STATE} which represents the current
+     * registered voice operator name in long alphanumeric format.
+     * {@code null} if the operator name is not known or unregistered.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_OPERATOR_ALPHA_LONG = "operator-alpha-long";
+
+    /**
+     * A string extra used with {@link #ACTION_SERVICE_STATE} which represents the current
+     * registered voice operator name in short alphanumeric format.
+     * {@code null} if the operator name is not known or unregistered.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_OPERATOR_ALPHA_SHORT = "operator-alpha-short";
+
+    /**
+     * A string extra used with {@link #ACTION_SERVICE_STATE} containing the MCC
+     * (Mobile Country Code, 3 digits) and MNC (Mobile Network code, 2-3 digits) for the mobile
+     * network.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_OPERATOR_NUMERIC = "operator-numeric";
+
+    /**
+     * A string extra used with {@link #ACTION_SERVICE_STATE} which represents the current
+     * registered data operator name in long alphanumeric format.
+     * {@code null} if the operator name is not known or unregistered.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_DATA_OPERATOR_ALPHA_LONG = "data-operator-alpha-long";
+
+    /**
+     * A string extra used with {@link #ACTION_SERVICE_STATE} which represents the current
+     * registered data operator name in short alphanumeric format.
+     * {@code null} if the operator name is not known or unregistered.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_DATA_OPERATOR_ALPHA_SHORT = "data-operator-alpha-short";
+
+    /**
+     * A string extra used with {@link #ACTION_SERVICE_STATE} containing the MCC
+     * (Mobile Country Code, 3 digits) and MNC (Mobile Network code, 2-3 digits) for the
+     * data operator.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_DATA_OPERATOR_NUMERIC = "data-operator-numeric";
+
+    /**
+     * A boolean extra used with {@link #ACTION_SERVICE_STATE} which indicates whether the current
+     * network selection mode is manual.
+     * Will be {@code true} if manual mode, {@code false} if automatic mode.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_MANUAL = "manual";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} which represents the current voice
+     * radio technology.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_VOICE_RADIO_TECH = "radioTechnology";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} which represents the current data
+     * radio technology.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_DATA_RADIO_TECH = "dataRadioTechnology";
+
+    /**
+     * A boolean extra used with {@link #ACTION_SERVICE_STATE} which represents concurrent service
+     * support on CDMA network.
+     * Will be {@code true} if support, {@code false} otherwise.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_CSS_INDICATOR = "cssIndicator";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} which represents the CDMA network
+     * id. {@code Integer.MAX_VALUE} if unknown.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_NETWORK_ID = "networkId";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} which represents the CDMA system id.
+     * {@code Integer.MAX_VALUE} if unknown.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_SYSTEM_ID = "systemId";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} represents the TSB-58 roaming
+     * indicator if registered on a CDMA or EVDO system or {@code -1} if not.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_CDMA_ROAMING_INDICATOR = "cdmaRoamingIndicator";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} represents the default roaming
+     * indicator from the PRL if registered on a CDMA or EVDO system {@code -1} if not.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_CDMA_DEFAULT_ROAMING_INDICATOR = "cdmaDefaultRoamingIndicator";
+
+    /**
+     * A boolean extra used with {@link #ACTION_SERVICE_STATE} which indicates if under emergency
+     * only mode.
+     * {@code true} if in emergency only mode, {@code false} otherwise.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_EMERGENCY_ONLY = "emergencyOnly";
+
+    /**
+     * A boolean extra used with {@link #ACTION_SERVICE_STATE} which indicates whether data network
+     * registration state is roaming.
+     * {@code true} if registration indicates roaming, {@code false} otherwise
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_IS_DATA_ROAMING_FROM_REGISTRATION =
+            "isDataRoamingFromRegistration";
+
+    /**
+     * A boolean extra used with {@link #ACTION_SERVICE_STATE} which indicates if carrier
+     * aggregation is in use.
+     * {@code true} if carrier aggregation is in use, {@code false} otherwise.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_IS_USING_CARRIER_AGGREGATION = "isUsingCarrierAggregation";
+
+    /**
+     * An integer extra used with {@link #ACTION_SERVICE_STATE} representing the offset which
+     * is reduced from the rsrp threshold while calculating signal strength level.
+     * @hide
+     */
+    @Deprecated
+    @SystemApi
+    public static final String EXTRA_LTE_EARFCN_RSRP_BOOST = "LteEarfcnRsrpBoost";
+
+    /**
      * The name of the extra used to define the text to be processed, as a
      * CharSequence. Note that this may be a styled CharSequence, so you must use
      * {@link Bundle#getCharSequence(String) Bundle.getCharSequence()} to retrieve it.
diff --git a/core/java/android/content/pm/BaseParceledListSlice.java b/core/java/android/content/pm/BaseParceledListSlice.java
index c4e4e06..aaa5f19 100644
--- a/core/java/android/content/pm/BaseParceledListSlice.java
+++ b/core/java/android/content/pm/BaseParceledListSlice.java
@@ -50,6 +50,8 @@
 
     private final List<T> mList;
 
+    private int mInlineCountLimit = Integer.MAX_VALUE;
+
     public BaseParceledListSlice(List<T> list) {
         mList = list;
     }
@@ -135,6 +137,14 @@
     }
 
     /**
+     * Set a limit on the maximum number of entries in the array that will be included
+     * inline in the initial parcelling of this object.
+     */
+    public void setInlineCountLimit(int maxCount) {
+        mInlineCountLimit = maxCount;
+    }
+
+    /**
      * 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.
@@ -149,7 +159,7 @@
             final Class<?> listElementClass = mList.get(0).getClass();
             writeParcelableCreator(mList.get(0), dest);
             int i = 0;
-            while (i < N && dest.dataSize() < MAX_IPC_SIZE) {
+            while (i < N && i < mInlineCountLimit && dest.dataSize() < MAX_IPC_SIZE) {
                 dest.writeInt(1);
 
                 final T parcelable = mList.get(i);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a493f33..50e3e68 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1688,6 +1688,10 @@
     @SdkConstant(SdkConstantType.FEATURE)
     public static final String FEATURE_CONSUMER_IR = "android.hardware.consumerir";
 
+    /** {@hide} */
+    @SdkConstant(SdkConstantType.FEATURE)
+    public static final String FEATURE_CTS = "android.software.cts";
+
     /**
      * Feature for {@link #getSystemAvailableFeatures} and
      * {@link #hasSystemFeature}: The device supports one or more methods of
@@ -6243,7 +6247,7 @@
      * Return the {@link ComponentName} of the activity providing Settings for the Instant App
      * resolver.
      *
-     * @see {@link android.content.intent#ACTION_EPHEMERAL_RESOLVER_SETTINGS}
+     * @see {@link android.content.intent#ACTION_INSTANT_APP_RESOLVER_SETTINGS}
      * @hide
      */
     @SystemApi
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index dd11f68..8349510 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -182,7 +182,7 @@
      * New in version 19:
      *   - Wakelock data (wl) gets current and max times.
      * New in version 20:
-     *   - Sensor, BluetoothScan, WifiScan get background timers and counter.
+     *   - Background timers and counters for: Sensor, BluetoothScan, WifiScan, Jobs.
      */
     static final String CHECKIN_VERSION = "20";
 
@@ -392,6 +392,16 @@
         }
 
         /**
+         * Returns the secondary Timer held by the Timer, if one exists. This secondary timer may be
+         * used, for example, for tracking background usage. Secondary timers are never pooled.
+         *
+         * Not all Timer subclasses have a secondary timer; those that don't return null.
+         */
+        public Timer getSubTimer() {
+            return null;
+        }
+
+        /**
          * Returns whether the timer is currently running.  Some types of timers
          * (e.g. BatchTimers) don't know whether the event is currently active,
          * and report false.
@@ -3393,9 +3403,13 @@
                 // Convert from microseconds to milliseconds with rounding
                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                 final int count = timer.getCountLocked(which);
+                final Timer bgTimer = timer.getSubTimer();
+                final long bgTime = bgTimer != null ?
+                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
                 if (totalTime != 0) {
                     dumpLine(pw, uid, category, JOB_DATA, "\"" + jobs.keyAt(ij) + "\"",
-                            totalTime, count);
+                            totalTime, count, bgTime, bgCount);
                 }
             }
 
@@ -4616,6 +4630,10 @@
                 // Convert from microseconds to milliseconds with rounding
                 final long totalTime = (timer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000;
                 final int count = timer.getCountLocked(which);
+                final Timer bgTimer = timer.getSubTimer();
+                final long bgTime = bgTimer != null ?
+                        (bgTimer.getTotalTimeLocked(rawRealtime, which) + 500) / 1000 : -1;
+                final int bgCount = bgTimer != null ? bgTimer.getCountLocked(which) : -1;
                 sb.setLength(0);
                 sb.append(prefix);
                 sb.append("    Job ");
@@ -4626,6 +4644,13 @@
                     sb.append("realtime (");
                     sb.append(count);
                     sb.append(" times)");
+                    if (bgTime > 0) {
+                        sb.append(", ");
+                        formatTimeMs(sb, bgTime);
+                        sb.append("background (");
+                        sb.append(bgCount);
+                        sb.append(" times)");
+                    }
                 } else {
                     sb.append("(not used)");
                 }
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index e5d73e0..b5af766 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -59,19 +59,14 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.os.AppFuseMount;
 import com.android.internal.os.FuseAppLoop;
-import com.android.internal.os.FuseAppLoop.UnmountedException;
 import com.android.internal.os.FuseUnavailableMountException;
 import com.android.internal.os.RoSystemProperties;
 import com.android.internal.os.SomeArgs;
 import com.android.internal.util.Preconditions;
 
-import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.ref.WeakReference;
@@ -84,7 +79,6 @@
 import java.util.Objects;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicInteger;
-import libcore.io.IoUtils;
 
 /**
  * StorageManager is the interface to the systems storage service. The storage
@@ -186,15 +180,6 @@
 
     private static volatile IStorageManager sStorageManager = null;
 
-    // TODO: the location of the primary storage block varies from device to device, so we need to
-    // try the most likely candidates - a long-term solution would be a device-specific vold
-    // function that returns the calculated size.
-    private static final String[] INTERNAL_STORAGE_SIZE_PATHS = {
-            "/sys/block/mmcblk0/size",
-            "/sys/block/sda/size"
-    };
-    private static final int INTERNAL_STORAGE_SECTOR_SIZE = 512;
-
     private final Context mContext;
     private final ContentResolver mResolver;
 
@@ -1011,38 +996,13 @@
 
     /** {@hide} */
     public static Pair<String, Long> getPrimaryStoragePathAndSize() {
-        for (String path : INTERNAL_STORAGE_SIZE_PATHS) {
-            final long numberBlocks = readLong(path);
-            if (numberBlocks > 0) {
-                return new Pair<>(path,
-                        FileUtils.roundStorageSize(numberBlocks * INTERNAL_STORAGE_SECTOR_SIZE));
-            }
-        }
-        return null;
+        return Pair.create(null,
+                FileUtils.roundStorageSize(Environment.getDataDirectory().getTotalSpace()));
     }
 
-
     /** {@hide} */
     public long getPrimaryStorageSize() {
-        final Pair<String, Long> pair = getPrimaryStoragePathAndSize();
-        return pair == null ? 0 : pair.second.longValue();
-    }
-
-    private static long readLong(String path) {
-        try (final FileInputStream fis = new FileInputStream(path);
-                final BufferedReader reader = new BufferedReader(new InputStreamReader(fis));) {
-            return Long.parseLong(reader.readLine());
-        } catch (FileNotFoundException e) {
-            // This is expected since we are trying to parse multiple paths.
-            Slog.i(TAG, "readLong(): Path doesn't exist: " + path + ": " + e);
-            return 0;
-        } catch (NumberFormatException e) {
-            Slog.e(TAG, "readLong(): Could not parse " + path + ": " + e);
-            return 0;
-        } catch (Exception e) {
-            Slog.e(TAG, "readLong(): Unknown exception while opening " + path + ": " + e);
-            return 0;
-       }
+        return FileUtils.roundStorageSize(Environment.getDataDirectory().getTotalSpace());
     }
 
     /** @removed */
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index a280e59..9d83bd7 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -114,7 +114,7 @@
          * download's content: uri is specified in the intent's data.
          */
         public static final String ACTION_DOWNLOAD_COMPLETED =
-                "android.intent.action.DOWNLOAD_COMPLETED";
+                DownloadManager.ACTION_DOWNLOAD_COMPLETED;
 
         /**
          * Broadcast Action: this is sent by the download manager to the app
@@ -127,7 +127,7 @@
          * successfully.
          */
         public static final String ACTION_NOTIFICATION_CLICKED =
-                "android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED";
+                DownloadManager.ACTION_NOTIFICATION_CLICKED;
 
         /**
          * The name of the column containing the URI of the data being downloaded.
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index fd9d4db..4deb4ab 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -72,15 +72,28 @@
          */
         public static final String VARIATION_SETTINGS = "font_variation_settings";
         /**
-         * Constant used to request data from a font provider. The cursor returned from the query
-         * should have this column populated with the int style for the resulting font. This should
-         * be one of {@link android.graphics.Typeface#NORMAL},
-         * {@link android.graphics.Typeface#BOLD}, {@link android.graphics.Typeface#ITALIC} or
-         * {@link android.graphics.Typeface#BOLD_ITALIC}
+         * DO NOT USE THIS COLUMN.
+         * This column is kept for preventing demo apps.
+         * TODO: Remove once nobody uses this column.
+         * @hide
+         * @removed
          */
         public static final String STYLE = "font_style";
         /**
          * Constant used to request data from a font provider. The cursor returned from the query
+         * should have this column populated with the int weight for the resulting font. This value
+         * should be between 100 and 900. The most common values are 400 for regular weight and 700
+         * for bold weight.
+         */
+        public static final String WEIGHT = "font_weight";
+        /**
+         * Constant used to request data from a font provider. The cursor returned from the query
+         * should have this column populated with the int italic for the resulting font. This should
+         * be 0 for regular style and 1 for italic.
+         */
+        public static final String ITALIC = "font_italic";
+        /**
+         * Constant used to request data from a font provider. The cursor returned from the query
          * should have this column populated to indicate the result status of the
          * query. This will be checked before any other data in the cursor. Possible values are
          * {@link #RESULT_CODE_OK}, {@link #RESULT_CODE_FONT_NOT_FOUND},
@@ -274,7 +287,7 @@
                 .build();
         try (Cursor cursor = mContext.getContentResolver().query(uri, new String[] { Columns._ID,
                         Columns.TTC_INDEX, Columns.VARIATION_SETTINGS, Columns.STYLE,
-                        Columns.RESULT_CODE },
+                        Columns.WEIGHT, Columns.ITALIC, Columns.RESULT_CODE },
                 "query = ?", new String[] { request.getQuery() }, null);) {
             // TODO: Should we restrict the amount of fonts that can be returned?
             // TODO: Write documentation explaining that all results should be from the same family.
@@ -285,6 +298,8 @@
                 final int idColumnIndex = cursor.getColumnIndexOrThrow(Columns._ID);
                 final int ttcIndexColumnIndex = cursor.getColumnIndex(Columns.TTC_INDEX);
                 final int vsColumnIndex = cursor.getColumnIndex(Columns.VARIATION_SETTINGS);
+                final int weightColumnIndex = cursor.getColumnIndex(Columns.WEIGHT);
+                final int italicColumnIndex = cursor.getColumnIndex(Columns.ITALIC);
                 final int styleColumnIndex = cursor.getColumnIndex(Columns.STYLE);
                 while (cursor.moveToNext()) {
                     resultCode = resultCodeColumnIndex != -1
@@ -313,9 +328,22 @@
                                 ? cursor.getInt(ttcIndexColumnIndex) : 0;
                         final String variationSettings = vsColumnIndex != -1
                                 ? cursor.getString(vsColumnIndex) : null;
-                        final int style = styleColumnIndex != -1
-                                ? cursor.getInt(styleColumnIndex) : Typeface.NORMAL;
-                        result.add(new FontResult(pfd, ttcIndex, variationSettings, style));
+                        // TODO: Stop using STYLE column and enforce WEIGHT/ITALIC column.
+                        int weight;
+                        boolean italic;
+                        if (weightColumnIndex != -1 && italicColumnIndex != -1) {
+                            weight = cursor.getInt(weightColumnIndex);
+                            italic = cursor.getInt(italicColumnIndex) == 1;
+                        } else if (styleColumnIndex != -1) {
+                            final int style = cursor.getInt(styleColumnIndex);
+                            weight = (style & Typeface.BOLD) != 0 ? 700 : 400;
+                            italic = (style & Typeface.ITALIC) != 0;
+                        } else {
+                            weight = 400;
+                            italic = false;
+                        }
+                        result.add(
+                                new FontResult(pfd, ttcIndex, variationSettings, weight, italic));
                     } catch (FileNotFoundException e) {
                         Log.e(TAG, "FileNotFoundException raised when interacting with content "
                                 + "provider " + authority, e);
diff --git a/core/java/android/service/autofill/AutofillService.java b/core/java/android/service/autofill/AutofillService.java
index 6f17d0e..9f8a621 100644
--- a/core/java/android/service/autofill/AutofillService.java
+++ b/core/java/android/service/autofill/AutofillService.java
@@ -71,7 +71,7 @@
      * Name under which a AutoFillService component publishes information about itself.
      * This meta-data should reference an XML resource containing a
      * <code>&lt;{@link
-     * android.R.styleable#AutoFillService autofill-service}&gt;</code> tag.
+     * android.R.styleable#AutofillService autofill-service}&gt;</code> tag.
      * This is a a sample XML file configuring an AutoFillService:
      * <pre> &lt;autofill-service
      *     android:settingsActivity="foo.bar.SettingsActivity"
diff --git a/core/java/android/service/autofill/AutofillServiceInfo.java b/core/java/android/service/autofill/AutofillServiceInfo.java
index f6d40db..0f4824e 100644
--- a/core/java/android/service/autofill/AutofillServiceInfo.java
+++ b/core/java/android/service/autofill/AutofillServiceInfo.java
@@ -36,7 +36,6 @@
 
 import java.io.IOException;
 
-// TODO(b/33197203 , b/33802548): add CTS tests
 /**
  * {@link ServiceInfo} and meta-data about an {@link AutofillService}.
  *
@@ -75,15 +74,8 @@
         mServiceInfo = si;
         final TypedArray metaDataArray = getMetaDataArray(pm, si);
         if (metaDataArray != null) {
-            // TODO(b/35956626): inline newSettingsActivity once clients migrate
-            final String newSettingsActivity =
-                    metaDataArray.getString(R.styleable.AutofillService_settingsActivity);
-            if (newSettingsActivity != null) {
-                mSettingsActivity = newSettingsActivity;
-            } else {
-                mSettingsActivity =
-                        metaDataArray.getString(R.styleable.AutoFillService_settingsActivity);
-            }
+            mSettingsActivity = metaDataArray
+                    .getString(R.styleable.AutofillService_settingsActivity);
             metaDataArray.recycle();
         } else {
             mSettingsActivity = null;
@@ -96,16 +88,11 @@
     @Nullable
     private static TypedArray getMetaDataArray(PackageManager pm, ServiceInfo si) {
         // Check for permissions.
-        // TODO(b/35956626): remove check for BIND_AUTO_FILL once clients migrate
-        if (!Manifest.permission.BIND_AUTOFILL.equals(si.permission)
-                && !Manifest.permission.BIND_AUTO_FILL.equals(si.permission)) {
+        if (!Manifest.permission.BIND_AUTOFILL.equals(si.permission)) {
             Log.e(TAG, "Service does not require permission " + Manifest.permission.BIND_AUTOFILL);
             return null;
         }
 
-        // TODO(b/35956626): remove once clients migrate
-        final boolean oldStyle = !Manifest.permission.BIND_AUTOFILL.equals(si.permission);
-
         // Get the AutoFill metadata, if declared.
         XmlResourceParser parser = si.loadXmlMetaData(pm, AutofillService.SERVICE_META_DATA);
         if (parser == null) {
@@ -141,8 +128,7 @@
                 return null;
             }
 
-            return oldStyle ? res.obtainAttributes(attrs, R.styleable.AutoFillService)
-                    : res.obtainAttributes(attrs, R.styleable.AutofillService);
+            return res.obtainAttributes(attrs, R.styleable.AutofillService);
         } finally {
             parser.close();
         }
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index e27fa06..e77bd0d 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -23,8 +23,6 @@
 import android.content.IntentSender;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.view.autofill.AutoFillId;
-import android.view.autofill.AutoFillValue;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 import android.widget.RemoteViews;
@@ -78,11 +76,6 @@
     }
 
     /** @hide */
-    public @Nullable RemoteViews getPresentation() {
-        return mPresentation;
-    }
-
-    /** @hide */
     public @Nullable IntentSender getAuthentication() {
         return mAuthentication;
     }
@@ -180,15 +173,6 @@
         }
 
         /**
-         * @hide
-         * @deprecated TODO(b/35956626): remove once clients use other setValue()
-         */
-       @Deprecated
-        public @NonNull Builder setValue(@NonNull AutoFillId id, @NonNull AutoFillValue value) {
-            return setValue(id.getDaRealId(), value.getDaRealValue());
-        }
-
-        /**
          * Sets the value of a field.
          *
          * @param id id returned by {@link
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index c43019d..717312b 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.service.autofill;
 
 import static android.view.autofill.Helper.DEBUG;
@@ -23,6 +24,7 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.widget.RemoteViews;
 
@@ -112,7 +114,7 @@
  *
  * <p>The service could require user authentication at the {@link FillResponse} or the
  * {@link Dataset} level, prior to autofilling an activity - see
- * {@link FillResponse.Builder#setAuthentication(IntentSender, RemoteViews)} and
+ * {@link FillResponse.Builder#setAuthentication(AutofillId[], IntentSender, RemoteViews)} and
  * {@link Dataset.Builder#setAuthentication(IntentSender)}.
  *
  * <p>It is recommended that you encrypt only the sensitive data but leave the labels unencrypted
@@ -126,7 +128,7 @@
  * possible options) which will start your auth flow and after successfully authenticating
  * the user will be presented with the Home and Work options to pick one. Hence, you have
  * flexibility how to implement your auth while storing labels non-encrypted and data
- * encrypted provides a better user experience.</p>
+ * encrypted provides a better user experience.
  */
 public final class FillResponse implements Parcelable {
 
@@ -135,6 +137,7 @@
     private final Bundle mExtras;
     private final RemoteViews mPresentation;
     private final IntentSender mAuthentication;
+    private AutofillId[] mAuthenticationIds;
 
     private FillResponse(@NonNull Builder builder) {
         mDatasets = builder.mDatasets;
@@ -142,6 +145,7 @@
         mExtras = builder.mExtras;
         mPresentation = builder.mPresentation;
         mAuthentication = builder.mAuthentication;
+        mAuthenticationIds = builder.mAuthenticationIds;
     }
 
     /** @hide */
@@ -169,6 +173,11 @@
         return mAuthentication;
     }
 
+    /** @hide */
+    public @Nullable AutofillId[] getAuthenticationIds() {
+        return mAuthenticationIds;
+    }
+
     /**
      * Builder for {@link FillResponse} objects. You must to provide at least
      * one dataset or set an authentication intent with a presentation view.
@@ -179,6 +188,7 @@
         private Bundle mExtras;
         private RemoteViews mPresentation;
         private IntentSender mAuthentication;
+        private AutofillId[] mAuthenticationIds;
         private boolean mDestroyed;
 
         /**
@@ -193,7 +203,7 @@
          * be encrypted. The provided {@link android.app.PendingIntent intent} must be an
          * activity which implements your authentication flow. Also if you provide an auth
          * intent you also need to specify the presentation view to be shown in the fill UI
-         * for the user to trigger your authentication flow.</p>
+         * for the user to trigger your authentication flow.
          *
          * <p>When a user triggers autofill, the system launches the provided intent
          * whose extras will have the {@link AutofillManager#EXTRA_ASSIST_STRUCTURE screen
@@ -205,40 +215,54 @@
          * user's data was locked and marked that the response needs an authentication then
          * in the response returned if authentication succeeds you need to provide all
          * available data sets some of which may need to be further authenticated, for
-         * example a credit card whose CVV needs to be entered.</p>
+         * example a credit card whose CVV needs to be entered.
          *
          * <p>If you provide an authentication intent you must also provide a presentation
          * which is used to visualize visualize the response for triggering the authentication
-         * flow.</p>
+         * flow.
          *
          * <p></><strong>Note:</strong> Do not make the provided pending intent
          * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
-         * platform needs to fill in the authentication arguments.</p>
+         * platform needs to fill in the authentication arguments.
          *
          * @param authentication Intent to an activity with your authentication flow.
          * @param presentation The presentation to visualize the response.
-         * @return This builder.
+         * @param ids id of Views that when focused will display the authentication UI affordance.
          *
+         * @return This builder.
          * @see android.app.PendingIntent#getIntentSender()
          */
-        public @NonNull Builder setAuthentication(@Nullable IntentSender authentication,
-                @Nullable RemoteViews presentation) {
+        public @NonNull Builder setAuthentication(@NonNull AutofillId[] ids,
+                @Nullable IntentSender authentication, @Nullable RemoteViews presentation) {
             throwIfDestroyed();
+            // TODO(b/33197203): assert ids is not null nor empty once old version is removed
             if (authentication == null ^ presentation == null) {
                 throw new IllegalArgumentException("authentication and presentation"
                         + " must be both non-null or null");
             }
             mAuthentication = authentication;
             mPresentation = presentation;
+            mAuthenticationIds = ids;
             return this;
         }
 
         /**
+         * TODO(b/33197203): will be removed once clients use the version that takes ids
+         * @hide
+         * @deprecated
+         */
+        @Deprecated
+        public @NonNull Builder setAuthentication(@Nullable IntentSender authentication,
+                @Nullable RemoteViews presentation) {
+            return setAuthentication(null, authentication, presentation);
+        }
+
+        /**
          * Adds a new {@link Dataset} to this response.
          *
          * @return This builder.
          */
-        public@NonNull Builder addDataset(@Nullable Dataset dataset) {
+        public @NonNull Builder addDataset(@Nullable Dataset dataset) {
             throwIfDestroyed();
             if (dataset == null) {
                 return this;
@@ -282,6 +306,7 @@
             return this;
         }
 
+
         /**
          * Builds a new {@link FillResponse} instance. You must provide at least
          * one dataset or some savable ids or an authentication with a presentation
@@ -308,7 +333,7 @@
     }
 
     /////////////////////////////////////
-    //  Object "contract" methods. //
+    // Object "contract" methods. //
     /////////////////////////////////////
     @Override
     public String toString() {
@@ -320,11 +345,13 @@
                 .append(", hasExtras=").append(mExtras != null)
                 .append(", hasPresentation=").append(mPresentation != null)
                 .append(", hasAuthentication=").append(mAuthentication != null)
+                .append(", authenticationSize=").append(mAuthenticationIds != null
+                        ? mAuthenticationIds.length : "N/A")
                 .toString();
     }
 
     /////////////////////////////////////
-    //  Parcelable "contract" methods. //
+    // Parcelable "contract" methods. //
     /////////////////////////////////////
 
     @Override
@@ -337,6 +364,7 @@
         parcel.writeTypedArrayList(mDatasets, flags);
         parcel.writeParcelable(mSaveInfo, flags);
         parcel.writeParcelable(mExtras, flags);
+        parcel.writeParcelableArray(mAuthenticationIds, flags);
         parcel.writeParcelable(mAuthentication, flags);
         parcel.writeParcelable(mPresentation, flags);
     }
@@ -356,8 +384,8 @@
             }
             builder.setSaveInfo(parcel.readParcelable(null));
             builder.setExtras(parcel.readParcelable(null));
-            builder.setAuthentication(parcel.readParcelable(null),
-                    parcel.readParcelable(null));
+            builder.setAuthentication(parcel.readParcelableArray(null, AutofillId.class),
+                    parcel.readParcelable(null), parcel.readParcelable(null));
             return builder.build();
         }
 
diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java
index 6213d27..95608a5 100644
--- a/core/java/android/service/autofill/SaveInfo.java
+++ b/core/java/android/service/autofill/SaveInfo.java
@@ -25,7 +25,6 @@
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.view.autofill.AutoFillId;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
 import android.view.autofill.AutofillValue;
@@ -269,26 +268,6 @@
             return this;
         }
 
-
-        /**
-         * @hide
-         */
-        // TODO(b/33197203): temporary fix to runtime crash
-        public @NonNull Builder addSavableIds(@Nullable AutoFillId... ids) {
-            throwIfDestroyed();
-
-            if (ids == null || ids.length == 0) {
-                return this;
-            }
-            if (mRequiredIds == null) {
-                mRequiredIds = new AutofillId[ids.length];
-            }
-            for (int i = 0; i < ids.length; i++) {
-                mRequiredIds[i] = ids[i].getDaRealId();
-            }
-            return this;
-        }
-
         /**
          * Sets an optional description to be shown in the UI when the user is asked to save.
          *
diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java
index 1e9deeb..6208c53 100644
--- a/core/java/android/text/DynamicLayout.java
+++ b/core/java/android/text/DynamicLayout.java
@@ -85,7 +85,7 @@
         this(base, display, paint, width, align, TextDirectionHeuristics.FIRSTSTRONG_LTR,
                 spacingmult, spacingadd, includepad,
                 StaticLayout.BREAK_STRATEGY_SIMPLE, StaticLayout.HYPHENATION_FREQUENCY_NONE,
-                false /* justify */, ellipsize, ellipsizedWidth);
+                Layout.JUSTIFICATION_MODE_NONE, ellipsize, ellipsizedWidth);
     }
 
     /**
@@ -102,7 +102,7 @@
                          int width, Alignment align, TextDirectionHeuristic textDir,
                          float spacingmult, float spacingadd,
                          boolean includepad, int breakStrategy, int hyphenationFrequency,
-                         boolean justify, TextUtils.TruncateAt ellipsize,
+                         int justificationMode, TextUtils.TruncateAt ellipsize,
                          int ellipsizedWidth) {
         super((ellipsize == null)
                 ? display
@@ -128,7 +128,7 @@
 
         mIncludePad = includepad;
         mBreakStrategy = breakStrategy;
-        mJustify = justify;
+        mJustificationMode = justificationMode;
         mHyphenationFrequency = hyphenationFrequency;
 
         /*
@@ -303,7 +303,7 @@
                 .setEllipsize(mEllipsizeAt)
                 .setBreakStrategy(mBreakStrategy)
                 .setHyphenationFrequency(mHyphenationFrequency)
-                .setJustify(mJustify);
+                .setJustificationMode(mJustificationMode);
         reflowed.generate(b, false, true);
         int n = reflowed.getLineCount();
         // If the new layout has a blank line at the end, but it is not
@@ -811,7 +811,7 @@
     private TextUtils.TruncateAt mEllipsizeAt;
     private int mBreakStrategy;
     private int mHyphenationFrequency;
-    private boolean mJustify;
+    private int mJustificationMode;
 
     private PackedIntVector mInts;
     private PackedObjectVector<Directions> mObjects;
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 53564f0..b47fce8 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -103,6 +103,21 @@
     private static final ParagraphStyle[] NO_PARA_SPANS =
         ArrayUtils.emptyArray(ParagraphStyle.class);
 
+    /** @hide */
+    @IntDef({JUSTIFICATION_MODE_NONE, JUSTIFICATION_MODE_INTER_WORD})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface JustificationMode {}
+
+    /**
+     * Value for justification mode indicating no justification.
+     */
+    public static final int JUSTIFICATION_MODE_NONE = 0;
+
+    /**
+     * Value for justification mode indicating the text is justified by stretching word spacing.
+     */
+    public static final int JUSTIFICATION_MODE_INTER_WORD = 1;
+
     /**
      * Return how wide a layout must be in order to display the specified text with one line per
      * paragraph.
@@ -219,8 +234,8 @@
     }
 
     /** @hide */
-    protected void setJustify(boolean justify) {
-        mJustify = justify;
+    protected void setJustificationMode(@JustificationMode int justificationMode) {
+        mJustificationMode = justificationMode;
     }
 
     /**
@@ -272,7 +287,7 @@
     }
 
     private boolean isJustificationRequired(int lineNum) {
-        if (!mJustify) return false;
+        if (mJustificationMode == JUSTIFICATION_MODE_NONE) return false;
         final int lineEnd = getLineEnd(lineNum);
         return lineEnd < mText.length() && mText.charAt(lineEnd - 1) != '\n';
     }
@@ -2229,7 +2244,7 @@
     private boolean mSpannedText;
     private TextDirectionHeuristic mTextDir;
     private SpanSet<LineBackgroundSpan> mLineBackgroundSpans;
-    private boolean mJustify;
+    private int mJustificationMode;
 
     public static final int DIR_LEFT_TO_RIGHT = 1;
     public static final int DIR_RIGHT_TO_LEFT = -1;
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 9a2e0bb..74ff6dc 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -94,7 +94,7 @@
             b.mMaxLines = Integer.MAX_VALUE;
             b.mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
             b.mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
-            b.mJustify = false;
+            b.mJustificationMode = Layout.JUSTIFICATION_MODE_NONE;
 
             b.mMeasuredText = MeasuredText.obtain();
             return b;
@@ -321,15 +321,15 @@
         }
 
         /**
-         * Enables or disables paragraph justification. The default value is disabled (false).
-         * If the last line is too short for justification, the last line will be displayed with
-         * the alignment set by {@link #setAlignment}.
+         * Set paragraph justification mode. The default value is
+         * {@link Layout#JUSTIFICATION_MODE_NONE}. If the last line is too short for justification,
+         * the last line will be displayed with the alignment set by {@link #setAlignment}.
          *
-         * @param justify true for enabling and false for disabling paragraph justification.
+         * @param justificationMode justification mode for the paragraph.
          * @return this builder, useful for chaining.
          */
-        public Builder setJustify(boolean justify) {
-            mJustify = justify;
+        public Builder setJustificationMode(@JustificationMode int justificationMode) {
+            mJustificationMode = justificationMode;
             return this;
         }
 
@@ -418,7 +418,7 @@
         int mHyphenationFrequency;
         int[] mLeftIndents;
         int[] mRightIndents;
-        boolean mJustify;
+        int mJustificationMode;
 
         Paint.FontMetricsInt mFontMetricsInt = new Paint.FontMetricsInt();
 
@@ -572,7 +572,7 @@
 
         mLeftIndents = b.mLeftIndents;
         mRightIndents = b.mRightIndents;
-        setJustify(b.mJustify);
+        setJustificationMode(b.mJustificationMode);
 
         generate(b, b.mIncludePad, b.mIncludePad);
     }
@@ -693,7 +693,8 @@
             nSetupParagraph(b.mNativePtr, chs, paraEnd - paraStart,
                     firstWidth, firstWidthLineCount, restWidth,
                     variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency,
-                    b.mJustify);
+                    // TODO: Support more justification mode, e.g. letter spacing, stretching.
+                    b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE);
             if (mLeftIndents != null || mRightIndents != null) {
                 // TODO(raph) performance: it would be better to do this once per layout rather
                 // than once per paragraph, but that would require a change to the native
diff --git a/core/java/android/view/FocusFinder.java b/core/java/android/view/FocusFinder.java
index d25e5f0..f3c2421 100644
--- a/core/java/android/view/FocusFinder.java
+++ b/core/java/android/view/FocusFinder.java
@@ -54,7 +54,9 @@
     final Rect mOtherRect = new Rect();
     final Rect mBestCandidateRect = new Rect();
     private final UserSpecifiedFocusComparator mUserSpecifiedFocusComparator =
-            new UserSpecifiedFocusComparator();
+            new UserSpecifiedFocusComparator((v) -> v.getNextFocusForwardId());
+    private final UserSpecifiedFocusComparator mUserSpecifiedClusterComparator =
+            new UserSpecifiedFocusComparator((v) -> v.getNextClusterForwardId());
     private final FocusComparator mFocusComparator = new FocusComparator();
 
     private final ArrayList<View> mTempList = new ArrayList<View>();
@@ -150,6 +152,12 @@
             @Nullable View currentCluster,
             @View.FocusDirection int direction) {
         View next = null;
+        if (currentCluster != null) {
+            next = findNextUserSpecifiedKeyboardNavigationCluster(root, currentCluster, direction);
+            if (next != null) {
+                return next;
+            }
+        }
 
         final ArrayList<View> clusters = mTempList;
         try {
@@ -165,6 +173,16 @@
         return next;
     }
 
+    private View findNextUserSpecifiedKeyboardNavigationCluster(View root, View currentCluster,
+            int direction) {
+        View userSetNextCluster =
+                currentCluster.findUserSetNextKeyboardNavigationCluster(root, direction);
+        if (userSetNextCluster != null && userSetNextCluster.hasFocusable()) {
+            return userSetNextCluster;
+        }
+        return null;
+    }
+
     private View findNextUserSpecifiedFocus(ViewGroup root, View focused, int direction) {
         // check for user specified next focus
         View userSetNextFocus = focused.findUserSetNextFocus(root, direction);
@@ -238,6 +256,13 @@
             View currentCluster,
             List<View> clusters,
             @View.FocusDirection int direction) {
+        try {
+            // Note: This sort is stable.
+            mUserSpecifiedClusterComparator.setFocusables(clusters);
+            Collections.sort(clusters, mUserSpecifiedClusterComparator);
+        } finally {
+            mUserSpecifiedClusterComparator.recycle();
+        }
         final int count = clusters.size();
 
         switch (direction) {
@@ -802,6 +827,15 @@
         private final SparseBooleanArray mIsConnectedTo = new SparseBooleanArray();
         private final ArrayMap<View, View> mHeadsOfChains = new ArrayMap<View, View>();
         private final ArrayMap<View, Integer> mOriginalOrdinal = new ArrayMap<>();
+        private final NextIdGetter mNextIdGetter;
+
+        public interface NextIdGetter {
+            int get(View view);
+        }
+
+        UserSpecifiedFocusComparator(NextIdGetter nextIdGetter) {
+            mNextIdGetter = nextIdGetter;
+        }
 
         public void recycle() {
             mFocusables.clear();
@@ -810,14 +844,14 @@
             mOriginalOrdinal.clear();
         }
 
-        public void setFocusables(ArrayList<View> focusables) {
+        public void setFocusables(List<View> focusables) {
             for (int i = focusables.size() - 1; i >= 0; i--) {
                 final View view = focusables.get(i);
                 final int id = view.getId();
                 if (isValidId(id)) {
                     mFocusables.put(id, view);
                 }
-                final int nextId = view.getNextFocusForwardId();
+                final int nextId = mNextIdGetter.get(view);
                 if (isValidId(nextId)) {
                     mIsConnectedTo.put(nextId, true);
                 }
@@ -825,7 +859,7 @@
 
             for (int i = focusables.size() - 1; i >= 0; i--) {
                 final View view = focusables.get(i);
-                final int nextId = view.getNextFocusForwardId();
+                final int nextId = mNextIdGetter.get(view);
                 if (isValidId(nextId) && !mIsConnectedTo.get(view.getId())) {
                     setHeadOfChain(view);
                 }
@@ -838,7 +872,7 @@
 
         private void setHeadOfChain(View head) {
             for (View view = head; view != null;
-                    view = mFocusables.get(view.getNextFocusForwardId())) {
+                    view = mFocusables.get(mNextIdGetter.get(view))) {
                 final View otherHead = mHeadsOfChains.get(view);
                 if (otherHead != null) {
                     if (otherHead == head) {
@@ -866,7 +900,7 @@
                     return -1; // first is the head, it should be first
                 } else if (second == firstHead) {
                     return 1; // second is the head, it should be first
-                } else if (isValidId(first.getNextFocusForwardId())) {
+                } else if (isValidId(mNextIdGetter.get(first))) {
                     return -1; // first is not the end of the chain
                 } else {
                     return 1; // first is end of chain
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b12a767..4ffcd95 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -707,13 +707,16 @@
  * @attr ref android.R.styleable#View_isScrollContainer
  * @attr ref android.R.styleable#View_focusable
  * @attr ref android.R.styleable#View_focusableInTouchMode
+ * @attr ref android.R.styleable#View_focusedByDefault
  * @attr ref android.R.styleable#View_hapticFeedbackEnabled
  * @attr ref android.R.styleable#View_keepScreenOn
+ * @attr ref android.R.styleable#View_keyboardNavigationCluster
  * @attr ref android.R.styleable#View_layerType
  * @attr ref android.R.styleable#View_layoutDirection
  * @attr ref android.R.styleable#View_longClickable
  * @attr ref android.R.styleable#View_minHeight
  * @attr ref android.R.styleable#View_minWidth
+ * @attr ref android.R.styleable#View_nextClusterForward
  * @attr ref android.R.styleable#View_nextFocusDown
  * @attr ref android.R.styleable#View_nextFocusLeft
  * @attr ref android.R.styleable#View_nextFocusRight
@@ -4076,7 +4079,9 @@
     int mNextFocusForwardId = View.NO_ID;
 
     /**
-     * User-specified next keyboard navigation cluster.
+     * User-specified next keyboard navigation cluster in the {@link #FOCUS_FORWARD} direction.
+     *
+     * @see #findUserSetNextKeyboardNavigationCluster(View, int)
      */
     int mNextClusterForwardId = View.NO_ID;
 
@@ -9968,6 +9973,29 @@
         return null;
     }
 
+    /**
+     * If a user manually specified the next keyboard-navigation cluster for a particular direction,
+     * use the root to look up the view.
+     *
+     * @param root the root view of the hierarchy containing this view
+     * @param direction {@link #FOCUS_FORWARD} or {@link #FOCUS_BACKWARD}
+     * @return the user-specified next cluster, or {@code null} if there is none
+     */
+    View findUserSetNextKeyboardNavigationCluster(View root, @FocusDirection int direction) {
+        switch (direction) {
+            case FOCUS_FORWARD:
+                if (mNextClusterForwardId == View.NO_ID) return null;
+                return findViewInsideOutShouldExist(root, mNextClusterForwardId);
+            case FOCUS_BACKWARD: {
+                if (mID == View.NO_ID) return null;
+                final int id = mID;
+                return root.findViewByPredicateInsideOut(this,
+                        (Predicate<View>) t -> t.mNextClusterForwardId == id);
+            }
+        }
+        return null;
+    }
+
     private View findViewInsideOutShouldExist(View root, int id) {
         if (mMatchIdPredicate == null) {
             mMatchIdPredicate = new MatchIdPredicate();
@@ -20780,11 +20808,18 @@
     }
 
     /**
-     * Look for a child view with the given id.  If this view has the given
-     * id, return this view.
+     * Finds the first descendant view with the given ID, the view itself if
+     * the ID matches {@link #getId()}, or {@code null} if the ID is invalid
+     * (< 0) or there is no matching view in the hierarchy.
+     * <p>
+     * <strong>Note:</strong> In most cases -- depending on compiler support --
+     * the resulting view is automatically cast to the target class type. If
+     * the target class type is unconstrained, an explicit cast may be
+     * necessary.
      *
-     * @param id The id to search for.
-     * @return The view that has the given id in the hierarchy or null
+     * @param id the ID to search for
+     * @return a view with given ID if found, or {@code null} otherwise
+     * @see View#findViewById(int)
      */
     @Nullable
     public final <T extends View> T findViewById(@IdRes int id) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index c250226..9e1ceee 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1258,15 +1258,18 @@
             return;
         }
 
-        final int count = mChildrenCount;
-        final View[] children = mChildren;
-
-        for (int i = 0; i < count; i++) {
-            final View child = children[i];
+        int count = 0;
+        final View[] visibleChildren = new View[mChildrenCount];
+        for (int i = 0; i < mChildrenCount; ++i) {
+            final View child = mChildren[i];
             if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) {
-                child.addKeyboardNavigationClusters(views, direction);
+                visibleChildren[count++] = child;
             }
         }
+        Arrays.sort(visibleChildren, 0, count, FocusFinder.getFocusComparator(this, false));
+        for (int i = 0; i < count; ++i) {
+            visibleChildren[i].addKeyboardNavigationClusters(views, direction);
+        }
     }
 
     /**
@@ -7344,6 +7347,7 @@
 
     /** @hide */
     protected void onSetLayoutParams(View child, LayoutParams layoutParams) {
+        requestLayout();
     }
 
     /** @hide */
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 2e201bf..58ef0af 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -4660,6 +4660,7 @@
             if (cluster != null && cluster.isRootNamespace()) {
                 // the default cluster. Try to find a non-clustered view to focus.
                 if (cluster.restoreFocusNotInCluster()) {
+                    playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
                     return true;
                 }
                 // otherwise skip to next actual cluster
@@ -4667,6 +4668,7 @@
             }
 
             if (cluster != null && cluster.restoreFocusInCluster(realDirection)) {
+                playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
                 return true;
             }
 
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 0053caa..6dd8ecf 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1308,15 +1308,22 @@
     }
 
     /**
-     * Finds a view that was identified by the id attribute from the XML that
-     * was processed in {@link android.app.Activity#onCreate}.  This will
-     * implicitly call {@link #getDecorView} for you, with all of the
-     * associated side-effects.
+     * Finds a view that was identified by the {@code android:id} XML attribute
+     * that was processed in {@link android.app.Activity#onCreate}. This will
+     * implicitly call {@link #getDecorView} with all of the associated
+     * side-effects.
+     * <p>
+     * <strong>Note:</strong> In most cases -- depending on compiler support --
+     * the resulting view is automatically cast to the target class type. If
+     * the target class type is unconstrained, an explicit cast may be
+     * necessary.
      *
-     * @return The view if found or null otherwise.
+     * @param id the ID to search for
+     * @return a view with given ID if found, or {@code null} otherwise
+     * @see View#findViewById(int)
      */
     @Nullable
-    public View findViewById(@IdRes int id) {
+    public <T extends View> T findViewById(@IdRes int id) {
         return getDecorView().findViewById(id);
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityManager.java b/core/java/android/view/accessibility/AccessibilityManager.java
index 35276cc..5e6ace7 100644
--- a/core/java/android/view/accessibility/AccessibilityManager.java
+++ b/core/java/android/view/accessibility/AccessibilityManager.java
@@ -41,6 +41,7 @@
 import android.view.IWindow;
 import android.view.View;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.util.IntPair;
 
 import java.util.ArrayList;
@@ -126,6 +127,8 @@
 
     final Handler mHandler;
 
+    final Handler.Callback mCallback;
+
     boolean mIsEnabled;
 
     int mRelevantEventTypes = AccessibilityEvent.TYPES_ALL_MASK;
@@ -217,12 +220,12 @@
             // is now off an exception will be thrown. We want to have the exception
             // enforcement to guard against apps that fire unnecessary accessibility
             // events when accessibility is off.
-            mHandler.obtainMessage(MyHandler.MSG_SET_STATE, state, 0).sendToTarget();
+            mHandler.obtainMessage(MyCallback.MSG_SET_STATE, state, 0).sendToTarget();
         }
 
         @Override
         public void notifyServicesStateChanged() {
-            mHandler.obtainMessage(MyHandler.MSG_NOTIFY_SERVICES_STATE_CHANGED).sendToTarget();
+            mHandler.obtainMessage(MyCallback.MSG_NOTIFY_SERVICES_STATE_CHANGED).sendToTarget();
         }
 
         @Override
@@ -271,7 +274,8 @@
     public AccessibilityManager(Context context, IAccessibilityManager service, int userId) {
         // Constructor can't be chained because we can't create an instance of an inner class
         // before calling another constructor.
-        mHandler = new MyHandler(context.getMainLooper());
+        mCallback = new MyCallback();
+        mHandler = new Handler(context.getMainLooper(), mCallback);
         mUserId = userId;
         synchronized (mLock) {
             tryConnectToServiceLocked(service);
@@ -288,6 +292,7 @@
      * @hide
      */
     public AccessibilityManager(Handler handler, IAccessibilityManager service, int userId) {
+        mCallback = new MyCallback();
         mHandler = handler;
         mUserId = userId;
         synchronized (mLock) {
@@ -303,6 +308,14 @@
     }
 
     /**
+     * @hide
+     */
+    @VisibleForTesting
+    public Handler.Callback getCallback() {
+        return mCallback;
+    }
+
+    /**
      * Returns if the accessibility in the system is enabled.
      *
      * @return True if accessibility is enabled, false otherwise.
@@ -711,15 +724,15 @@
         mIsHighTextContrastEnabled = highTextContrastEnabled;
 
         if (wasEnabled != enabled) {
-            mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED);
+            mHandler.sendEmptyMessage(MyCallback.MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED);
         }
 
         if (wasTouchExplorationEnabled != touchExplorationEnabled) {
-            mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_EXPLORATION_STATE_CHANGED);
+            mHandler.sendEmptyMessage(MyCallback.MSG_NOTIFY_EXPLORATION_STATE_CHANGED);
         }
 
         if (wasHighTextContrastEnabled != highTextContrastEnabled) {
-            mHandler.sendEmptyMessage(MyHandler.MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED);
+            mHandler.sendEmptyMessage(MyCallback.MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED);
         }
     }
 
@@ -960,19 +973,15 @@
         }
     }
 
-    private final class MyHandler extends Handler {
+    private final class MyCallback implements Handler.Callback {
         public static final int MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED = 1;
         public static final int MSG_NOTIFY_EXPLORATION_STATE_CHANGED = 2;
         public static final int MSG_NOTIFY_HIGH_TEXT_CONTRAST_STATE_CHANGED = 3;
         public static final int MSG_SET_STATE = 4;
         public static final int MSG_NOTIFY_SERVICES_STATE_CHANGED = 5;
 
-        public MyHandler(Looper looper) {
-            super(looper, null, false);
-        }
-
         @Override
-        public void handleMessage(Message message) {
+        public boolean handleMessage(Message message) {
             switch (message.what) {
                 case MSG_NOTIFY_ACCESSIBILITY_STATE_CHANGED: {
                     handleNotifyAccessibilityStateChanged();
@@ -998,6 +1007,7 @@
                     }
                 } break;
             }
+            return true;
         }
     }
 }
diff --git a/core/java/android/view/autofill/AutoFillId.aidl b/core/java/android/view/autofill/AutoFillId.aidl
deleted file mode 100644
index fc57ce7..0000000
--- a/core/java/android/view/autofill/AutoFillId.aidl
+++ /dev/null
@@ -1,20 +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.view.autofill;
-
-//  @deprecated TODO(b/35956626): remove once clients use AutofillId
-parcelable AutoFillId;
\ No newline at end of file
diff --git a/core/java/android/view/autofill/AutoFillId.java b/core/java/android/view/autofill/AutoFillId.java
deleted file mode 100644
index 081fb02..0000000
--- a/core/java/android/view/autofill/AutoFillId.java
+++ /dev/null
@@ -1,85 +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.
- */
-package android.view.autofill;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * @hide
- * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
- */
-@Deprecated
-public final class AutoFillId implements Parcelable {
-
-    private final AutofillId mRealId;
-
-    /** @hide */
-    public AutoFillId(AutofillId daRealId) {
-        this.mRealId = daRealId;
-    }
-
-    @Override
-    public int hashCode() {
-        return mRealId.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        final AutoFillId other = (AutoFillId) obj;
-        return mRealId.equals(other.mRealId);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeParcelable(mRealId, 0);
-    }
-
-    private AutoFillId(Parcel parcel) {
-        mRealId = parcel.readParcelable(null);
-    }
-
-    /** @hide */
-    public AutofillId getDaRealId() {
-        return mRealId;
-    }
-
-    /** @hide */
-    public static AutoFillId forDaRealId(AutofillId id) {
-        return id == null ? null : new AutoFillId(id);
-    }
-
-    public static final Parcelable.Creator<AutoFillId> CREATOR =
-            new Parcelable.Creator<AutoFillId>() {
-        @Override
-        public AutoFillId createFromParcel(Parcel source) {
-            return new AutoFillId(source);
-        }
-
-        @Override
-        public AutoFillId[] newArray(int size) {
-            return new AutoFillId[size];
-        }
-    };
-}
diff --git a/core/java/android/view/autofill/AutoFillType.java b/core/java/android/view/autofill/AutoFillType.java
deleted file mode 100644
index c508ba4..0000000
--- a/core/java/android/view/autofill/AutoFillType.java
+++ /dev/null
@@ -1,188 +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.
- */
-
-package android.view.autofill;
-
-import static android.view.autofill.Helper.DEBUG;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.View;
-
-/**
- * Defines the type of a object that can be used to autofill a {@link View} so the
- * {@link android.service.autofill.AutofillService} can use the proper {@link AutofillValue} to
- * fill it.
- *
- * @hide
- * @deprecated TODO(b/35956626): remove once clients use getAutoFilltype
- */
-@Deprecated
-public final class AutoFillType implements Parcelable {
-
-    // Cached instance for types that don't have subtype; it uses the "lazy initialization holder
-    // class idiom" (Effective Java, Item 71) to avoid memory utilization when autofill is not
-    // enabled.
-    private static class DefaultTypesHolder {
-        static final AutoFillType TEXT = new AutoFillType(TYPE_TEXT);
-        static final AutoFillType TOGGLE = new AutoFillType(TYPE_TOGGLE);
-        static final AutoFillType LIST = new AutoFillType(TYPE_LIST);
-        static final AutoFillType DATE = new AutoFillType(TYPE_DATE);
-    }
-
-    private static final int TYPE_TEXT = 1;
-    private static final int TYPE_TOGGLE = 2;
-    private static final int TYPE_LIST = 3;
-    private static final int TYPE_DATE = 4;
-
-    private final int mType;
-
-    private AutoFillType(int type) {
-        mType = type;
-    }
-
-    /**
-     * Checks if this is a type for a text field, which is filled by a {@link CharSequence}.
-     */
-    public boolean isText() {
-        return mType == TYPE_TEXT;
-    }
-
-    /**
-     * Checks if this is a a type for a togglable field, which is filled by a {@code boolean}.
-     */
-    public boolean isToggle() {
-        return mType == TYPE_TOGGLE;
-    }
-
-    /**
-     * Checks if this is a type for a selection list field, which is filled by a {@code integer}
-     * representing the element index inside the list (starting at {@code 0}.
-      */
-    public boolean isList() {
-        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()}.
-     */
-    public boolean isDate() {
-        return mType == TYPE_DATE;
-    }
-
-    /////////////////////////////////////
-    //  Object "contract" methods. //
-    /////////////////////////////////////
-
-    @Override
-    public String toString() {
-        if (!DEBUG) return super.toString();
-
-        return "AutoFillType [type=" + mType + "]";
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + mType;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        final AutoFillType other = (AutoFillType) obj;
-        if (mType != other.mType) return false;
-        return true;
-    }
-
-    /////////////////////////////////////
-    //  Parcelable "contract" methods. //
-    /////////////////////////////////////
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeInt(mType);
-    }
-
-    private AutoFillType(Parcel parcel) {
-        mType = parcel.readInt();
-    }
-
-    public static final Parcelable.Creator<AutoFillType> CREATOR =
-            new Parcelable.Creator<AutoFillType>() {
-        @Override
-        public AutoFillType createFromParcel(Parcel source) {
-            return new AutoFillType(source);
-        }
-
-        @Override
-        public AutoFillType[] newArray(int size) {
-            return new AutoFillType[size];
-        }
-    };
-
-    ////////////////////
-    // Factory methods //
-    ////////////////////
-
-    /**
-     * Creates a text field type, which is filled by a {@link CharSequence}.
-     *
-     * <p>See {@link #isText()} for more info.
-     */
-    public static AutoFillType forText() {
-        return DefaultTypesHolder.TEXT;
-    }
-
-    /**
-     * Creates a type that can be toggled which is filled by a {@code boolean}.
-     *
-     * <p>See {@link #isToggle()} for more info.
-     */
-    public static AutoFillType forToggle() {
-        return DefaultTypesHolder.TOGGLE;
-    }
-
-    /**
-     * Creates a selection list, which is filled by a {@code integer} representing the element index
-     * inside the list (starting at {@code 0}.
-     *
-     * <p>See {@link #isList()} for more info.
-     */
-    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
deleted file mode 100644
index 4774d8f..0000000
--- a/core/java/android/view/autofill/AutoFillValue.java
+++ /dev/null
@@ -1,181 +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.view.autofill;
-
-import static android.view.autofill.Helper.DEBUG;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.view.View;
-
-/**
- * @hide
- * @deprecated TODO(b/35956626): remove once clients use AutofillValue
- */
-@Deprecated
-public final class AutoFillValue implements Parcelable {
-    private final AutofillValue mRealValue;
-
-    private AutoFillValue(AutofillValue daRealValue) {
-        this.mRealValue = daRealValue;
-    }
-
-    /**
-     * Gets the value to autofill a text field.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
-     */
-    public CharSequence getTextValue() {
-        return mRealValue.getTextValue();
-    }
-
-    /**
-     * Gets the value to autofill a toggable field.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_TOGGLE} for more info.
-     */
-    public boolean getToggleValue() {
-        return mRealValue.getToggleValue();
-    }
-
-    /**
-     * Gets the value to autofill a selection list field.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_LIST} for more info.
-     */
-    public int getListValue() {
-        return mRealValue.getListValue();
-    }
-
-    /**
-     * Gets the value to autofill a date field.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_DATE} for more info.
-     */
-    public long getDateValue() {
-        return mRealValue.getDateValue();
-    }
-
-    /////////////////////////////////////
-    //  Object "contract" methods. //
-    /////////////////////////////////////
-
-    @Override
-    public int hashCode() {
-        return mRealValue.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        final AutoFillValue other = (AutoFillValue) obj;
-        return mRealValue.equals(other.mRealValue);
-    }
-
-    @Override
-    public String toString() {
-        if (!DEBUG) return super.toString();
-
-        return mRealValue.toString();
-    }
-
-    /////////////////////////////////////
-    //  Parcelable "contract" methods. //
-    /////////////////////////////////////
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeParcelable(mRealValue, 0);
-    }
-
-    private AutoFillValue(Parcel parcel) {
-        mRealValue = parcel.readParcelable(null);
-    }
-
-    public static final Parcelable.Creator<AutoFillValue> CREATOR =
-            new Parcelable.Creator<AutoFillValue>() {
-        @Override
-        public AutoFillValue createFromParcel(Parcel source) {
-            return new AutoFillValue(source);
-        }
-
-        @Override
-        public AutoFillValue[] newArray(int size) {
-            return new AutoFillValue[size];
-        }
-    };
-
-    ////////////////////
-    // Factory methods //
-    ////////////////////
-    /**
-     * Creates a new {@link AutoFillValue} to autofill a {@link View} representing a text field.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_TEXT} for more info.
-     */
-    @Nullable
-    public static AutoFillValue forText(@Nullable CharSequence value) {
-        return value == null ? null : new AutoFillValue(AutofillValue.forText(value));
-    }
-
-    /**
-     * Creates a new {@link AutoFillValue} to autofill a {@link View} representing a toggable
-     * field.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_TOGGLE} for more info.
-     */
-    public static AutoFillValue forToggle(boolean value) {
-        return new AutoFillValue(AutofillValue.forToggle(value));
-    }
-
-    /**
-     * Creates a new {@link AutoFillValue} to autofill a {@link View} representing a selection
-     * list.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_LIST} for more info.
-     */
-    public static AutoFillValue forList(int value) {
-        return new AutoFillValue(AutofillValue.forList(value));
-    }
-
-    /**
-     * Creates a new {@link AutoFillValue} to autofill a {@link View} representing a date.
-     *
-     * <p>See {@link View#AUTOFILL_TYPE_DATE} for more info.
-     */
-    public static AutoFillValue forDate(long date) {
-        return new AutoFillValue(AutofillValue.forDate(date));
-    }
-
-    /** @hide */
-    public static AutoFillValue forDaRealValue(AutofillValue daRealValue) {
-        return new AutoFillValue(daRealValue);
-    }
-
-    /** @hide */
-    public AutofillValue getDaRealValue() {
-        return mRealValue;
-    }
-}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 636fa7d..61920bd 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -411,8 +411,16 @@
     public abstract  boolean getUseWebViewBackgroundForOverscrollBackground();
 
     /**
-     * Sets whether the WebView should save form data. The default is true.
+     * Sets whether the WebView should save form data. In Android O, the
+     * platform has implemented a fully functional Autofill feature to store
+     * form data. Therefore, the Webview form data save feature is disabled.
+     *
+     * Note that the feature will continue to be supported on older versions of
+     * Android as before.
+     *
+     * This function does not have any effect.
      */
+    @Deprecated
     public abstract  void setSaveFormData(boolean save);
 
     /**
@@ -421,6 +429,7 @@
      * @return whether the WebView saves form data
      * @see #setSaveFormData
      */
+    @Deprecated
     public abstract boolean getSaveFormData();
 
     /**
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index 87d3c7b..982c57b 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -143,6 +143,7 @@
      * @return whether there is any saved data for web forms
      * @see #clearFormData
      */
+    @Deprecated
     public abstract boolean hasFormData();
 
     /**
@@ -150,5 +151,6 @@
      *
      * @see #hasFormData
      */
+    @Deprecated
     public abstract void clearFormData();
 }
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index da00d9c..0bf2460 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -1443,7 +1443,7 @@
 
     @Override
     public void requestChildFocus(View child, View focused) {
-        if (focused.getRevealOnFocusHint()) {
+        if (focused != null && focused.getRevealOnFocusHint()) {
             if (!mIsLayoutDirty) {
                 scrollToChild(focused);
             } else {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 0a9e361..8fc4f50 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1468,7 +1468,7 @@
 
     @Override
     public void requestChildFocus(View child, View focused) {
-        if (focused.getRevealOnFocusHint()) {
+        if (focused != null && focused.getRevealOnFocusHint()) {
             if (!mIsLayoutDirty) {
                 scrollToChild(focused);
             } else {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2721afd..7d9253b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -615,7 +615,7 @@
 
     private int mBreakStrategy;
     private int mHyphenationFrequency;
-    private boolean mJustify;
+    private int mJustificationMode;
 
     private int mMaximum = Integer.MAX_VALUE;
     private int mMaxMode = LINES;
@@ -826,7 +826,7 @@
         String fontFeatureSettings = null;
         mBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE;
         mHyphenationFrequency = Layout.HYPHENATION_FREQUENCY_NONE;
-        mJustify = false;
+        mJustificationMode = Layout.JUSTIFICATION_MODE_NONE;
 
         final Resources.Theme theme = context.getTheme();
 
@@ -3774,14 +3774,15 @@
     }
 
     /**
-     * Enables or disables full justification. The default value is false. If the last line is too
-     * short for justification, the last line will be displayed with the alignment set by
-     * {@link android.view.View#setTextAlignment}.
+     * Set justification mode. The default value is {@link Layout#JUSTIFICATION_MODE_NONE}. If the
+     * last line is too short for justification, the last line will be displayed with the
+     * alignment set by {@link android.view.View#setTextAlignment}.
      *
-     * @see #getJustify()
+     * @see #getJustificationMode()
      */
-    public void setJustify(boolean justify) {
-        mJustify = justify;
+    @Layout.JustificationMode
+    public void setJustificationMode(@Layout.JustificationMode int justificationMode) {
+        mJustificationMode = justificationMode;
         if (mLayout != null) {
             nullLayouts();
             requestLayout();
@@ -3790,12 +3791,12 @@
     }
 
     /**
-     * @return true if currently paragraph justification is enabled.
+     * @return true if currently paragraph justification mode.
      *
-     * @see #setJustify(boolean)
+     * @see #setJustificationMode(int)
      */
-    public boolean getJustify() {
-        return mJustify;
+    public @Layout.JustificationMode int getJustificationMode() {
+        return mJustificationMode;
     }
 
     /**
@@ -7728,7 +7729,7 @@
                         .setIncludePad(mIncludePad)
                         .setBreakStrategy(mBreakStrategy)
                         .setHyphenationFrequency(mHyphenationFrequency)
-                        .setJustify(mJustify)
+                        .setJustificationMode(mJustificationMode)
                         .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
                 if (shouldEllipsize) {
                     builder.setEllipsize(mEllipsize)
@@ -7770,7 +7771,7 @@
         if (mText instanceof Spannable) {
             result = new DynamicLayout(mText, mTransformed, mTextPaint, wantWidth,
                     alignment, mTextDir, mSpacingMult, mSpacingAdd, mIncludePad,
-                    mBreakStrategy, mHyphenationFrequency, mJustify,
+                    mBreakStrategy, mHyphenationFrequency, mJustificationMode,
                     getKeyListener() == null ? effectiveEllipsize : null, ellipsisWidth);
         } else {
             if (boring == UNKNOWN_BORING) {
@@ -7820,7 +7821,7 @@
                     .setIncludePad(mIncludePad)
                     .setBreakStrategy(mBreakStrategy)
                     .setHyphenationFrequency(mHyphenationFrequency)
-                    .setJustify(mJustify)
+                    .setJustificationMode(mJustificationMode)
                     .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
             if (shouldEllipsize) {
                 builder.setEllipsize(effectiveEllipsize)
@@ -8160,7 +8161,7 @@
                     .setIncludePad(getIncludeFontPadding())
                     .setBreakStrategy(getBreakStrategy())
                     .setHyphenationFrequency(getHyphenationFrequency())
-                    .setJustify(getJustify())
+                    .setJustificationMode(getJustificationMode())
                     .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE)
                     .setTextDirection(getTextDirectionHeuristic());
 
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
index f987a9f..caf35b3 100644
--- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -55,8 +55,8 @@
             in RemoteViews views);
     void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views);
     void notifyAppWidgetViewDataChanged(String packageName, in int[] appWidgetIds, int viewId);
-    ParceledListSlice getInstalledProvidersForProfile(int categoryFilter,
-            int profileId);
+    ParceledListSlice getInstalledProvidersForProfile(int categoryFilter, int profileId,
+            String packageName);
     AppWidgetProviderInfo getAppWidgetInfo(String callingPackage, int appWidgetId);
     boolean hasBindAppWidgetPermission(in String packageName, int userId);
     void setBindAppWidgetPermission(in String packageName, int userId, in boolean permission);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index b263657..d19ffad 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -114,7 +114,7 @@
     private static final int MAGIC = 0xBA757475; // 'BATSTATS'
 
     // Current on-disk Parcel version
-    private static final int VERSION = 152 + (USE_OLD_HISTORY ? 1000 : 0);
+    private static final int VERSION = 153 + (USE_OLD_HISTORY ? 1000 : 0);
 
     // Maximum number of items we will record in the history.
     private static final int MAX_HISTORY_ITEMS = 2000;
@@ -2006,107 +2006,92 @@
      * State for keeping track of two DurationTimers with different TimeBases, presumably where one
      * TimeBase is effectively a subset of the other.
      */
-    public static class DualTimer {
-        // mMainTimer typically tracks the total time. May be pooled (but since it's a durationTimer,
-        // it also has the unpooled getTotalDurationMsLocked() for STATS_SINCE_CHARGED).
-        private final DurationTimer mMainTimer;
+    public static class DualTimer extends DurationTimer {
+        // This class both is a DurationTimer and also holds a second DurationTimer.
+        // The main timer (this) typically tracks the total time. It may be pooled (but since it's a
+        // durationTimer, it also has the unpooled getTotalDurationMsLocked() for
+        // STATS_SINCE_CHARGED).
         // mSubTimer typically tracks only part of the total time, such as background time, as
         // determined by a subTimeBase. It is NOT pooled.
         private final DurationTimer mSubTimer;
 
         /**
-         * Creates a DualTimer to hold a mMainTimer and a mSubTimer.
-         * The mMainTimer is based on the given timeBase and timerPool.
+         * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
+         * The main timer (this) is based on the given timeBase and timerPool.
          * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
-         * the mMainTimer is.
+         * the main timer is.
          */
         public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
                 TimeBase timeBase, TimeBase subTimeBase, Parcel in) {
-            mMainTimer = new DurationTimer(clocks, uid, type, timerPool, timeBase, in);
+            super(clocks, uid, type, timerPool, timeBase, in);
             mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in);
         }
 
         /**
-         * Creates a DualTimer to hold a mMainTimer and a mSubTimer.
-         * The mMainTimer is based on the given timeBase and timerPool.
+         * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
+         * The main timer (this) is based on the given timeBase and timerPool.
          * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
-         * the mMainTimer is.
+         * the main timer is.
          */
         public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
                 TimeBase timeBase, TimeBase subTimeBase) {
-            mMainTimer = new DurationTimer(clocks, uid, type, timerPool, timeBase);
+            super(clocks, uid, type, timerPool, timeBase);
             mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase);
         }
 
-        /** Get the main timer. */
-        public DurationTimer getMainTimer() {
-            return mMainTimer;
-        }
-
         /** Get the secondary timer. */
+        @Override
         public DurationTimer getSubTimer() {
             return mSubTimer;
         }
 
+        @Override
         public void startRunningLocked(long elapsedRealtimeMs) {
-            mMainTimer.startRunningLocked(elapsedRealtimeMs);
+            super.startRunningLocked(elapsedRealtimeMs);
             mSubTimer.startRunningLocked(elapsedRealtimeMs);
         }
 
+        @Override
         public void stopRunningLocked(long elapsedRealtimeMs) {
-            mMainTimer.stopRunningLocked(elapsedRealtimeMs);
+            super.stopRunningLocked(elapsedRealtimeMs);
             mSubTimer.stopRunningLocked(elapsedRealtimeMs);
         }
 
+        @Override
         public void stopAllRunningLocked(long elapsedRealtimeMs) {
-            mMainTimer.stopAllRunningLocked(elapsedRealtimeMs);
+            super.stopAllRunningLocked(elapsedRealtimeMs);
             mSubTimer.stopAllRunningLocked(elapsedRealtimeMs);
         }
 
-        public void setMark(long elapsedRealtimeMs) {
-            mMainTimer.setMark(elapsedRealtimeMs);
-            mSubTimer.setMark(elapsedRealtimeMs);
-        }
-
+        @Override
         public boolean reset(boolean detachIfReset) {
             boolean active = false;
-            active |= !mMainTimer.reset(detachIfReset);
+            active |= !super.reset(detachIfReset);
             active |= !mSubTimer.reset(detachIfReset);
             return !active;
         }
 
+        @Override
         public void detach() {
-            mMainTimer.detach();
+            super.detach();
             mSubTimer.detach();
         }
 
-        /**
-         * Writes a possibly null DualTimer to a Parcel.
-         *
-         * @param out the Parcel to which to write.
-         * @param t a DualTimer, or null.
-         */
-        public static void writeDualTimerToParcel(Parcel out, DualTimer t, long elapsedRealtimeUs) {
-            if (t != null) {
-                out.writeInt(1);
-                t.writeToParcel(out, elapsedRealtimeUs);
-            } else {
-                out.writeInt(0);
-            }
-        }
-
+        @Override
         public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
-            mMainTimer.writeToParcel(out, elapsedRealtimeUs);
+            super.writeToParcel(out, elapsedRealtimeUs);
             mSubTimer.writeToParcel(out, elapsedRealtimeUs);
         }
 
+        @Override
         public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
-            mMainTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
+            super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
             mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
         }
 
+        @Override
         public void readSummaryFromParcelLocked(Parcel in) {
-            mMainTimer.readSummaryFromParcelLocked(in);
+            super.readSummaryFromParcelLocked(in);
             mSubTimer.readSummaryFromParcelLocked(in);
         }
     }
@@ -5488,7 +5473,7 @@
         /**
          * The statistics we have collected for this uid's jobs.
          */
-        final OverflowArrayMap<StopwatchTimer> mJobStats;
+        final OverflowArrayMap<DualTimer> mJobStats;
 
         /**
          * The statistics we have collected for this uid's sensor activations.
@@ -5533,10 +5518,10 @@
                             mBsi.mOnBatteryTimeBase);
                 }
             };
-            mJobStats = mBsi.new OverflowArrayMap<StopwatchTimer>(uid) {
-                @Override public StopwatchTimer instantiateObject() {
-                    return new StopwatchTimer(mBsi.mClocks, Uid.this, JOB, null,
-                            mBsi.mOnBatteryTimeBase);
+            mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) {
+                @Override public DualTimer instantiateObject() {
+                    return new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
+                            mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
                 }
             };
 
@@ -5918,7 +5903,7 @@
             if (mWifiScanTimer == null) {
                 return 0;
             }
-            return mWifiScanTimer.getMainTimer().getTotalTimeLocked(elapsedRealtimeUs, which);
+            return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
         }
 
         @Override
@@ -5926,12 +5911,12 @@
             if (mWifiScanTimer == null) {
                 return 0;
             }
-            return mWifiScanTimer.getMainTimer().getCountLocked(which);
+            return mWifiScanTimer.getCountLocked(which);
         }
 
         @Override
         public int getWifiScanBackgroundCount(int which) {
-            if (mWifiScanTimer == null) {
+            if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
                 return 0;
             }
             return mWifiScanTimer.getSubTimer().getCountLocked(which);
@@ -5943,12 +5928,12 @@
                 return 0;
             }
             final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
-            return mWifiScanTimer.getMainTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
+            return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
         }
 
         @Override
         public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) {
-            if (mWifiScanTimer == null) {
+            if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
                 return 0;
             }
             final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
@@ -6008,10 +5993,7 @@
 
         @Override
         public Timer getBluetoothScanTimer() {
-            if (mBluetoothScanTimer == null) {
-                return null;
-            }
-            return mBluetoothScanTimer.getMainTimer();
+            return mBluetoothScanTimer;
         }
 
         @Override
@@ -6361,9 +6343,9 @@
                 }
             }
             mSyncStats.cleanup();
-            final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
+            final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
             for (int ij=jobStats.size()-1; ij>=0; ij--) {
-                StopwatchTimer timer = jobStats.valueAt(ij);
+                DualTimer timer = jobStats.valueAt(ij);
                 if (timer.reset(false)) {
                     jobStats.removeAt(ij);
                     timer.detach();
@@ -6531,12 +6513,12 @@
                 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
             }
 
-            final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
+            final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
             int NJ = jobStats.size();
             out.writeInt(NJ);
             for (int ij=0; ij<NJ; ij++) {
                 out.writeString(jobStats.keyAt(ij));
-                StopwatchTimer timer = jobStats.valueAt(ij);
+                DualTimer timer = jobStats.valueAt(ij);
                 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
             }
 
@@ -6756,8 +6738,8 @@
             for (int j = 0; j < numJobs; j++) {
                 String jobName = in.readString();
                 if (in.readInt() != 0) {
-                    mJobStats.add(jobName, new StopwatchTimer(mBsi.mClocks, Uid.this, JOB, null,
-                                timeBase, in));
+                    mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
+                            mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
                 }
             }
 
@@ -7196,15 +7178,12 @@
             }
 
             void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
-                DualTimer.writeDualTimerToParcel(out, mTimer, elapsedRealtimeUs);
+                Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
             }
 
             @Override
             public Timer getSensorTime() {
-                if (mTimer == null) {
-                    return null;
-                }
-                return mTimer.getMainTimer();
+                return mTimer;
             }
 
             @Override
@@ -8023,7 +8002,7 @@
         }
 
         public void readJobSummaryFromParcelLocked(String name, Parcel in) {
-            StopwatchTimer timer = mJobStats.instantiateObject();
+            DualTimer timer = mJobStats.instantiateObject();
             timer.readSummaryFromParcelLocked(in);
             mJobStats.add(name, timer);
         }
@@ -8084,14 +8063,14 @@
         }
 
         public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
-            StopwatchTimer t = mJobStats.startObject(name);
+            DualTimer t = mJobStats.startObject(name);
             if (t != null) {
                 t.startRunningLocked(elapsedRealtimeMs);
             }
         }
 
         public void noteStopJobLocked(String name, long elapsedRealtimeMs) {
-            StopwatchTimer t = mJobStats.stopObject(name);
+            DualTimer t = mJobStats.stopObject(name);
             if (t != null) {
                 t.stopRunningLocked(elapsedRealtimeMs);
             }
@@ -9149,7 +9128,7 @@
                 final Uid uid = mUidStats.valueAt(i);
 
                 // Sum the total scan power for all apps.
-                totalScanTimeMs += uid.mWifiScanTimer.getMainTimer().getTimeSinceMarkLocked(
+                totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
                         elapsedRealtimeMs * 1000) / 1000;
 
                 // Sum the total time holding wifi lock for all apps.
@@ -9170,7 +9149,7 @@
             for (int i = 0; i < uidStatsSize; i++) {
                 final Uid uid = mUidStats.valueAt(i);
 
-                long scanTimeSinceMarkMs = uid.mWifiScanTimer.getMainTimer().getTimeSinceMarkLocked(
+                long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
                         elapsedRealtimeMs * 1000) / 1000;
                 if (scanTimeSinceMarkMs > 0) {
                     // Set the new mark so that next time we get new data since this point.
@@ -9444,7 +9423,7 @@
                 continue;
             }
 
-            totalScanTimeMs += u.mBluetoothScanTimer.getMainTimer().getTimeSinceMarkLocked(
+            totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked(
                     elapsedRealtimeMs * 1000) / 1000;
         }
 
@@ -9465,7 +9444,7 @@
                 continue;
             }
 
-            long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getMainTimer().getTimeSinceMarkLocked(
+            long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked(
                     elapsedRealtimeMs * 1000) / 1000;
             if (scanTimeSinceMarkMs > 0) {
                 // Set the new mark so that next time we get new data since this point.
@@ -11526,7 +11505,7 @@
                 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
             }
 
-            final ArrayMap<String, StopwatchTimer> jobStats = u.mJobStats.getMap();
+            final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap();
             int NJ = jobStats.size();
             out.writeInt(NJ);
             for (int ij=0; ij<NJ; ij++) {
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 4e68602..3010dc1 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -245,8 +245,7 @@
     }
 
     sk_sp<SkData> data(SkData::MakeWithProc(buf, asset->getLength(), releaseAsset, asset));
-    addSkTypeface(builder, std::move(data), ttcIndex, weight, isItalic);
-    return true;
+    return addSkTypeface(builder, std::move(data), ttcIndex, weight, isItalic);
 }
 
 static void FontFamily_addAxisValue(jlong builderPtr, jint tag, jfloat value) {
diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp
index a77ed62..214d97c 100644
--- a/core/jni/android/graphics/Shader.cpp
+++ b/core/jni/android/graphics/Shader.cpp
@@ -10,6 +10,14 @@
 
 using namespace android::uirenderer;
 
+/**
+ * By default Skia gradients will interpolate their colors in unpremul space
+ * and then premultiply each of the results. We must set this flag to preserve
+ * backwards compatiblity by premultiplying the colors of the gradient first,
+ * and then interpolating between them.
+ */
+static const uint32_t sGradientShaderFlags = SkGradientShader::kInterpolateColorsInPremul_Flag;
+
 static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
     if (NULL == ptr) {
         doThrowIAE(env);
@@ -60,11 +68,18 @@
     }
 
     sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
-    sk_sp<SkShader> shader = image->makeShader(
-            (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY, matrix);
+    sk_sp<SkShader> baseShader = image->makeShader(
+            (SkShader::TileMode)tileModeX, (SkShader::TileMode)tileModeY);
 
-    ThrowIAE_IfNull(env, shader.get());
-    return reinterpret_cast<jlong>(shader.release());
+    SkShader* shader;
+    if (matrix) {
+        shader = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        shader = baseShader.release();
+    }
+
+    ThrowIAE_IfNull(env, shader);
+    return reinterpret_cast<jlong>(shader);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -87,9 +102,16 @@
     #error Need to convert float array to SkScalar array before calling the following function.
 #endif
 
-    SkShader* shader = SkGradientShader::MakeLinear(pts,
+    sk_sp<SkShader> baseShader(SkGradientShader::MakeLinear(pts,
             reinterpret_cast<const SkColor*>(colorValues), pos, count,
-            static_cast<SkShader::TileMode>(tileMode), /* flags */ 0, matrix).release();
+            static_cast<SkShader::TileMode>(tileMode), sGradientShaderFlags, NULL));
+
+    SkShader* shader;
+    if (matrix) {
+        shader = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        shader = baseShader.release();
+    }
 
     env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
     ThrowIAE_IfNull(env, shader);
@@ -108,8 +130,15 @@
     colors[0] = color0;
     colors[1] = color1;
 
-    SkShader* s = SkGradientShader::MakeLinear(pts, colors, NULL, 2,
-            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();
+    sk_sp<SkShader> baseShader(SkGradientShader::MakeLinear(pts, colors, NULL, 2,
+            static_cast<SkShader::TileMode>(tileMode), sGradientShaderFlags, NULL));
+
+    SkShader* s;
+    if (matrix) {
+        s = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        s = baseShader.release();
+    }
 
     ThrowIAE_IfNull(env, s);
     return reinterpret_cast<jlong>(s);
@@ -133,9 +162,17 @@
     #error Need to convert float array to SkScalar array before calling the following function.
 #endif
 
-    SkShader* shader = SkGradientShader::MakeRadial(center, radius,
+    sk_sp<SkShader> baseShader = SkGradientShader::MakeRadial(center, radius,
             reinterpret_cast<const SkColor*>(colorValues), pos, count,
-            static_cast<SkShader::TileMode>(tileMode), /* flags */ 0, matrix).release();
+            static_cast<SkShader::TileMode>(tileMode), sGradientShaderFlags, NULL);
+
+    SkShader* shader;
+    if (matrix) {
+        shader = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        shader = baseShader.release();
+    }
+
     env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues),
                                  JNI_ABORT);
 
@@ -153,10 +190,17 @@
     colors[0] = color0;
     colors[1] = color1;
 
-    SkShader* s = SkGradientShader::MakeRadial(center, radius, colors, NULL, 2,
-            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();
-    ThrowIAE_IfNull(env, s);
-    return reinterpret_cast<jlong>(s);
+    sk_sp<SkShader> baseShader = SkGradientShader::MakeRadial(center, radius, colors, NULL, 2,
+            static_cast<SkShader::TileMode>(tileMode), sGradientShaderFlags, NULL);
+
+    SkShader* shader;
+    if (matrix) {
+        shader = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        shader = baseShader.release();
+    }
+    ThrowIAE_IfNull(env, shader);
+    return reinterpret_cast<jlong>(shader);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -174,8 +218,17 @@
     #error Need to convert float array to SkScalar array before calling the following function.
 #endif
 
-    SkShader* shader = SkGradientShader::MakeSweep(x, y,
-            reinterpret_cast<const SkColor*>(colors), pos, count, /* flags */ 0, matrix).release();
+    sk_sp<SkShader> baseShader = SkGradientShader::MakeSweep(x, y,
+            reinterpret_cast<const SkColor*>(colors), pos, count,
+            sGradientShaderFlags, NULL);
+
+    SkShader* shader;
+    if (matrix) {
+        shader = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        shader = baseShader.release();
+    }
+
     env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors),
                                  JNI_ABORT);
     ThrowIAE_IfNull(env, shader);
@@ -188,10 +241,18 @@
     SkColor colors[2];
     colors[0] = color0;
     colors[1] = color1;
-    SkShader* s = SkGradientShader::MakeSweep(x, y, colors, NULL, 2,
-            /* flags */ 0, matrix).release();
-    ThrowIAE_IfNull(env, s);
-    return reinterpret_cast<jlong>(s);
+
+    sk_sp<SkShader> baseShader = SkGradientShader::MakeSweep(x, y, colors,
+            NULL, 2, sGradientShaderFlags, NULL);
+
+    SkShader* shader;
+    if (matrix) {
+        shader = baseShader->makeWithLocalMatrix(*matrix).release();
+    } else {
+        shader = baseShader.release();
+    }
+    ThrowIAE_IfNull(env, shader);
+    return reinterpret_cast<jlong>(shader);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
index 80f9d57..7121194 100644
--- a/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
+++ b/core/jni/android_hardware_camera2_legacy_LegacyCameraDevice.cpp
@@ -182,7 +182,7 @@
     err = native_window_dequeue_buffer_and_wait(anw.get(), &anb);
     if (err != NO_ERROR) return err;
 
-    sp<GraphicBuffer> buf(new GraphicBuffer(anb, /*keepOwnership*/false));
+    sp<GraphicBuffer> buf(GraphicBuffer::from(anb));
     uint32_t grallocBufWidth = buf->getWidth();
     uint32_t grallocBufHeight = buf->getHeight();
     uint32_t grallocBufStride = buf->getStride();
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e7a447c..7922250 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -528,6 +528,7 @@
     <protected-broadcast android:name="com.android.internal.autofill.action.REQUEST_AUTOFILL" />
     <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.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED" />
 
     <protected-broadcast android:name="android.content.pm.action.SESSION_COMMITTED" />
     <protected-broadcast android:name="android.os.action.USER_RESTRICTIONS_CHANGED" />
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index a165621..5a2bf4e 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -17,27 +17,24 @@
 
 <NotificationHeaderView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:theme="@style/Theme.Material.Notification"
     android:id="@+id/notification_header"
     android:orientation="horizontal"
     android:layout_width="wrap_content"
     android:layout_height="@dimen/notification_header_height"
     android:clipChildren="false"
-    android:paddingTop="@dimen/notification_header_padding_top"
-    android:paddingBottom="@dimen/notification_header_padding_bottom"
-    android:layout_marginBottom="5dp"
-    android:paddingStart="@dimen/notification_content_margin_start"
-    android:paddingEnd="16dp">
+    style="?attr/notificationHeaderStyle">
     <com.android.internal.widget.CachingIconView
         android:id="@+id/icon"
-        android:layout_width="@dimen/notification_header_icon_size"
-        android:layout_height="@dimen/notification_header_icon_size"
+        android:layout_width="?attr/notificationHeaderIconSize"
+        android:layout_height="?attr/notificationHeaderIconSize"
         android:layout_marginEnd="3dp"
         />
     <TextView
         android:id="@+id/app_name_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearance.Material.Notification.Info"
+        android:textAppearance="?attr/notificationHeaderTextAppearance"
         android:layout_marginStart="3dp"
         android:layout_marginEnd="2dp"
         android:singleLine="true"
@@ -46,7 +43,7 @@
         android:id="@+id/header_text_divider"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearance.Material.Notification.Info"
+        android:textAppearance="?attr/notificationHeaderTextAppearance"
         android:layout_marginStart="2dp"
         android:layout_marginEnd="2dp"
         android:text="@string/notification_header_divider_symbol"
@@ -55,7 +52,7 @@
         android:id="@+id/header_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearance.Material.Notification.Info"
+        android:textAppearance="?attr/notificationHeaderTextAppearance"
         android:layout_marginStart="2dp"
         android:layout_marginEnd="2dp"
         android:visibility="gone"
@@ -64,7 +61,7 @@
         android:id="@+id/time_divider"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:textAppearance="@style/TextAppearance.Material.Notification.Info"
+        android:textAppearance="?attr/notificationHeaderTextAppearance"
         android:layout_marginStart="2dp"
         android:layout_marginEnd="2dp"
         android:text="@string/notification_header_divider_symbol"
diff --git a/core/res/res/layout/notification_template_material_ambient.xml b/core/res/res/layout/notification_template_material_ambient.xml
index e2c68b5..026bc6e 100644
--- a/core/res/res/layout/notification_template_material_ambient.xml
+++ b/core/res/res/layout/notification_template_material_ambient.xml
@@ -20,8 +20,11 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:tag="ambient"
+    android:paddingStart="@dimen/notification_extra_margin_ambient"
+    android:paddingEnd="@dimen/notification_extra_margin_ambient"
     >
-    <include layout="@layout/notification_template_header" />
+    <include layout="@layout/notification_template_header"
+        android:theme="@style/Theme.Material.Notification.Ambient" />
 
     <LinearLayout
             android:id="@+id/notification_action_list_margin_target"
@@ -52,7 +55,7 @@
                 android:ellipsize="marquee"
                 android:fadingEdge="horizontal"
                 android:textSize="20sp"
-                android:textColor="#e6fafafa"
+                android:textColor="#ffffffff"
             />
             <TextView android:id="@+id/text"
                 android:layout_width="match_parent"
@@ -63,7 +66,7 @@
                 android:gravity="top"
                 android:visibility="gone"
                 android:textSize="16sp"
-                android:textColor="#ccfafafa"
+                android:textColor="#eeffffff"
                 android:layout_marginTop="4dp"
             />
         </LinearLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index ee73b69..d26d952 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7739,13 +7739,6 @@
         <attr name="settingsActivity" />
     </declare-styleable>
 
-    <!--  TODO(b/35956626): temporary until clients change to AutofillService -->
-    <declare-styleable name="AutoFillService">
-        <!-- Fully qualified class name of an activity that allows the user to modify
-             the settings for this service. -->
-        <attr name="settingsActivity" />
-    </declare-styleable>
-
     <!-- =============================== -->
     <!-- Contacts meta-data attributes -->
     <!-- =============================== -->
@@ -8635,5 +8628,12 @@
         <attr name="stackFromEnd" format="boolean" />
     </declare-styleable>
 
+    <!-- @hide -->
+    <declare-styleable name="NotificationTheme">
+        <attr name="notificationHeaderStyle" format="reference" />
+        <attr name="notificationHeaderTextAppearance" format="reference" />
+        <attr name="notificationHeaderIconSize" format="dimension" />
+    </declare-styleable>
+
     <attr name="lockPatternStyle" format="reference" />
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 85ecaff..221e308 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2822,4 +2822,11 @@
 
     <!-- Whether the device supports quick settings and its associated APIs -->
     <bool name="config_quickSettingsSupported">true</bool>
+
+    <!-- The component name, flattened to a string, for the default autofill service
+         to  enabled for an user. This service must be trusted, as it can be activated
+         without explicit consent of the user. If no autofill service with the
+          specified name exists on the device, autofill will be disabled by default.
+    -->
+    <string name="config_defaultAutofillService" translatable="false"></string>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 1129647..c5316c6 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -165,6 +165,9 @@
     -->
     <dimen name="notification_content_plus_picture_margin_end">72dp</dimen>
 
+    <!-- The additional margin on the sides of the ambient view. -->
+    <dimen name="notification_extra_margin_ambient">16dp</dimen>
+
     <!-- The height of the notification action list -->
     <dimen name="notification_action_list_height">56dp</dimen>
 
@@ -188,6 +191,9 @@
     <!-- size (width and height) of the icon in the notification header -->
     <dimen name="notification_header_icon_size">18dp</dimen>
 
+    <!-- size (width and height) of the icon in the notification header -->
+    <dimen name="notification_header_icon_size_ambient">20dp</dimen>
+
     <!-- Height of a small notification in the status bar -->
     <dimen name="notification_min_height">92dp</dimen>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 831cf89..bf2f355 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -20,8 +20,10 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Suffix added to a number to signify size in bytes. -->
     <string name="byteShort">B</string>
-    <!-- Suffix added to a number to signify size in kilobytes (1000 bytes). -->
-    <string name="kilobyteShort">KB</string>
+    <!-- Suffix added to a number to signify size in kilobytes (1000 bytes).
+        If you retain the Latin script for the localization, please use the lowercase
+        'k', as it signifies 1000 bytes as opposed to 1024 bytes. -->
+    <string name="kilobyteShort">kB</string>
     <!-- Suffix added to a number to signify size in megabytes. -->
     <string name="megabyteShort">MB</string>
     <!-- Suffix added to a number to signify size in gigabytes. -->
@@ -3172,7 +3174,7 @@
     <string name="alert_windows_notification_channel_name"><xliff:g id="name" example="Google Maps">%s</xliff:g> displaying over other apps</string>
     <!-- Notification title when an application is displaying ui on-top of other apps
          [CHAR LIMIT=30] -->
-    <string name="alert_windows_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is displaying over other apps.</string>
+    <string name="alert_windows_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> is displaying over other apps</string>
     <!-- Notification body when an application is displaying ui on-top of other apps
          [CHAR LIMIT=NONE] -->
     <string name="alert_windows_notification_message">If you don’t want <xliff:g id="name" example="Google Maps">%s</xliff:g> to use this feature, tap to open settings and turn it off.</string>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 8f061a3..ec16611 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -488,6 +488,10 @@
 
     <style name="TextAppearance.Material.Notification.Time" parent="TextAppearance.Material.Notification.Info" />
 
+    <style name="TextAppearance.Material.Notification.Info.Ambient">
+        <item name="textSize">@dimen/notification_text_size</item>
+    </style>
+
     <style name="TextAppearance.Material.Notification.Emphasis">
         <item name="textColor">#66000000</item>
     </style>
@@ -1283,4 +1287,12 @@
 
     <style name="DialogWindowTitle.Material.Light" />
 
+    <style name="Notification.Header" parent="">
+        <item name="paddingTop">@dimen/notification_header_padding_top</item>
+        <item name="paddingBottom">@dimen/notification_header_padding_bottom</item>
+        <item name="layout_marginBottom">5dp</item>
+        <item name="paddingStart">@dimen/notification_content_margin_start</item>
+        <item name="paddingEnd">16dp</item>
+    </style>
+
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ae05a69..c12116a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2944,6 +2944,7 @@
   <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" />
+  <java-symbol type="string" name="config_defaultAutofillService" />
 
   <!-- ETWS primary messages -->
   <java-symbol type="string" name="etws_primary_default_message_earthquake" />
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 008c817..9dafa7a 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -1321,6 +1321,19 @@
         <item name="windowNoTitle">true</item>
     </style>
 
+    <!-- Theme for inflating notifications -->
+    <style name="Theme.Material.Notification" parent="">
+        <item name="notificationHeaderStyle">@style/Notification.Header</item>
+        <item name="notificationHeaderTextAppearance">@style/TextAppearance.Material.Notification.Info</item>
+        <item name="notificationHeaderIconSize">@dimen/notification_header_icon_size</item>
+    </style>
+
+    <!-- Theme for inflating ambient notification -->
+    <style name="Theme.Material.Notification.Ambient">
+        <item name="notificationHeaderTextAppearance">@style/TextAppearance.Material.Notification.Info.Ambient</item>
+        <item name="notificationHeaderIconSize">@dimen/notification_header_icon_size_ambient</item>
+    </style>
+
     <!-- Default theme for Settings and activities launched from Settings. -->
     <style name="Theme.Material.Settings" parent="Theme.Material.Light.LightStatusBar">
         <item name="colorPrimary">@color/primary_material_settings_light</item>
diff --git a/core/res/res/xml/time_zones_by_country.xml b/core/res/res/xml/time_zones_by_country.xml
index 6c1ce44..22bfea1 100644
--- a/core/res/res/xml/time_zones_by_country.xml
+++ b/core/res/res/xml/time_zones_by_country.xml
@@ -31,11 +31,11 @@
 
     <!-- ANTIGUA AND BARBUDA, -4:00 -->
 
-    <timezone code="ag">America/Port_of_Spain</timezone>
+    <timezone code="ag">America/Antigua</timezone>
 
     <!-- ANGUILLA, -4:00 -->
 
-    <timezone code="ai">America/Port_of_Spain</timezone>
+    <timezone code="ai">America/Anguilla</timezone>
 
     <!-- ALBANIA, 1:00 -->
 
@@ -47,11 +47,11 @@
 
     <!-- ANGOLA, 1:00 -->
 
-    <timezone code="ao">Africa/Lagos</timezone>
+    <timezone code="ao">Africa/Luanda</timezone>
 
     <!-- ANTARCTICA, 12:00 -->
 
-    <timezone code="aq">Pacific/Auckland</timezone>
+    <timezone code="aq">Antarctica/McMurdo</timezone>
 
     <!-- ANTARCTICA, 10:00 -->
 
@@ -144,11 +144,11 @@
 
     <!-- ARUBA, -4:00 -->
 
-    <timezone code="aw">America/Curacao</timezone>
+    <timezone code="aw">America/Aruba</timezone>
 
     <!-- ALAND ISLANDS, 2:00 -->
 
-    <timezone code="ax">Europe/Helsinki</timezone>
+    <timezone code="ax">Europe/Mariehamn</timezone>
 
     <!-- AZERBAIJAN, 4:00 -->
 
@@ -156,7 +156,7 @@
 
     <!-- BOSNIA AND HERZEGOVINA, 1:00 -->
 
-    <timezone code="ba">Europe/Belgrade</timezone>
+    <timezone code="ba">Europe/Sarajevo</timezone>
 
     <!-- BARBADOS, -4:00 -->
 
@@ -172,7 +172,7 @@
 
     <!-- BURKINA FASO, 0:00 -->
 
-    <timezone code="bf">Africa/Abidjan</timezone>
+    <timezone code="bf">Africa/Ouagadougou</timezone>
 
     <!-- BULGARIA, 2:00 -->
 
@@ -180,19 +180,19 @@
 
     <!-- BAHRAIN, 3:00 -->
 
-    <timezone code="bh">Asia/Qatar</timezone>
+    <timezone code="bh">Asia/Bahrain</timezone>
 
     <!-- BURUNDI, 2:00 -->
 
-    <timezone code="bi">Africa/Maputo</timezone>
+    <timezone code="bi">Africa/Bujumbura</timezone>
 
     <!-- BENIN, 1:00 -->
 
-    <timezone code="bj">Africa/Lagos</timezone>
+    <timezone code="bj">Africa/Porto-Novo</timezone>
 
     <!-- Saint Barthélemy, -4:00 -->
 
-    <timezone code="bl">America/Port_of_Spain</timezone>
+    <timezone code="bl">America/St_Barthelemy</timezone>
 
     <!-- BERMUDA, -4:00 -->
 
@@ -208,7 +208,7 @@
 
     <!-- Caribbean Netherlands, -4:00 -->
 
-    <timezone code="bq">America/Curacao</timezone>
+    <timezone code="bq">America/Kralendijk</timezone>
 
     <!-- BRAZIL, -2:00 -->
 
@@ -248,7 +248,7 @@
 
     <!-- BOTSWANA, 2:00 -->
 
-    <timezone code="bw">Africa/Maputo</timezone>
+    <timezone code="bw">Africa/Gaborone</timezone>
 
     <!-- BELARUS, 3:00 -->
 
@@ -310,19 +310,19 @@
 
     <!-- CONGO, THE DEMOCRATIC REPUBLIC OF THE, 2:00 -->
 
-    <timezone code="cd">Africa/Maputo</timezone>
+    <timezone code="cd">Africa/Lubumbashi</timezone>
 
     <!-- CONGO, THE DEMOCRATIC REPUBLIC OF THE, 1:00 -->
 
-    <timezone code="cd">Africa/Lagos</timezone>
+    <timezone code="cd">Africa/Kinshasa</timezone>
 
     <!-- CENTRAL AFRICAN REPUBLIC, 1:00 -->
 
-    <timezone code="cf">Africa/Lagos</timezone>
+    <timezone code="cf">Africa/Bangui</timezone>
 
     <!-- CONGO, 1:00 -->
 
-    <timezone code="cg">Africa/Lagos</timezone>
+    <timezone code="cg">Africa/Brazzaville</timezone>
 
     <!-- SWITZERLAND, 1:00 -->
 
@@ -350,7 +350,7 @@
 
     <!-- CAMEROON, 1:00 -->
 
-    <timezone code="cm">Africa/Lagos</timezone>
+    <timezone code="cm">Africa/Douala</timezone>
 
     <!-- CHINA, 8:00 -->
 
@@ -388,6 +388,10 @@
 
     <timezone code="cy">Asia/Nicosia</timezone>
 
+    <!-- CYPRUS, 3:00 -->
+
+    <timezone code="cy">Asia/Famagusta</timezone>
+
     <!-- CZECH REPUBLIC, 1:00 -->
 
     <timezone code="cz">Europe/Prague</timezone>
@@ -395,11 +399,11 @@
     <!-- GERMANY, 1:00 -->
 
     <timezone code="de">Europe/Berlin</timezone>
-    <timezone code="de">Europe/Zurich</timezone>
+    <timezone code="de">Europe/Busingen</timezone>
 
     <!-- DJIBOUTI, 3:00 -->
 
-    <timezone code="dj">Africa/Nairobi</timezone>
+    <timezone code="dj">Africa/Djibouti</timezone>
 
     <!-- DENMARK, 1:00 -->
 
@@ -407,7 +411,7 @@
 
     <!-- DOMINICA, -4:00 -->
 
-    <timezone code="dm">America/Port_of_Spain</timezone>
+    <timezone code="dm">America/Dominica</timezone>
 
     <!-- DOMINICAN REPUBLIC, -4:00 -->
 
@@ -439,7 +443,7 @@
 
     <!-- ERITREA, 3:00 -->
 
-    <timezone code="er">Africa/Nairobi</timezone>
+    <timezone code="er">Africa/Asmara</timezone>
 
     <!-- SPAIN, 1:00 -->
 
@@ -452,7 +456,7 @@
 
     <!-- ETHIOPIA, 3:00 -->
 
-    <timezone code="et">Africa/Nairobi</timezone>
+    <timezone code="et">Africa/Addis_Ababa</timezone>
 
     <!-- FINLAND, 2:00 -->
 
@@ -468,7 +472,7 @@
 
     <!-- MICRONESIA, FEDERATED STATES OF, 11:00 -->
 
-    <timezone code="fm">Pacific/Ponape</timezone>
+    <timezone code="fm">Pacific/Pohnpei</timezone>
     <timezone code="fm">Pacific/Kosrae</timezone>
 
     <!-- MICRONESIA, FEDERATED STATES OF, 10:00 -->
@@ -485,7 +489,7 @@
 
     <!-- GABON, 1:00 -->
 
-    <timezone code="ga">Africa/Lagos</timezone>
+    <timezone code="ga">Africa/Libreville</timezone>
 
     <!-- UNITED KINGDOM, 0:00 -->
 
@@ -493,7 +497,7 @@
 
     <!-- GRENADA, -4:00 -->
 
-    <timezone code="gd">America/Port_of_Spain</timezone>
+    <timezone code="gd">America/Grenada</timezone>
 
     <!-- GEORGIA, 4:00 -->
 
@@ -505,7 +509,7 @@
 
     <!-- GUERNSEY, 0:00 -->
 
-    <timezone code="gg">Europe/London</timezone>
+    <timezone code="gg">Europe/Guernsey</timezone>
 
     <!-- GHANA, 0:00 -->
 
@@ -533,19 +537,19 @@
 
     <!-- GAMBIA, 0:00 -->
 
-    <timezone code="gm">Africa/Abidjan</timezone>
+    <timezone code="gm">Africa/Banjul</timezone>
 
     <!-- GUINEA, 0:00 -->
 
-    <timezone code="gn">Africa/Abidjan</timezone>
+    <timezone code="gn">Africa/Conakry</timezone>
 
     <!-- GUADELOUPE, -4:00 -->
 
-    <timezone code="gp">America/Port_of_Spain</timezone>
+    <timezone code="gp">America/Guadeloupe</timezone>
 
     <!-- EQUATORIAL GUINEA, 1:00 -->
 
-    <timezone code="gq">Africa/Lagos</timezone>
+    <timezone code="gq">Africa/Malabo</timezone>
 
     <!-- GREECE, 2:00 -->
 
@@ -581,7 +585,7 @@
 
     <!-- CROATIA, 1:00 -->
 
-    <timezone code="hr">Europe/Belgrade</timezone>
+    <timezone code="hr">Europe/Zagreb</timezone>
 
     <!-- HAITI, -5:00 -->
 
@@ -614,7 +618,7 @@
 
     <!-- ISLE OF MAN, 0:00 -->
 
-    <timezone code="im">Europe/London</timezone>
+    <timezone code="im">Europe/Isle_of_Man</timezone>
 
     <!-- INDIA, 5:30 -->
 
@@ -642,7 +646,7 @@
 
     <!-- JERSEY, 0:00 -->
 
-    <timezone code="je">Europe/London</timezone>
+    <timezone code="je">Europe/Jersey</timezone>
 
     <!-- JAMAICA, -5:00 -->
 
@@ -666,7 +670,7 @@
 
     <!-- CAMBODIA, 7:00 -->
 
-    <timezone code="kh">Asia/Bangkok</timezone>
+    <timezone code="kh">Asia/Phnom_Penh</timezone>
 
     <!-- KIRIBATI, 14:00 -->
 
@@ -682,11 +686,11 @@
 
     <!-- COMOROS, 3:00 -->
 
-    <timezone code="km">Africa/Nairobi</timezone>
+    <timezone code="km">Indian/Comoro</timezone>
 
     <!-- SAINT KITTS AND NEVIS, -4:00 -->
 
-    <timezone code="kn">America/Port_of_Spain</timezone>
+    <timezone code="kn">America/St_Kitts</timezone>
 
     <!-- KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF, 8:30 -->
 
@@ -698,11 +702,11 @@
 
     <!-- KUWAIT, 3:00 -->
 
-    <timezone code="kw">Asia/Riyadh</timezone>
+    <timezone code="kw">Asia/Kuwait</timezone>
 
     <!-- CAYMAN ISLANDS, -5:00 -->
 
-    <timezone code="ky">America/Panama</timezone>
+    <timezone code="ky">America/Cayman</timezone>
 
     <!-- KAZAKHSTAN, 6:00 -->
 
@@ -714,10 +718,11 @@
     <timezone code="kz">Asia/Aqtau</timezone>
     <timezone code="kz">Asia/Oral</timezone>
     <timezone code="kz">Asia/Aqtobe</timezone>
+    <timezone code="kz">Asia/Atyrau</timezone>
 
     <!-- LAO PEOPLE'S DEMOCRATIC REPUBLIC, 7:00 -->
 
-    <timezone code="la">Asia/Bangkok</timezone>
+    <timezone code="la">Asia/Vientiane</timezone>
 
     <!-- LEBANON, 2:00 -->
 
@@ -725,11 +730,11 @@
 
     <!-- SAINT LUCIA, -4:00 -->
 
-    <timezone code="lc">America/Port_of_Spain</timezone>
+    <timezone code="lc">America/St_Lucia</timezone>
 
     <!-- LIECHTENSTEIN, 1:00 -->
 
-    <timezone code="li">Europe/Zurich</timezone>
+    <timezone code="li">Europe/Vaduz</timezone>
 
     <!-- SRI LANKA, 5:30 -->
 
@@ -741,7 +746,7 @@
 
     <!-- LESOTHO, 2:00 -->
 
-    <timezone code="ls">Africa/Johannesburg</timezone>
+    <timezone code="ls">Africa/Maseru</timezone>
 
     <!-- LITHUANIA, 2:00 -->
 
@@ -773,15 +778,15 @@
 
     <!-- MONTENEGRO, 1:00 -->
 
-    <timezone code="me">Europe/Belgrade</timezone>
+    <timezone code="me">Europe/Podgorica</timezone>
 
     <!-- Collectivity of Saint Martin, -4:00 -->
 
-    <timezone code="mf">America/Port_of_Spain</timezone>
+    <timezone code="mf">America/Marigot</timezone>
 
     <!-- MADAGASCAR, 3:00 -->
 
-    <timezone code="mg">Africa/Nairobi</timezone>
+    <timezone code="mg">Indian/Antananarivo</timezone>
 
     <!-- MARSHALL ISLANDS, 12:00 -->
 
@@ -790,11 +795,11 @@
 
     <!-- MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF, 1:00 -->
 
-    <timezone code="mk">Europe/Belgrade</timezone>
+    <timezone code="mk">Europe/Skopje</timezone>
 
     <!-- MALI, 0:00 -->
 
-    <timezone code="ml">Africa/Abidjan</timezone>
+    <timezone code="ml">Africa/Bamako</timezone>
 
     <!-- MYANMAR, 6:30 -->
 
@@ -815,7 +820,7 @@
 
     <!-- NORTHERN MARIANA ISLANDS, 10:00 -->
 
-    <timezone code="mp">Pacific/Guam</timezone>
+    <timezone code="mp">Pacific/Saipan</timezone>
 
     <!-- MARTINIQUE, -4:00 -->
 
@@ -823,11 +828,11 @@
 
     <!-- MAURITANIA, 0:00 -->
 
-    <timezone code="mr">Africa/Abidjan</timezone>
+    <timezone code="mr">Africa/Nouakchott</timezone>
 
     <!-- MONTSERRAT, -4:00 -->
 
-    <timezone code="ms">America/Port_of_Spain</timezone>
+    <timezone code="ms">America/Montserrat</timezone>
 
     <!-- MALTA, 1:00 -->
 
@@ -843,7 +848,7 @@
 
     <!-- MALAWI, 2:00 -->
 
-    <timezone code="mw">Africa/Maputo</timezone>
+    <timezone code="mw">Africa/Blantyre</timezone>
 
     <!-- MEXICO, -6:00 -->
 
@@ -887,7 +892,7 @@
 
     <!-- NIGER, 1:00 -->
 
-    <timezone code="ne">Africa/Lagos</timezone>
+    <timezone code="ne">Africa/Niamey</timezone>
 
     <!-- NORFOLK ISLAND, 11:30 -->
 
@@ -911,7 +916,7 @@
 
     <!-- NEPAL, 5:45 -->
 
-    <timezone code="np">Asia/Katmandu</timezone>
+    <timezone code="np">Asia/Kathmandu</timezone>
 
     <!-- NAURU, 12:00 -->
 
@@ -931,7 +936,7 @@
 
     <!-- OMAN, 4:00 -->
 
-    <timezone code="om">Asia/Dubai</timezone>
+    <timezone code="om">Asia/Muscat</timezone>
 
     <!-- PANAMA, -5:00 -->
 
@@ -1070,6 +1075,7 @@
     <timezone code="ru">Europe/Samara</timezone>
     <timezone code="ru">Europe/Astrakhan</timezone>
     <timezone code="ru">Europe/Ulyanovsk</timezone>
+    <timezone code="ru">Europe/Saratov</timezone>
 
     <!-- RUSSIAN FEDERATION, 3:00 -->
 
@@ -1084,7 +1090,7 @@
 
     <!-- RWANDA, 2:00 -->
 
-    <timezone code="rw">Africa/Maputo</timezone>
+    <timezone code="rw">Africa/Kigali</timezone>
 
     <!-- SAUDI ARABIA, 3:00 -->
 
@@ -1112,35 +1118,35 @@
 
     <!-- SAINT HELENA, 0:00 -->
 
-    <timezone code="sh">Africa/Abidjan</timezone>
+    <timezone code="sh">Atlantic/St_Helena</timezone>
 
     <!-- SLOVENIA, 1:00 -->
 
-    <timezone code="si">Europe/Belgrade</timezone>
+    <timezone code="si">Europe/Ljubljana</timezone>
 
     <!-- SVALBARD AND JAN MAYEN, 1:00 -->
 
-    <timezone code="sj">Europe/Oslo</timezone>
+    <timezone code="sj">Arctic/Longyearbyen</timezone>
 
     <!-- SLOVAKIA, 1:00 -->
 
-    <timezone code="sk">Europe/Prague</timezone>
+    <timezone code="sk">Europe/Bratislava</timezone>
 
     <!-- SIERRA LEONE, 0:00 -->
 
-    <timezone code="sl">Africa/Abidjan</timezone>
+    <timezone code="sl">Africa/Freetown</timezone>
 
     <!-- SAN MARINO, 1:00 -->
 
-    <timezone code="sm">Europe/Rome</timezone>
+    <timezone code="sm">Europe/San_Marino</timezone>
 
     <!-- SENEGAL, 0:00 -->
 
-    <timezone code="sn">Africa/Abidjan</timezone>
+    <timezone code="sn">Africa/Dakar</timezone>
 
     <!-- SOMALIA, 3:00 -->
 
-    <timezone code="so">Africa/Nairobi</timezone>
+    <timezone code="so">Africa/Mogadishu</timezone>
 
     <!-- SURINAME, -3:00 -->
 
@@ -1148,11 +1154,11 @@
 
     <!-- South Sudan, 3:00 -->
 
-    <timezone code="ss">Africa/Khartoum</timezone>
+    <timezone code="ss">Africa/Juba</timezone>
 
     <!-- SAO TOME AND PRINCIPE, 0:00 -->
 
-    <timezone code="st">Africa/Abidjan</timezone>
+    <timezone code="st">Africa/Sao_Tome</timezone>
 
     <!-- EL SALVADOR, -6:00 -->
 
@@ -1160,7 +1166,7 @@
 
     <!-- Sint Maarten, -4:00 -->
 
-    <timezone code="sx">America/Curacao</timezone>
+    <timezone code="sx">America/Lower_Princes</timezone>
 
     <!-- SYRIAN ARAB REPUBLIC, 2:00 -->
 
@@ -1168,7 +1174,7 @@
 
     <!-- SWAZILAND, 2:00 -->
 
-    <timezone code="sz">Africa/Johannesburg</timezone>
+    <timezone code="sz">Africa/Mbabane</timezone>
 
     <!-- TURKS AND CAICOS ISLANDS, -4:00 -->
 
@@ -1182,13 +1188,9 @@
 
     <timezone code="tf">Indian/Kerguelen</timezone>
 
-    <!-- FRENCH SOUTHERN TERRITORIES, 4:00 -->
-
-    <timezone code="tf">Indian/Reunion</timezone>
-
     <!-- TOGO, 0:00 -->
 
-    <timezone code="tg">Africa/Abidjan</timezone>
+    <timezone code="tg">Africa/Lome</timezone>
 
     <!-- THAILAND, 7:00 -->
 
@@ -1236,7 +1238,7 @@
 
     <!-- TANZANIA, UNITED REPUBLIC OF, 3:00 -->
 
-    <timezone code="tz">Africa/Nairobi</timezone>
+    <timezone code="tz">Africa/Dar_es_Salaam</timezone>
 
     <!-- UKRAINE, 2:00 -->
 
@@ -1246,19 +1248,15 @@
 
     <!-- UGANDA, 3:00 -->
 
-    <timezone code="ug">Africa/Nairobi</timezone>
+    <timezone code="ug">Africa/Kampala</timezone>
 
     <!-- UNITED STATES MINOR OUTLYING ISLANDS, 12:00 -->
 
     <timezone code="um">Pacific/Wake</timezone>
 
-    <!-- UNITED STATES MINOR OUTLYING ISLANDS, -10:00 -->
-
-    <timezone code="um">Pacific/Honolulu</timezone>
-
     <!-- UNITED STATES MINOR OUTLYING ISLANDS, -11:00 -->
 
-    <timezone code="um">Pacific/Pago_Pago</timezone>
+    <timezone code="um">Pacific/Midway</timezone>
 
     <!-- UNITED STATES, -5:00 -->
 
@@ -1318,11 +1316,11 @@
 
     <!-- HOLY SEE (VATICAN CITY STATE), 1:00 -->
 
-    <timezone code="va">Europe/Rome</timezone>
+    <timezone code="va">Europe/Vatican</timezone>
 
     <!-- SAINT VINCENT AND THE GRENADINES, -4:00 -->
 
-    <timezone code="vc">America/Port_of_Spain</timezone>
+    <timezone code="vc">America/St_Vincent</timezone>
 
     <!-- VENEZUELA, -4:00 -->
 
@@ -1330,16 +1328,15 @@
 
     <!-- VIRGIN ISLANDS, BRITISH, -4:00 -->
 
-    <timezone code="vg">America/Port_of_Spain</timezone>
+    <timezone code="vg">America/Tortola</timezone>
 
     <!-- VIRGIN ISLANDS, U.S., -4:00 -->
 
-    <timezone code="vi">America/Port_of_Spain</timezone>
+    <timezone code="vi">America/St_Thomas</timezone>
 
     <!-- VIET NAM, 7:00 -->
 
     <timezone code="vn">Asia/Ho_Chi_Minh</timezone>
-    <timezone code="vn">Asia/Bangkok</timezone>
 
     <!-- VANUATU, 11:00 -->
 
@@ -1355,11 +1352,11 @@
 
     <!-- YEMEN, 3:00 -->
 
-    <timezone code="ye">Asia/Riyadh</timezone>
+    <timezone code="ye">Asia/Aden</timezone>
 
     <!-- MAYOTTE, 3:00 -->
 
-    <timezone code="yt">Africa/Nairobi</timezone>
+    <timezone code="yt">Indian/Mayotte</timezone>
 
     <!-- SOUTH AFRICA, 2:00 -->
 
@@ -1367,9 +1364,9 @@
 
     <!-- ZAMBIA, 2:00 -->
 
-    <timezone code="zm">Africa/Maputo</timezone>
+    <timezone code="zm">Africa/Lusaka</timezone>
 
     <!-- ZIMBABWE, 2:00 -->
 
-    <timezone code="zw">Africa/Maputo</timezone>
+    <timezone code="zw">Africa/Harare</timezone>
 </timezones>
diff --git a/core/tests/coretests/src/android/provider/FontsContractTest.java b/core/tests/coretests/src/android/provider/FontsContractTest.java
index 6820e92..1dd3ef6 100644
--- a/core/tests/coretests/src/android/provider/FontsContractTest.java
+++ b/core/tests/coretests/src/android/provider/FontsContractTest.java
@@ -94,7 +94,8 @@
         FontResult fontResult = resultList.get(0);
         assertEquals(TestFontsProvider.TTC_INDEX, fontResult.getTtcIndex());
         assertEquals(TestFontsProvider.VARIATION_SETTINGS, fontResult.getFontVariationSettings());
-        assertEquals(TestFontsProvider.STYLE, fontResult.getStyle());
+        assertEquals(TestFontsProvider.NORMAL_WEIGHT, fontResult.getWeight());
+        assertEquals(TestFontsProvider.ITALIC, fontResult.getItalic());
         assertNotNull(fontResult.getFileDescriptor());
     }
 
@@ -115,7 +116,8 @@
         FontResult fontResult = resultList.get(0);
         assertEquals(0, fontResult.getTtcIndex());
         assertNull(fontResult.getFontVariationSettings());
-        assertEquals(Typeface.NORMAL, fontResult.getStyle());
+        assertEquals(400, fontResult.getWeight());
+        assertFalse(fontResult.getItalic());
         assertNotNull(fontResult.getFileDescriptor());
     }
 
@@ -146,10 +148,10 @@
     public void testGetFontFromProvider_resultFontNotFoundSecondRow() {
         MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
                 FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
-                FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
-        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
-                FontsContract.Columns.RESULT_CODE_OK});
-        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC,
+                FontsContract.Columns.RESULT_CODE });
+        cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
+        cursor.addRow(new Object[] { 1, 0, null, 400, 0,
                 FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND});
         mProvider.setCustomCursor(cursor);
         mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
@@ -160,13 +162,12 @@
     public void testGetFontFromProvider_resultFontNotFoundOtherRow() {
         MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
                 FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
-                FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
-        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
-                FontsContract.Columns.RESULT_CODE_OK});
-        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
+                FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC,
+                FontsContract.Columns.RESULT_CODE });
+        cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
+        cursor.addRow(new Object[] { 1, 0, null, 400, 0,
                 FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND});
-        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
-                FontsContract.Columns.RESULT_CODE_OK});
+        cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
         mProvider.setCustomCursor(cursor);
         mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
 
@@ -176,10 +177,10 @@
     public void testGetFontFromProvider_resultCodeIsNegativeNumber() {
         MatrixCursor cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
                 FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
-                FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
-        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL,
-                FontsContract.Columns.RESULT_CODE_OK});
-        cursor.addRow(new Object[] { 1, 0, null, Typeface.NORMAL, -5});
+                FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC,
+                FontsContract.Columns.RESULT_CODE });
+        cursor.addRow(new Object[] { 1, 0, null, 400, 0, FontsContract.Columns.RESULT_CODE_OK});
+        cursor.addRow(new Object[] { 1, 0, null, 400, 0, -5});
         mProvider.setCustomCursor(cursor);
         mContract.getFontFromProvider(request, mResultReceiver, TestFontsProvider.AUTHORITY);
 
diff --git a/core/tests/coretests/src/android/provider/TestFontsProvider.java b/core/tests/coretests/src/android/provider/TestFontsProvider.java
index 13f5318..46906df 100644
--- a/core/tests/coretests/src/android/provider/TestFontsProvider.java
+++ b/core/tests/coretests/src/android/provider/TestFontsProvider.java
@@ -37,7 +37,8 @@
     static final String AUTHORITY = "android.provider.TestFontsProvider";
     static final int TTC_INDEX = 2;
     static final String VARIATION_SETTINGS = "'wdth' 1";
-    static final int STYLE = Typeface.BOLD;
+    static final int NORMAL_WEIGHT = 400;
+    static final boolean ITALIC = false;
 
     private ParcelFileDescriptor mPfd;
     private boolean mReturnAllFields = true;
@@ -81,8 +82,9 @@
         if (mReturnAllFields) {
             cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID,
                     FontsContract.Columns.TTC_INDEX, FontsContract.Columns.VARIATION_SETTINGS,
-                    FontsContract.Columns.STYLE, FontsContract.Columns.RESULT_CODE });
-            cursor.addRow(new Object[] { 1, TTC_INDEX, VARIATION_SETTINGS, STYLE, mResultCode });
+                    FontsContract.Columns.WEIGHT, FontsContract.Columns.ITALIC,
+                    FontsContract.Columns.RESULT_CODE });
+            cursor.addRow(new Object[] { 1, TTC_INDEX, VARIATION_SETTINGS, 400, 0, mResultCode });
         } else {
             cursor = new MatrixCursor(new String[] { FontsContract.Columns._ID });
             cursor.addRow(new Object[] { 1 });
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
index 6b52b98..8283335 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBackgroundStatsTest.java
@@ -21,6 +21,7 @@
 import android.os.BatteryStats;
 import android.os.WorkSource;
 import android.support.test.filters.SmallTest;
+import android.util.ArrayMap;
 
 import junit.framework.TestCase;
 
@@ -187,4 +188,65 @@
         assertEquals((305 - 202) * 1000, actualTime);
         assertEquals((305 - 254) * 1000, bgTime);
     }
+
+    @SmallTest
+    public void testJob() throws Exception {
+        final MockClocks clocks = new MockClocks();
+        MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+        final String jobName = "job_name";
+        long curr = 0; // realtime in us
+
+        // On battery
+        curr = 1000 * (clocks.realtime = clocks.uptime = 100);
+        bi.updateTimeBasesLocked(true, false, curr, curr); // on battery
+        // App in foreground
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
+
+        // Start timer
+        curr = 1000 * (clocks.realtime = clocks.uptime = 151);
+        bi.noteJobStartLocked(jobName, UID);
+
+        // Stop timer
+        curr = 1000 * (clocks.realtime = clocks.uptime = 161);
+        bi.noteJobFinishLocked(jobName, UID);
+
+        // Start timer
+        curr = 1000 * (clocks.realtime = clocks.uptime = 202);
+        bi.noteJobStartLocked(jobName, UID);
+
+        // Move to background
+        curr = 1000 * (clocks.realtime = clocks.uptime = 254);
+        bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+        // Off battery
+        curr = 1000 * (clocks.realtime = clocks.uptime = 305);
+        bi.updateTimeBasesLocked(false, false, curr, curr); // off battery
+
+        // Stop timer
+        curr = 1000 * (clocks.realtime = clocks.uptime = 409);
+        bi.noteJobFinishLocked(jobName, UID);
+
+        // Test
+        curr = 1000 * (clocks.realtime = clocks.uptime = 657);
+        final ArrayMap<String, ? extends BatteryStats.Timer> jobs =
+                bi.getUidStats().get(UID).getJobStats();
+        assertEquals(1, jobs.size());
+        BatteryStats.Timer timer = jobs.valueAt(0);
+        BatteryStats.Timer bgTimer = timer.getSubTimer();
+        long time = timer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED);
+        int count = timer.getCountLocked(STATS_SINCE_CHARGED);
+        int bgCount = bgTimer.getCountLocked(STATS_SINCE_CHARGED);
+        long bgTime = bgTimer.getTotalTimeLocked(curr, STATS_SINCE_CHARGED);
+        assertEquals((161 - 151 + 305 - 202) * 1000, time);
+        assertEquals(2, count);
+        assertEquals(1, bgCount);
+        assertEquals((305 - 254) * 1000, bgTime);
+
+        // Test that a second job is separate.
+        curr = 1000 * (clocks.realtime = clocks.uptime = 3000);
+        final String jobName2 = "second_job";
+        bi.noteJobStartLocked(jobName2, UID);
+        assertEquals(2, bi.getUidStats().get(UID).getJobStats().size());
+        bi.noteJobFinishLocked(jobName2, UID);
+    }
 }
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 560d29f..5afe5e9 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -357,8 +357,8 @@
                 long fontSize = fileChannel.size();
                 ByteBuffer fontBuffer = fileChannel.map(
                         FileChannel.MapMode.READ_ONLY, 0, fontSize);
-                int style = result.getStyle();
-                int weight = (style & BOLD) != 0 ? 700 : 400;
+                int weight = result.getWeight();
+                int italic = result.getItalic() ? Builder.ITALIC : Builder.NORMAL;
                 FontVariationAxis[] axes = null;
                 try {
                     axes = FontVariationAxis.fromFontVariationSettings(
@@ -366,8 +366,8 @@
                 } catch (FontVariationAxis.InvalidFormatException e) {
                     // TODO: Nice to pass FontVariationAxis[] directly instead of string.
                 }
-                if (!fontFamily.addFontFromBuffer(fontBuffer, result.getTtcIndex(), axes, weight,
-                        (style & ITALIC) == 0 ? Builder.NORMAL : Builder.ITALIC)) {
+                if (!fontFamily.addFontFromBuffer(fontBuffer, result.getTtcIndex(),
+                        axes, weight, italic)) {
                     Log.e(TAG, "Error creating font " + request.getQuery());
                     callback.onTypefaceRequestFailed(
                             FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR);
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index d88aee9..a491d7e 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -210,6 +210,7 @@
     /**
      * Change the global fade duration when a new drawable is entering
      * the scene.
+     *
      * @param ms The amount of time to fade in milliseconds.
      */
     public void setEnterFadeDuration(int ms) {
@@ -219,6 +220,7 @@
     /**
      * Change the global fade duration when a new drawable is leaving
      * the scene.
+     *
      * @param ms The amount of time to fade in milliseconds.
      */
     public void setExitFadeDuration(int ms) {
@@ -375,6 +377,13 @@
 
     @Override
     public void invalidateDrawable(@NonNull Drawable who) {
+        // This may have been called as the result of a tint changing, in
+        // which case we may need to refresh the cached statefulness or
+        // opacity.
+        if (mDrawableContainerState != null) {
+            mDrawableContainerState.invalidateCache();
+        }
+
         if (who == mCurrDrawable && getCallback() != null) {
             getCallback().invalidateDrawable(this);
         }
@@ -822,8 +831,8 @@
             mDrawables[pos] = dr;
             mNumChildren++;
             mChildrenChangingConfigurations |= dr.getChangingConfigurations();
-            mCheckedStateful = false;
-            mCheckedOpacity = false;
+
+            invalidateCache();
 
             mConstantPadding = null;
             mCheckedPadding = false;
@@ -833,6 +842,14 @@
             return pos;
         }
 
+        /**
+         * Invalidates the cached opacity and statefulness.
+         */
+        void invalidateCache() {
+            mCheckedOpacity = false;
+            mCheckedStateful = false;
+        }
+
         final int getCapacity() {
             return mDrawables.length;
         }
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index 355e45e..b159f0f 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -32,6 +32,7 @@
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.LayoutDirection;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
 
@@ -66,6 +67,8 @@
  * @attr ref android.R.styleable#LayerDrawableItem_id
 */
 public class LayerDrawable extends Drawable implements Drawable.Callback {
+    private static final String LOG_TAG = "LayerDrawable";
+
     /**
      * Padding mode used to nest each layer inside the padding of the previous
      * layer.
@@ -89,6 +92,7 @@
      */
     public static final int INSET_UNDEFINED = Integer.MIN_VALUE;
 
+    @NonNull
     LayerState mLayerState;
 
     private int[] mPaddingL;
@@ -170,13 +174,9 @@
             throws XmlPullParserException, IOException {
         super.inflate(r, parser, attrs, theme);
 
-        final LayerState state = mLayerState;
-        if (state == null) {
-            return;
-        }
-
         // The density may have changed since the last update. This will
         // apply scaling to any existing constant state properties.
+        final LayerState state = mLayerState;
         final int density = Drawable.resolveDensity(r, 0);
         state.setDensity(density);
 
@@ -202,10 +202,6 @@
         super.applyTheme(t);
 
         final LayerState state = mLayerState;
-        if (state == null) {
-            return;
-        }
-
         final int density = Drawable.resolveDensity(t.getResources(), 0);
         state.setDensity(density);
 
@@ -403,7 +399,7 @@
 
     @Override
     public boolean canApplyTheme() {
-        return (mLayerState != null && mLayerState.canApplyTheme()) || super.canApplyTheme();
+        return mLayerState.canApplyTheme() || super.canApplyTheme();
     }
 
     /**
@@ -986,6 +982,11 @@
         if (mSuspendChildInvalidation) {
             mChildRequestedInvalidation = true;
         } else {
+            // This may have been called as the result of a tint changing, in
+            // which case we may need to refresh the cached statefulness or
+            // opacity.
+            mLayerState.invalidateCache();
+
             invalidateSelf();
         }
     }
@@ -1836,15 +1837,24 @@
                 final ConstantState cs = dr.getConstantState();
                 if (cs == null) {
                     clone = dr;
+                    if (dr.getCallback() != null) {
+                        // This drawable already has an owner.
+                        Log.w(LOG_TAG, "Invalid drawable added to LayerDrawable! Drawable already "
+                                + "belongs to another owner but does not expose a constant state.",
+                                new RuntimeException());
+                    }
                 } else if (res != null) {
                     clone = cs.newDrawable(res);
                 } else {
                     clone = cs.newDrawable();
                 }
-                clone.setCallback(owner);
                 clone.setLayoutDirection(dr.getLayoutDirection());
                 clone.setBounds(dr.getBounds());
                 clone.setLevel(dr.getLevel());
+
+                // Set the callback last to prevent invalidation from
+                // propagating before the constant state has been set.
+                clone.setCallback(owner);
             } else {
                 clone = null;
             }
@@ -2121,7 +2131,10 @@
             return true;
         }
 
-        public void invalidateCache() {
+        /**
+         * Invalidates the cached opacity and statefulness.
+         */
+        void invalidateCache() {
             mCheckedOpacity = false;
             mCheckedStateful = false;
         }
diff --git a/graphics/java/android/graphics/fonts/FontResult.java b/graphics/java/android/graphics/fonts/FontResult.java
index 3ef99fd..20e736e 100644
--- a/graphics/java/android/graphics/fonts/FontResult.java
+++ b/graphics/java/android/graphics/fonts/FontResult.java
@@ -35,7 +35,8 @@
     private final ParcelFileDescriptor mFileDescriptor;
     private final int mTtcIndex;
     private final String mFontVariationSettings;
-    private final int mStyle;
+    private final int mWeight;
+    private final boolean mItalic;
 
     /**
      * Creates a FontResult with all the information needed about a provided font.
@@ -45,16 +46,16 @@
      *                       will fail to load in the client application.
      * @param ttcIndex If providing a TTC_INDEX file, the index to point to. Otherwise, 0.
      * @param fontVariationSettings If providing a variation font, the settings for it. May be null.
-     * @param style One of {@link android.graphics.Typeface#NORMAL},
-     *              {@link android.graphics.Typeface#BOLD}, {@link android.graphics.Typeface#ITALIC}
-     *              or {@link android.graphics.Typeface#BOLD_ITALIC}
+     * @param weight An integer that indicates the font weight.
+     * @param italic A boolean that indicates the font is italic style or not.
      */
     public FontResult(@NonNull ParcelFileDescriptor fileDescriptor, int ttcIndex,
-            @Nullable String fontVariationSettings, int style) {
+            @Nullable String fontVariationSettings, int weight, boolean italic) {
         mFileDescriptor = Preconditions.checkNotNull(fileDescriptor);
         mTtcIndex = ttcIndex;
         mFontVariationSettings = fontVariationSettings;
-        mStyle = style;
+        mWeight = weight;
+        mItalic = italic;
     }
 
     public ParcelFileDescriptor getFileDescriptor() {
@@ -69,8 +70,12 @@
         return mFontVariationSettings;
     }
 
-    public int getStyle() {
-        return mStyle;
+    public int getWeight() {
+        return mWeight;
+    }
+
+    public boolean getItalic() {
+        return mItalic;
     }
 
     @Override
@@ -83,14 +88,16 @@
         dest.writeParcelable(mFileDescriptor, flags);
         dest.writeInt(mTtcIndex);
         dest.writeString(mFontVariationSettings);
-        dest.writeInt(mStyle);
+        dest.writeInt(mWeight);
+        dest.writeBoolean(mItalic);
     }
 
     private FontResult(Parcel in) {
         mFileDescriptor = in.readParcelable(null);
         mTtcIndex = in.readInt();
         mFontVariationSettings = in.readString();
-        mStyle = in.readInt();
+        mWeight = in.readInt();
+        mItalic = in.readBoolean();
     }
 
     public static final Parcelable.Creator<FontResult> CREATOR =
diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp
index dceb285..d4d0c99 100644
--- a/libs/hwui/GradientCache.cpp
+++ b/libs/hwui/GradientCache.cpp
@@ -189,9 +189,9 @@
         float amount, uint8_t*& dst) const {
     float oppAmount = 1.0f - amount;
     float a = start.a * oppAmount + end.a * amount;
-    *dst++ = uint8_t(a * OECF(start.r * oppAmount + end.r * amount) * 255.0f);
-    *dst++ = uint8_t(a * OECF(start.g * oppAmount + end.g * amount) * 255.0f);
-    *dst++ = uint8_t(a * OECF(start.b * oppAmount + end.b * amount) * 255.0f);
+    *dst++ = uint8_t(OECF(start.r * oppAmount + end.r * amount) * 255.0f);
+    *dst++ = uint8_t(OECF(start.g * oppAmount + end.g * amount) * 255.0f);
+    *dst++ = uint8_t(OECF(start.b * oppAmount + end.b * amount) * 255.0f);
     *dst++ = uint8_t(a * 255.0f);
 }
 
@@ -202,13 +202,13 @@
     float* d = (float*) dst;
 #ifdef ANDROID_ENABLE_LINEAR_BLENDING
     // We want to stay linear
-    *d++ = a * (start.r * oppAmount + end.r * amount);
-    *d++ = a * (start.g * oppAmount + end.g * amount);
-    *d++ = a * (start.b * oppAmount + end.b * amount);
+    *d++ = (start.r * oppAmount + end.r * amount);
+    *d++ = (start.g * oppAmount + end.g * amount);
+    *d++ = (start.b * oppAmount + end.b * amount);
 #else
-    *d++ = a * OECF(start.r * oppAmount + end.r * amount);
-    *d++ = a * OECF(start.g * oppAmount + end.g * amount);
-    *d++ = a * OECF(start.b * oppAmount + end.b * amount);
+    *d++ = OECF(start.r * oppAmount + end.r * amount);
+    *d++ = OECF(start.g * oppAmount + end.g * amount);
+    *d++ = OECF(start.b * oppAmount + end.b * amount);
 #endif
     *d++ = a;
     dst += 4 * sizeof(float);
@@ -229,10 +229,10 @@
     ChannelMixer mix = gMixers[mUseFloatTexture];
 
     FloatColor start;
-    start.setUnPreMultiplied(colors[0]);
+    start.set(colors[0]);
 
     FloatColor end;
-    end.setUnPreMultiplied(colors[1]);
+    end.set(colors[1]);
 
     int currentPos = 1;
     float startPos = positions[0];
@@ -247,7 +247,7 @@
 
             currentPos++;
 
-            end.setUnPreMultiplied(colors[currentPos]);
+            end.set(colors[currentPos]);
             distance = positions[currentPos] - startPos;
         }
 
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index 1f78e09..d0f0949 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -295,10 +295,6 @@
         vec4 dither(const vec4 color) {
             return color + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
         }
-        vec4 gradientMix(const vec4 a, const vec4 b, float v) {
-            vec4 c = mix(a, b, v);
-            return vec4(c.rgb * c.a, c.a);
-        }
         )__SHADER__",
         // sRGB framebuffer
         R"__SHADER__(
@@ -306,10 +302,6 @@
             vec3 dithered = sqrt(color.rgb) + (triangleNoise(gl_FragCoord.xy * screenSize.xy) / 255.0);
             return vec4(dithered * dithered, color.a);
         }
-        vec4 gradientMixMix(const vec4 a, const vec4 b, float v) {
-            vec4 c = mix(a, b, v);
-            return vec4(c.rgb * c.a, c.a);
-        }
         )__SHADER__",
 };
 
@@ -364,19 +356,19 @@
         // Linear
         "    vec4 gradientColor = texture2D(gradientSampler, linear);\n",
 
-        "    vec4 gradientColor = gradientMix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
+        "    vec4 gradientColor = mix(startColor, endColor, clamp(linear, 0.0, 1.0));\n",
 
         // Circular
         "    vec4 gradientColor = texture2D(gradientSampler, vec2(length(circular), 0.5));\n",
 
-        "    vec4 gradientColor = gradientMix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
+        "    vec4 gradientColor = mix(startColor, endColor, clamp(length(circular), 0.0, 1.0));\n",
 
         // Sweep
         "    highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
         "    vec4 gradientColor = texture2D(gradientSampler, vec2(index - floor(index), 0.5));\n",
 
         "    highp float index = atan(sweep.y, sweep.x) * 0.15915494309; // inv(2 * PI)\n"
-        "    vec4 gradientColor = gradientMix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
+        "    vec4 gradientColor = mix(startColor, endColor, clamp(index - floor(index), 0.0, 1.0));\n"
 };
 const char* gFS_Main_FetchBitmap =
         "    vec4 bitmapColor = colorConvert(texture2D(bitmapSampler, outBitmapTexCoords));\n";
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 8a504d4..5c5378b 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -173,8 +173,8 @@
         outData->gradientSampler = 0;
         outData->gradientTexture = nullptr;
 
-        outData->startColor.setUnPreMultiplied(gradInfo.fColors[0]);
-        outData->endColor.setUnPreMultiplied(gradInfo.fColors[1]);
+        outData->startColor.set(gradInfo.fColors[0]);
+        outData->endColor.set(gradInfo.fColors[1]);
     }
 
     return true;
diff --git a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
index 2ead5c5..d26eb59 100644
--- a/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
+++ b/libs/hwui/pipeline/skia/ReorderBarrierDrawables.cpp
@@ -162,7 +162,7 @@
     SkAutoCanvasRestore acr(canvas, true);
 
     SkMatrix shadowMatrix;
-    mat4 hwuiMatrix(caster->getRecordedMatrix());
+    mat4 hwuiMatrix;
     // TODO we don't pass the optional boolean to treat it as a 4x4 matrix
     caster->getRenderNode()->applyViewPropertyTransforms(hwuiMatrix);
     hwuiMatrix.copyTo(shadowMatrix);
diff --git a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
index 652954b..686d06f 100644
--- a/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
+++ b/libs/hwui/tests/unit/RenderNodeDrawableTests.cpp
@@ -941,3 +941,67 @@
     EXPECT_EQ(2, canvas.mDrawCounter);
 }
 
+
+TEST(ReorderBarrierDrawable, testShadowMatrix) {
+    static const int CANVAS_WIDTH = 100;
+    static const int CANVAS_HEIGHT = 100;
+    static const float TRANSLATE_X = 11.0f;
+    static const float TRANSLATE_Y = 22.0f;
+    static const float CASTER_X = 40.0f;
+    static const float CASTER_Y = 40.0f;
+    static const float CASTER_WIDTH = 20.0f;
+    static const float CASTER_HEIGHT = 20.0f;
+
+
+    class ShadowTestCanvas : public SkCanvas {
+    public:
+        ShadowTestCanvas(int width, int height) : SkCanvas(width, height) {}
+        int getIndex() { return mDrawCounter; }
+
+        virtual void onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix) override {
+            // expect to draw 2 RenderNodeDrawable, 1 StartReorderBarrierDrawable,
+            // 1 EndReorderBarrierDrawable
+            mDrawCounter++;
+            SkCanvas::onDrawDrawable(drawable, matrix);
+        }
+
+        virtual void didTranslate(SkScalar dx, SkScalar dy) override {
+            mDrawCounter++;
+            EXPECT_EQ(dx, TRANSLATE_X);
+            EXPECT_EQ(dy, TRANSLATE_Y);
+        }
+
+        virtual void didConcat(const SkMatrix& matrix) override {
+            // This function is invoked by EndReorderBarrierDrawable::drawShadow to apply shadow
+            // matrix.
+            mDrawCounter++;
+            EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X, CASTER_Y), matrix);
+            EXPECT_EQ(SkMatrix::MakeTrans(CASTER_X+TRANSLATE_X, CASTER_Y+TRANSLATE_Y),
+                    getTotalMatrix());
+        }
+    protected:
+        int mDrawCounter = 0;
+    };
+
+    auto parent = TestUtils::createSkiaNode(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT,
+            [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+        canvas.translate(TRANSLATE_X, TRANSLATE_Y);
+        canvas.insertReorderBarrier(true);
+
+        auto node = TestUtils::createSkiaNode(CASTER_X, CASTER_Y, CASTER_X + CASTER_WIDTH,
+                CASTER_Y + CASTER_HEIGHT,
+                [](RenderProperties& props, SkiaRecordingCanvas& canvas) {
+                    props.setElevation(42);
+                    props.mutableOutline().setRoundRect(0, 0, 20, 20, 5, 1);
+                    props.mutableOutline().setShouldClip(true);
+                });
+        canvas.drawRenderNode(node.get());
+        canvas.insertReorderBarrier(false);
+    });
+
+    //create a canvas not backed by any device/pixels, but with dimensions to avoid quick rejection
+    ShadowTestCanvas canvas(CANVAS_WIDTH, CANVAS_HEIGHT);
+    RenderNodeDrawable drawable(parent.get(), &canvas, false);
+    canvas.drawDrawable(&drawable);
+    EXPECT_EQ(6, canvas.getIndex());
+}
\ No newline at end of file
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index e36ceb8..77a82ec 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -913,6 +913,29 @@
         }
     }
 
+    // TODO remove, replaced by non-static API getVolumeControlStream()
+    /**
+     * Returns the stream type matching the given attributes for volume control.
+     * Use this method to derive the stream type needed to configure the volume
+     * control slider in an {@link android.app.Activity} with
+     * {@link android.app.Activity#setVolumeControlStream(int)}.
+     * <BR>Do not use this method to set the stream type on an audio player object
+     * (e.g. {@link AudioTrack}, {@link MediaPlayer}) as this is deprecated,
+     * use <code>AudioAttributes</code> instead.
+     * @param aa non-null AudioAttributes.
+     * @return a valid stream type for <code>Activity</code> or stream volume control that matches
+     *     the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct
+     *     match. Note that <code>USE_DEFAULT_STREAM_TYPE</code> is not a valid value
+     *     for {@link AudioManager#setStreamVolume(int, int, int)}.
+     * @deprecated use {@link #getVolumeControlStream()}
+     */
+    public static int getVolumeControlStream(@NonNull AudioAttributes aa) {
+        if (aa == null) {
+            throw new IllegalArgumentException("Invalid null audio attributes");
+        }
+        return toVolumeStreamType(true /*fromGetVolumeControlStream*/, aa);
+    }
+
     /**
      * Returns the stream type matching this {@code AudioAttributes} instance for volume control.
      * Use this method to derive the stream type needed to configure the volume
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index d8c3eca..0b27d18 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -568,9 +568,10 @@
     }
 
     /**
-     * Common base for the tables of TV programs.
+     * Common columns for the tables of TV programs.
+     * @hide
      */
-    public interface BaseProgramColumns extends BaseTvColumns {
+    interface ProgramColumns {
         /**
          * The title of this TV program.
          *
@@ -836,9 +837,10 @@
     }
 
     /**
-     * Common base for the tables of preview programs.
+     * Common columns for the tables of preview programs.
+     * @hide
      */
-    public interface BasePreviewProgramColumns extends BaseProgramColumns {
+    interface PreviewProgramColumns {
 
         /** @hide */
         @IntDef({
@@ -2227,7 +2229,7 @@
      * <p>By default, the query results will be sorted by
      * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order.
      */
-    public static final class Programs implements BaseProgramColumns {
+    public static final class Programs implements BaseTvColumns, ProgramColumns {
 
         /** The content:// style URI for this table. */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
@@ -2541,7 +2543,7 @@
      * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in
      * ascending order.
      */
-    public static final class RecordedPrograms implements BaseProgramColumns {
+    public static final class RecordedPrograms implements BaseTvColumns, ProgramColumns {
 
         /** The content:// style URI for this table. */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
@@ -2663,7 +2665,8 @@
     /**
      * Column definitions for the preview TV programs table.
      */
-    public static final class PreviewPrograms implements BasePreviewProgramColumns {
+    public static final class PreviewPrograms implements BaseTvColumns, ProgramColumns,
+        PreviewProgramColumns {
 
         /** The content:// style URI for this table. */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
@@ -2709,7 +2712,8 @@
     /**
      * Column definitions for the "watch next" TV programs table.
      */
-    public static final class WatchNextPrograms implements BasePreviewProgramColumns {
+    public static final class WatchNextPrograms implements BaseTvColumns, ProgramColumns,
+        PreviewProgramColumns {
 
         /** The content:// style URI for this table. */
         public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
diff --git a/media/jni/android_media_ImageWriter.cpp b/media/jni/android_media_ImageWriter.cpp
index d5d9fc9..0149d76 100644
--- a/media/jni/android_media_ImageWriter.cpp
+++ b/media/jni/android_media_ImageWriter.cpp
@@ -342,7 +342,7 @@
     }
     // New GraphicBuffer object doesn't own the handle, thus the native buffer
     // won't be freed when this object is destroyed.
-    sp<GraphicBuffer> buffer(new GraphicBuffer(anb, /*keepOwnership*/false));
+    sp<GraphicBuffer> buffer(GraphicBuffer::from(anb));
 
     // Note that:
     // 1. No need to lock buffer now, will only lock it when the first getPlanes() is called.
diff --git a/packages/CarrierDefaultApp/res/values/strings.xml b/packages/CarrierDefaultApp/res/values/strings.xml
index f9342b7..fa5c3ff 100644
--- a/packages/CarrierDefaultApp/res/values/strings.xml
+++ b/packages/CarrierDefaultApp/res/values/strings.xml
@@ -6,6 +6,7 @@
     <string name="no_data_notification_id">Your mobile data has been deactivated</string>
     <string name="portal_notification_detail">Tap to visit the %s website</string>
     <string name="no_data_notification_detail">Please contact your service provider %s</string>
+    <string name="mobile_data_status_notification_channel_name">Mobile data status</string>
     <string name="action_bar_label">Sign in to mobile network</string>
     <string name="ssl_error_warning">The network you&#8217;re trying to join has security issues.</string>
     <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index 73ff3a9..7fd1601 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -16,6 +16,7 @@
 package com.android.carrierdefaultapp;
 
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.content.Context;
@@ -35,6 +36,7 @@
 
     private static final String PORTAL_NOTIFICATION_TAG = "CarrierDefault.Portal.Notification";
     private static final String NO_DATA_NOTIFICATION_TAG = "CarrierDefault.NoData.Notification";
+    private static final String NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS = "mobile_data_status";
     private static final int PORTAL_NOTIFICATION_ID = 0;
     private static final int NO_DATA_NOTIFICATION_ID = 1;
     private static boolean ENABLE = true;
@@ -150,9 +152,18 @@
     private static Notification getNotification(Context context, int titleId, int textId,
                                          PendingIntent pendingIntent) {
         final TelephonyManager telephonyMgr = context.getSystemService(TelephonyManager.class);
+        final NotificationManager notificationManager = context.getSystemService(
+                NotificationManager.class);
         final Resources resources = context.getResources();
         final Bundle extras = Bundle.forPair(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                 resources.getString(R.string.android_system_label));
+        /* Creates the notification channel and registers it with NotificationManager. If a channel
+         * with the same ID is already registered, NotificationManager will ignore this call.
+         */
+        notificationManager.createNotificationChannel(new NotificationChannel(
+                NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS,
+                resources.getString(R.string.mobile_data_status_notification_channel_name),
+                NotificationManager.IMPORTANCE_DEFAULT));
         Notification.Builder builder = new Notification.Builder(context)
                 .setContentTitle(resources.getString(titleId))
                 .setContentText(String.format(resources.getString(textId),
@@ -167,7 +178,8 @@
                 .setLocalOnly(true)
                 .setWhen(System.currentTimeMillis())
                 .setShowWhen(false)
-                .setExtras(extras);
+                .setExtras(extras)
+                .setChannel(NOTIFICATION_CHANNEL_ID_MOBILE_DATA_STATUS);
 
         if (pendingIntent != null) {
             builder.setContentIntent(pendingIntent);
diff --git a/packages/SettingsLib/Android.mk b/packages/SettingsLib/Android.mk
index 67ef40a..1ad4fea 100644
--- a/packages/SettingsLib/Android.mk
+++ b/packages/SettingsLib/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_MODULE := SettingsLib
 
 LOCAL_SHARED_ANDROID_LIBRARIES := \
+    android-support-annotations \
     android-support-v4 \
     android-support-v7-recyclerview \
     android-support-v7-preference \
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index f14d0d1..ad985c7 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -928,4 +928,18 @@
          [CHAR LIMIT=35] -->
     <string name="use_system_language_to_select_input_method_subtypes">Use system languages</string>
 
+    <!-- Toast that settings for an application is failed to open. -->
+    <string name="failed_to_open_app_settings_toast">Failed to open settings for <xliff:g id="spell_application_name">%1$s</xliff:g></string>
+
+    <!-- Warning message about security implications of enabling an input method, displayed as a dialog
+         message when the user selects to enable an IME. -->
+    <string name="ime_security_warning">This input method may be able to collect
+        all the text you type, including personal data like passwords and credit
+        card numbers.  It comes from the app
+        <xliff:g id="ime_application_name">%1$s</xliff:g>.
+        Use this input method?</string>
+
+    <!-- [CHAR LIMIT=NONE] Dialog body explaining that the app just selected by the user will not work after a reboot until until after the user enters their credentials, such as a PIN or password. -->
+    <string name="direct_boot_unaware_dialog_message">Note: After a reboot, this app can\'t start until you unlock your phone</string>
+
 </resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
index 40abb6c..88f133c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/PrivateStorageInfo.java
@@ -41,8 +41,8 @@
         long privateTotalBytes = 0;
         for (VolumeInfo info : sm.getVolumes()) {
             if (info.getType() == VolumeInfo.TYPE_PRIVATE && info.isMountedReadable()) {
-                privateTotalBytes += stats.getTotalBytes(info.getFsUuid());
-                privateFreeBytes += stats.getFreeBytes(info.getFsUuid());
+                privateTotalBytes += sm.getTotalBytes(stats, info);
+                privateFreeBytes += sm.getFreeBytes(stats, info);
             }
         }
         return new PrivateStorageInfo(privateFreeBytes, privateTotalBytes);
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java
index 320494c..11060e6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageManagerVolumeProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.deviceinfo;
 
+import android.app.usage.StorageStatsManager;
 import android.os.storage.StorageManager;
 import android.os.storage.VolumeInfo;
 
@@ -46,4 +47,14 @@
     public VolumeInfo findEmulatedForPrivate(VolumeInfo privateVolume) {
         return mStorageManager.findEmulatedForPrivate(privateVolume);
     }
+
+    @Override
+    public long getTotalBytes(StorageStatsManager stats, VolumeInfo volume) {
+        return stats.getTotalBytes(volume.getFsUuid());
+    }
+
+    @Override
+    public long getFreeBytes(StorageStatsManager stats, VolumeInfo volume) {
+        return stats.getFreeBytes(volume.getFsUuid());
+    }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java
index 646c42f..e5d85d1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java
+++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageVolumeProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib.deviceinfo;
 
+import android.app.usage.StorageStatsManager;
 import android.os.storage.VolumeInfo;
 
 import java.util.List;
@@ -39,4 +40,18 @@
      * Returns the emulated volume for a given private volume.
      */
     VolumeInfo findEmulatedForPrivate(VolumeInfo privateVolume);
+
+    /**
+     * Returns the total bytes for a given storage volume.
+     *
+     * @pre The volume is a private volume and is readable.
+     */
+    long getTotalBytes(StorageStatsManager stats, VolumeInfo volume);
+
+    /**
+     * Returns the free bytes for a given storage volume.
+     *
+     * @pre The volume is a private volume and is readable.
+     */
+    long getFreeBytes(StorageStatsManager stats, VolumeInfo volume);
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
new file mode 100755
index 0000000..1bbc878b
--- /dev/null
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
@@ -0,0 +1,300 @@
+/*
+ * 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.inputmethod;
+
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.UserHandle;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.Preference.OnPreferenceChangeListener;
+import android.support.v7.preference.Preference.OnPreferenceClickListener;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.inputmethod.InputMethodInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.view.inputmethod.InputMethodSubtype;
+import android.widget.Toast;
+
+import com.android.internal.inputmethod.InputMethodUtils;
+import com.android.settingslib.R;
+import com.android.settingslib.RestrictedLockUtils;
+import com.android.settingslib.RestrictedSwitchPreference;
+
+import java.text.Collator;
+import java.util.List;
+
+/**
+ * Input method preference.
+ *
+ * This preference represents an IME. It is used for two purposes. 1) An instance with a switch
+ * is used to enable or disable the IME. 2) An instance without a switch is used to invoke the
+ * setting activity of the IME.
+ */
+public class InputMethodPreference extends RestrictedSwitchPreference implements OnPreferenceClickListener,
+        OnPreferenceChangeListener {
+    private static final String TAG = InputMethodPreference.class.getSimpleName();
+    private static final String EMPTY_TEXT = "";
+    private static final int NO_WIDGET = 0;
+
+    public interface OnSavePreferenceListener {
+        /**
+         * Called when this preference needs to be saved its state.
+         *
+         * Note that this preference is non-persistent and needs explicitly to be saved its state.
+         * Because changing one IME state may change other IMEs' state, this is a place to update
+         * other IMEs' state as well.
+         *
+         * @param pref This preference.
+         */
+        void onSaveInputMethodPreference(InputMethodPreference pref);
+    }
+
+    private final InputMethodInfo mImi;
+    private final boolean mHasPriorityInSorting;
+    private final OnSavePreferenceListener mOnSaveListener;
+    private final InputMethodSettingValuesWrapper mInputMethodSettingValues;
+    private final boolean mIsAllowedByOrganization;
+
+    private AlertDialog mDialog = null;
+
+    /**
+     * A preference entry of an input method.
+     *
+     * @param context The Context this is associated with.
+     * @param imi The {@link InputMethodInfo} of this preference.
+     * @param isImeEnabler true if this preference is the IME enabler that has enable/disable
+     *     switches for all available IMEs, not the list of enabled IMEs.
+     * @param isAllowedByOrganization false if the IME has been disabled by a device or profile
+     *     owner.
+     * @param onSaveListener The listener called when this preference has been changed and needs
+     *     to save the state to shared preference.
+     */
+    public InputMethodPreference(final Context context, final InputMethodInfo imi,
+            final boolean isImeEnabler, final boolean isAllowedByOrganization,
+            final OnSavePreferenceListener onSaveListener) {
+        super(context);
+        setPersistent(false);
+        mImi = imi;
+        mIsAllowedByOrganization = isAllowedByOrganization;
+        mOnSaveListener = onSaveListener;
+        if (!isImeEnabler) {
+            // Remove switch widget.
+            setWidgetLayoutResource(NO_WIDGET);
+        }
+        // Disable on/off switch texts.
+        setSwitchTextOn(EMPTY_TEXT);
+        setSwitchTextOff(EMPTY_TEXT);
+        setKey(imi.getId());
+        setTitle(imi.loadLabel(context.getPackageManager()));
+        final String settingsActivity = imi.getSettingsActivity();
+        if (TextUtils.isEmpty(settingsActivity)) {
+            setIntent(null);
+        } else {
+            // Set an intent to invoke settings activity of an input method.
+            final Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.setClassName(imi.getPackageName(), settingsActivity);
+            setIntent(intent);
+        }
+        mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
+        mHasPriorityInSorting = InputMethodUtils.isSystemIme(imi)
+                && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
+        setOnPreferenceClickListener(this);
+        setOnPreferenceChangeListener(this);
+    }
+
+    public InputMethodInfo getInputMethodInfo() {
+        return mImi;
+    }
+
+    private boolean isImeEnabler() {
+        // If this {@link SwitchPreference} doesn't have a widget layout, we explicitly hide the
+        // switch widget at constructor.
+        return getWidgetLayoutResource() != NO_WIDGET;
+    }
+
+    @Override
+    public boolean onPreferenceChange(final Preference preference, final Object newValue) {
+        // Always returns false to prevent default behavior.
+        // See {@link TwoStatePreference#onClick()}.
+        if (!isImeEnabler()) {
+            // Prevent disabling an IME because this preference is for invoking a settings activity.
+            return false;
+        }
+        if (isChecked()) {
+            // Disable this IME.
+            setCheckedInternal(false);
+            return false;
+        }
+        if (InputMethodUtils.isSystemIme(mImi)) {
+            // Enable a system IME. No need to show a security warning dialog,
+            // but we might need to prompt if it's not Direct Boot aware.
+            // TV doesn't doesn't need to worry about this, but other platforms should show
+            // a warning.
+            if (mImi.getServiceInfo().directBootAware || isTv()) {
+                setCheckedInternal(true);
+            } else if (!isTv()){
+                showDirectBootWarnDialog();
+            }
+        } else {
+            // Once security is confirmed, we might prompt if the IME isn't
+            // Direct Boot aware.
+            showSecurityWarnDialog();
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onPreferenceClick(final Preference preference) {
+        // Always returns true to prevent invoking an intent without catching exceptions.
+        // See {@link Preference#performClick(PreferenceScreen)}/
+        if (isImeEnabler()) {
+            // Prevent invoking a settings activity because this preference is for enabling and
+            // disabling an input method.
+            return true;
+        }
+        final Context context = getContext();
+        try {
+            final Intent intent = getIntent();
+            if (intent != null) {
+                // Invoke a settings activity of an input method.
+                context.startActivity(intent);
+            }
+        } catch (final ActivityNotFoundException e) {
+            Log.d(TAG, "IME's Settings Activity Not Found", e);
+            final String message = context.getString(
+                    R.string.failed_to_open_app_settings_toast,
+                    mImi.loadLabel(context.getPackageManager()));
+            Toast.makeText(context, message, Toast.LENGTH_LONG).show();
+        }
+        return true;
+    }
+
+    public void updatePreferenceViews() {
+        final boolean isAlwaysChecked = mInputMethodSettingValues.isAlwaysCheckedIme(
+                mImi, getContext());
+        // When this preference has a switch and an input method should be always enabled,
+        // this preference should be disabled to prevent accidentally disabling an input method.
+        // This preference should also be disabled in case the admin does not allow this input
+        // method.
+        if (isAlwaysChecked && isImeEnabler()) {
+            setDisabledByAdmin(null);
+            setEnabled(false);
+        } else if (!mIsAllowedByOrganization) {
+            EnforcedAdmin admin =
+                    RestrictedLockUtils.checkIfInputMethodDisallowed(getContext(),
+                            mImi.getPackageName(), UserHandle.myUserId());
+            setDisabledByAdmin(admin);
+        } else {
+            setEnabled(true);
+        }
+        setChecked(mInputMethodSettingValues.isEnabledImi(mImi));
+        if (!isDisabledByAdmin()) {
+            setSummary(getSummaryString());
+        }
+    }
+
+    private InputMethodManager getInputMethodManager() {
+        return (InputMethodManager)getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+    }
+
+    private String getSummaryString() {
+        final InputMethodManager imm = getInputMethodManager();
+        final List<InputMethodSubtype> subtypes = imm.getEnabledInputMethodSubtypeList(mImi, true);
+        return InputMethodAndSubtypeUtil.getSubtypeLocaleNameListAsSentence(
+                subtypes, getContext(), mImi);
+    }
+
+    private void setCheckedInternal(boolean checked) {
+        super.setChecked(checked);
+        mOnSaveListener.onSaveInputMethodPreference(InputMethodPreference.this);
+        notifyChanged();
+    }
+
+    private void showSecurityWarnDialog() {
+        if (mDialog != null && mDialog.isShowing()) {
+            mDialog.dismiss();
+        }
+        final Context context = getContext();
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setCancelable(true /* cancelable */);
+        builder.setTitle(android.R.string.dialog_alert_title);
+        final CharSequence label = mImi.getServiceInfo().applicationInfo.loadLabel(
+                context.getPackageManager());
+        builder.setMessage(context.getString(R.string.ime_security_warning, label));
+        builder.setPositiveButton(android.R.string.ok, (dialog, which) -> {
+            // The user confirmed to enable a 3rd party IME, but we might
+            // need to prompt if it's not Direct Boot aware.
+            // TV doesn't doesn't need to worry about this, but other platforms should show
+            // a warning.
+            if (mImi.getServiceInfo().directBootAware || isTv()) {
+                setCheckedInternal(true);
+            } else {
+                showDirectBootWarnDialog();
+            }
+        });
+        builder.setNegativeButton(android.R.string.cancel, (dialog, which) -> {
+            // The user canceled to enable a 3rd party IME.
+            setCheckedInternal(false);
+        });
+        mDialog = builder.create();
+        mDialog.show();
+    }
+
+    private boolean isTv() {
+        return (getContext().getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION;
+    }
+
+    private void showDirectBootWarnDialog() {
+        if (mDialog != null && mDialog.isShowing()) {
+            mDialog.dismiss();
+        }
+        final Context context = getContext();
+        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
+        builder.setCancelable(true /* cancelable */);
+        builder.setMessage(context.getText(R.string.direct_boot_unaware_dialog_message));
+        builder.setPositiveButton(android.R.string.ok, (dialog, which) -> setCheckedInternal(true));
+        builder.setNegativeButton(android.R.string.cancel,
+                (dialog, which) -> setCheckedInternal(false));
+        mDialog = builder.create();
+        mDialog.show();
+    }
+
+    public int compareTo(final InputMethodPreference rhs, final Collator collator) {
+        if (this == rhs) {
+            return 0;
+        }
+        if (mHasPriorityInSorting == rhs.mHasPriorityInSorting) {
+            final CharSequence t0 = getTitle();
+            final CharSequence t1 = rhs.getTitle();
+            if (TextUtils.isEmpty(t0)) {
+                return 1;
+            }
+            if (TextUtils.isEmpty(t1)) {
+                return -1;
+            }
+            return collator.compare(t0.toString(), t1.toString());
+        }
+        // Prefer always checked system IMEs
+        return mHasPriorityInSorting ? -1 : 1;
+    }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java
index d3bdeb7..ab7c6d2 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTrackerFactory.java
@@ -17,6 +17,7 @@
 
 import android.content.Context;
 import android.os.Looper;
+import android.support.annotation.Keep;
 
 /**
  * Factory method used to inject WifiTracker instances.
@@ -26,14 +27,7 @@
 
     private static WifiTracker sTestingWifiTracker;
 
-    public static void enableTestingMode() {
-        sTestingMode = true;
-    }
-
-    public static void disableTestingMode() {
-        sTestingMode = false;
-    }
-
+    @Keep
     public static void setTestingWifiTracker(WifiTracker tracker) {
         sTestingWifiTracker = tracker;
     }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 0d0ddf2..1f559e4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2798,7 +2798,7 @@
         }
 
         private final class UpgradeController {
-            private static final int SETTINGS_VERSION = 143;
+            private static final int SETTINGS_VERSION = 144;
 
             private final int mUserId;
 
@@ -3324,7 +3324,7 @@
                 }
 
                 if (currentVersion == 141) {
-                    // Version 141: We added the notion of a default and whether the system set
+                    // Version 142: We added the notion of a default and whether the system set
                     // the setting. This is used for resetting the internal state and we need
                     // to make sure this value is updated for the existing settings, otherwise
                     // we would delete system set settings while they should stay unmodified.
@@ -3344,7 +3344,7 @@
                 }
 
                 if (currentVersion == 142) {
-                    // Version 142: Set a default value for Wi-Fi wakeup feature.
+                    // Version 143: Set a default value for Wi-Fi wakeup feature.
                     if (userId == UserHandle.USER_SYSTEM) {
                         final SettingsState globalSettings = getGlobalSettingsLocked();
                         Setting currentSetting = globalSettings.getSettingLocked(
@@ -3361,6 +3361,27 @@
                     currentVersion = 143;
                 }
 
+                if (currentVersion == 143) {
+                    // Version 144: Set a default value for Autofill service.
+                    final SettingsState secureSettings = getSecureSettingsLocked(userId);
+                    final Setting currentSetting = secureSettings
+                            .getSettingLocked(Settings.Secure.AUTOFILL_SERVICE);
+                    if (currentSetting.isNull()) {
+                        final String defaultValue = getContext().getResources().getString(
+                                com.android.internal.R.string.config_defaultAutofillService);
+                        if (defaultValue != null) {
+                            Slog.d(LOG_TAG, "Setting [" + defaultValue + "] as Autofill Service "
+                                    + "for user " + userId);
+                            secureSettings.insertSettingLocked(Settings.Secure.AUTOFILL_SERVICE,
+                                    defaultValue, null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+                        }
+                    }
+
+                    currentVersion = 144;
+                }
+
+                // vXXX: Add new settings above this point.
+
                 if (currentVersion != newVersion) {
                     Slog.wtf("SettingsProvider", "warning: upgrading settings database to version "
                             + newVersion + " left it at "
@@ -3372,8 +3393,6 @@
                     }
                 }
 
-                // vXXX: Add new settings above this point.
-
                 // Return the current version.
                 return currentVersion;
             }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 2655837..80b4da8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -34,9 +34,11 @@
 import android.widget.TextClock;
 import android.widget.TextView;
 
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.widget.LockPatternUtils;
 import com.android.systemui.ChargingView;
 
+import java.util.Arrays;
 import java.util.Locale;
 
 public class KeyguardStatusView extends GridLayout {
@@ -53,6 +55,10 @@
     private ViewGroup mClockContainer;
     private ChargingView mBatteryDoze;
 
+    private View[] mVisibleInDoze;
+    private boolean mPulsing;
+    private boolean mDark;
+
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
 
         @Override
@@ -117,6 +123,7 @@
         mClockView.setShowCurrentUserTime(true);
         mOwnerInfo = (TextView) findViewById(R.id.owner_info);
         mBatteryDoze = (ChargingView) findViewById(R.id.battery_doze);
+        mVisibleInDoze = new View[]{mBatteryDoze, mClockView};
 
         boolean shouldMarquee = KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
         setEnableMarquee(shouldMarquee);
@@ -273,14 +280,28 @@
     }
 
     public void setDark(boolean dark) {
+        mDark = dark;
+
         final int N = mClockContainer.getChildCount();
         for (int i = 0; i < N; i++) {
             View child = mClockContainer.getChildAt(i);
-            if (child == mClockView || child == mBatteryDoze) {
+            if (ArrayUtils.contains(mVisibleInDoze, child)) {
                 continue;
             }
             child.setAlpha(dark ? 0 : 1);
         }
+        updateDozeVisibleViews();
         mBatteryDoze.setDark(dark);
     }
+
+    public void setPulsing(boolean pulsing) {
+        mPulsing = pulsing;
+        updateDozeVisibleViews();
+    }
+
+    private void updateDozeVisibleViews() {
+        for (View child : mVisibleInDoze) {
+            child.setAlpha(mDark && mPulsing ? 0.5f : 1);
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index bcf1957..fbd9f0c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -86,6 +86,7 @@
     private static final float DISABLED_ACTION_ALPHA = 0.54f;
 
     private boolean mMenuVisible;
+    private boolean mAllowMenuTimeout = true;
     private final List<RemoteAction> mActions = new ArrayList<>();
     private View mViewRoot;
     private Drawable mBackgroundDrawable;
@@ -190,7 +191,9 @@
 
     @Override
     public void onUserInteraction() {
-        repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+        if (mAllowMenuTimeout) {
+            repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+        }
     }
 
     @Override
@@ -255,6 +258,7 @@
     }
 
     private void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) {
+        mAllowMenuTimeout = allowMenuTimeout;
         if (!mMenuVisible) {
             updateActionViews(stackBounds);
             if (mMenuContainerAnimator != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
index 9efe224..d2a2919 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -242,7 +242,7 @@
         mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
         mDetailSettingsButton.setOnClickListener(v -> {
             Dependency.get(MetricsLogger.class).action(ACTION_QS_MORE_SETTINGS,
-                    mDetailAdapter.getMetricsCategory());
+                    adapter.getMetricsCategory());
             Dependency.get(ActivityStarter.class)
                     .postStartActivityDismissingKeyguard(settingsIntent, 0);
         });
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index dc666e9..311f8ff 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -524,7 +524,7 @@
      * changes.
      */
     public void onTaskDataLoaded() {
-        if (mTask.icon != null) {
+        if (mTask != null && mTask.icon != null) {
             mIconView.setImageDrawable(mTask.icon);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 21a0dc9..8298f35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -228,6 +228,7 @@
         // Settings button.
         final TextView settingsButton = (TextView) findViewById(R.id.more_settings);
         if (mAppUid >= 0 && onSettingsClick != null) {
+            settingsButton.setVisibility(View.VISIBLE);
             final int appUidF = mAppUid;
             settingsButton.setOnClickListener(
                     (View view) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index 5055dda..bb82b60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -120,6 +120,9 @@
     @Override
     public void createMenu(ViewGroup parent) {
         mParent = (ExpandableNotificationRow) parent;
+        if (mMenuContainer != null) {
+            mMenuContainer.removeAllViews();
+        }
         mMenuContainer = new FrameLayout(mContext);
         for (int i = 0; i < mMenuItems.size(); i++) {
             addMenuView(mMenuItems.get(i), mMenuContainer);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 8da17fa..8042321 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -23,7 +23,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import com.android.internal.widget.CachingIconView;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
@@ -127,12 +126,8 @@
         super.setDark(dark, fade, delay);
         if (mDark == dark) return;
         mDark = dark;
-        if (fade) {
-            mViewInvertHelper.fade(dark, delay);
-        } else {
-            mViewInvertHelper.update(dark);
-        }
-        mShelfIcons.setAmbient(dark);
+        mShelfIcons.setDark(dark, fade, delay);
+        updateInteractiveness();
     }
 
     @Override
@@ -167,7 +162,7 @@
             openedAmount = Math.min(1.0f, openedAmount);
             mShelfState.openedAmount = openedAmount;
             mShelfState.clipTopAmount = 0;
-            mShelfState.alpha = 1.0f;
+            mShelfState.alpha = mAmbientState.isPulsing() ? 0 : 1;
             mShelfState.belowSpeedBump = mAmbientState.getSpeedBumpIndex() == 0;
             mShelfState.shadowAlpha = 1.0f;
             mShelfState.hideSensitive = false;
@@ -576,7 +571,8 @@
     }
 
     private void updateInteractiveness() {
-        mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf;
+        mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf
+                && !mDark;
         setClickable(mInteractive);
         setFocusable(mInteractive);
         setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
@@ -602,6 +598,11 @@
     }
 
     @Override
+    public boolean hasOverlappingRendering() {
+        return false;  // Shelf only uses alpha for transitions where the difference can't be seen.
+    }
+
+    @Override
     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
             int oldTop, int oldRight, int oldBottom) {
         updateRelativeOffset();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index b9c8a78..92bfae9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -27,6 +27,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -46,6 +47,7 @@
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.NotificationIconDozeHelper;
 import com.android.systemui.statusbar.notification.NotificationUtils;
 
 import java.text.NumberFormat;
@@ -99,7 +101,6 @@
     private int mDensity;
     private float mIconScale = 1.0f;
     private final Paint mDotPaint = new Paint();
-    private boolean mDotVisible;
     private float mDotRadius;
     private int mStaticDotRadius;
     private int mVisibleState = STATE_ICON;
@@ -110,6 +111,8 @@
     private OnVisibilityChangedListener mOnVisibilityChangedListener;
     private int mDrawableColor;
     private int mIconColor;
+    private int mDecorColor;
+    private float mDarkAmount;
     private ValueAnimator mColorAnimator;
     private int mCurrentSetColor = NO_COLOR;
     private int mAnimationStartColor = NO_COLOR;
@@ -119,6 +122,7 @@
                 animation.getAnimatedFraction());
         setColorInternal(newColor);
     };
+    private final NotificationIconDozeHelper mDozer;
 
     public StatusBarIconView(Context context, String slot, Notification notification) {
         this(context, slot, notification, false);
@@ -127,6 +131,7 @@
     public StatusBarIconView(Context context, String slot, Notification notification,
             boolean blocked) {
         super(context);
+        mDozer = new NotificationIconDozeHelper(context);
         mBlocked = blocked;
         mSlot = slot;
         mNumberPain = new Paint();
@@ -190,6 +195,7 @@
 
     public StatusBarIconView(Context context, AttributeSet attrs) {
         super(context, attrs);
+        mDozer = new NotificationIconDozeHelper(context);
         mBlocked = false;
         mAlwaysScaleIcon = true;
         updateIconScale();
@@ -466,7 +472,19 @@
      * to the drawable.
      */
     public void setDecorColor(int iconTint) {
-        mDotPaint.setColor(iconTint);
+        mDecorColor = iconTint;
+        updateDecorColor();
+    }
+
+    private void updateDecorColor() {
+        int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDarkAmount);
+        if (mDotPaint.getColor() != color) {
+            mDotPaint.setColor(color);
+
+            if (mDotAppearAmount != 0) {
+                invalidate();
+            }
+        }
     }
 
     /**
@@ -477,6 +495,7 @@
         mDrawableColor = color;
         setColorInternal(color);
         mIconColor = color;
+        mDozer.setColor(color);
     }
 
     private void setColorInternal(int color) {
@@ -649,6 +668,14 @@
         mOnVisibilityChangedListener = listener;
     }
 
+    public void setDark(boolean dark, boolean fade, long delay) {
+        mDozer.setImageDark(this, dark, fade, delay, mIconColor == NO_COLOR);
+        mDozer.setIntensityDark(f -> {
+            mDarkAmount = f;
+            updateDecorColor();
+        }, dark, fade, delay);
+    }
+
     public interface OnVisibilityChangedListener {
         void onVisibilityChanged(int newVisibility);
     }
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 3efa29f..bca4b43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -18,7 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
+import android.content.Context;
 import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Paint;
 import android.view.View;
@@ -38,8 +38,8 @@
     private boolean mIsLegacy;
     private int mLegacyColor;
 
-    protected NotificationCustomViewWrapper(View view, ExpandableNotificationRow row) {
-        super(view, row);
+    protected NotificationCustomViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
+        super(ctx, view, row);
         mInvertHelper = new ViewInvertHelper(view, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mLegacyColor = row.getContext().getColor(R.color.notification_legacy_background_color);
     }
@@ -67,13 +67,11 @@
     }
 
     protected void fadeGrayscale(final boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateGrayscaleMatrix((float) animation.getAnimatedValue());
-                mGreyPaint.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
-                mView.setLayerPaint(mGreyPaint);
-            }
+        getDozer().startIntensityAnimation(animation -> {
+            getDozer().updateGrayscaleMatrix((float) animation.getAnimatedValue());
+            mGreyPaint.setColorFilter(
+                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
+            mView.setLayerPaint(mGreyPaint);
         }, dark, delay, new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -86,9 +84,9 @@
 
     protected void updateGrayscale(boolean dark) {
         if (dark) {
-            updateGrayscaleMatrix(1f);
+            getDozer().updateGrayscaleMatrix(1f);
             mGreyPaint.setColorFilter(
-                    new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+                    new ColorMatrixColorFilter(getDozer().getGrayscaleColorMatrix()));
             mView.setLayerPaint(mGreyPaint);
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
new file mode 100644
index 0000000..d592c5f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -0,0 +1,92 @@
+/*
+ * 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.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.widget.ImageView;
+
+import com.android.systemui.Interpolators;
+import com.android.systemui.statusbar.phone.NotificationPanelView;
+
+import java.util.function.Consumer;
+
+public class NotificationDozeHelper {
+    private final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
+
+    public void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
+        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
+            @Override
+            public void onAnimationUpdate(ValueAnimator animation) {
+                updateGrayscaleMatrix((float) animation.getAnimatedValue());
+                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+            }
+        }, dark, delay, new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                if (!dark) {
+                    target.setColorFilter(null);
+                }
+            }
+        });
+    }
+
+    public void updateGrayscale(ImageView target, boolean dark) {
+        if (dark) {
+            updateGrayscaleMatrix(1f);
+            target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
+        } else {
+            target.setColorFilter(null);
+        }
+    }
+
+    public void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
+            boolean dark, long delay, Animator.AnimatorListener listener) {
+        float startIntensity = dark ? 0f : 1f;
+        float endIntensity = dark ? 1f : 0f;
+        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
+        animator.addUpdateListener(updateListener);
+        animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
+        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+        animator.setStartDelay(delay);
+        if (listener != null) {
+            animator.addListener(listener);
+        }
+        animator.start();
+    }
+
+    public void setIntensityDark(Consumer<Float> listener, boolean dark,
+            boolean animate, long delay) {
+        if (animate) {
+            startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dark, delay,
+                    null /* listener */);
+        } else {
+            listener.accept(dark ? 1f : 0f);
+        }
+    }
+
+    public void updateGrayscaleMatrix(float intensity) {
+        mGrayscaleColorMatrix.setSaturation(1 - intensity);
+    }
+
+    public ColorMatrix getGrayscaleColorMatrix() {
+        return mGrayscaleColorMatrix;
+    }
+}
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 38e4ec1..1ffc944 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -16,17 +16,10 @@
 
 package com.android.systemui.statusbar.notification;
 
-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;
-import android.graphics.ColorMatrixColorFilter;
-import android.graphics.PorterDuff;
 import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.Drawable;
 import android.util.ArraySet;
 import android.view.NotificationHeaderView;
 import android.view.View;
@@ -37,7 +30,6 @@
 import android.widget.TextView;
 
 import com.android.systemui.Interpolators;
-import com.android.systemui.R;
 import com.android.systemui.ViewInvertHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
@@ -55,10 +47,6 @@
 
     private static final Interpolator LOW_PRIORITY_HEADER_CLOSE
             = new PathInterpolator(0.4f, 0f, 0.7f, 1f);
-    private final PorterDuffColorFilter mIconColorFilter = new PorterDuffColorFilter(
-            0, PorterDuff.Mode.SRC_ATOP);
-    private final int mIconDarkAlpha;
-    private final int mIconDarkColor = 0xffffffff;
 
     protected final ViewInvertHelper mInvertHelper;
     protected final ViewTransformationHelper mTransformationHelper;
@@ -74,8 +62,7 @@
     private boolean mTransformLowPriorityTitle;
 
     protected NotificationHeaderViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
-        super(view, row);
-        mIconDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
+        super(ctx, view, row);
         mInvertHelper = new ViewInvertHelper(ctx, NotificationPanelView.DOZE_ANIMATION_DURATION);
         mTransformationHelper = new ViewTransformationHelper();
 
@@ -108,6 +95,16 @@
         updateInvertHelper();
     }
 
+    @Override
+    protected NotificationDozeHelper createDozer(Context ctx) {
+        return new NotificationIconDozeHelper(ctx);
+    }
+
+    @Override
+    protected NotificationIconDozeHelper getDozer() {
+        return (NotificationIconDozeHelper) super.getDozer();
+    }
+
     protected void resolveHeaderViews() {
         mIcon = (ImageView) mView.findViewById(com.android.internal.R.id.icon);
         mHeaderText = (TextView) mView.findViewById(com.android.internal.R.id.header_text);
@@ -116,6 +113,7 @@
         mColor = resolveColor(mExpandButton);
         mNotificationHeader = (NotificationHeaderView) mView.findViewById(
                 com.android.internal.R.id.notification_header);
+        getDozer().setColor(mColor);
     }
 
     private int resolveColor(ImageView icon) {
@@ -223,90 +221,8 @@
             // It also may lead to bugs where the icon isn't correctly greyed out.
             boolean hadColorFilter = mNotificationHeader.getOriginalIconColor()
                     != NotificationHeaderView.NO_COLOR;
-            if (fade) {
-                if (hadColorFilter) {
-                    fadeIconColorFilter(mIcon, dark, delay);
-                    fadeIconAlpha(mIcon, dark, delay);
-                } else {
-                    fadeGrayscale(mIcon, dark, delay);
-                }
-            } else {
-                if (hadColorFilter) {
-                    updateIconColorFilter(mIcon, dark);
-                    updateIconAlpha(mIcon, dark);
-                } else {
-                    updateGrayscale(mIcon, dark);
-                }
-            }
-        }
-    }
 
-    private void fadeIconColorFilter(final ImageView target, boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateIconColorFilter(target, (Float) animation.getAnimatedValue());
-            }
-        }, dark, delay, null /* listener */);
-    }
-
-    private void fadeIconAlpha(final ImageView target, boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float t = (float) animation.getAnimatedValue();
-                target.setImageAlpha((int) (255 * (1f - t) + mIconDarkAlpha * t));
-            }
-        }, dark, delay, null /* listener */);
-    }
-
-    protected void fadeGrayscale(final ImageView target, final boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                updateGrayscaleMatrix((float) animation.getAnimatedValue());
-                target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
-            }
-        }, dark, delay, new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                if (!dark) {
-                    target.setColorFilter(null);
-                }
-            }
-        });
-    }
-
-    private void updateIconColorFilter(ImageView target, boolean dark) {
-        updateIconColorFilter(target, dark ? 1f : 0f);
-    }
-
-    private void updateIconColorFilter(ImageView target, float intensity) {
-        int color = interpolateColor(mColor, mIconDarkColor, intensity);
-        mIconColorFilter.setColor(color);
-        Drawable iconDrawable = target.getDrawable();
-
-        // Also, the notification might have been modified during the animation, so background
-        // might be null here.
-        if (iconDrawable != null) {
-            Drawable d = iconDrawable.mutate();
-            // DrawableContainer ignores the color filter if it's already set, so clear it first to
-            // get it set and invalidated properly.
-            d.setColorFilter(null);
-            d.setColorFilter(mIconColorFilter);
-        }
-    }
-
-    private void updateIconAlpha(ImageView target, boolean dark) {
-        target.setImageAlpha(dark ? mIconDarkAlpha : 255);
-    }
-
-    protected void updateGrayscale(ImageView target, boolean dark) {
-        if (dark) {
-            updateGrayscaleMatrix(1f);
-            target.setColorFilter(new ColorMatrixColorFilter(mGrayscaleColorMatrix));
-        } else {
-            target.setColorFilter(null);
+            getDozer().setImageDark(mIcon, dark, fade, delay, !hadColorFilter);
         }
     }
 
@@ -316,22 +232,6 @@
         mNotificationHeader.setOnClickListener(expandable ? onClickListener : null);
     }
 
-    private static int interpolateColor(int source, int target, float t) {
-        int aSource = Color.alpha(source);
-        int rSource = Color.red(source);
-        int gSource = Color.green(source);
-        int bSource = Color.blue(source);
-        int aTarget = Color.alpha(target);
-        int rTarget = Color.red(target);
-        int gTarget = Color.green(target);
-        int bTarget = Color.blue(target);
-        return Color.argb(
-                (int) (aSource * (1f - t) + aTarget * t),
-                (int) (rSource * (1f - t) + rTarget * t),
-                (int) (gSource * (1f - t) + gTarget * t),
-                (int) (bSource * (1f - t) + bTarget * t));
-    }
-
     @Override
     public NotificationHeaderView getNotificationHeader() {
         return mNotificationHeader;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java
new file mode 100644
index 0000000..9f79ef2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationIconDozeHelper.java
@@ -0,0 +1,101 @@
+/*
+ * 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.content.Context;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.widget.ImageView;
+
+import com.android.systemui.R;
+
+public class NotificationIconDozeHelper extends NotificationDozeHelper {
+
+    private final int mImageDarkAlpha;
+    private final int mImageDarkColor = 0xffffffff;
+    private final PorterDuffColorFilter mImageColorFilter = new PorterDuffColorFilter(
+            0, PorterDuff.Mode.SRC_ATOP);
+
+    private int mColor = Color.BLACK;
+
+    public NotificationIconDozeHelper(Context ctx) {
+        mImageDarkAlpha = ctx.getResources().getInteger(R.integer.doze_small_icon_alpha);
+    }
+
+    public void setColor(int color) {
+        mColor = color;
+    }
+
+    public void setImageDark(ImageView target, boolean dark, boolean fade, long delay,
+            boolean useGrayscale) {
+        if (fade) {
+            if (!useGrayscale) {
+                fadeImageColorFilter(target, dark, delay);
+                fadeImageAlpha(target, dark, delay);
+            } else {
+                fadeGrayscale(target, dark, delay);
+            }
+        } else {
+            if (!useGrayscale) {
+                updateImageColorFilter(target, dark);
+                updateImageAlpha(target, dark);
+            } else {
+                updateGrayscale(target, dark);
+            }
+        }
+    }
+
+    private void fadeImageColorFilter(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(animation -> {
+            updateImageColorFilter(target, (Float) animation.getAnimatedValue());
+        }, dark, delay, null /* listener */);
+    }
+
+    private void fadeImageAlpha(final ImageView target, boolean dark, long delay) {
+        startIntensityAnimation(animation -> {
+            float t = (float) animation.getAnimatedValue();
+            target.setImageAlpha((int) (255 * (1f - t) + mImageDarkAlpha * t));
+        }, dark, delay, null /* listener */);
+    }
+
+    private void updateImageColorFilter(ImageView target, boolean dark) {
+        updateImageColorFilter(target, dark ? 1f : 0f);
+    }
+
+    private void updateImageColorFilter(ImageView target, float intensity) {
+        int color = NotificationUtils.interpolateColors(mColor, mImageDarkColor, intensity);
+        mImageColorFilter.setColor(color);
+        Drawable imageDrawable = target.getDrawable();
+
+        // Also, the notification might have been modified during the animation, so background
+        // might be null here.
+        if (imageDrawable != null) {
+            Drawable d = imageDrawable.mutate();
+            // DrawableContainer ignores the color filter if it's already set, so clear it first to
+            // get it set and invalidated properly.
+            d.setColorFilter(null);
+            d.setColorFilter(mImageColorFilter);
+        }
+    }
+
+    private void updateImageAlpha(ImageView target, boolean dark) {
+        target.setImageAlpha(dark ? mImageDarkAlpha : 255);
+    }
+
+}
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 846d03a..f0b6b2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTemplateViewWrapper.java
@@ -16,7 +16,6 @@
 
 package com.android.systemui.statusbar.notification;
 
-import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Color;
 import android.service.notification.StatusBarNotification;
@@ -46,7 +45,8 @@
     private int mContentHeight;
     private int mMinHeightHint;
 
-    protected NotificationTemplateViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
+    protected NotificationTemplateViewWrapper(Context ctx, View view,
+            ExpandableNotificationRow row) {
         super(ctx, view, row);
         mTransformationHelper.setCustomTransformation(
                 new ViewTransformationHelper.CustomTransformation() {
@@ -154,16 +154,20 @@
         // This also clears the existing types
         super.updateTransformedTypes();
         if (mTitle != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE, mTitle);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TITLE,
+                    mTitle);
         }
         if (mText != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TEXT, mText);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_TEXT,
+                    mText);
         }
         if (mPicture != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_IMAGE, mPicture);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_IMAGE,
+                    mPicture);
         }
         if (mProgressBar != null) {
-            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_PROGRESS, mProgressBar);
+            mTransformationHelper.addTransformedView(TransformableView.TRANSFORMING_VIEW_PROGRESS,
+                    mProgressBar);
         }
     }
 
@@ -173,7 +177,7 @@
             return;
         }
         super.setDark(dark, fade, delay);
-        setPictureGrayscale(dark, fade, delay);
+        setPictureDark(dark, fade, delay);
         setProgressBarDark(dark, fade, delay);
     }
 
@@ -188,12 +192,9 @@
     }
 
     private void fadeProgressDark(final ProgressBar target, final boolean dark, long delay) {
-        startIntensityAnimation(new ValueAnimator.AnimatorUpdateListener() {
-            @Override
-            public void onAnimationUpdate(ValueAnimator animation) {
-                float t = (float) animation.getAnimatedValue();
-                updateProgressDark(target, t);
-            }
+        getDozer().startIntensityAnimation(animation -> {
+            float t = (float) animation.getAnimatedValue();
+            updateProgressDark(target, t);
         }, dark, delay, null /* listener */);
     }
 
@@ -207,13 +208,9 @@
         updateProgressDark(target, dark ? 1f : 0f);
     }
 
-    protected void setPictureGrayscale(boolean grayscale, boolean fade, long delay) {
+    private void setPictureDark(boolean dark, boolean fade, long delay) {
         if (mPicture != null) {
-            if (fade) {
-                fadeGrayscale(mPicture, grayscale, delay);
-            } else {
-                updateGrayscale(mPicture, grayscale);
-            }
+            getDozer().setImageDark(mPicture, dark, fade, delay, true /* useGrayscale */);
         }
     }
 
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 c85e8d8..f4db9a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationViewWrapper.java
@@ -16,24 +16,17 @@
 
 package com.android.systemui.statusbar.notification;
 
-import android.animation.Animator;
-import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Color;
-import android.graphics.ColorMatrix;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.service.notification.StatusBarNotification;
 import android.support.v4.graphics.ColorUtils;
 import android.view.NotificationHeaderView;
 import android.view.View;
 
-import com.android.systemui.Interpolators;
-import com.android.systemui.R;
 import com.android.systemui.statusbar.CrossFadeHelper;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.TransformableView;
-import com.android.systemui.statusbar.phone.NotificationPanelView;
 
 /**
  * Wraps the actual notification content view; used to implement behaviors which are different for
@@ -41,14 +34,14 @@
  */
 public abstract class NotificationViewWrapper implements TransformableView {
 
-    protected final ColorMatrix mGrayscaleColorMatrix = new ColorMatrix();
     protected final View mView;
     protected final ExpandableNotificationRow mRow;
+    private final NotificationDozeHelper mDozer;
+
     protected boolean mDark;
     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) {
@@ -65,13 +58,22 @@
         } else if (v instanceof NotificationHeaderView) {
             return new NotificationHeaderViewWrapper(ctx, v, row);
         } else {
-            return new NotificationCustomViewWrapper(v, row);
+            return new NotificationCustomViewWrapper(ctx, v, row);
         }
     }
 
-    protected NotificationViewWrapper(View view, ExpandableNotificationRow row) {
+    protected NotificationViewWrapper(Context ctx, View view, ExpandableNotificationRow row) {
         mView = view;
         mRow = row;
+        mDozer = createDozer(ctx);
+    }
+
+    protected NotificationDozeHelper createDozer(Context ctx) {
+        return new NotificationDozeHelper();
+    }
+
+    protected NotificationDozeHelper getDozer() {
+        return mDozer;
     }
 
     /**
@@ -112,26 +114,6 @@
                 || ColorUtils.calculateLuminance(backgroundColor) > 0.5;
     }
 
-
-    protected void startIntensityAnimation(ValueAnimator.AnimatorUpdateListener updateListener,
-            boolean dark, long delay, Animator.AnimatorListener listener) {
-        float startIntensity = dark ? 0f : 1f;
-        float endIntensity = dark ? 1f : 0f;
-        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
-        animator.addUpdateListener(updateListener);
-        animator.setDuration(NotificationPanelView.DOZE_ANIMATION_DURATION);
-        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
-        animator.setStartDelay(delay);
-        if (listener != null) {
-            animator.addListener(listener);
-        }
-        animator.start();
-    }
-
-    protected void updateGrayscaleMatrix(float intensity) {
-        mGrayscaleColorMatrix.setSaturation(1 - intensity);
-    }
-
     /**
      * Update the appearance of the expand button.
      *
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 3706dc8..dee15d8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -95,7 +95,7 @@
     private int mActualLayoutWidth = NO_VALUE;
     private float mActualPaddingEnd = NO_VALUE;
     private float mActualPaddingStart = NO_VALUE;
-    private boolean mCentered;
+    private boolean mDark;
     private boolean mChangingViewPositions;
     private int mAddAnimationStartIndex = -1;
     private int mCannedAnimationStartIndex = -1;
@@ -183,6 +183,9 @@
                 mAddAnimationStartIndex = Math.min(mAddAnimationStartIndex, childIndex);
             }
         }
+        if (mDark && child instanceof StatusBarIconView) {
+            ((StatusBarIconView) child).setDark(mDark, false, 0);
+        }
     }
 
     @Override
@@ -312,7 +315,8 @@
                 numDots++;
             }
         }
-        if (mCentered && translationX < getLayoutEnd()) {
+        boolean center = mDark;
+        if (center && translationX < getLayoutEnd()) {
             float delta = (getLayoutEnd() - translationX) / 2;
             for (int i = 0; i < childCount; i++) {
                 View view = getChildAt(i);
@@ -390,9 +394,15 @@
         mChangingViewPositions = changingViewPositions;
     }
 
-    public void setAmbient(boolean ambient) {
-        mCentered = ambient;
+    public void setDark(boolean dark, boolean fade, long delay) {
+        mDark = dark;
         mDisallowNextAnimation = true;
+        for (int i = 0; i < getChildCount(); i++) {
+            View view = getChildAt(i);
+            if (view instanceof StatusBarIconView) {
+                ((StatusBarIconView) view).setDark(dark, fade, delay);
+            }
+        }
     }
 
     public IconState getIconState(StatusBarIconView icon) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index c24a2a0..307a8c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2472,4 +2472,8 @@
     public void setNoVisibleNotifications(boolean noNotifications) {
         mNoVisibleNotifications = noNotifications;
     }
+
+    public void setPulsing(boolean pulsing) {
+        mKeyguardStatusView.setPulsing(pulsing);
+    }
 }
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 9a71ed7..472af65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -89,7 +89,6 @@
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.StatusBarNotification;
-import android.support.annotation.VisibleForTesting;
 import android.util.ArraySet;
 import android.util.DisplayMetrics;
 import android.util.EventLog;
@@ -242,7 +241,6 @@
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.SystemUI;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
-import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.statusbar.policy.RemoteInputView;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -5012,19 +5010,25 @@
                 @Override
                 public void onPulseStarted() {
                     callback.onPulseStarted();
-                    if (!mHeadsUpManager.getAllEntries().isEmpty()) {
+                    Collection<HeadsUpManager.HeadsUpEntry> pulsingEntries =
+                            mHeadsUpManager.getAllEntries();
+                    if (!pulsingEntries.isEmpty()) {
                         // Only pulse the stack scroller if there's actually something to show.
                         // Otherwise just show the always-on screen.
-                        mStackScroller.setPulsing(true);
-                        mVisualStabilityManager.setPulsing(true);
+                        setPulsing(pulsingEntries);
                     }
                 }
 
                 @Override
                 public void onPulseFinished() {
                     callback.onPulseFinished();
-                    mStackScroller.setPulsing(false);
-                    mVisualStabilityManager.setPulsing(false);
+                    setPulsing(null);
+                }
+
+                private void setPulsing(Collection<HeadsUpManager.HeadsUpEntry> pulsing) {
+                    mStackScroller.setPulsing(pulsing);
+                    mNotificationPanel.setPulsing(pulsing != null);
+                    mVisualStabilityManager.setPulsing(pulsing != null);
                 }
             }, reason);
         }
@@ -5767,12 +5771,16 @@
                     ServiceManager.getService(Context.NOTIFICATION_SERVICE));
             final String pkg = sbn.getPackageName();
             NotificationInfo info = (NotificationInfo) gutsView;
-            final NotificationInfo.OnSettingsClickListener onSettingsClick = (View v,
-                    NotificationChannel channel, int appUid) -> {
-                mMetricsLogger.action(MetricsEvent.ACTION_NOTE_INFO);
-                guts.resetFalsingCheck();
-                startAppNotificationSettingsActivity(pkg, appUid, channel);
-            };
+            // Settings link is only valid for notifications that specify a user, unless this is the
+            // system user.
+            NotificationInfo.OnSettingsClickListener onSettingsClick = null;
+            if (!userHandle.equals(UserHandle.ALL) || mCurrentUserId == UserHandle.USER_SYSTEM) {
+                onSettingsClick = (View v, NotificationChannel channel, int appUid) -> {
+                    mMetricsLogger.action(MetricsEvent.ACTION_NOTE_INFO);
+                    guts.resetFalsingCheck();
+                    startAppNotificationSettingsActivity(pkg, appUid, channel);
+                };
+            }
             final View.OnClickListener onDoneClick = (View v) -> {
                 saveAndCloseNotificationMenu(info, row, guts, v);
             };
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
index fe83dc4..b2b23a55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AmbientState.java
@@ -59,6 +59,7 @@
     private boolean mPanelTracking;
     private boolean mExpansionChanging;
     private boolean mPanelFullWidth;
+    private boolean mPulsing;
 
     public AmbientState(Context context) {
         reload(context);
@@ -285,6 +286,14 @@
         mPanelTracking = panelTracking;
     }
 
+    public boolean isPulsing() {
+        return mPulsing;
+    }
+
+    public void setPulsing(boolean pulsing) {
+        mPulsing = pulsing;
+    }
+
     public boolean isPanelTracking() {
         return mPanelTracking;
     }
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 7d2d0df..15fcb38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -72,6 +72,7 @@
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.NotificationData;
 import com.android.systemui.statusbar.NotificationGuts;
 import com.android.systemui.statusbar.NotificationShelf;
 import com.android.systemui.statusbar.StackScrollerDecorView;
@@ -86,6 +87,7 @@
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
@@ -331,7 +333,7 @@
         }
     };
     private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
-    private boolean mPulsing;
+    private Collection<HeadsUpManager.HeadsUpEntry> mPulsing;
     private boolean mDrawBackgroundAsSrc;
     private boolean mFadingOut;
     private boolean mParentNotFullyVisible;
@@ -1917,15 +1919,19 @@
         int numShownItems = 0;
         boolean finish = false;
         int maxDisplayedNotifications = mAmbientState.isDark()
-                ? (mPulsing ? 1 : 0)
+                ? (isPulsing() ? 1 : 0)
                 : mMaxDisplayedNotifications;
 
         for (int i = 0; i < getChildCount(); i++) {
             ExpandableView expandableView = (ExpandableView) getChildAt(i);
             if (expandableView.getVisibility() != View.GONE
                     && !expandableView.hasNoContentHeight()) {
-                if (maxDisplayedNotifications != -1
-                        && numShownItems >= maxDisplayedNotifications) {
+                boolean limitReached = maxDisplayedNotifications != -1
+                        && numShownItems >= maxDisplayedNotifications;
+                boolean notificationOnAmbientThatIsNotPulsing = isPulsing()
+                        && expandableView instanceof ExpandableNotificationRow
+                        && !isPulsing(((ExpandableNotificationRow) expandableView).getEntry());
+                if (limitReached || notificationOnAmbientThatIsNotPulsing) {
                     expandableView = mShelf;
                     finish = true;
                 }
@@ -1971,6 +1977,19 @@
         mAmbientState.setLayoutMaxHeight(mContentHeight);
     }
 
+    private boolean isPulsing(NotificationData.Entry entry) {
+        for (HeadsUpManager.HeadsUpEntry e : mPulsing) {
+            if (e.entry == entry) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isPulsing() {
+        return mPulsing != null;
+    }
+
     private void updateScrollability() {
         boolean scrollable = getScrollRange() > 0;
         if (scrollable != mScrollable) {
@@ -2784,7 +2803,7 @@
     }
 
     private void updateNotificationAnimationStates() {
-        boolean running = mAnimationsEnabled || mPulsing;
+        boolean running = mAnimationsEnabled || isPulsing();
         mShelf.setAnimationsEnabled(running);
         int childCount = getChildCount();
         for (int i = 0; i < childCount; i++) {
@@ -2795,7 +2814,7 @@
     }
 
     private void updateAnimationState(View child) {
-        updateAnimationState((mAnimationsEnabled || mPulsing)
+        updateAnimationState((mAnimationsEnabled || isPulsing())
                 && (mIsExpanded || isPinnedHeadsUp(child)), child);
     }
 
@@ -4055,14 +4074,16 @@
         return mIsExpanded;
     }
 
-    public void setPulsing(boolean pulsing) {
-        if (mPulsing == pulsing) {
+    public void setPulsing(Collection<HeadsUpManager.HeadsUpEntry> pulsing) {
+        if (mPulsing == null && pulsing == null) {
             return;
         }
         mPulsing = pulsing;
+        mAmbientState.setPulsing(isPulsing());
         updateNotificationAnimationStates();
         updateContentHeight();
         notifyHeightChangeListener(mShelf);
+        requestChildrenUpdate();
     }
 
     public void setFadingOut(boolean fadingOut) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
index c67cccc..8609eeb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSDetailTest.java
@@ -100,4 +100,10 @@
         ViewUtils.detachView(mQsDetail);
         mTestableLooper.processAllMessages();
     }
+
+    @Test
+    public void testNullAdapterClick() {
+        mQsDetail.setupDetailFooter(mock(DetailAdapter.class));
+        mQsDetail.findViewById(android.R.id.button2).performClick();
+    }
 }
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 21930a3..0621f4a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -206,6 +206,29 @@
     }
 
     @Test
+    public void testBindNotification_SettingsButtonInvisibleWhenNoClickListener() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                null, null, null, null);
+        final TextView settingsButton =
+                (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+        assertTrue(settingsButton.getVisibility() != View.VISIBLE);
+    }
+
+    @Test
+    public void testBindNotification_SettingsButtonReappersAfterSecondBind() throws Exception {
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                null, null, null, null);
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
+                (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
+        final TextView settingsButton =
+                (TextView) mNotificationInfo.findViewById(R.id.more_settings);
+        assertEquals(View.VISIBLE, settingsButton.getVisibility());
+    }
+
+    @Test
     public void testOnClickListenerPassesNullChannelForBundle() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index 31b9bae..efb9fea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -44,4 +44,11 @@
         ViewUtils.detachView(row.getMenuView());
         TestableLooper.get(this).processAllMessages();
     }
+
+    @Test
+    public void testRecreateMenu() {
+        NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
+        row.createMenu(null);
+        row.createMenu(null);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
new file mode 100644
index 0000000..a69de7a
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationViewWrapperTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class NotificationViewWrapperTest {
+
+    private Context mContext;
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+    }
+
+    @Test
+    public void constructor_doesntUseViewContext() throws Exception {
+        new TestableNotificationViewWrapper(mContext, new View(null /* context */), null /* row */);
+    }
+
+    static class TestableNotificationViewWrapper extends NotificationViewWrapper {
+        protected TestableNotificationViewWrapper(Context ctx, View view,
+                ExpandableNotificationRow row) {
+            super(ctx, view, row);
+        }
+    }
+}
\ No newline at end of file
diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp
index c532efb..0acbb02 100644
--- a/rs/jni/android_renderscript_RenderScript.cpp
+++ b/rs/jni/android_renderscript_RenderScript.cpp
@@ -1282,7 +1282,9 @@
 
     ANativeWindow *anw = nullptr;
     if (sur != 0) {
+        // Connect the native window handle to buffer queue.
         anw = ANativeWindow_fromSurface(_env, sur);
+        native_window_api_connect(anw, NATIVE_WINDOW_API_CPU);
     }
 
     rsAllocationSetSurface((RsContext)con, (RsAllocation)alloc, anw);
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 0482e73..ac81565 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -1631,7 +1631,7 @@
 
     @Override
     public ParceledListSlice<AppWidgetProviderInfo> getInstalledProvidersForProfile(int categoryFilter,
-            int profileId) {
+            int profileId, String packageName) {
         final int userId = UserHandle.getCallingUserId();
 
         if (DEBUG) {
@@ -1653,8 +1653,11 @@
                 Provider provider = mProviders.get(i);
                 AppWidgetProviderInfo info = provider.info;
 
-                // Ignore an invalid provider or one not matching the filter.
-                if (provider.zombie || (info.widgetCategory & categoryFilter) == 0) {
+                // Ignore an invalid provider, one not matching the filter,
+                // or one that isn't in the given package, if any.
+                boolean inPackage = packageName == null
+                        || provider.id.componentName.getPackageName().equals(packageName);
+                if (provider.zombie || (info.widgetCategory & categoryFilter) == 0 || !inPackage) {
                     continue;
                 }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index be14440..502b5fc 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -23,7 +23,6 @@
 import static com.android.server.autofill.Helper.VERBOSE;
 import static com.android.server.autofill.Helper.bundleToString;
 
-import android.Manifest;
 import android.annotation.NonNull;
 import android.app.ActivityManagerInternal;
 import android.content.BroadcastReceiver;
@@ -36,7 +35,6 @@
 import android.database.ContentObserver;
 import android.graphics.Rect;
 import android.net.Uri;
-import android.os.Binder;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 3d1c251..15ec98f 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -57,6 +57,7 @@
 import android.view.autofill.AutofillValue;
 import android.view.autofill.IAutoFillManagerClient;
 
+import com.android.internal.R;
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.os.HandlerCaller;
 import com.android.internal.os.IResultReceiver;
@@ -290,7 +291,8 @@
                 + " f=" + flags;
         mRequestsHistory.log(historyItem);
 
-        // TODO(b/33197203): Handle partitioning
+        // TODO(b/33197203): Handle scenario when user forced autofill after app was already
+        // autofilled.
         final Session session = mSessions.get(activityToken);
         if (session != null) {
             // Already started...
@@ -430,8 +432,11 @@
     void dumpLocked(String prefix, PrintWriter pw) {
         final String prefix2 = prefix + "  ";
 
+        pw.print(prefix); pw.print("User :"); pw.println(mUserId);
         pw.print(prefix); pw.print("Component:"); pw.println(mInfo != null
                 ? mInfo.getServiceInfo().getComponentName() : null);
+        pw.print(prefix); pw.print("Default component: ");
+            pw.println(mContext.getString(R.string.config_defaultAutofillService));
         pw.print(prefix); pw.print("Disabled:"); pw.println(mDisabled);
 
         if (VERBOSE && mInfo != null) {
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index ac7d19e..801769c 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -48,6 +48,7 @@
 import android.service.autofill.FillResponse;
 import android.service.autofill.SaveInfo;
 import android.util.ArrayMap;
+import android.util.DebugUtils;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillManager;
@@ -112,20 +113,19 @@
     @GuardedBy("mLock")
     RemoteFillService mRemoteFillService;
 
-    // TODO(b/33197203 , b/35707731): Use List once it supports partitioning
     @GuardedBy("mLock")
-    private FillResponse mCurrentResponse;
+    private ArrayList<FillResponse> mResponses;
 
     /**
-     * Used to remember which {@link Dataset} filled the session.
+     * Response that requires a service authentitcation request.
      */
-    // TODO(b/33197203 , b/35707731): will be removed once it supports partitioning
     @GuardedBy("mLock")
-    private Dataset mAutoFilledDataset;
+    private FillResponse mResponseWaitingAuth;
 
     /**
      * Dataset that when tapped launched a service authentication request.
      */
+    @GuardedBy("mLock")
     private Dataset mDatasetWaitingAuth;
 
     /**
@@ -163,8 +163,8 @@
         mClient = IAutoFillManagerClient.Stub.asInterface(client);
         try {
             client.linkToDeath(() -> {
-                if (DEBUG) {
-                    Slog.d(TAG, "app binder died");
+                if (VERBOSE) {
+                    Slog.v(TAG, "app binder died");
                 }
 
                 removeSelf();
@@ -193,6 +193,10 @@
             notifyUnavailableToClient();
         }
         synchronized (mLock) {
+            if (response.getAuthentication() != null) {
+                // TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
+                mResponseWaitingAuth = response;
+            }
             processResponseLocked(response);
         }
 
@@ -318,23 +322,27 @@
     }
 
     public void setAuthenticationResultLocked(Bundle data) {
-        if (mCurrentResponse == null || data == null) {
+        if ((mResponseWaitingAuth == null && mDatasetWaitingAuth == null) || data == null) {
             removeSelf();
         } else {
             final Parcelable result = data.getParcelable(
                     AutofillManager.EXTRA_AUTHENTICATION_RESULT);
             if (result instanceof FillResponse) {
                 mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
-
-                mCurrentResponse = (FillResponse) result;
-                processResponseLocked(mCurrentResponse);
+                mResponseWaitingAuth = null;
+                processResponseLocked((FillResponse) result);
             } else if (result instanceof Dataset) {
                 final Dataset dataset = (Dataset) result;
-                final int index = mCurrentResponse.getDatasets().indexOf(mDatasetWaitingAuth);
-                if (index >= 0) {
-                    mCurrentResponse.getDatasets().set(index, dataset);
-                    autoFill(dataset);
-                    mDatasetWaitingAuth = null;
+                for (int i = 0; i < mResponses.size(); i++) {
+                    final FillResponse response = mResponses.get(i);
+                    final int index = response.getDatasets().indexOf(mDatasetWaitingAuth);
+                    if (index >= 0) {
+                        response.getDatasets().set(index, dataset);
+                        mDatasetWaitingAuth = null;
+                        autoFill(dataset);
+                        resetViewStatesLocked(dataset, ViewState.STATE_WAITING_DATASET_AUTH);
+                        return;
+                    }
                 }
             }
         }
@@ -354,15 +362,19 @@
             Slog.wtf(TAG, "showSaveLocked(): no mStructure");
             return true;
         }
-        if (mCurrentResponse == null) {
+        if (mResponses == null) {
             // Happens when the activity / session was finished before the service replied, or
             // when the service cannot autofill it (and returned a null response).
             if (DEBUG) {
-                Slog.d(TAG, "showSaveLocked(): no mCurrentResponse");
+                Slog.d(TAG, "showSaveLocked(): no responses on session");
             }
             return true;
         }
-        final SaveInfo saveInfo = mCurrentResponse.getSaveInfo();
+
+        // TODO(b/33197203 , b/35707731): must iterate over all responses
+        final FillResponse response = mResponses.get(0);
+
+        final SaveInfo saveInfo = response.getSaveInfo();
         if (DEBUG) {
             Slog.d(TAG, "showSaveLocked(): saveInfo=" + saveInfo);
         }
@@ -385,7 +397,6 @@
             return true;
         }
 
-        // TODO(b/33197203 , b/35707731): refactor excessive calls to getCurrentValue()
         boolean allRequiredAreNotEmpty = true;
         boolean atLeastOneChanged = false;
         for (int i = 0; i < requiredIds.length; i++) {
@@ -393,7 +404,8 @@
             final ViewState viewState = mViewStates.get(id);
             if (viewState == null) {
                 Slog.w(TAG, "showSaveLocked(): no ViewState for required " + id);
-                continue;
+                allRequiredAreNotEmpty = false;
+                break;
             }
 
             final AutofillValue currentValue = viewState.getCurrentValue();
@@ -462,7 +474,8 @@
             Slog.d(TAG, "callSaveLocked(): mViewStates=" + mViewStates);
         }
 
-        final Bundle extras = this.mCurrentResponse.getExtras();
+        // TODO(b/33197203 , b/35707731): decide how to handle bundle in multiple partitions
+        final Bundle extras = mResponses != null ? mResponses.get(0).getExtras() : null;
 
         for (Entry<AutofillId, ViewState> entry : mViewStates.entrySet()) {
             final AutofillValue value = entry.getValue().getCurrentValue();
@@ -497,16 +510,21 @@
     }
 
     void updateLocked(AutofillId id, Rect virtualBounds, AutofillValue value, int flags) {
-        if (mAutoFilledDataset != null && (flags & FLAG_VALUE_CHANGED) == 0) {
-            // TODO(b/33197203): ignoring because we don't support partitions yet
-            Slog.d(TAG, "updateLocked(): ignoring " + id + " after app was autofilled");
-            return;
-        }
-
         ViewState viewState = mViewStates.get(id);
+
         if (viewState == null) {
-            viewState = new ViewState(this, id, this, ViewState.STATE_INITIAL);
-            mViewStates.put(id, viewState);
+            if ((flags & (FLAG_START_SESSION | FLAG_VALUE_CHANGED)) != 0) {
+                if (DEBUG) {
+                    Slog.d(TAG, "Creating viewState for " + id + " on " + getFlagAsString(flags));
+                }
+                viewState = new ViewState(this, id, this, ViewState.STATE_INITIAL);
+                mViewStates.put(id, viewState);
+            } else if ((flags & FLAG_VIEW_ENTERED) != 0) {
+                viewState = startPartitionLocked(id);
+            } else {
+                if (VERBOSE) Slog.v(TAG, "Ignored " + getFlagAsString(flags) + " for " + id);
+                return;
+            }
         }
 
         if ((flags & FLAG_START_SESSION) != 0) {
@@ -530,7 +548,8 @@
                 }
                 // Update the internal state...
                 viewState.setState(ViewState.STATE_CHANGED);
-                // ... and the chooser UI.
+
+                //..and the UI
                 if (value.isText()) {
                     getUiForShowing().filterFillUi(value.getTextValue().toString());
                 } else {
@@ -551,10 +570,6 @@
             // If the ViewState is ready to be displayed, onReady() will be called.
             viewState.update(value, virtualBounds);
 
-            if (mCurrentResponse != null) {
-                viewState.setResponse(mCurrentResponse);
-            }
-
             return;
         }
 
@@ -566,7 +581,28 @@
             return;
         }
 
-        Slog.w(TAG, "updateLocked(): unknown flags " + flags);
+        Slog.w(TAG, "updateLocked(): unknown flags " + flags + ": " + getFlagAsString(flags));
+    }
+
+    private ViewState startPartitionLocked(AutofillId id) {
+        if (DEBUG) {
+            Slog.d(TAG, "Starting partition for view id " + id);
+        }
+        final ViewState viewState =
+                new ViewState(this, id, this,ViewState.STATE_STARTED_PARTITION);
+        mViewStates.put(id, viewState);
+
+        /*
+         * TODO(b/33197203 , b/35707731): when start a new partition, it should
+         *
+         * - add autofilled fields as sanitized
+         * - set focus on ViewStructure that triggered it
+         * - pass the first onFillRequest() bundle
+         * - optional: perhaps add a new flag onFilLRequest() to indicate it's a new partition?
+         */
+        mRemoteFillService.onFillRequest(mStructure, null, 0);
+
+        return viewState;
     }
 
     @Override
@@ -580,6 +616,10 @@
         getUiForShowing().showFillUi(filledId, response, filterText, mPackageName);
     }
 
+    String getFlagAsString(int flag) {
+        return DebugUtils.flagsToString(AutofillManager.class, "FLAG_", flag);
+    }
+
     private void notifyUnavailableToClient() {
         if (mCurrentViewId == null) {
             // TODO(b/33197203): temporary sanity check; should never happen
@@ -597,8 +637,7 @@
 
     private void processResponseLocked(FillResponse response) {
         if (DEBUG) {
-            Slog.d(TAG, "processResponseLocked(auth=" + response.getAuthentication()
-                + "):" + response);
+            Slog.d(TAG, "processResponseLocked(mCurrentViewId=" + mCurrentViewId + "):" + response);
         }
 
         if (mCurrentViewId == null) {
@@ -607,7 +646,10 @@
             return;
         }
 
-        mCurrentResponse = response;
+        if (mResponses == null) {
+            mResponses = new ArrayList<>(4);
+        }
+        mResponses.add(response);
 
         setViewStatesLocked(response, ViewState.STATE_FILLABLE);
 
@@ -669,10 +711,22 @@
         }
     }
 
+    /**
+     * Resets the given state from all existing views in the given dataset.
+     */
+    private void resetViewStatesLocked(@NonNull Dataset dataset, int state) {
+        final ArrayList<AutofillId> ids = dataset.getFieldIds();
+        for (int j = 0; j < ids.size(); j++) {
+            final AutofillId id = ids.get(j);
+            final ViewState viewState = mViewStates.get(id);
+            if (viewState != null)  {
+                viewState.resetState(state);
+            }
+        }
+    }
+
     void autoFill(Dataset dataset) {
         synchronized (mLock) {
-            mAutoFilledDataset = dataset;
-
             // Autofill it directly...
             if (dataset.getAuthentication() == null) {
                 autoFillApp(dataset);
@@ -680,7 +734,9 @@
             }
 
             // ...or handle authentication.
+            // TODO(b/33197203 , b/35707731): make sure it's ignored if there is one already
             mDatasetWaitingAuth = dataset;
+            setViewStatesLocked(null, dataset, ViewState.STATE_WAITING_DATASET_AUTH);
             final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
             startAuthentication(dataset.getAuthentication(), fillInIntent);
         }
@@ -690,8 +746,8 @@
         return mService.getServiceName();
     }
 
-    FillResponse getCurrentResponse() {
-        return mCurrentResponse;
+    FillResponse getResponseWaitingAuth() {
+        return mResponseWaitingAuth;
     }
 
     private Intent createAuthFillInIntent(AssistStructure structure, Bundle extras) {
@@ -714,8 +770,8 @@
     void dumpLocked(String prefix, PrintWriter pw) {
         pw.print(prefix); pw.print("mActivityToken: "); pw.println(mActivityToken);
         pw.print(prefix); pw.print("mFlags: "); pw.println(mFlags);
-        pw.print(prefix); pw.print("mCurrentResponse: "); pw.println(mCurrentResponse);
-        pw.print(prefix); pw.print("mAutoFilledDataset: "); pw.println(mAutoFilledDataset);
+        pw.print(prefix); pw.print("mResponses: "); pw.println(mResponses);
+        pw.print(prefix); pw.print("mResponseWaitingAuth: "); pw.println(mResponseWaitingAuth);
         pw.print(prefix); pw.print("mDatasetWaitingAuth: "); pw.println(mDatasetWaitingAuth);
         pw.print(prefix); pw.print("mCurrentViewId: "); pw.println(mCurrentViewId);
         pw.print(prefix); pw.print("mViewStates size: "); pw.println(mViewStates.size());
@@ -811,4 +867,4 @@
         destroyLocked();
         mService.removeSessionLocked(mActivityToken);
     }
-}
\ No newline at end of file
+}
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 20def0c..549f231 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -16,10 +16,13 @@
 
 package com.android.server.autofill;
 
+import static com.android.server.autofill.Helper.DEBUG;
+
 import android.annotation.Nullable;
 import android.graphics.Rect;
 import android.service.autofill.FillResponse;
 import android.util.DebugUtils;
+import android.util.Slog;
 import android.view.autofill.AutofillId;
 import android.view.autofill.AutofillValue;
 
@@ -40,6 +43,8 @@
                 @Nullable AutofillValue value);
     }
 
+    private static final String TAG = "ViewState";
+
     // NOTE: state constants must be public because of flagstoString().
     public static final int STATE_UNKNOWN = 0x00;
     /** Initial state. */
@@ -52,6 +57,10 @@
     public static final int STATE_CHANGED = 0x08;
     /** Set only in the View that started a session. */
     public static final int STATE_STARTED_SESSION = 0x10;
+    /** View that started a new partition when focused on. */
+    public static final int STATE_STARTED_PARTITION = 0x20;
+    /** User select a dataset in this view, but service must authenticate first. */
+    public static final int STATE_WAITING_DATASET_AUTH = 0x40;
 
     public final AutofillId id;
     private final Listener mListener;
@@ -122,9 +131,15 @@
     }
 
     void setState(int state) {
-        // TODO(b/33197203 , b/35707731): currently it's always setting one state, but once it
-        // supports partitioning it will need to 'or' some of them..
-        mState = state;
+        if (mState == STATE_INITIAL) {
+            mState = state;
+        } else {
+            mState |= state;
+        }
+    }
+
+    void resetState(int state) {
+        mState &= ~state;
     }
 
     // TODO(b/33197203): need to refactor / rename / document this method to make it clear that
@@ -147,6 +162,12 @@
      * fill UI is ready to be displayed (i.e. when response and bounds are set).
      */
     void maybeCallOnFillReady() {
+        if ((mState & (STATE_AUTOFILLED | STATE_WAITING_DATASET_AUTH)) != 0) {
+            if (DEBUG) {
+                Slog.d(TAG, "Ignoring UI for " + id + " on " + getStateAsString());
+            }
+            return;
+        }
         // First try the current response associated with this View.
         if (mResponse != null) {
             if (mResponse.getDatasets() != null) {
@@ -155,9 +176,9 @@
             return;
         }
         // Then checks if the session has a response waiting authentication; if so, uses it instead.
-        final FillResponse currentResponse = mSession.getCurrentResponse();
-        if (currentResponse != null && currentResponse.getAuthentication() != null) {
-            mListener.onFillReady(currentResponse, this.id, mCurrentValue);
+        final FillResponse responseWaitingAuth = mSession.getResponseWaitingAuth();
+        if (responseWaitingAuth != null) {
+            mListener.onFillReady(responseWaitingAuth, this.id, mCurrentValue);
         }
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d38fb96..b69d1dc 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -101,8 +101,9 @@
             content.measure(widthMeasureSpec, heightMeasureSpec);
             content.setOnClickListener(v -> mCallback.onResponsePicked(response));
             content.setElevation(context.getResources().getDimension(R.dimen.floating_window_z));
-            mContentWidth = content.getMeasuredWidth();
-            mContentHeight = content.getMeasuredHeight();
+            // TODO(b/33197203 , b/36660292): temporary limiting maximum height and minimum width
+            mContentWidth = Math.max(content.getMeasuredWidth(), 1000);
+            mContentHeight = Math.min(content.getMeasuredHeight(), 500);
 
             mWindow = new AnchoredWindow(content);
             mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index a5debda..9218c25 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -280,6 +280,7 @@
         if (DBG) Log.d(TAG, "refreshBinding()");
         // Make sure the scorer is up-to-date
         mNetworkScorerAppManager.updateState();
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
         registerPackageMonitorIfNeeded();
         bindToScoringServiceIfNeeded();
     }
diff --git a/services/core/java/com/android/server/NetworkScorerAppManager.java b/services/core/java/com/android/server/NetworkScorerAppManager.java
index 1a3bb35..8404025 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -286,6 +286,57 @@
         }
     }
 
+    /**
+     * Migrates the NETWORK_SCORER_APP Setting to the USE_OPEN_WIFI_PACKAGE Setting.
+     */
+    @VisibleForTesting
+    public void migrateNetworkScorerAppSettingIfNeeded() {
+        final String scorerAppPkgNameSetting =
+                mSettingsFacade.getString(mContext, Settings.Global.NETWORK_SCORER_APP);
+        if (TextUtils.isEmpty(scorerAppPkgNameSetting)) {
+            // Early exit, nothing to do.
+            return;
+        }
+
+        final NetworkScorerAppData currentAppData = getActiveScorer();
+        if (currentAppData == null) {
+            // Don't touch anything until we have an active scorer to work with.
+            return;
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "Migrating Settings.Global.NETWORK_SCORER_APP "
+                    + "(" + scorerAppPkgNameSetting + ")...");
+        }
+
+        // If the new (useOpenWifi) Setting isn't set and the old Setting's value matches the
+        // new metadata value then update the new Setting with the old value. Otherwise it's a
+        // mismatch so we shouldn't enable the Setting automatically.
+        final ComponentName enableUseOpenWifiActivity =
+                currentAppData.getEnableUseOpenWifiActivity();
+        final String useOpenWifiSetting =
+                mSettingsFacade.getString(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE);
+        if (TextUtils.isEmpty(useOpenWifiSetting)
+                && enableUseOpenWifiActivity != null
+                && scorerAppPkgNameSetting.equals(enableUseOpenWifiActivity.getPackageName())) {
+            mSettingsFacade.putString(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE,
+                    scorerAppPkgNameSetting);
+            if (DEBUG) {
+                Log.d(TAG, "Settings.Global.USE_OPEN_WIFI_PACKAGE set to "
+                        + "'" + scorerAppPkgNameSetting + "'.");
+            }
+        }
+
+        // Clear out the old setting so we don't run through the migration code again.
+        mSettingsFacade.putString(mContext, Settings.Global.NETWORK_SCORER_APP, null);
+        if (DEBUG) {
+            Log.d(TAG, "Settings.Global.NETWORK_SCORER_APP migration complete.");
+            final String setting =
+                    mSettingsFacade.getString(mContext, Settings.Global.USE_OPEN_WIFI_PACKAGE);
+            Log.d(TAG, "Settings.Global.USE_OPEN_WIFI_PACKAGE is: '" + setting + "'.");
+        }
+    }
+
     private String getDefaultPackageSetting() {
         return mContext.getResources().getString(
                 R.string.config_defaultNetworkRecommendationProviderPackage);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index e560d32..738365d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -427,14 +427,13 @@
     public boolean addAccountExplicitlyWithVisibility(Account account, String password,
             Bundle extras, Map packageToVisibility) {
         Bundle.setDefusable(extras, true);
-
-        final int callingUid = Binder.getCallingUid();
+        int callingUid = Binder.getCallingUid();
+        int userId = UserHandle.getCallingUserId();
         if (Log.isLoggable(TAG, Log.VERBOSE)) {
             Log.v(TAG, "addAccountExplicitly: " + account + ", caller's uid " + callingUid
                     + ", pid " + Binder.getCallingPid());
         }
         Preconditions.checkNotNull(account, "account cannot be null");
-        int userId = UserHandle.getCallingUserId();
         if (!isAccountManagedByCaller(account.type, callingUid, userId)) {
             String msg = String.format("uid %s cannot explicitly add accounts of type: %s",
                     callingUid, account.type);
@@ -461,9 +460,9 @@
     public Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
             String accountType) {
         int callingUid = Binder.getCallingUid();
+        int userId = UserHandle.getCallingUserId();
         boolean isSystemUid = UserHandle.isSameApp(callingUid, Process.SYSTEM_UID);
-        List<String> managedTypes =
-                getTypesForCaller(callingUid, UserHandle.getUserId(callingUid), isSystemUid);
+        List<String> managedTypes = getTypesForCaller(callingUid, userId, isSystemUid);
 
         if ((accountType != null && !managedTypes.contains(accountType))
                 || (accountType == null && !isSystemUid)) {
@@ -478,8 +477,9 @@
 
         long identityToken = clearCallingIdentity();
         try {
+            UserAccounts accounts = getUserAccounts(userId);
             return getAccountsAndVisibilityForPackage(packageName, managedTypes, callingUid,
-                    getUserAccounts(UserHandle.getUserId(callingUid)));
+                    accounts);
         } finally {
             restoreCallingIdentity(identityToken);
         }
@@ -490,12 +490,8 @@
      */
     private Map<Account, Integer> getAccountsAndVisibilityForPackage(String packageName,
             List<String> accountTypes, Integer callingUid, UserAccounts accounts) {
-        int uid = 0;
-        try {
-            uid = mPackageManager.getPackageUidAsUser(packageName,
-                    UserHandle.getUserId(callingUid));
-        } catch (NameNotFoundException e) {
-            Log.d(TAG, "Package not found " + e.getMessage());
+        if (!packageExistsForUser(packageName, accounts.userId)) {
+            Log.d(TAG, "Package not found " + packageName);
             return new LinkedHashMap<>();
         }
 
@@ -520,19 +516,26 @@
     public Map<String, Integer> getPackagesAndVisibilityForAccount(Account account) {
         Preconditions.checkNotNull(account, "account cannot be null");
         int callingUid = Binder.getCallingUid();
-        int userId = UserHandle.getUserId(callingUid);
-        UserAccounts accounts = getUserAccounts(userId);
+        int userId = UserHandle.getCallingUserId();
         if (!isAccountManagedByCaller(account.type, callingUid, userId)
                 && !isSystemUid(callingUid)) {
             String msg =
                     String.format("uid %s cannot get secrets for account %s", callingUid, account);
             throw new SecurityException(msg);
         }
-        synchronized (accounts.dbLock) {
-            synchronized (accounts.cacheLock) {
-                return getPackagesAndVisibilityForAccountLocked(account, accounts);
+
+        long identityToken = clearCallingIdentity();
+        try {
+            UserAccounts accounts = getUserAccounts(userId);
+            synchronized (accounts.dbLock) {
+                synchronized (accounts.cacheLock) {
+                    return getPackagesAndVisibilityForAccountLocked(account, accounts);
+                }
             }
+        } finally {
+            restoreCallingIdentity(identityToken);
         }
+
     }
 
     /**
@@ -560,8 +563,8 @@
         Preconditions.checkNotNull(account, "account cannot be null");
         Preconditions.checkNotNull(packageName, "packageName cannot be null");
         int callingUid = Binder.getCallingUid();
-        UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid));
-        if (!isAccountManagedByCaller(account.type, callingUid, accounts.userId)
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)
             && !isSystemUid(callingUid)) {
             String msg = String.format(
                     "uid %s cannot get secrets for accounts of type: %s",
@@ -569,7 +572,13 @@
                     account.type);
             throw new SecurityException(msg);
         }
-        return resolveAccountVisibility(account, packageName, accounts);
+        long identityToken = clearCallingIdentity();
+        try {
+            UserAccounts accounts = getUserAccounts(userId);
+            return resolveAccountVisibility(account, packageName, accounts);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
     }
 
     /**
@@ -708,8 +717,8 @@
         Preconditions.checkNotNull(account, "account cannot be null");
         Preconditions.checkNotNull(packageName, "packageName cannot be null");
         int callingUid = Binder.getCallingUid();
-        UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid));
-        if (!isAccountManagedByCaller(account.type, callingUid, accounts.userId)
+        int userId = UserHandle.getCallingUserId();
+        if (!isAccountManagedByCaller(account.type, callingUid, userId)
             && !isSystemUid(callingUid)) {
             String msg = String.format(
                     "uid %s cannot get secrets for accounts of type: %s",
@@ -717,8 +726,14 @@
                     account.type);
             throw new SecurityException(msg);
         }
-        return setAccountVisibility(account, packageName, newVisibility, true /* notify */,
+        long identityToken = clearCallingIdentity();
+        try {
+            UserAccounts accounts = getUserAccounts(userId);
+            return setAccountVisibility(account, packageName, newVisibility, true /* notify */,
                 accounts);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
     }
 
     /**
@@ -805,8 +820,15 @@
     public void registerAccountListener(String[] accountTypes, String opPackageName) {
         int callingUid = Binder.getCallingUid();
         mAppOpsManager.checkPackage(callingUid, opPackageName);
-        registerAccountListener(accountTypes, opPackageName,
-            getUserAccounts(UserHandle.getUserId(callingUid)));
+
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            UserAccounts accounts = getUserAccounts(userId);
+            registerAccountListener(accountTypes, opPackageName, accounts);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
     }
 
     private void registerAccountListener(String[] accountTypes, String opPackageName,
@@ -832,7 +854,18 @@
     public void unregisterAccountListener(String[] accountTypes, String opPackageName) {
         int callingUid = Binder.getCallingUid();
         mAppOpsManager.checkPackage(callingUid, opPackageName);
-        UserAccounts accounts = getUserAccounts(UserHandle.getUserId(callingUid));
+        int userId = UserHandle.getCallingUserId();
+        long identityToken = clearCallingIdentity();
+        try {
+            UserAccounts accounts = getUserAccounts(userId);
+            unregisterAccountListener(accountTypes, opPackageName, accounts);
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    private void unregisterAccountListener(String[] accountTypes, String opPackageName,
+            UserAccounts accounts) {
         synchronized (accounts.mReceiversForType) {
             if (accountTypes == null) {
                 // null for any type
@@ -903,7 +936,7 @@
             long identityToken = clearCallingIdentity();
             try {
                 mPackageManager.getPackageUidAsUser(packageName, userId);
-                return true; // package exist
+                return true;
             } finally {
                 restoreCallingIdentity(identityToken);
             }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 4cbfb27..7dd75df 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -31,8 +31,10 @@
 
 import android.app.ActivityThread;
 import android.app.AppOpsManager;
+import android.app.ServiceStartArgs;
 import android.content.IIntentSender;
 import android.content.IntentSender;
+import android.content.pm.ParceledListSlice;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.DeadObjectException;
@@ -369,7 +371,8 @@
                     }
                     // This app knows it is in the new model where this operation is not
                     // allowed, so tell it what has happened.
-                    return new ComponentName("?", "app is in background");
+                    UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
+                    return new ComponentName("?", "app is in background uid " + uidRec);
                 }
             } finally {
                 Binder.restoreCallingIdentity(token);
@@ -1956,78 +1959,86 @@
             return;
         }
 
-        while (r.pendingStarts.size() > 0) {
-            Exception caughtException = null;
-            ServiceRecord.StartItem si = null;
-            try {
-                si = r.pendingStarts.remove(0);
-                if (DEBUG_SERVICE) {
-                    Slog.v(TAG_SERVICE, "Sending arguments to: "
-                            + r + " " + r.intent + " args=" + si.intent);
-                }
-                if (si.intent == null && N > 1) {
-                    // If somehow we got a dummy null intent in the middle,
-                    // then skip it.  DO NOT skip a null intent when it is
-                    // the only one in the list -- this is to support the
-                    // onStartCommand(null) case.
-                    continue;
-                }
-                si.deliveredTime = SystemClock.uptimeMillis();
-                r.deliveredStarts.add(si);
-                si.deliveryCount++;
-                if (si.neededGrants != null) {
-                    mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
-                            si.getUriPermissionsLocked());
-                }
-                mAm.grantEphemeralAccessLocked(r.userId, si.intent,
-                        r.appInfo.uid, UserHandle.getAppId(si.callingId));
-                bumpServiceExecutingLocked(r, execInFg, "start");
-                if (!oomAdjusted) {
-                    oomAdjusted = true;
-                    mAm.updateOomAdjLocked(r.app);
-                }
-                if (r.fgRequired && !r.fgWaiting) {
-                    if (!r.isForeground) {
-                        if (DEBUG_BACKGROUND_CHECK) {
-                            Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r);
-                        }
-                        scheduleServiceForegroundTransitionTimeoutLocked(r);
-                    } else {
-                        if (DEBUG_BACKGROUND_CHECK) {
-                            Slog.i(TAG, "Service already foreground; no new timeout: " + r);
-                        }
-                        r.fgRequired = false;
-                    }
-                }
-                int flags = 0;
-                if (si.deliveryCount > 1) {
-                    flags |= Service.START_FLAG_RETRY;
-                }
-                if (si.doneExecutingCount > 0) {
-                    flags |= Service.START_FLAG_REDELIVERY;
-                }
-                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
-            } catch (TransactionTooLargeException e) {
-                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large: intent="
-                        + si.intent);
-                caughtException = e;
-            } catch (RemoteException e) {
-                // Remote process gone...  we'll let the normal cleanup take care of this.
-                if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
-                caughtException = e;
-            } catch (Exception e) {
-                Slog.w(TAG, "Unexpected exception", e);
-                caughtException = e;
-            }
+        ArrayList<ServiceStartArgs> args = new ArrayList<>();
 
-            if (caughtException != null) {
-                // Keep nesting count correct
-                final boolean inDestroying = mDestroyingServices.contains(r);
-                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
-                if (caughtException instanceof TransactionTooLargeException) {
-                    throw (TransactionTooLargeException)caughtException;
+        while (r.pendingStarts.size() > 0) {
+            ServiceRecord.StartItem si = r.pendingStarts.remove(0);
+            if (DEBUG_SERVICE) {
+                Slog.v(TAG_SERVICE, "Sending arguments to: "
+                        + r + " " + r.intent + " args=" + si.intent);
+            }
+            if (si.intent == null && N > 1) {
+                // If somehow we got a dummy null intent in the middle,
+                // then skip it.  DO NOT skip a null intent when it is
+                // the only one in the list -- this is to support the
+                // onStartCommand(null) case.
+                continue;
+            }
+            si.deliveredTime = SystemClock.uptimeMillis();
+            r.deliveredStarts.add(si);
+            si.deliveryCount++;
+            if (si.neededGrants != null) {
+                mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
+                        si.getUriPermissionsLocked());
+            }
+            mAm.grantEphemeralAccessLocked(r.userId, si.intent,
+                    r.appInfo.uid, UserHandle.getAppId(si.callingId));
+            bumpServiceExecutingLocked(r, execInFg, "start");
+            if (!oomAdjusted) {
+                oomAdjusted = true;
+                mAm.updateOomAdjLocked(r.app);
+            }
+            if (r.fgRequired && !r.fgWaiting) {
+                if (!r.isForeground) {
+                    if (DEBUG_BACKGROUND_CHECK) {
+                        Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r);
+                    }
+                    scheduleServiceForegroundTransitionTimeoutLocked(r);
+                } else {
+                    if (DEBUG_BACKGROUND_CHECK) {
+                        Slog.i(TAG, "Service already foreground; no new timeout: " + r);
+                    }
+                    r.fgRequired = false;
                 }
-                break;
+            }
+            int flags = 0;
+            if (si.deliveryCount > 1) {
+                flags |= Service.START_FLAG_RETRY;
+            }
+            if (si.doneExecutingCount > 0) {
+                flags |= Service.START_FLAG_REDELIVERY;
+            }
+            args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
+        }
+
+        ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
+        slice.setInlineCountLimit(4);
+        Exception caughtException = null;
+        try {
+            r.app.thread.scheduleServiceArgs(r, slice);
+        } catch (TransactionTooLargeException e) {
+            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large for " + args.size()
+                    + " args, first: " + args.get(0).args);
+            Slog.w(TAG, "Failed delivering service starts", e);
+            caughtException = e;
+        } catch (RemoteException e) {
+            // Remote process gone...  we'll let the normal cleanup take care of this.
+            if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
+            Slog.w(TAG, "Failed delivering service starts", e);
+            caughtException = e;
+        } catch (Exception e) {
+            Slog.w(TAG, "Unexpected exception", e);
+            caughtException = e;
+        }
+
+        if (caughtException != null) {
+            // Keep nesting count correct
+            final boolean inDestroying = mDestroyingServices.contains(r);
+            for (int i = 0; i < args.size(); i++) {
+                serviceDoneExecutingLocked(r, inDestroying, inDestroying);
+            }
+            if (caughtException instanceof TransactionTooLargeException) {
+                throw (TransactionTooLargeException)caughtException;
             }
         }
     }
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 19fc2b8..ee2fdba 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -12143,6 +12143,24 @@
         return false;
     }
 
+    @Override
+    public void backgroundWhitelistUid(final int uid) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
+        }
+
+        if (DEBUG_BACKGROUND_CHECK) {
+            Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
+        }
+        synchronized (this) {
+            final int N = mBackgroundUidWhitelist.length;
+            int[] newList = new int[N+1];
+            System.arraycopy(mBackgroundUidWhitelist, 0, newList, 0, N);
+            newList[N] = uid;
+            mBackgroundUidWhitelist = newList;
+        }
+    }
+
     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
             String abiOverride) {
         ProcessRecord app;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b72cd73..3e3fee5 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -745,7 +745,7 @@
     }
 
     /**
-     * Returns a {@link TaskRecord} for the input id if available. Null otherwise.
+     * Returns a {@link TaskRecord} for the input id if available. {@code null} otherwise.
      * @param id Id of the task we would like returned.
      * @param matchMode The mode to match the given task id in.
      * @param stackId The stack to restore the task to (default launch stack will be used if
@@ -765,7 +765,7 @@
             ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
             for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                 ActivityStack stack = stacks.get(stackNdx);
-                TaskRecord task = stack.taskForIdLocked(id);
+                final TaskRecord task = stack.taskForIdLocked(id);
                 if (task != null) {
                     return task;
                 }
@@ -780,11 +780,17 @@
         // Otherwise, check the recent tasks and return if we find it there and we are not restoring
         // the task from recents
         if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
-        TaskRecord task = mRecentTasks.taskForIdLocked(id);
-        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
-            if (DEBUG_RECENTS && task == null) {
+        final TaskRecord task = mRecentTasks.taskForIdLocked(id);
+
+        if (task == null) {
+            if (DEBUG_RECENTS) {
                 Slog.d(TAG_RECENTS, "\tDidn't find task id=" + id + " in recents");
             }
+
+            return null;
+        }
+
+        if (matchMode == MATCH_TASK_IN_STACKS_OR_RECENT_TASKS) {
             return task;
         }
 
diff --git a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
index 82a0ff6..51aa4f8 100644
--- a/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/PlaybackActivityMonitor.java
@@ -103,6 +103,13 @@
         apc.init();
         synchronized(mPlayerLock) {
             mPlayers.put(newPiid, apc);
+            if (mDuckedUids.contains(new Integer(apc.getClientUid()))) {
+                if (DEBUG) { Log.v(TAG, "  > trackPlayer() piid=" + newPiid + " must be ducked"); }
+                mDuckedPlayers.add(new Integer(newPiid));
+                // FIXME here the player needs to be put in a state that is the same as if it
+                //   had been ducked as it starts. At the moment, this works already for linked
+                //   players, as is the case in gapless playback.
+            }
         }
         return newPiid;
     }
@@ -141,6 +148,13 @@
                 Log.e(TAG, "Error handling event " + event);
                 change = false;
             }
+            if (change && event == AudioPlaybackConfiguration.PLAYER_STATE_STARTED
+                    && mDuckedUids.contains(new Integer(apc.getClientUid()))) {
+                if (DEBUG) { Log.v(TAG, "  > playerEvent() piid=" + piid + " must be ducked"); }
+                if (!mDuckedPlayers.contains(new Integer(piid))) {
+                    mDuckedPlayers.add(new Integer(piid));
+                }
+            }
         }
         if (change) {
             dispatchPlaybackChange();
@@ -273,13 +287,20 @@
     // PlayerFocusEnforcer implementation
     private final ArrayList<Integer> mDuckedPlayers = new ArrayList<Integer>();
     private final ArrayList<Integer> mMutedPlayers = new ArrayList<Integer>();
+    // size of 2 for typical cases of double-ducking, not expected to grow beyond that, but can
+    private final ArrayList<Integer> mDuckedUids = new ArrayList<Integer>(2);
 
     @Override
     public boolean duckPlayers(FocusRequester winner, FocusRequester loser) {
         if (DEBUG) {
             Log.v(TAG, String.format("duckPlayers: uids winner=%d loser=%d",
-                    winner.getClientUid(), loser.getClientUid())); }
+                    winner.getClientUid(), loser.getClientUid()));
+        }
         synchronized (mPlayerLock) {
+            final Integer loserUid = new Integer(loser.getClientUid());
+            if (!mDuckedUids.contains(loserUid)) {
+                mDuckedUids.add(loserUid);
+            }
             if (mPlayers.isEmpty()) {
                 return true;
             }
@@ -296,7 +317,7 @@
                         && loser.hasSameUid(apc.getClientUid())
                         && apc.getPlayerState() == AudioPlaybackConfiguration.PLAYER_STATE_STARTED)
                 {
-                    if (mDuckedPlayers.contains(piid)) {
+                    if (mDuckedPlayers.contains(new Integer(piid))) {
                         if (DEBUG) { Log.v(TAG, "player " + piid + " already ducked"); }
                     } else if (apc.getAudioAttributes().getContentType() ==
                             AudioAttributes.CONTENT_TYPE_SPEECH) {
@@ -313,7 +334,7 @@
                             apc.getPlayerProxy().applyVolumeShaper(
                                     DUCK_VSHAPE,
                                     PLAY_CREATE_IF_NEEDED);
-                            mDuckedPlayers.add(piid);
+                            mDuckedPlayers.add(new Integer(piid));
                         } catch (Exception e) {
                             Log.e(TAG, "Error ducking player " + piid, e);
                             // something went wrong trying to duck, so let the app handle it
@@ -332,25 +353,36 @@
         if (DEBUG) { Log.v(TAG, "unduckPlayers: uids winner=" + winner.getClientUid()); }
         synchronized (mPlayerLock) {
             if (mDuckedPlayers.isEmpty()) {
+                mDuckedUids.remove(new Integer(winner.getClientUid()));
                 return;
             }
+            final ArrayList<Integer> playersToRemove =
+                    new ArrayList<Integer>(mDuckedPlayers.size());
             for (int piid : mDuckedPlayers) {
                 final AudioPlaybackConfiguration apc = mPlayers.get(piid);
-                if (apc != null
-                        && winner.hasSameUid(apc.getClientUid())) {
-                    try {
-                        Log.v(TAG, "unducking player" + piid);
-                        mDuckedPlayers.remove(new Integer(piid));
-                        apc.getPlayerProxy().applyVolumeShaper(
-                                DUCK_ID,
-                                VolumeShaper.Operation.REVERSE);
-                    } catch (Exception e) {
-                        Log.e(TAG, "Error unducking player " + piid, e);
+                if (apc != null) {
+                    if (winner.hasSameUid(apc.getClientUid())) {
+                        try {
+                            Log.v(TAG, "unducking player " + piid);
+                            apc.getPlayerProxy().applyVolumeShaper(
+                                    DUCK_ID,
+                                    VolumeShaper.Operation.REVERSE);
+                        } catch (Exception e) {
+                            Log.e(TAG, "Error unducking player " + piid, e);
+                        } finally {
+                            playersToRemove.add(piid);
+                        }
                     }
                 } else {
-                    Log.e(TAG, "Error unducking player " + piid + ", player not found");
+                    // this piid was in the list of ducked players, but wasn't found, discard it
+                    Log.v(TAG, "Error unducking player " + piid + ", player not found");
+                    playersToRemove.add(piid);
                 }
             }
+            for (int piid : playersToRemove) {
+                mDuckedPlayers.remove(new Integer(piid));
+            }
+            mDuckedUids.remove(new Integer(winner.getClientUid()));
         }
     }
 
@@ -383,7 +415,7 @@
                     try {
                         Log.v(TAG, "call: muting player" + piid);
                         apc.getPlayerProxy().setVolume(0.0f);
-                        mMutedPlayers.add(piid);
+                        mMutedPlayers.add(new Integer(piid));
                     } catch (Exception e) {
                         Log.e(TAG, "call: error muting player " + piid, e);
                     }
diff --git a/services/core/java/com/android/server/job/JobPackageTracker.java b/services/core/java/com/android/server/job/JobPackageTracker.java
index 0a6d8a4..8ad1bea 100644
--- a/services/core/java/com/android/server/job/JobPackageTracker.java
+++ b/services/core/java/com/android/server/job/JobPackageTracker.java
@@ -345,6 +345,7 @@
 
     public void notePending(JobStatus job) {
         final long now = SystemClock.uptimeMillis();
+        job.madePending = now;
         rebatchIfNeeded(now);
         mCurDataSet.incPending(job.getSourceUid(), job.getSourcePackageName(), now);
     }
@@ -357,6 +358,7 @@
 
     public void noteActive(JobStatus job) {
         final long now = SystemClock.uptimeMillis();
+        job.madeActive = now;
         rebatchIfNeeded(now);
         if (job.lastEvaluatedPriority >= JobInfo.PRIORITY_TOP_APP) {
             mCurDataSet.incActiveTop(job.getSourceUid(), job.getSourcePackageName(), now);
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 7c231ff..cd3ba4c 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -2035,27 +2035,35 @@
                     pw.print("    Evaluated priority: "); pw.println(priority);
                 }
                 pw.print("    Tag: "); pw.println(job.getTag());
+                pw.print("    Enq: ");
+                TimeUtils.formatDuration(now - job.madePending, pw);
+                pw.println(" ago");
             }
             pw.println();
             pw.println("Active jobs:");
             for (int i=0; i<mActiveServices.size(); i++) {
                 JobServiceContext jsc = mActiveServices.get(i);
                 pw.print("  Slot #"); pw.print(i); pw.print(": ");
-                if (jsc.getRunningJob() == null) {
+                final JobStatus job = jsc.getRunningJob();
+                if (job == null) {
                     pw.println("inactive");
                     continue;
                 } else {
-                    pw.println(jsc.getRunningJob().toShortString());
+                    pw.println(job.toShortString());
                     pw.print("    Running for: ");
                     TimeUtils.formatDuration(now - jsc.getExecutionStartTimeElapsed(), pw);
                     pw.print(", timeout at: ");
                     TimeUtils.formatDuration(jsc.getTimeoutElapsed() - now, pw);
                     pw.println();
-                    jsc.getRunningJob().dump(pw, "    ", false);
+                    job.dump(pw, "    ", false);
                     int priority = evaluateJobPriorityLocked(jsc.getRunningJob());
                     if (priority != JobInfo.PRIORITY_DEFAULT) {
                         pw.print("    Evaluated priority: "); pw.println(priority);
                     }
+                    pw.print("    Active at "); pw.println(job.madeActive);
+                    pw.print("    Pending for ");
+                    TimeUtils.formatDuration(job.madeActive - job.madePending, pw);
+                    pw.println();
                 }
             }
             if (filterUid == -1) {
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index f41e187..0e04d24 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -147,7 +147,6 @@
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
-
             if (action.equals(Intent.ACTION_SCREEN_ON)
                     || action.equals(Intent.ACTION_DREAMING_STOPPED)) {
                 if (DEBUG) {
@@ -183,6 +182,11 @@
                     }
                     mIdle = true;
                     reportNewIdleState(mIdle);
+                } else {
+                    if (DEBUG) {
+                        Slog.v(TAG, "TRIGGER_IDLE received but not changing state; idle="
+                                + mIdle + " screen=" + mScreenOn);
+                    }
                 }
             }
         }
@@ -191,7 +195,7 @@
     @Override
     public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
         pw.print("Idle: ");
-        pw.println(mIdleTracker.isIdle() ? "true" : "false");
+        pw.println(mIdleTracker.isIdle());
         pw.print("Tracking ");
         pw.print(mTrackedTasks.size());
         pw.println(":");
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 47630d0..d27d0e5 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -129,6 +129,10 @@
     // Used by shell commands
     public int overrideState = 0;
 
+    // Metrics about queue latency
+    public long madePending;
+    public long madeActive;
+
     /**
      * For use only by ContentObserverController: state it is maintaining about content URIs
      * being observed.
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 5bdef9e..3705946 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -325,13 +325,11 @@
             // Disable all other overlays.
             allOverlays.remove(oi);
             for (int i = 0; i < allOverlays.size(); i++) {
-                mSettings.setEnabled(allOverlays.get(i).packageName, userId, false);
+                // TODO: Optimize this to only send updates after all changes.
+                setEnabled(allOverlays.get(i).packageName, false, userId);
             }
 
-            final PackageInfo targetPackage =
-                    mPackageManager.getPackageInfo(oi.targetPackageName, userId);
-            mSettings.setEnabled(packageName, userId, enable);
-            updateState(targetPackage, overlayPackage, userId);
+            setEnabled(packageName, enable, userId);
             return true;
         } catch (OverlayManagerSettings.BadKeyException e) {
             return false;
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index b0730ef..f6e96b2 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -27,6 +27,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
 import android.os.IRemoteCallback;
 import android.os.RemoteException;
 import android.os.SystemClock;
@@ -47,7 +48,7 @@
  * service and handling all interactions in a timely manner.
  * @hide
  */
-final class EphemeralResolverConnection {
+final class EphemeralResolverConnection implements DeathRecipient {
     // This is running in a critical section and the timeout must be sufficiently low
     private static final long BIND_SERVICE_TIMEOUT_MS =
             ("eng".equals(Build.TYPE)) ? 300 : 200;
@@ -65,7 +66,7 @@
 
     public EphemeralResolverConnection(Context context, ComponentName componentName) {
         mContext = context;
-        mIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE).setComponent(componentName);
+        mIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE).setComponent(componentName);
     }
 
     public final List<InstantAppResolveInfo> getInstantAppResolveInfoList(int hashPrefix[],
@@ -171,6 +172,15 @@
         }
     }
 
+    @Override
+    public void binderDied() {
+        if (mRemoteInstance != null) {
+            mRemoteInstance.asBinder().unlinkToDeath(this, 0 /*flags*/);
+        }
+        mRemoteInstance = null;
+        mBindRequested = false;
+    }
+
     /**
      * Asynchronous callback when results come back from ephemeral resolution phase two.
      */
@@ -183,7 +193,11 @@
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
             synchronized (mLock) {
-                mRemoteInstance = IInstantAppResolver.Stub.asInterface(service);
+                try {
+                    service.linkToDeath(EphemeralResolverConnection.this, 0 /*flags*/);
+                    mRemoteInstance = IInstantAppResolver.Stub.asInterface(service);
+                } catch (RemoteException e) {
+                }
                 mLock.notifyAll();
             }
         }
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 7eef7ad..9f7c4a2 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -66,6 +66,7 @@
     public static final int FLAG_FREE_CACHE_V2 = 1 << 13;
     public static final int FLAG_FREE_CACHE_V2_DEFY_QUOTA = 1 << 14;
     public static final int FLAG_FREE_CACHE_NOOP = 1 << 15;
+    public static final int FLAG_FORCE = 1 << 16;
 
     private final boolean mIsolated;
 
@@ -202,6 +203,15 @@
         }
     }
 
+    public void fixupAppData(String uuid, int flags) throws InstallerException {
+        if (!checkBeforeRemote()) return;
+        try {
+            mInstalld.fixupAppData(uuid, flags);
+        } catch (Exception e) {
+            throw InstallerException.from(e);
+        }
+    }
+
     public void moveCompleteApp(String fromUuid, String toUuid, String packageName,
             String dataAppName, int appId, String seInfo, int targetSdkVersion)
             throws InstallerException {
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index 59f8a2d..6f593b0 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -86,22 +86,18 @@
         final List<InstantAppResolveInfo> instantAppResolveInfoList =
                 connection.getInstantAppResolveInfoList(shaPrefix, token);
 
-        final AuxiliaryResolveInfo resolveInfo;
         if (instantAppResolveInfoList == null || instantAppResolveInfoList.size() == 0) {
             // No hash prefix match; there are no instant apps for this domain.
             if (DEBUG_EPHEMERAL) {
                 Log.d(TAG, "No results returned");
             }
-            resolveInfo = null;
-        } else {
-            resolveInfo = InstantAppResolver.filterInstantAppIntent(instantAppResolveInfoList,
-                    intent, requestObj.resolvedType, requestObj.userId,
-                    intent.getPackage(), digest, token);
+            return null;
         }
-
+        final AuxiliaryResolveInfo resolveInfo = InstantAppResolver.filterInstantAppIntent(
+                instantAppResolveInfoList, intent, requestObj.resolvedType, requestObj.userId,
+                intent.getPackage(), digest, token);
         logMetrics(ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE, startTime, token,
-                resolveInfo != null ? RESOLUTION_SUCCESS : RESOLUTION_FAILURE);
-
+                RESOLUTION_SUCCESS);
         return resolveInfo;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index d9ea728..acbd446 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -151,6 +151,7 @@
         // TODO(calin,jeffhao): shared library paths should be adjusted to include previous code
         // paths (b/34169257).
         final String sharedLibrariesPath = getSharedLibrariesPath(sharedLibraries);
+        // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
         final int dexoptFlags = getDexFlags(pkg, compilerFilter);
 
         int result = DEX_OPT_SKIPPED;
@@ -254,6 +255,8 @@
     @GuardedBy("mInstallLock")
     private int dexOptSecondaryDexPathLI(ApplicationInfo info, String path, Set<String> isas,
             String compilerFilter, boolean isUsedByOtherApps) {
+        compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps);
+        // Get the dexopt flags after getRealCompilerFilter to make sure we get the correct flags.
         int dexoptFlags = getDexFlags(info, compilerFilter) | DEXOPT_SECONDARY_DEX;
         // Check the app storage and add the appropriate flags.
         if (info.dataDir.equals(info.deviceProtectedDataDir)) {
@@ -264,7 +267,6 @@
             Slog.e(TAG, "Could not infer CE/DE storage for package " + info.packageName);
             return DEX_OPT_FAILED;
         }
-        compilerFilter = getRealCompilerFilter(info, compilerFilter, isUsedByOtherApps);
         Log.d(TAG, "Running dexopt on: " + path
                 + " pkg=" + info.packageName + " isa=" + isas
                 + " dexoptFlags=" + printDexoptFlags(dexoptFlags)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d89b12e..f62f115 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -608,6 +608,10 @@
     final boolean mIsPreNUpgrade;
     final boolean mIsPreNMR1Upgrade;
 
+    // Have we told the Activity Manager to whitelist the default container service by uid yet?
+    @GuardedBy("mPackages")
+    boolean mDefaultContainerWhitelisted = false;
+
     @GuardedBy("mPackages")
     private boolean mDexOptDialogShown;
 
@@ -842,11 +846,11 @@
 
     /** The service connection to the ephemeral resolver */
     final EphemeralResolverConnection mInstantAppResolverConnection;
+    /** Component used to show resolver settings for Instant Apps */
+    final ComponentName mInstantAppResolverSettingsComponent;
 
     /** Component used to install ephemeral applications */
     ComponentName mInstantAppInstallerComponent;
-    /** Component used to show resolver settings for Instant Apps */
-    ComponentName mInstantAppResolverSettingsComponent;
     ActivityInfo mInstantAppInstallerActivity;
     final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
 
@@ -2717,6 +2721,15 @@
                     UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
                     true /* onlyCoreApps */);
             mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
+                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "fixup");
+                try {
+                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
+                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
+                } catch (InstallerException e) {
+                    Slog.w(TAG, "Trouble fixing GIDs", e);
+                }
+                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+
                 if (deferPackages == null || deferPackages.isEmpty()) {
                     return;
                 }
@@ -2807,11 +2820,13 @@
                 }
                 mInstantAppResolverConnection =
                         new EphemeralResolverConnection(mContext, ephemeralResolverComponent);
+                mInstantAppResolverSettingsComponent =
+                        getEphemeralResolverSettingsLPr(ephemeralResolverComponent);
             } else {
                 mInstantAppResolverConnection = null;
+                mInstantAppResolverSettingsComponent = null;
             }
             updateInstantAppInstallerLocked();
-            mInstantAppResolverSettingsComponent = getEphemeralResolverSettingsLPr();
 
             // Read and update the usage of dex files.
             // Do this at the end of PM init so that all the packages have their
@@ -3045,10 +3060,18 @@
                 MATCH_DIRECT_BOOT_AWARE
                 | MATCH_DIRECT_BOOT_UNAWARE
                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
-        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
-        final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
+        final Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
+        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
-
+        // temporarily look for the old action
+        if (resolvers.size() == 0) {
+            if (DEBUG_EPHEMERAL) {
+                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
+            }
+            resolverIntent.setAction(Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE);
+            resolvers = queryIntentServicesInternal(resolverIntent, null,
+                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
+        }
         final int N = resolvers.size();
         if (N == 0) {
             if (DEBUG_EPHEMERAL) {
@@ -3087,7 +3110,7 @@
     }
 
     private @Nullable ActivityInfo getEphemeralInstallerLPr() {
-        final Intent intent = new Intent(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
+        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
         intent.addCategory(Intent.CATEGORY_DEFAULT);
         intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
 
@@ -3095,8 +3118,17 @@
                 MATCH_DIRECT_BOOT_AWARE
                 | MATCH_DIRECT_BOOT_UNAWARE
                 | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
-        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
+        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
                 resolveFlags, UserHandle.USER_SYSTEM);
+        // temporarily look for the old action
+        if (matches.isEmpty()) {
+            if (DEBUG_EPHEMERAL) {
+                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
+            }
+            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
+            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
+                    resolveFlags, UserHandle.USER_SYSTEM);
+        }
         Iterator<ResolveInfo> iter = matches.iterator();
         while (iter.hasNext()) {
             final ResolveInfo rInfo = iter.next();
@@ -3119,35 +3151,27 @@
         }
     }
 
-    private @Nullable ComponentName getEphemeralResolverSettingsLPr() {
-        final Intent intent = new Intent(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
-        intent.addCategory(Intent.CATEGORY_DEFAULT);
-        final int resolveFlags =
-                MATCH_DIRECT_BOOT_AWARE
-                | MATCH_DIRECT_BOOT_UNAWARE
-                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
-        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
-                resolveFlags, UserHandle.USER_SYSTEM);
-        Iterator<ResolveInfo> iter = matches.iterator();
-        while (iter.hasNext()) {
-            final ResolveInfo rInfo = iter.next();
-            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
-            if (ps != null) {
-                final PermissionsState permissionsState = ps.getPermissionsState();
-                if (permissionsState.hasPermission(Manifest.permission.ACCESS_INSTANT_APPS, 0)) {
-                    continue;
-                }
+    private @Nullable ComponentName getEphemeralResolverSettingsLPr(
+            @NonNull ComponentName resolver) {
+        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
+                .addCategory(Intent.CATEGORY_DEFAULT)
+                .setPackage(resolver.getPackageName());
+        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
+        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
+                UserHandle.USER_SYSTEM);
+        // temporarily look for the old action
+        if (matches.isEmpty()) {
+            if (DEBUG_EPHEMERAL) {
+                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
             }
-            iter.remove();
+            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
+            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
+                    UserHandle.USER_SYSTEM);
         }
-        if (matches.size() == 0) {
+        if (matches.isEmpty()) {
             return null;
-        } else if (matches.size() == 1) {
-            return matches.get(0).getComponentInfo().getComponentName();
-        } else {
-            throw new RuntimeException(
-                    "There must be at most one ephemeral resolver settings; found " + matches);
         }
+        return matches.get(0).getComponentInfo().getComponentName();
     }
 
     private void primeDomainVerificationsLPw(int userId) {
@@ -5729,20 +5753,23 @@
         synchronized (mPackages) {
             final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
             for (int n = 0; n < count; n++) {
-                ResolveInfo info = resolvedActivities.get(n);
-                String packageName = info.activityInfo.packageName;
-                PackageSetting ps = mSettings.mPackages.get(packageName);
+                final ResolveInfo info = resolvedActivities.get(n);
+                final String packageName = info.activityInfo.packageName;
+                final PackageSetting ps = mSettings.mPackages.get(packageName);
                 if (ps != null) {
-                    // Try to get the status from User settings first
-                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
-                    int status = (int) (packedStatus >> 32);
-                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
+                    // only check domain verification status if the app is not a browser
+                    if (!info.handleAllWebDataURI) {
+                        // Try to get the status from User settings first
+                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
+                        final int status = (int) (packedStatus >> 32);
+                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
                             || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
-                        if (DEBUG_EPHEMERAL) {
-                            Slog.v(TAG, "DENY ephemeral apps;"
-                                + " pkg: " + packageName + ", status: " + status);
+                            if (DEBUG_EPHEMERAL) {
+                                Slog.v(TAG, "DENY instant app;"
+                                    + " pkg: " + packageName + ", status: " + status);
+                            }
+                            return false;
                         }
-                        return false;
                     }
                     if (ps.getInstantApp(userId)) {
                         if (DEBUG_EPHEMERAL) {
@@ -13030,7 +13057,18 @@
         intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
         IActivityManager am = ActivityManager.getService();
         if (am != null) {
+            int dcsUid = -1;
+            synchronized (mPackages) {
+                if (!mDefaultContainerWhitelisted) {
+                    mDefaultContainerWhitelisted = true;
+                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
+                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
+                }
+            }
             try {
+                if (dcsUid > 0) {
+                    am.backgroundWhitelistUid(dcsUid);
+                }
                 am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
                         UserHandle.USER_SYSTEM);
             } catch (RemoteException e) {
@@ -16965,6 +17003,15 @@
                 return;
             }
 
+            // Shared libraries for the package need to be updated.
+            synchronized (mPackages) {
+                try {
+                    updateSharedLibrariesLPr(pkg, null);
+                } catch (PackageManagerException e) {
+                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
+                }
+            }
+
             Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
             // Do not run PackageDexOptimizer through the local performDexOpt
             // method because `pkg` may not be in `mPackages` yet.
@@ -17013,6 +17060,7 @@
                         args.user, installerPackageName, volumeUuid, res, args.installReason);
             }
         }
+
         synchronized (mPackages) {
             final PackageSetting ps = mSettings.mPackages.get(pkgName);
             if (ps != null) {
@@ -17639,6 +17687,7 @@
         int removedAppId = -1;
         int[] origUsers;
         int[] removedUsers = null;
+        int[] broadcastUsers = null;
         SparseArray<Integer> installReasons;
         boolean isRemovedPackageSystemUpdate = false;
         boolean isUpdate;
@@ -17712,16 +17761,16 @@
             extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
             if (removedPackage != null) {
                 sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED, removedPackage,
-                        extras, 0, null, null, removedUsers);
+                        extras, 0, null, null, broadcastUsers);
                 if (dataRemoved && !isRemovedPackageSystemUpdate) {
                     sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
                             removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
-                            null, null, removedUsers);
+                            null, null, broadcastUsers);
                 }
             }
             if (removedAppId >= 0) {
                 sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras, 0, null, null,
-                        removedUsers);
+                        broadcastUsers);
             }
         }
     }
@@ -17750,6 +17799,20 @@
                 outInfo.removedUsers = deletedPs != null
                         ? deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true)
                         : null;
+                if (outInfo.removedUsers == null) {
+                    outInfo.broadcastUsers = null;
+                } else {
+                    outInfo.broadcastUsers = EMPTY_INT_ARRAY;
+                    int[] allUsers = outInfo.removedUsers;
+                    for (int i = allUsers.length - 1; i >= 0; --i) {
+                        final int userId = allUsers[i];
+                        if (deletedPs.getInstantApp(userId)) {
+                            continue;
+                        }
+                        outInfo.broadcastUsers =
+                                ArrayUtils.appendInt(outInfo.broadcastUsers, userId);
+                    }
+                }
             }
         }
 
@@ -20858,13 +20921,6 @@
                 mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
             }
 
-            if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
-                // XXX should handle packageName != null by dumping only install data that
-                // the given package is involved with.
-                if (dumpState.onTitlePrinted()) pw.println();
-                mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
-            }
-
             if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
                 // XXX should handle packageName != null by dumping only install data that
                 // the given package is involved with.
@@ -20935,6 +20991,14 @@
                 }
             }
         }
+
+        // PackageInstaller should be called outside of mPackages lock
+        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
+            // XXX should handle packageName != null by dumping only install data that
+            // the given package is involved with.
+            if (dumpState.onTitlePrinted()) pw.println();
+            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
+        }
     }
 
     private void dumpProto(FileDescriptor fd) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6fb056a..554deae 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -4777,7 +4777,7 @@
             pw.print(" notLaunched=");
             pw.print(ps.getNotLaunched(user.id));
             pw.print(" enabled=");
-            pw.println(ps.getEnabled(user.id));
+            pw.print(ps.getEnabled(user.id));
             pw.print(" instant=");
             pw.println(ps.getInstantApp(user.id));
             String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
index 218d218..32871bb 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java
@@ -763,8 +763,10 @@
         enforceStatusBarService();
         long identity = Binder.clearCallingIdentity();
         try {
+            // ShutdownThread displays UI, so give it a UI context.
             mHandler.post(() ->
-                    ShutdownThread.shutdown(mContext, PowerManager.SHUTDOWN_USER_REQUESTED, false));
+                    ShutdownThread.shutdown(getUiContext(),
+                        PowerManager.SHUTDOWN_USER_REQUESTED, false));
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
@@ -780,11 +782,11 @@
         try {
             mHandler.post(() -> {
                 // ShutdownThread displays UI, so give it a UI context.
-                Context uiContext = ActivityThread.currentActivityThread().getSystemUiContext();
                 if (safeMode) {
-                    ShutdownThread.rebootSafeMode(uiContext, false);
+                    ShutdownThread.rebootSafeMode(getUiContext(), false);
                 } else {
-                    ShutdownThread.reboot(uiContext, PowerManager.SHUTDOWN_USER_REQUESTED, false);
+                    ShutdownThread.reboot(getUiContext(),
+                            PowerManager.SHUTDOWN_USER_REQUESTED, false);
                 }
             });
         } finally {
@@ -1018,4 +1020,8 @@
             }
         }
     }
+
+    private static final Context getUiContext() {
+        return ActivityThread.currentActivityThread().getSystemUiContext();
+    }
 }
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 6c7f146..205c8de 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -52,20 +52,6 @@
     <application>
         <uses-library android:name="android.test.runner" />
 
-        <service android:name="com.android.server.AccessibilityManagerServiceTest$MyFirstMockAccessibilityService"
-            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
-          <intent-filter>
-            <action android:name="android.accessibilityservice.AccessibilityService"/>
-          </intent-filter>
-        </service>
-
-        <service android:name="com.android.server.AccessibilityManagerServiceTest$MySecondMockAccessibilityService"
-            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
-          <intent-filter>
-            <action android:name="android.accessibilityservice.AccessibilityService"/>
-          </intent-filter>
-        </service>
-
         <service android:name="com.android.server.accounts.TestAccountType1AuthenticatorService"
             android:exported="false">
           <intent-filter>
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
deleted file mode 100644
index 340c624..0000000
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerServiceTest.java
+++ /dev/null
@@ -1,762 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.accessibilityservice.AccessibilityService;
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.ServiceInfo;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.IAccessibilityManager;
-import android.view.accessibility.IAccessibilityManagerClient;
-
-import com.android.internal.util.IntPair;
-
-/**
- * This test exercises the
- * {@link com.android.server.accessibility.AccessibilityManagerService} by mocking the
- * {@link android.view.accessibility.AccessibilityManager} which talks to to the
- * service. The service itself is interacting with the platform. Note: Testing
- * the service in full isolation would require significant amount of work for
- * mocking all system interactions. It would also require a lot of mocking code.
- */
-public class AccessibilityManagerServiceTest extends AndroidTestCase {
-
-    /**
-     * Timeout required for pending Binder calls or event processing to
-     * complete.
-     */
-    private static final long TIMEOUT_BINDER_CALL = 100;
-
-    /**
-     * Timeout in which we are waiting for the system to start the mock
-     * accessibility services.
-     */
-    private static final long TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES = 1000;
-
-    /**
-     * Timeout used for testing that a service is notified only upon a
-     * notification timeout.
-     */
-    private static final long TIMEOUT_TEST_NOTIFICATION_TIMEOUT = 300;
-
-    /**
-     * The interface used to talk to the tested service.
-     */
-    private IAccessibilityManager mManagerService;
-
-    @Override
-    protected void setUp() throws Exception {
-        // Reset the state.
-        ensureOnlyMockServicesEnabled(getContext(), false, false);
-    }
-
-    @Override
-    public void setContext(Context context) {
-        super.setContext(context);
-        if (MyFirstMockAccessibilityService.sComponentName == null) {
-            MyFirstMockAccessibilityService.sComponentName = new ComponentName(
-                    context.getPackageName(), MyFirstMockAccessibilityService.class.getName())
-                    .flattenToShortString();
-        }
-        if (MySecondMockAccessibilityService.sComponentName == null) {
-            MySecondMockAccessibilityService.sComponentName = new ComponentName(
-                    context.getPackageName(), MySecondMockAccessibilityService.class.getName())
-                    .flattenToShortString();
-        }
-    }
-
-    /**
-     * Creates a new instance.
-     */
-    public AccessibilityManagerServiceTest() {
-        IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
-        mManagerService = IAccessibilityManager.Stub.asInterface(iBinder);
-    }
-
-    @LargeTest
-    public void testAddClient_AccessibilityDisabledThenEnabled() throws Exception {
-        // at least some service must be enabled, otherwise accessibility will always be disabled.
-        ensureOnlyMockServicesEnabled(mContext, true, false);
-
-        // make sure accessibility is disabled
-        ensureAccessibilityEnabled(mContext, false);
-
-        // create a client mock instance
-        MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
-
-        // invoke the method under test
-        final int stateFlagsDisabled =
-                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
-        boolean enabledAccessibilityDisabled =
-            (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
-
-        // check expected result
-        assertFalse("The client must be disabled since accessibility is disabled.",
-                enabledAccessibilityDisabled);
-
-        // enable accessibility
-        ensureAccessibilityEnabled(mContext, true);
-
-        // invoke the method under test
-        final int stateFlagsEnabled =
-                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
-        boolean enabledAccessibilityEnabled =
-            (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
-
-        // check expected result
-        assertTrue("The client must be enabled since accessibility is enabled.",
-                enabledAccessibilityEnabled);
-    }
-
-    @LargeTest
-    public void testAddClient_AccessibilityEnabledThenDisabled() throws Exception {
-        // at least some service must be enabled, otherwise accessibility will always be disabled.
-        ensureOnlyMockServicesEnabled(mContext, true, false);
-
-        // enable accessibility before registering the client
-        ensureAccessibilityEnabled(mContext, true);
-
-        // create a client mock instance
-        MyMockAccessibilityManagerClient mockClient = new MyMockAccessibilityManagerClient();
-
-        // invoke the method under test
-        final int stateFlagsEnabled =
-                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
-        boolean enabledAccessibilityEnabled =
-            (stateFlagsEnabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
-
-        // check expected result
-        assertTrue("The client must be enabled since accessibility is enabled.",
-                enabledAccessibilityEnabled);
-
-        // disable accessibility
-        ensureAccessibilityEnabled(mContext, false);
-
-        // invoke the method under test
-        final int stateFlagsDisabled =
-                IntPair.first(mManagerService.addClient(mockClient, UserHandle.USER_CURRENT));
-        boolean enabledAccessibilityDisabled =
-            (stateFlagsDisabled & AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED) != 0;
-
-        // check expected result
-        assertFalse("The client must be disabled since accessibility is disabled.",
-                enabledAccessibilityDisabled);
-    }
-
-    @LargeTest
-    public void testGetAccessibilityServicesList() throws Exception {
-        boolean firstMockServiceInstalled = false;
-        boolean secondMockServiceInstalled = false;
-
-        String packageName = getContext().getPackageName();
-        String firstMockServiceClassName = MyFirstMockAccessibilityService.class.getName();
-        String secondMockServiceClassName = MySecondMockAccessibilityService.class.getName();
-
-        // look for the two mock services
-        for (AccessibilityServiceInfo info : mManagerService.getInstalledAccessibilityServiceList(
-                UserHandle.USER_CURRENT)) {
-            ServiceInfo serviceInfo = info.getResolveInfo().serviceInfo;
-            if (packageName.equals(serviceInfo.packageName)) {
-                if (firstMockServiceClassName.equals(serviceInfo.name)) {
-                    firstMockServiceInstalled = true;
-                } else if (secondMockServiceClassName.equals(serviceInfo.name)) {
-                    secondMockServiceInstalled = true;
-                }
-            }
-        }
-
-        // check expected result
-        assertTrue("First mock service must be installed", firstMockServiceInstalled);
-        assertTrue("Second mock service must be installed", secondMockServiceInstalled);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_OneService_MatchingPackageAndEventType()
-            throws Exception {
-        // enable the mock accessibility service
-        ensureOnlyMockServicesEnabled(mContext, true, false);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the mock service
-        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
-        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
-
-        // wait for the binder call to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate an event to be sent
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(sentEvent);
-
-        // set expectations
-        service.expectEvent(sentEvent);
-        service.replay();
-
-        // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(service);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_OneService_NotMatchingPackage() throws Exception {
-        // enable the mock accessibility service
-        ensureOnlyMockServicesEnabled(mContext, true, false);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the mock service
-        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
-        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
-
-        // wait for the binder call to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate an event to be sent
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(sentEvent);
-        sentEvent.setPackageName("no.service.registered.for.this.package");
-
-        // set expectations
-        service.replay();
-
-        // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(service);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_OneService_NotMatchingEventType() throws Exception {
-        // enable the mock accessibility service
-        ensureOnlyMockServicesEnabled(mContext, true, false);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the mock service
-        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
-        service.setServiceInfo(MockAccessibilityService.createDefaultInfo());
-
-        // wait for the binder call to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate an event to be sent
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(sentEvent);
-        sentEvent.setEventType(AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
-
-        // set expectations
-        service.replay();
-
-        // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(service);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_OneService_NotificationAfterTimeout() throws Exception {
-        // enable the mock accessibility service
-        ensureOnlyMockServicesEnabled(mContext, true, false);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the mock service
-        MockAccessibilityService service = MyFirstMockAccessibilityService.sInstance;
-        AccessibilityServiceInfo info = MockAccessibilityService.createDefaultInfo();
-        info.notificationTimeout = TIMEOUT_TEST_NOTIFICATION_TIMEOUT;
-        service.setServiceInfo(info);
-
-        // wait for the binder call to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate the first event to be sent
-        AccessibilityEvent firstEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(firstEvent);
-
-        // create and populate the second event to be sent
-        AccessibilityEvent secondEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(secondEvent);
-
-        // set expectations
-        service.expectEvent(secondEvent);
-        service.replay();
-
-        // send the events
-        mManagerService.sendAccessibilityEvent(firstEvent, UserHandle.USER_CURRENT);
-        mManagerService.sendAccessibilityEvent(secondEvent, UserHandle.USER_CURRENT);
-
-        // wait for #sendAccessibilityEvent to reach the backing service
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        try {
-            service.verify();
-            fail("No events must be dispatched before the expiration of the notification timeout.");
-        } catch (IllegalStateException ise) {
-            /* expected */
-        }
-
-        // wait for the configured notification timeout to expire
-        Thread.sleep(TIMEOUT_TEST_NOTIFICATION_TIMEOUT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(service);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_DiffFeedback()
-            throws Exception {
-        // enable the mock accessibility services
-        ensureOnlyMockServicesEnabled(mContext, true, true);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the first mock service
-        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
-        AccessibilityServiceInfo firstInfo = MockAccessibilityService.createDefaultInfo();
-        firstInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
-        firstService.setServiceInfo(firstInfo);
-
-        // configure the second mock service
-        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
-        AccessibilityServiceInfo secondInfo = MockAccessibilityService.createDefaultInfo();
-        secondInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_HAPTIC;
-        secondService.setServiceInfo(secondInfo);
-
-        // wait for the binder calls to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate an event to be sent
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(sentEvent);
-
-        // set expectations for the first mock service
-        firstService.expectEvent(sentEvent);
-        firstService.replay();
-
-        // set expectations for the second mock service
-        secondService.expectEvent(sentEvent);
-        secondService.replay();
-
-        // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(firstService);
-        assertMockServiceVerifiedWithinTimeout(secondService);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType()
-            throws Exception {
-        // enable the mock accessibility services
-        ensureOnlyMockServicesEnabled(mContext, true, true);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the first mock service
-        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
-        firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
-
-        // configure the second mock service
-        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
-        secondService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
-
-        // wait for the binder calls to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate an event to be sent
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(sentEvent);
-
-        // set expectations for the first mock service
-        firstService.expectEvent(sentEvent);
-        firstService.replay();
-
-        // set expectations for the second mock service
-        secondService.replay();
-
-        // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(firstService);
-        assertMockServiceVerifiedWithinTimeout(secondService);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_OneDefault()
-            throws Exception {
-        // enable the mock accessibility services
-        ensureOnlyMockServicesEnabled(mContext, true, true);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the first mock service
-        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
-        AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
-        firstInfo.flags = AccessibilityServiceInfo.DEFAULT;
-        firstService.setServiceInfo(firstInfo);
-
-        // configure the second mock service
-        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
-        secondService.setServiceInfo(MySecondMockAccessibilityService.createDefaultInfo());
-
-        // wait for the binder calls to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate an event to be sent
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(sentEvent);
-
-        // set expectations for the first mock service
-        firstService.replay();
-
-        // set expectations for the second mock service
-        secondService.expectEvent(sentEvent);
-        secondService.replay();
-
-        // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(firstService);
-        assertMockServiceVerifiedWithinTimeout(secondService);
-    }
-
-    @LargeTest
-    public void testSendAccessibilityEvent_TwoServices_MatchingPackageAndEventType_TwoDefault()
-            throws Exception {
-        // enable the mock accessibility services
-        ensureOnlyMockServicesEnabled(mContext, true, true);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the first mock service
-        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
-        AccessibilityServiceInfo firstInfo = MyFirstMockAccessibilityService.createDefaultInfo();
-        firstInfo.flags = AccessibilityServiceInfo.DEFAULT;
-        firstService.setServiceInfo(firstInfo);
-
-        // configure the second mock service
-        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
-        AccessibilityServiceInfo secondInfo = MyFirstMockAccessibilityService.createDefaultInfo();
-        secondInfo.flags = AccessibilityServiceInfo.DEFAULT;
-        secondService.setServiceInfo(firstInfo);
-
-        // wait for the binder calls to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // create and populate an event to be sent
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-        fullyPopulateDefaultAccessibilityEvent(sentEvent);
-
-        // set expectations for the first mock service
-        firstService.expectEvent(sentEvent);
-        firstService.replay();
-
-        // set expectations for the second mock service
-        secondService.replay();
-
-        // send the event
-        mManagerService.sendAccessibilityEvent(sentEvent, UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(firstService);
-        assertMockServiceVerifiedWithinTimeout(secondService);
-    }
-
-    @LargeTest
-    public void testInterrupt() throws Exception {
-        // enable the mock accessibility services
-        ensureOnlyMockServicesEnabled(mContext, true, true);
-
-        // set the accessibility setting value
-        ensureAccessibilityEnabled(mContext, true);
-
-        // configure the first mock service
-        MockAccessibilityService firstService = MyFirstMockAccessibilityService.sInstance;
-        firstService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
-
-        // configure the second mock service
-        MockAccessibilityService secondService = MySecondMockAccessibilityService.sInstance;
-        secondService.setServiceInfo(MockAccessibilityService.createDefaultInfo());
-
-        // wait for the binder calls to #setService to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // set expectations for the first mock service
-        firstService.expectInterrupt();
-        firstService.replay();
-
-        // set expectations for the second mock service
-        secondService.expectInterrupt();
-        secondService.replay();
-
-        // call the method under test
-        mManagerService.interrupt(UserHandle.USER_CURRENT);
-
-        // verify if all expected methods have been called
-        assertMockServiceVerifiedWithinTimeout(firstService);
-        assertMockServiceVerifiedWithinTimeout(secondService);
-    }
-
-    /**
-     * Fully populates the {@link AccessibilityEvent} to marshal.
-     *
-     * @param sentEvent The event to populate.
-     */
-    private void fullyPopulateDefaultAccessibilityEvent(AccessibilityEvent sentEvent) {
-        sentEvent.setAddedCount(1);
-        sentEvent.setBeforeText("BeforeText");
-        sentEvent.setChecked(true);
-        sentEvent.setClassName("foo.bar.baz.Class");
-        sentEvent.setContentDescription("ContentDescription");
-        sentEvent.setCurrentItemIndex(1);
-        sentEvent.setEnabled(true);
-        sentEvent.setEventType(AccessibilityEvent.TYPE_ANNOUNCEMENT);
-        sentEvent.setEventTime(1000);
-        sentEvent.setFromIndex(1);
-        sentEvent.setFullScreen(true);
-        sentEvent.setItemCount(1);
-        sentEvent.setPackageName("foo.bar.baz");
-        sentEvent.setParcelableData(Message.obtain(null, 1, null));
-        sentEvent.setPassword(true);
-        sentEvent.setRemovedCount(1);
-    }
-
-    /**
-     * This class is a mock {@link IAccessibilityManagerClient}.
-     */
-    public class MyMockAccessibilityManagerClient extends IAccessibilityManagerClient.Stub {
-        int mState;
-
-        public void setState(int state) {
-            mState = state;
-        }
-
-        public void notifyServicesStateChanged() {}
-
-        public void setRelevantEventTypes(int eventTypes) {}
-
-        public void setTouchExplorationEnabled(boolean enabled) {}
-    }
-
-    /**
-     * Ensures accessibility is in a given state by writing the state to the
-     * settings and waiting until the accessibility manager service pick it up.
-     *
-     * @param context A context handle to access the settings.
-     * @param enabled The accessibility state to write to the settings.
-     * @throws Exception If any error occurs.
-     */
-    private void ensureAccessibilityEnabled(Context context, boolean enabled) throws Exception {
-        boolean isEnabled = Settings.Secure.getInt(context.getContentResolver(),
-                Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
-
-        if (isEnabled == enabled) {
-            return;
-        }
-
-        Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED,
-                enabled ? 1 : 0);
-
-        // wait the accessibility manager service to pick the change up
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-    }
-
-    /**
-     * Ensures the only {@link MockAccessibilityService}s with given component
-     * names are enabled by writing to the system settings and waiting until the
-     * accessibility manager service picks that up or the
-     * {@link #TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES} is exceeded.
-     *
-     * @param context A context handle to access the settings.
-     * @param firstMockServiceEnabled If the first mock accessibility service is enabled.
-     * @param secondMockServiceEnabled If the second mock accessibility service is enabled.
-     * @throws IllegalStateException If some of the requested for enabling mock services
-     *         is not properly started.
-     * @throws Exception Exception If any error occurs.
-     */
-    private void ensureOnlyMockServicesEnabled(Context context, boolean firstMockServiceEnabled,
-            boolean secondMockServiceEnabled) throws Exception {
-        String enabledServices = Settings.Secure.getString(context.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
-
-        StringBuilder servicesToEnable = new StringBuilder();
-        if (firstMockServiceEnabled) {
-            servicesToEnable.append(MyFirstMockAccessibilityService.sComponentName).append(":");
-        }
-        if (secondMockServiceEnabled) {
-            servicesToEnable.append(MySecondMockAccessibilityService.sComponentName).append(":");
-        }
-
-        Settings.Secure.putString(context.getContentResolver(),
-                Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, servicesToEnable.toString());
-
-        // Optimization. If things will not change, we don't have to do anything.
-        if (servicesToEnable.equals(enabledServices)) {
-            return;
-        }
-
-        // we have enabled the services of interest and need to wait until they
-        // are instantiated and started (if needed) and the system binds to them
-        boolean firstMockServiceOK = false;
-        boolean secondMockServiceOK = false;
-        long start = SystemClock.uptimeMillis();
-        long pollingInterval = TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES / 6;
-
-        while (SystemClock.uptimeMillis() - start < TIMEOUT_START_MOCK_ACCESSIBILITY_SERVICES)  {
-            firstMockServiceOK = !firstMockServiceEnabled
-                    || (MyFirstMockAccessibilityService.sInstance != null
-                    && MyFirstMockAccessibilityService.sInstance.isSystemBoundAsClient());
-
-            secondMockServiceOK = !secondMockServiceEnabled
-                    || (MySecondMockAccessibilityService.sInstance != null
-                    && MySecondMockAccessibilityService.sInstance.isSystemBoundAsClient());
-
-            if (firstMockServiceOK && secondMockServiceOK) {
-                return;
-            }
-
-            Thread.sleep(pollingInterval);
-        }
-
-        StringBuilder message = new StringBuilder();
-        message.append("Mock accessibility services not started or system not bound as a client: ");
-        if (!firstMockServiceOK) {
-            message.append(MyFirstMockAccessibilityService.sComponentName);
-            message.append(" ");
-        }
-        if (!secondMockServiceOK) {
-            message.append(MySecondMockAccessibilityService.sComponentName);
-        }
-        throw new IllegalStateException(message.toString());
-    }
-
-    /**
-     * Asserts the the mock accessibility service has been successfully verified
-     * (which is it has received the expected method calls with expected
-     * arguments) within the {@link #TIMEOUT_BINDER_CALL}. The verified state is
-     * checked by polling upon small intervals.
-     *
-     * @param service The service to verify.
-     * @throws Exception If the verification has failed with exception after the
-     *             {@link #TIMEOUT_BINDER_CALL}.
-     */
-    private void assertMockServiceVerifiedWithinTimeout(MockAccessibilityService service)
-            throws Exception {
-        Exception lastVerifyException = null;
-        long beginTime = SystemClock.uptimeMillis();
-        long pollTimeout = TIMEOUT_BINDER_CALL / 5;
-
-        // poll until the timeout has elapsed
-        while (SystemClock.uptimeMillis() - beginTime < TIMEOUT_BINDER_CALL) {
-            // sleep first since immediate call will always fail
-            try {
-                Thread.sleep(pollTimeout);
-            } catch (InterruptedException ie) {
-                /* ignore */
-            }
-            // poll for verification and if this fails save the exception and
-            // keep polling
-            try {
-                service.verify();
-                // reset so it does not accept more events
-                service.reset();
-                return;
-            } catch (Exception e) {
-                lastVerifyException = e;
-            }
-        }
-
-        // reset, we have already failed
-        service.reset();
-
-        // always not null
-        throw lastVerifyException;
-    }
-
-    /**
-     * This class is the first mock {@link AccessibilityService}.
-     */
-    public static class MyFirstMockAccessibilityService extends MockAccessibilityService {
-
-        /**
-         * The service {@link ComponentName} flattened as a string.
-         */
-        static String sComponentName;
-
-        /**
-         * Handle to the service instance.
-         */
-        static MyFirstMockAccessibilityService sInstance;
-
-        /**
-         * Creates a new instance.
-         */
-        public MyFirstMockAccessibilityService() {
-            sInstance = this;
-        }
-    }
-
-    /**
-     * This class is the first mock {@link AccessibilityService}.
-     */
-    public static class MySecondMockAccessibilityService extends MockAccessibilityService {
-
-        /**
-         * The service {@link ComponentName} flattened as a string.
-         */
-        static String sComponentName;
-
-        /**
-         * Handle to the service instance.
-         */
-        static MySecondMockAccessibilityService sInstance;
-
-        /**
-         * Creates a new instance.
-         */
-        public MySecondMockAccessibilityService() {
-            sInstance = this;
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java b/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
deleted file mode 100644
index 9261771..0000000
--- a/services/tests/servicestests/src/com/android/server/AccessibilityManagerTest.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.os.UserHandle;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.IAccessibilityManager;
-import android.view.accessibility.IAccessibilityManagerClient;
-
-import com.android.internal.util.IntPair;
-
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests for the AccessibilityManager which mocking the backing service.
- */
-public class AccessibilityManagerTest extends AndroidTestCase {
-
-    /**
-     * Timeout required for pending Binder calls or event processing to
-     * complete.
-     */
-    public static final long TIMEOUT_BINDER_CALL = 50;
-
-    @Mock
-    private IAccessibilityManager mMockService;
-
-    @Override
-    public void setUp() throws Exception {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    private AccessibilityManager createManager(boolean enabled) throws Exception {
-        if (enabled) {
-            when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
-                    .thenReturn(
-                            IntPair.of(AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED,
-                                    AccessibilityEvent.TYPES_ALL_MASK));
-        } else {
-            when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
-                    .thenReturn(IntPair.of(0, AccessibilityEvent.TYPES_ALL_MASK));
-        }
-
-        AccessibilityManager manager =
-                new AccessibilityManager(mContext, mMockService, UserHandle.USER_CURRENT);
-
-        verify(mMockService).addClient(any(IAccessibilityManagerClient.class), anyInt());
-
-        return manager;
-    }
-
-    @MediumTest
-    public void testGetAccessibilityServiceList() throws Exception {
-        // create a list of installed accessibility services the mock service returns
-        List<AccessibilityServiceInfo> expectedServices = new ArrayList<>();
-        AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
-        accessibilityServiceInfo.packageNames = new String[] { "foo.bar" };
-        expectedServices.add(accessibilityServiceInfo);
-
-        // configure the mock service behavior
-        when(mMockService.getInstalledAccessibilityServiceList(anyInt()))
-                .thenReturn(expectedServices);
-
-        // invoke the method under test
-        AccessibilityManager manager = createManager(true);
-        List<AccessibilityServiceInfo> receivedServices =
-                manager.getInstalledAccessibilityServiceList();
-
-        verify(mMockService).getInstalledAccessibilityServiceList(UserHandle.USER_CURRENT);
-        // check expected result (list equals() compares it contents as well)
-        assertEquals("All expected services must be returned", expectedServices, receivedServices);
-    }
-
-    @MediumTest
-    public void testInterrupt() throws Exception {
-        AccessibilityManager manager = createManager(true);
-        manager.interrupt();
-
-        verify(mMockService).interrupt(UserHandle.USER_CURRENT);
-    }
-
-    @LargeTest
-    public void testIsEnabled() throws Exception {
-        // invoke the method under test
-        AccessibilityManager manager = createManager(true);
-        boolean isEnabledServiceEnabled = manager.isEnabled();
-
-        // check expected result
-        assertTrue("Must be enabled since the mock service is enabled", isEnabledServiceEnabled);
-
-        // disable accessibility
-        manager.getClient().setState(0);
-
-        // wait for the asynchronous IBinder call to complete
-        Thread.sleep(TIMEOUT_BINDER_CALL);
-
-        // invoke the method under test
-        boolean isEnabledServcieDisabled = manager.isEnabled();
-
-        // check expected result
-        assertFalse("Must be disabled since the mock service is disabled",
-                isEnabledServcieDisabled);
-    }
-
-    @MediumTest
-    public void testSendAccessibilityEvent_AccessibilityEnabled() throws Exception {
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-
-        AccessibilityManager manager = createManager(true);
-        manager.sendAccessibilityEvent(sentEvent);
-
-        assertSame("The event should be recycled.", sentEvent, AccessibilityEvent.obtain());
-    }
-
-    @MediumTest
-    public void testSendAccessibilityEvent_AccessibilityDisabled() throws Exception {
-        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
-
-        AccessibilityManager manager = createManager(false  /* disabled */);
-
-        try {
-            manager.sendAccessibilityEvent(sentEvent);
-            fail("No accessibility events are sent if accessibility is disabled");
-        } catch (IllegalStateException ise) {
-            // check expected result
-            assertEquals("Accessibility off. Did you forget to check that?", ise.getMessage());
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java b/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
deleted file mode 100644
index e1c5cee..0000000
--- a/services/tests/servicestests/src/com/android/server/MockAccessibilityService.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import android.accessibilityservice.AccessibilityService;
-import android.accessibilityservice.AccessibilityServiceInfo;
-import android.content.Intent;
-import android.os.Message;
-import android.view.accessibility.AccessibilityEvent;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-
-import junit.framework.TestCase;
-
-/**
- * This is the base class for mock {@link AccessibilityService}s.
- */
-public abstract class MockAccessibilityService extends AccessibilityService {
-
-    /**
-     * The event this service expects to receive.
-     */
-    private final Queue<AccessibilityEvent> mExpectedEvents = new LinkedList<AccessibilityEvent>();
-
-    /**
-     * Interruption call this service expects to receive.
-     */
-    private boolean mExpectedInterrupt;
-
-    /**
-     * Flag if the mock is currently replaying.
-     */
-    private boolean mReplaying;
-
-    /**
-     * Flag if the system is bound as a client to this service.
-     */
-    private boolean mIsSystemBoundAsClient;
-
-    /**
-     * Creates an {@link AccessibilityServiceInfo} populated with default
-     * values.
-     *
-     * @return The default info.
-     */
-    public static AccessibilityServiceInfo createDefaultInfo() {
-        AccessibilityServiceInfo defaultInfo = new AccessibilityServiceInfo();
-        defaultInfo.eventTypes = AccessibilityEvent.TYPE_ANNOUNCEMENT;
-        defaultInfo.feedbackType = AccessibilityServiceInfo.FEEDBACK_AUDIBLE;
-        defaultInfo.flags = 0;
-        defaultInfo.notificationTimeout = 0;
-        defaultInfo.packageNames = new String[] {
-            "foo.bar.baz"
-        };
-
-        return defaultInfo;
-    }
-
-    /**
-     * Starts replaying the mock.
-     */
-    public void replay() {
-        mReplaying = true;
-    }
-
-    /**
-     * Verifies if all expected service methods have been called.
-     */
-    public void verify() {
-        if (!mReplaying) {
-            throw new IllegalStateException("Did you forget to call replay()");
-        }
-
-        if (mExpectedInterrupt) {
-            throw new IllegalStateException("Expected call to #interrupt() not received");
-        }
-        if (!mExpectedEvents.isEmpty()) {
-            throw new IllegalStateException("Expected a call to onAccessibilityEvent() for "
-                    + "events \"" + mExpectedEvents + "\" not received");
-        }
-    }
-
-    /**
-     * Resets this instance so it can be reused.
-     */
-    public void reset() {
-        mExpectedEvents.clear();
-        mExpectedInterrupt = false;
-        mReplaying = false;
-    }
-
-    /**
-     * Sets an expected call to
-     * {@link #onAccessibilityEvent(AccessibilityEvent)} with given event as
-     * argument.
-     *
-     * @param expectedEvent The expected event argument.
-     */
-    public void expectEvent(AccessibilityEvent expectedEvent) {
-        mExpectedEvents.add(expectedEvent);
-    }
-
-    /**
-     * Sets an expected call of {@link #onInterrupt()}.
-     */
-    public void expectInterrupt() {
-        mExpectedInterrupt = true;
-    }
-
-    @Override
-    public void onAccessibilityEvent(AccessibilityEvent receivedEvent) {
-        if (!mReplaying) {
-            return;
-        }
-
-        if (mExpectedEvents.isEmpty()) {
-            throw new IllegalStateException("Unexpected event: " + receivedEvent);
-        }
-
-        AccessibilityEvent expectedEvent = mExpectedEvents.poll();
-        assertEqualsAccessiblityEvent(expectedEvent, receivedEvent);
-    }
-
-    @Override
-    public void onInterrupt() {
-        if (!mReplaying) {
-            return;
-        }
-
-        if (!mExpectedInterrupt) {
-            throw new IllegalStateException("Unexpected call to onInterrupt()");
-        }
-
-        mExpectedInterrupt = false;
-    }
-
-    @Override
-    protected void onServiceConnected() {
-        mIsSystemBoundAsClient = true;
-    }
-
-    @Override
-    public boolean onUnbind(Intent intent) {
-        mIsSystemBoundAsClient = false;
-        return false;
-    }
-
-    /**
-     * Returns if the system is bound as client to this service.
-     *
-     * @return True if the system is bound, false otherwise.
-     */
-    public boolean isSystemBoundAsClient() {
-        return mIsSystemBoundAsClient;
-    }
-
-    /**
-     * Compares all properties of the <code>expectedEvent</code> and the
-     * <code>receviedEvent</code> to verify that the received event is the one
-     * that is expected.
-     */
-    private void assertEqualsAccessiblityEvent(AccessibilityEvent expectedEvent,
-            AccessibilityEvent receivedEvent) {
-        TestCase.assertEquals("addedCount has incorrect value", expectedEvent.getAddedCount(),
-                receivedEvent.getAddedCount());
-        TestCase.assertEquals("beforeText has incorrect value", expectedEvent.getBeforeText(),
-                receivedEvent.getBeforeText());
-        TestCase.assertEquals("checked has incorrect value", expectedEvent.isChecked(),
-                receivedEvent.isChecked());
-        TestCase.assertEquals("className has incorrect value", expectedEvent.getClassName(),
-                receivedEvent.getClassName());
-        TestCase.assertEquals("contentDescription has incorrect value", expectedEvent
-                .getContentDescription(), receivedEvent.getContentDescription());
-        TestCase.assertEquals("currentItemIndex has incorrect value", expectedEvent
-                .getCurrentItemIndex(), receivedEvent.getCurrentItemIndex());
-        TestCase.assertEquals("enabled has incorrect value", expectedEvent.isEnabled(),
-                receivedEvent.isEnabled());
-        TestCase.assertEquals("eventType has incorrect value", expectedEvent.getEventType(),
-                receivedEvent.getEventType());
-        TestCase.assertEquals("fromIndex has incorrect value", expectedEvent.getFromIndex(),
-                receivedEvent.getFromIndex());
-        TestCase.assertEquals("fullScreen has incorrect value", expectedEvent.isFullScreen(),
-                receivedEvent.isFullScreen());
-        TestCase.assertEquals("itemCount has incorrect value", expectedEvent.getItemCount(),
-                receivedEvent.getItemCount());
-        assertEqualsNotificationAsParcelableData(expectedEvent, receivedEvent);
-        TestCase.assertEquals("password has incorrect value", expectedEvent.isPassword(),
-                receivedEvent.isPassword());
-        TestCase.assertEquals("removedCount has incorrect value", expectedEvent.getRemovedCount(),
-                receivedEvent.getRemovedCount());
-        assertEqualsText(expectedEvent, receivedEvent);
-    }
-
-    /**
-     * Compares the {@link android.os.Parcelable} data of the
-     * <code>expectedEvent</code> and <code>receivedEvent</code> to verify that
-     * the received event is the one that is expected.
-     */
-    private void assertEqualsNotificationAsParcelableData(AccessibilityEvent expectedEvent,
-            AccessibilityEvent receivedEvent) {
-        String message = "parcelableData has incorrect value";
-        Message expectedMessage = (Message) expectedEvent.getParcelableData();
-        Message receivedMessage = (Message) receivedEvent.getParcelableData();
-
-        if (expectedMessage == null) {
-            if (receivedMessage == null) {
-                return;
-            }
-        }
-
-        TestCase.assertNotNull(message, receivedMessage);
-
-        // we do a very simple sanity check since we do not test Message
-        TestCase.assertEquals(message, expectedMessage.what, receivedMessage.what);
-    }
-
-    /**
-     * Compares the text of the <code>expectedEvent</code> and
-     * <code>receivedEvent</code> by comparing the string representation of the
-     * corresponding {@link CharSequence}s.
-     */
-    private void assertEqualsText(AccessibilityEvent expectedEvent,
-            AccessibilityEvent receivedEvent) {
-        String message = "text has incorrect value";
-        List<CharSequence> expectedText = expectedEvent.getText();
-        List<CharSequence> receivedText = receivedEvent.getText();
-
-        TestCase.assertEquals(message, expectedText.size(), receivedText.size());
-
-        Iterator<CharSequence> expectedTextIterator = expectedText.iterator();
-        Iterator<CharSequence> receivedTextIterator = receivedText.iterator();
-
-        for (int i = 0; i < expectedText.size(); i++) {
-            // compare the string representation
-            TestCase.assertEquals(message, expectedTextIterator.next().toString(),
-                    receivedTextIterator.next().toString());
-        }
-    }
-}
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index e0ac393..353199a 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -645,20 +645,6 @@
     }
 
     @Test
-    public void testDump_noDumpPermission() {
-        doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
-                eq(permission.DUMP), anyString());
-
-        try {
-            mNetworkScoreService.dump(
-                    new FileDescriptor(), new PrintWriter(new StringWriter()), new String[0]);
-            fail("SecurityException expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    @Test
     public void testDump_doesNotCrash() {
         when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
         StringWriter stringWriter = new StringWriter();
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
index 9197ccf9..0694eae 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScorerAppManagerTest.java
@@ -22,6 +22,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.junit.Assert.assertFalse;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
@@ -170,6 +171,7 @@
         mockScoreNetworksGranted(recoComponent.getPackageName());
         mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
                 enableUseOpenWifiComponent.getPackageName());
+        mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
 
         final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer();
         assertNotNull(activeScorer);
@@ -350,6 +352,173 @@
                 eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), any());
     }
 
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerAppIsNull()
+            throws Exception {
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP)).thenReturn(null);
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade, never()).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString());
+    }
+
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerAppIsEmpty()
+            throws Exception {
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP)).thenReturn("");
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade, never()).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString());
+    }
+
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerIsNotActive()
+            throws Exception {
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP)).thenReturn("com.foo.package");
+        // Make getActiveScorer() return null.
+        setRecommendationsEnabledSetting(NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF);
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade, never()).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString());
+    }
+
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiSettingIsNotEmpty()
+            throws Exception {
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
+        setNetworkRecoPackageSetting(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+                enableUseOpenWifiComponent.getPackageName());
+        mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP))
+                .thenReturn(enableUseOpenWifiComponent.getPackageName());
+        // The setting has a value so the migration shouldn't touch it.
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.USE_OPEN_WIFI_PACKAGE))
+                .thenReturn(enableUseOpenWifiComponent.getPackageName());
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade, never()).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString());
+        verify(mSettingsFacade).putString(eq(mMockContext),
+                eq(Settings.Global.NETWORK_SCORER_APP), eq(null));
+    }
+
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiActivityNotAvail()
+            throws Exception {
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
+        setNetworkRecoPackageSetting(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        // The active component doesn't have an open wifi activity so the migration shouldn't
+        // set USE_OPEN_WIFI_PACKAGE.
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+                null /*useOpenWifiActivityPackage*/);
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP))
+                .thenReturn(enableUseOpenWifiComponent.getPackageName());
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null);
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade, never()).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString());
+        verify(mSettingsFacade).putString(eq(mMockContext),
+                eq(Settings.Global.NETWORK_SCORER_APP), eq(null));
+    }
+
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_activity()
+            throws Exception {
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
+        setNetworkRecoPackageSetting(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+                enableUseOpenWifiComponent.getPackageName());
+        mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
+        // The older network scorer app setting doesn't match the new use open wifi activity package
+        // so the migration shouldn't set USE_OPEN_WIFI_PACKAGE.
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP))
+                .thenReturn(enableUseOpenWifiComponent.getPackageName() + ".diff");
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null);
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade, never()).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString());
+        verify(mSettingsFacade).putString(eq(mMockContext),
+                eq(Settings.Global.NETWORK_SCORER_APP), eq(null));
+    }
+
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_service()
+            throws Exception {
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
+        setNetworkRecoPackageSetting(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+                enableUseOpenWifiComponent.getPackageName());
+        mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
+        // The older network scorer app setting doesn't match the active package so the migration
+        // shouldn't set USE_OPEN_WIFI_PACKAGE.
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP))
+                .thenReturn(recoComponent.getPackageName() + ".diff");
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null);
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade, never()).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString());
+        verify(mSettingsFacade).putString(eq(mMockContext),
+                eq(Settings.Global.NETWORK_SCORER_APP), eq(null));
+    }
+
+    @Test
+    public void testMigrateNetworkScorerAppSettingIfNeeded_packageMatch_activity()
+            throws Exception {
+        final ComponentName recoComponent = new ComponentName("package1", "class1");
+        final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2");
+        setNetworkRecoPackageSetting(recoComponent.getPackageName());
+        mockScoreNetworksGranted(recoComponent.getPackageName());
+        mockRecommendationServiceAvailable(recoComponent, 924 /* packageUid */,
+                enableUseOpenWifiComponent.getPackageName());
+        mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent);
+        // Old setting matches the new activity package, migration should happen.
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.NETWORK_SCORER_APP))
+                .thenReturn(enableUseOpenWifiComponent.getPackageName());
+        when(mSettingsFacade.getString(mMockContext,
+                Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null);
+
+        mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded();
+
+        verify(mSettingsFacade).putString(eq(mMockContext),
+                eq(Settings.Global.USE_OPEN_WIFI_PACKAGE),
+                eq(enableUseOpenWifiComponent.getPackageName()));
+        verify(mSettingsFacade).putString(eq(mMockContext),
+                eq(Settings.Global.NETWORK_SCORER_APP), eq(null));
+    }
+
     private void setRecommendationsEnabledSetting(int value) {
         when(mSettingsFacade.getInt(eq(mMockContext),
                 eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt())).thenReturn(value);
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerTest.java
new file mode 100644
index 0000000..5d09e31
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2010 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.accessibility;
+
+import static junit.framework.TestCase.assertFalse;
+import static junit.framework.TestCase.assertSame;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.accessibilityservice.AccessibilityServiceInfo;
+import android.app.Instrumentation;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.IAccessibilityManager;
+import android.view.accessibility.IAccessibilityManagerClient;
+
+import com.android.internal.util.IntPair;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for the AccessibilityManager by mocking the backing service.
+ */
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityManagerTest {
+    private static final boolean WITH_A11Y_ENABLED = true;
+    private static final boolean WITH_A11Y_DISABLED = false;
+
+    @Mock private IAccessibilityManager mMockService;
+    private MessageCapturingHandler mHandler;
+    private Instrumentation mInstrumentation;
+
+    @BeforeClass
+    public static void oneTimeInitialization() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mHandler = new MessageCapturingHandler(null);
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+    }
+
+    private AccessibilityManager createManager(boolean enabled) throws Exception {
+        long serviceReturnValue = IntPair.of(
+                (enabled) ? AccessibilityManager.STATE_FLAG_ACCESSIBILITY_ENABLED : 0,
+                AccessibilityEvent.TYPES_ALL_MASK);
+        when(mMockService.addClient(any(IAccessibilityManagerClient.class), anyInt()))
+                .thenReturn(serviceReturnValue);
+
+        AccessibilityManager manager =
+                new AccessibilityManager(mHandler, mMockService, UserHandle.USER_CURRENT);
+
+        verify(mMockService).addClient(any(IAccessibilityManagerClient.class), anyInt());
+        mHandler.setCallback(manager.getCallback());
+        mHandler.sendAllMessages();
+        return manager;
+    }
+
+    @Test
+    public void testGetAccessibilityServiceList() throws Exception {
+        // create a list of installed accessibility services the mock service returns
+        List<AccessibilityServiceInfo> expectedServices = new ArrayList<>();
+        AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
+        accessibilityServiceInfo.packageNames = new String[] { "foo.bar" };
+        expectedServices.add(accessibilityServiceInfo);
+
+        // configure the mock service behavior
+        when(mMockService.getInstalledAccessibilityServiceList(anyInt()))
+                .thenReturn(expectedServices);
+
+        // invoke the method under test
+        AccessibilityManager manager = createManager(true);
+        List<AccessibilityServiceInfo> receivedServices =
+                manager.getInstalledAccessibilityServiceList();
+
+        verify(mMockService).getInstalledAccessibilityServiceList(UserHandle.USER_CURRENT);
+        // check expected result (list equals() compares it contents as well)
+        assertEquals("All expected services must be returned", expectedServices, receivedServices);
+    }
+
+    @Test
+    public void testInterrupt() throws Exception {
+        AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+        manager.interrupt();
+
+        verify(mMockService).interrupt(UserHandle.USER_CURRENT);
+    }
+
+    @Test
+    public void testIsEnabled() throws Exception {
+        // Create manager with a11y enabled
+        AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+        assertTrue("Must be enabled since the mock service is enabled", manager.isEnabled());
+
+        // Disable accessibility
+        manager.getClient().setState(0);
+        mHandler.sendAllMessages();
+        assertFalse("Must be disabled since the mock service is disabled", manager.isEnabled());
+    }
+
+    @Test
+    public void testSendAccessibilityEvent_AccessibilityEnabled() throws Exception {
+        AccessibilityEvent sentEvent = AccessibilityEvent.obtain(
+                AccessibilityEvent.TYPE_ANNOUNCEMENT);
+
+        AccessibilityManager manager = createManager(WITH_A11Y_ENABLED);
+        manager.sendAccessibilityEvent(sentEvent);
+
+        assertSame("The event should be recycled.", sentEvent, AccessibilityEvent.obtain());
+    }
+
+    @Test
+    public void testSendAccessibilityEvent_AccessibilityDisabled() throws Exception {
+        AccessibilityEvent sentEvent = AccessibilityEvent.obtain();
+
+        AccessibilityManager manager = createManager(WITH_A11Y_DISABLED);
+        mInstrumentation.runOnMainSync(() -> {
+            try {
+                manager.sendAccessibilityEvent(sentEvent);
+                fail("No accessibility events are sent if accessibility is disabled");
+            } catch (IllegalStateException ise) {
+                // check expected result
+                assertEquals("Accessibility off. Did you forget to check that?", ise.getMessage());
+            }
+        });
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
index d44c1ca..5887215 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MagnificationControllerTest.java
@@ -20,11 +20,12 @@
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.assertFalse;
-import static org.mockito.Matchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -48,6 +49,7 @@
 import android.view.WindowManagerInternal.MagnificationCallbacks;
 
 import com.android.internal.R;
+
 import org.hamcrest.CoreMatchers;
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeMatcher;
@@ -471,9 +473,10 @@
     public void testResetIfNeeded_doesWhatItSays() {
         mMagnificationController.register();
         zoomIn2xToMiddle();
+        reset(mMockAms);
         assertTrue(mMagnificationController.resetIfNeeded(false));
         verify(mMockAms).notifyMagnificationChanged(
-                eq(INITIAL_MAGNIFICATION_REGION), eq(1.0f), anyInt(), anyInt());
+                eq(INITIAL_MAGNIFICATION_REGION), eq(1.0f), anyFloat(), anyFloat());
         assertFalse(mMagnificationController.isMagnifying());
         assertFalse(mMagnificationController.resetIfNeeded(false));
     }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java b/services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java
index 003f7ab..0dba35f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MessageCapturingHandler.java
@@ -42,6 +42,10 @@
         return super.sendMessageAtTime(message, uptimeMillis);
     }
 
+    public void setCallback(Handler.Callback callback) {
+        mCallback = callback;
+    }
+
     public void sendOneMessage() {
         Message message = timedMessages.remove(0).first;
         removeMessages(message.what, message.obj);
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
index aa37407..5d0c23f 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
@@ -149,7 +149,7 @@
         // 2nd account
         Account account2 = new Account("name", "example2.com");
         long accId2 = mAccountsDb.insertCeAccount(account2, "password");
-        mAccountsDb.insertDeAccount(account2, accId);
+        mAccountsDb.insertDeAccount(account2, accId2);
         mAccountsDb.insertAuthToken(accId2, "type", "token");
 
         mAccountsDb.deleteAuthTokensByAccountId(accId2);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
new file mode 100644
index 0000000..8423aff
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -0,0 +1,52 @@
+/*
+ * 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 org.junit.Assert.assertNull;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE;
+
+/**
+ * Tests for the {@link ActivityStackSupervisor} class.
+ *
+ * Build/Install/Run:
+ *  bit FrameworksServicesTests:com.android.server.am.ActivityStackSupervisorTests
+ */
+@MediumTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class ActivityStackSupervisorTests extends ActivityTestsBase {
+    /**
+     * This test ensures that we do not try to restore a task based off an invalid task id. The
+     * stack supervisor is a test version so there will be no tasks present. We should expect
+     * {@code null} to be returned in this case.
+     */
+    @Test
+    public void testRestoringInvalidTask() throws Exception {
+        final ActivityManagerService service = createActivityManagerService();
+        TaskRecord task = service.mStackSupervisor.anyTaskForIdLocked(0 /*taskId*/,
+                MATCH_TASK_IN_STACKS_OR_RECENT_TASKS_AND_RESTORE, 0 /*stackId*/);
+        assertNull(task);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index c5cc2ff..5240586 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -25,7 +25,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
-import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.Looper;
 import android.support.test.InstrumentationRegistry;
 import com.android.server.AttributeCache;
@@ -34,6 +34,7 @@
 
 import com.android.server.wm.WindowManagerService;
 import com.android.server.wm.WindowTestUtils;
+import org.junit.After;
 import org.junit.Before;
 import org.mockito.MockitoAnnotations;
 
@@ -42,8 +43,7 @@
  */
 public class ActivityTestsBase {
     private final Context mContext = InstrumentationRegistry.getContext();
-    private static boolean sLooperPrepared;
-    private Handler mHandler;
+    private HandlerThread mHandlerThread;
 
     // Grabbing an instance of {@link WindowManagerService} creates it if not present so this must
     // be called at before any tests.
@@ -52,11 +52,13 @@
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
+        mHandlerThread = new HandlerThread("ActivityTestsBaseThread");
+        mHandlerThread.start();
+    }
 
-        if (!sLooperPrepared) {
-            sLooperPrepared = true;
-            Looper.prepare();
-        }
+    @After
+    public void tearDown() {
+        mHandlerThread.quitSafely();
     }
 
     protected ActivityManagerService createActivityManagerService() {
@@ -126,7 +128,7 @@
 
         @Override
         protected ActivityStackSupervisor createStackSupervisor() {
-            return new TestActivityStackSupervisor(this, new Handler().getLooper());
+            return new TestActivityStackSupervisor(this, mHandlerThread.getLooper());
         }
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
index f3f68ff..2663aaf 100644
--- a/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/appwidget/AppWidgetServiceImplTest.java
@@ -50,6 +50,7 @@
 
 import org.mockito.ArgumentCaptor;
 
+import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
 import java.util.concurrent.CountDownLatch;
@@ -249,6 +250,25 @@
         assertEquals(7, updates.size());
     }
 
+    public void testGetInstalledProvidersForPackage() {
+        List<AppWidgetProviderInfo> allProviders = mManager.getInstalledProviders();
+        assertTrue(!allProviders.isEmpty());
+        String packageName = allProviders.get(0).provider.getPackageName();
+        List<AppWidgetProviderInfo> providersForPackage = mManager.getInstalledProvidersForPackage(
+                packageName, null);
+        // Remove providers from allProviders that don't have the given package name.
+        Iterator<AppWidgetProviderInfo> iter = allProviders.iterator();
+        while (iter.hasNext()) {
+            if (!iter.next().provider.getPackageName().equals(packageName)) {
+                iter.remove();
+            }
+        }
+        assertEquals(allProviders.size(), providersForPackage.size());
+        for (int i = 0; i < allProviders.size(); i++) {
+            assertEquals(allProviders.get(i).provider, providersForPackage.get(i).provider);
+        }
+    }
+
     private int setupHostAndWidget() {
         List<PendingHostUpdate> updates = mService.startListening(
                 mMockHost, mPkgName, HOST_ID, new int[0]).getList();
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 92233b1..f80ee73 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -356,6 +356,7 @@
         private final StatusHints mStatusHints;
         private final Bundle mExtras;
         private final Bundle mIntentExtras;
+        private final long mCreationTimeMillis;
 
         /**
          * Whether the supplied capabilities  supports the specified capability.
@@ -578,9 +579,12 @@
         }
 
         /**
-         * @return The time the {@code Call} has been connected. This information is updated
-         * periodically, but user interfaces should not rely on this to display any "call time
-         * clock".
+         * Returns the time the {@link Call} connected (i.e. became active).  This information is
+         * updated periodically, but user interfaces should not rely on this to display the "call
+         * time clock".  For the time when the call was first added to Telecom, see
+         * {@link #getCreationTimeMillis()}.
+         *
+         * @return The time the {@link Call} connected in milliseconds since the epoch.
          */
         public final long getConnectTimeMillis() {
             return mConnectTimeMillis;
@@ -622,6 +626,18 @@
             return mIntentExtras;
         }
 
+        /**
+         * Returns the time when the call was first created and added to Telecom.  This is the same
+         * time that is logged as the start time in the Call Log (see
+         * {@link android.provider.CallLog.Calls#DATE}).  To determine when the call was connected
+         * (became active), see {@link #getConnectTimeMillis()}.
+         *
+         * @return The creation time of the call, in millis since the epoch.
+         */
+        public long getCreationTimeMillis() {
+            return mCreationTimeMillis;
+        }
+
         @Override
         public boolean equals(Object o) {
             if (o instanceof Details) {
@@ -641,28 +657,29 @@
                         Objects.equals(mVideoState, d.mVideoState) &&
                         Objects.equals(mStatusHints, d.mStatusHints) &&
                         areBundlesEqual(mExtras, d.mExtras) &&
-                        areBundlesEqual(mIntentExtras, d.mIntentExtras);
+                        areBundlesEqual(mIntentExtras, d.mIntentExtras) &&
+                        Objects.equals(mCreationTimeMillis, d.mCreationTimeMillis);
             }
             return false;
         }
 
         @Override
         public int hashCode() {
-            return
-                    Objects.hashCode(mHandle) +
-                    Objects.hashCode(mHandlePresentation) +
-                    Objects.hashCode(mCallerDisplayName) +
-                    Objects.hashCode(mCallerDisplayNamePresentation) +
-                    Objects.hashCode(mAccountHandle) +
-                    Objects.hashCode(mCallCapabilities) +
-                    Objects.hashCode(mCallProperties) +
-                    Objects.hashCode(mDisconnectCause) +
-                    Objects.hashCode(mConnectTimeMillis) +
-                    Objects.hashCode(mGatewayInfo) +
-                    Objects.hashCode(mVideoState) +
-                    Objects.hashCode(mStatusHints) +
-                    Objects.hashCode(mExtras) +
-                    Objects.hashCode(mIntentExtras);
+            return Objects.hash(mHandle,
+                            mHandlePresentation,
+                            mCallerDisplayName,
+                            mCallerDisplayNamePresentation,
+                            mAccountHandle,
+                            mCallCapabilities,
+                            mCallProperties,
+                            mDisconnectCause,
+                            mConnectTimeMillis,
+                            mGatewayInfo,
+                            mVideoState,
+                            mStatusHints,
+                            mExtras,
+                            mIntentExtras,
+                            mCreationTimeMillis);
         }
 
         /** {@hide} */
@@ -681,7 +698,8 @@
                 int videoState,
                 StatusHints statusHints,
                 Bundle extras,
-                Bundle intentExtras) {
+                Bundle intentExtras,
+                long creationTimeMillis) {
             mTelecomCallId = telecomCallId;
             mHandle = handle;
             mHandlePresentation = handlePresentation;
@@ -697,6 +715,7 @@
             mStatusHints = statusHints;
             mExtras = extras;
             mIntentExtras = intentExtras;
+            mCreationTimeMillis = creationTimeMillis;
         }
 
         /** {@hide} */
@@ -716,7 +735,8 @@
                     parcelableCall.getVideoState(),
                     parcelableCall.getStatusHints(),
                     parcelableCall.getExtras(),
-                    parcelableCall.getIntentExtras());
+                    parcelableCall.getIntentExtras(),
+                    parcelableCall.getCreationTimeMillis());
         }
 
         @Override
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index 85a92d1..6212a77 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -59,6 +59,7 @@
     private final List<String> mConferenceableCallIds;
     private final Bundle mIntentExtras;
     private final Bundle mExtras;
+    private final long mCreationTimeMillis;
 
     public ParcelableCall(
             String id,
@@ -85,7 +86,8 @@
             int videoState,
             List<String> conferenceableCallIds,
             Bundle intentExtras,
-            Bundle extras) {
+            Bundle extras,
+            long creationTimeMillis) {
         mId = id;
         mState = state;
         mDisconnectCause = disconnectCause;
@@ -111,6 +113,7 @@
         mConferenceableCallIds = Collections.unmodifiableList(conferenceableCallIds);
         mIntentExtras = intentExtras;
         mExtras = extras;
+        mCreationTimeMillis = creationTimeMillis;
     }
 
     /** The unique ID of the call. */
@@ -289,6 +292,13 @@
         return mIsVideoCallProviderChanged;
     }
 
+    /**
+     * @return The time the call was created, in milliseconds since the epoch.
+     */
+    public long getCreationTimeMillis() {
+        return mCreationTimeMillis;
+    }
+
     /** Responsible for creating ParcelableCall objects for deserialized Parcels. */
     public static final Parcelable.Creator<ParcelableCall> CREATOR =
             new Parcelable.Creator<ParcelableCall> () {
@@ -324,6 +334,7 @@
             int supportedAudioRoutes = source.readInt();
             boolean isRttCallChanged = source.readByte() == 1;
             ParcelableRttCall rttCall = source.readParcelable(classLoader);
+            long creationTimeMillis = source.readLong();
             return new ParcelableCall(
                     id,
                     state,
@@ -349,7 +360,8 @@
                     videoState,
                     conferenceableCallIds,
                     intentExtras,
-                    extras);
+                    extras,
+                    creationTimeMillis);
         }
 
         @Override
@@ -393,6 +405,7 @@
         destination.writeInt(mSupportedAudioRoutes);
         destination.writeByte((byte) (mIsRttCallChanged ? 1 : 0));
         destination.writeParcelable(mRttCall, 0);
+        destination.writeLong(mCreationTimeMillis);
     }
 
     @Override
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index b4c531e..f9875c5 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -53,8 +53,9 @@
      *
      * <p class="note">This is a protected intent that can only be sent
      * by the system.
+     * @deprecated use {@link Intent#ACTION_SERVICE_STATE}
      */
-    public static final String ACTION_SERVICE_STATE_CHANGED = "android.intent.action.SERVICE_STATE";
+    public static final String ACTION_SERVICE_STATE_CHANGED = Intent.ACTION_SERVICE_STATE;
 
     /**
      * <p>Broadcast Action: The radio technology has changed. The intent will have the following
diff --git a/tests/UiBench/Android.mk b/tests/UiBench/Android.mk
index 36ebc90..71067ae 100644
--- a/tests/UiBench/Android.mk
+++ b/tests/UiBench/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := 24
+LOCAL_SDK_VERSION := current
 LOCAL_MIN_SDK_VERSION := 21
 
 # omit gradle 'build' dir
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 8461905..90f713b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -155,7 +155,10 @@
     xml::XmlPullParser* parser, std::string* out_raw_string, StyleString* out_style_string,
     std::vector<UntranslatableSection>* out_untranslatable_sections) {
   // Keeps track of formatting tags (<b>, <i>) and the range of characters for which they apply.
-  std::vector<Span> span_stack;
+  // The stack elements refer to the indices in out_style_string->spans.
+  // By first adding to the out_style_string->spans vector, and then using the stack to refer
+  // to this vector, the original order of tags is preserved in cases such as <b><i>hello</b></i>.
+  std::vector<size_t> span_stack;
 
   // Clear the output variables.
   out_raw_string->clear();
@@ -192,7 +195,9 @@
           return false;
         }
 
-        span_stack.push_back(Span{std::move(span_name), static_cast<uint32_t>(builder.Utf16Len())});
+        out_style_string->spans.push_back(
+            Span{std::move(span_name), static_cast<uint32_t>(builder.Utf16Len())});
+        span_stack.push_back(out_style_string->spans.size() - 1);
       } else if (parser->element_namespace() == sXliffNamespaceUri) {
         if (parser->element_name() == "g") {
           if (untranslatable_start_depth) {
@@ -233,9 +238,8 @@
       if (parser->element_namespace().empty()) {
         // This is an HTML tag which we encode as a span. Update the span
         // stack and pop the top entry.
-        Span& top_span = span_stack.back();
+        Span& top_span = out_style_string->spans[span_stack.back()];
         top_span.last_char = builder.Utf16Len() - 1;
-        out_style_string->spans.push_back(std::move(top_span));
         span_stack.pop_back();
       } else if (untranslatable_start_depth == make_value(depth)) {
         // This is the end of an untranslatable section. Use UTF8 indices/lengths.
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index eefa320..8062c2e6 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -101,20 +101,24 @@
   // Use a surrogate pair unicode point so that we can verify that the span
   // indices use UTF-16 length and not UTF-8 length.
   std::string input =
-      "<string name=\"foo\">This is my aunt\u2019s <b>string</b></string>";
+      "<string name=\"foo\">This is my aunt\u2019s <b>fickle <small>string</small></b></string>";
   ASSERT_TRUE(TestParse(input));
 
   StyledString* str = test::GetValue<StyledString>(&table_, "string/foo");
   ASSERT_NE(nullptr, str);
 
-  const std::string expected_str = "This is my aunt\u2019s string";
+  const std::string expected_str = "This is my aunt\u2019s fickle string";
   EXPECT_EQ(expected_str, *str->value->str);
-  EXPECT_EQ(1u, str->value->spans.size());
+  EXPECT_EQ(2u, str->value->spans.size());
   EXPECT_TRUE(str->untranslatable_sections.empty());
 
   EXPECT_EQ(std::string("b"), *str->value->spans[0].name);
   EXPECT_EQ(17u, str->value->spans[0].first_char);
-  EXPECT_EQ(23u, str->value->spans[0].last_char);
+  EXPECT_EQ(30u, str->value->spans[0].last_char);
+
+  EXPECT_EQ(std::string("small"), *str->value->spans[1].name);
+  EXPECT_EQ(24u, str->value->spans[1].first_char);
+  EXPECT_EQ(30u, str->value->spans[1].last_char);
 }
 
 TEST_F(ResourceParserTest, ParseStringWithWhitespace) {
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index fad9edd..a031ea4 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -22,136 +22,194 @@
 #include "ResourceValues.h"
 #include "ValueVisitor.h"
 #include "compile/Pseudolocalizer.h"
+#include "util/Util.h"
 
 using android::StringPiece;
+using android::StringPiece16;
 
 namespace aapt {
 
-std::unique_ptr<StyledString> PseudolocalizeStyledString(
-    StyledString* string, Pseudolocalizer::Method method, StringPool* pool) {
+// The struct that represents both Span objects and UntranslatableSections.
+struct UnifiedSpan {
+  // Only present for Span objects. If not present, this was an UntranslatableSection.
+  Maybe<std::string> tag;
+
+  // The UTF-16 index into the string where this span starts.
+  uint32_t first_char;
+
+  // The UTF-16 index into the string where this span ends, inclusive.
+  uint32_t last_char;
+};
+
+inline static bool operator<(const UnifiedSpan& left, const UnifiedSpan& right) {
+  if (left.first_char < right.first_char) {
+    return true;
+  } else if (left.first_char > right.first_char) {
+    return false;
+  } else if (left.last_char < right.last_char) {
+    return true;
+  }
+  return false;
+}
+
+inline static UnifiedSpan SpanToUnifiedSpan(const StringPool::Span& span) {
+  return UnifiedSpan{*span.name, span.first_char, span.last_char};
+}
+
+inline static UnifiedSpan UntranslatableSectionToUnifiedSpan(const UntranslatableSection& section) {
+  return UnifiedSpan{
+      {}, static_cast<uint32_t>(section.start), static_cast<uint32_t>(section.end) - 1};
+}
+
+// Merges the Span and UntranslatableSections of this StyledString into a single vector of
+// UnifiedSpans. This will first check that the Spans are sorted in ascending order.
+static std::vector<UnifiedSpan> MergeSpans(const StyledString& string) {
+  // Ensure the Spans are sorted and converted.
+  std::vector<UnifiedSpan> sorted_spans;
+  sorted_spans.reserve(string.value->spans.size());
+  std::transform(string.value->spans.begin(), string.value->spans.end(),
+                 std::back_inserter(sorted_spans), SpanToUnifiedSpan);
+
+  // Stable sort to ensure tag sequences like "<b><i>" are preserved.
+  std::stable_sort(sorted_spans.begin(), sorted_spans.end());
+
+  // Ensure the UntranslatableSections are sorted and converted.
+  std::vector<UnifiedSpan> sorted_untranslatable_sections;
+  sorted_untranslatable_sections.reserve(string.untranslatable_sections.size());
+  std::transform(string.untranslatable_sections.begin(), string.untranslatable_sections.end(),
+                 std::back_inserter(sorted_untranslatable_sections),
+                 UntranslatableSectionToUnifiedSpan);
+  std::sort(sorted_untranslatable_sections.begin(), sorted_untranslatable_sections.end());
+
+  std::vector<UnifiedSpan> merged_spans;
+  merged_spans.reserve(sorted_spans.size() + sorted_untranslatable_sections.size());
+  auto span_iter = sorted_spans.begin();
+  auto untranslatable_iter = sorted_untranslatable_sections.begin();
+  while (span_iter != sorted_spans.end() &&
+         untranslatable_iter != sorted_untranslatable_sections.end()) {
+    if (*span_iter < *untranslatable_iter) {
+      merged_spans.push_back(std::move(*span_iter));
+      ++span_iter;
+    } else {
+      merged_spans.push_back(std::move(*untranslatable_iter));
+      ++untranslatable_iter;
+    }
+  }
+
+  while (span_iter != sorted_spans.end()) {
+    merged_spans.push_back(std::move(*span_iter));
+    ++span_iter;
+  }
+
+  while (untranslatable_iter != sorted_untranslatable_sections.end()) {
+    merged_spans.push_back(std::move(*untranslatable_iter));
+    ++untranslatable_iter;
+  }
+  return merged_spans;
+}
+
+std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
+                                                         Pseudolocalizer::Method method,
+                                                         StringPool* pool) {
   Pseudolocalizer localizer(method);
 
-  const StringPiece original_text = *string->value->str;
+  // Collect the spans and untranslatable sections into one set of spans, sorted by first_char.
+  // This will effectively subdivide the string into multiple sections that can be individually
+  // pseudolocalized, while keeping the span indices synchronized.
+  std::vector<UnifiedSpan> merged_spans = MergeSpans(*string);
+
+  // All Span indices are UTF-16 based, according to the resources.arsc format expected by the
+  // runtime. So we will do all our processing in UTF-16, then convert back.
+  const std::u16string text16 = util::Utf8ToUtf16(*string->value->str);
+
+  // Convenient wrapper around the text that allows us to work with StringPieces.
+  const StringPiece16 text(text16);
+
+  // The new string.
+  std::string new_string = localizer.Start();
+
+  // The stack that keeps track of what nested Span we're in.
+  std::vector<size_t> span_stack;
+
+  // The current position in the original text.
+  uint32_t cursor = 0u;
+
+  // The current position in the new text.
+  uint32_t new_cursor = utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(new_string.data()),
+                                             new_string.size(), false);
+
+  // We assume no nesting of untranslatable sections, since XLIFF doesn't allow it.
+  bool translatable = true;
+  size_t span_idx = 0u;
+  while (span_idx < merged_spans.size() || !span_stack.empty()) {
+    UnifiedSpan* span = span_idx >= merged_spans.size() ? nullptr : &merged_spans[span_idx];
+    UnifiedSpan* parent_span = span_stack.empty() ? nullptr : &merged_spans[span_stack.back()];
+
+    if (span != nullptr) {
+      if (parent_span == nullptr || parent_span->last_char > span->first_char) {
+        // There is no parent, or this span is the child of the parent.
+        // Pseudolocalize all the text until this span.
+        const StringPiece16 substr = text.substr(cursor, span->first_char - cursor);
+        cursor += substr.size();
+
+        // Pseudolocalize the substring.
+        std::string new_substr = util::Utf16ToUtf8(substr);
+        if (translatable) {
+          new_substr = localizer.Text(new_substr);
+        }
+        new_cursor += utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(new_substr.data()),
+                                           new_substr.size(), false);
+        new_string += new_substr;
+
+        // Rewrite the first_char.
+        span->first_char = new_cursor;
+        if (!span->tag) {
+          // An untranslatable section has begun!
+          translatable = false;
+        }
+        span_stack.push_back(span_idx);
+        ++span_idx;
+        continue;
+      }
+    }
+
+    if (parent_span != nullptr) {
+      // There is a parent, and either this span is not a child of it, or there are no more spans.
+      // Pop this off the stack.
+      const StringPiece16 substr = text.substr(cursor, parent_span->last_char - cursor + 1);
+      cursor += substr.size();
+
+      // Pseudolocalize the substring.
+      std::string new_substr = util::Utf16ToUtf8(substr);
+      if (translatable) {
+        new_substr = localizer.Text(new_substr);
+      }
+      new_cursor += utf8_to_utf16_length(reinterpret_cast<const uint8_t*>(new_substr.data()),
+                                         new_substr.size(), false);
+      new_string += new_substr;
+
+      parent_span->last_char = new_cursor - 1;
+      if (parent_span->tag) {
+        // An end to an untranslatable section.
+        translatable = true;
+      }
+      span_stack.pop_back();
+    }
+  }
+
+  // Finish the pseudolocalization at the end of the string.
+  new_string += localizer.Text(util::Utf16ToUtf8(text.substr(cursor, text.size() - cursor)));
+  new_string += localizer.End();
 
   StyleString localized;
+  localized.str = std::move(new_string);
 
-  // Copy the spans. We will update their offsets when we localize.
-  localized.spans.reserve(string->value->spans.size());
-  for (const StringPool::Span& span : string->value->spans) {
-    localized.spans.push_back(
-        Span{*span.name, span.first_char, span.last_char});
-  }
-
-  // The ranges are all represented with a single value. This is the start of
-  // one range and end of another.
-  struct Range {
-    size_t start;
-
-    // If set to true, toggles the state of translatability.
-    bool toggle_translatability;
-
-    // Once the new string is localized, these are the pointers to the spans to adjust.
-    // Since this struct represents the start of one range and end of another,
-    // we have the two pointers respectively.
-    uint32_t* update_start;
-    uint32_t* update_end;
-  };
-
-  auto cmp = [](const Range& r, size_t index) -> bool {
-    return r.start < index;
-  };
-
-  // Construct the ranges. The ranges are represented like so: [0, 2, 5, 7]
-  // The ranges are the spaces in between. In this example, with a total string
-  // length of 9, the vector represents: (0,1], (2,4], (5,6], (7,9]
-  //
-  std::vector<Range> ranges;
-  ranges.push_back(Range{0, false, nullptr, nullptr});
-  ranges.push_back(Range{original_text.size() - 1, false, nullptr, nullptr});
-  for (size_t i = 0; i < string->value->spans.size(); i++) {
-    const StringPool::Span& span = string->value->spans[i];
-
-    // Insert or update the Range marker for the start of this span.
-    auto iter =
-        std::lower_bound(ranges.begin(), ranges.end(), span.first_char, cmp);
-    if (iter != ranges.end() && iter->start == span.first_char) {
-      iter->update_start = &localized.spans[i].first_char;
-    } else {
-      ranges.insert(iter, Range{span.first_char, false, &localized.spans[i].first_char, nullptr});
-    }
-
-    // Insert or update the Range marker for the end of this span.
-    iter = std::lower_bound(ranges.begin(), ranges.end(), span.last_char, cmp);
-    if (iter != ranges.end() && iter->start == span.last_char) {
-      iter->update_end = &localized.spans[i].last_char;
-    } else {
-      ranges.insert(iter, Range{span.last_char, false, nullptr, &localized.spans[i].last_char});
+  // Convert the UnifiedSpans into regular Spans, skipping the UntranslatableSections.
+  for (UnifiedSpan& span : merged_spans) {
+    if (span.tag) {
+      localized.spans.push_back(Span{std::move(span.tag.value()), span.first_char, span.last_char});
     }
   }
-
-  // Parts of the string may be untranslatable. Merge those ranges
-  // in as well, so that we have continuous sections of text to
-  // feed into the pseudolocalizer.
-  // We do this by marking the beginning of a range as either toggling
-  // the translatability state or not.
-  for (const UntranslatableSection& section : string->untranslatable_sections) {
-    auto iter = std::lower_bound(ranges.begin(), ranges.end(), section.start, cmp);
-    if (iter != ranges.end() && iter->start == section.start) {
-      // An existing span starts (or ends) here. We just need to mark that
-      // the translatability should toggle here. If translatability was
-      // already being toggled, then that means we have two adjacent ranges of untranslatable
-      // text, so remove the toggle and only toggle at the end of this range,
-      // effectively merging these ranges.
-      iter->toggle_translatability = !iter->toggle_translatability;
-    } else {
-      // Insert a new range that specifies to toggle the translatability.
-      iter = ranges.insert(iter, Range{section.start, true, nullptr, nullptr});
-    }
-
-    // Update/create an end to the untranslatable section.
-    iter = std::lower_bound(iter, ranges.end(), section.end, cmp);
-    if (iter != ranges.end() && iter->start == section.end) {
-      iter->toggle_translatability = true;
-    } else {
-      iter = ranges.insert(iter, Range{section.end, true, nullptr, nullptr});
-    }
-  }
-
-  localized.str += localizer.Start();
-
-  // Iterate over the ranges and localize each section.
-  // The text starts as translatable, and each time a range has toggle_translatability
-  // set to true, we toggle whether to translate or not.
-  // This assumes no untranslatable ranges overlap.
-  bool translatable = true;
-  for (size_t i = 0; i < ranges.size(); i++) {
-    const size_t start = ranges[i].start;
-    size_t len = original_text.size() - start;
-    if (i + 1 < ranges.size()) {
-      len = ranges[i + 1].start - start;
-    }
-
-    if (ranges[i].update_start) {
-      *ranges[i].update_start = localized.str.size();
-    }
-
-    if (ranges[i].update_end) {
-      *ranges[i].update_end = localized.str.size();
-    }
-
-    if (ranges[i].toggle_translatability) {
-      translatable = !translatable;
-    }
-
-    if (translatable) {
-      localized.str += localizer.Text(original_text.substr(start, len));
-    } else {
-      localized.str += original_text.substr(start, len);
-    }
-  }
-
-  localized.str += localizer.End();
-
   return util::make_unique<StyledString>(pool->MakeRef(localized));
 }
 
@@ -175,8 +233,7 @@
         if (sub_visitor.value) {
           localized->values[i] = std::move(sub_visitor.item);
         } else {
-          localized->values[i] =
-              std::unique_ptr<Item>(plural->values[i]->Clone(pool_));
+          localized->values[i] = std::unique_ptr<Item>(plural->values[i]->Clone(pool_));
         }
       }
     }
@@ -210,8 +267,7 @@
     }
     result += localizer_.End();
 
-    std::unique_ptr<String> localized =
-        util::make_unique<String>(pool_->MakeRef(result));
+    std::unique_ptr<String> localized = util::make_unique<String>(pool_->MakeRef(result));
     localized->SetSource(string->GetSource());
     localized->SetWeak(true);
     item = std::move(localized);
@@ -282,14 +338,10 @@
   }
 }
 
-/**
- * A value is pseudolocalizable if it does not define a locale (or is the
- * default locale)
- * and is translatable.
- */
+// A value is pseudolocalizable if it does not define a locale (or is the default locale) and is
+// translatable.
 static bool IsPseudolocalizable(ResourceConfigValue* config_value) {
-  const int diff =
-      config_value->config.diff(ConfigDescription::DefaultConfig());
+  const int diff = config_value->config.diff(ConfigDescription::DefaultConfig());
   if (diff & ConfigDescription::CONFIG_LOCALE) {
     return false;
   }
@@ -298,19 +350,16 @@
 
 }  // namespace
 
-bool PseudolocaleGenerator::Consume(IAaptContext* context,
-                                    ResourceTable* table) {
+bool PseudolocaleGenerator::Consume(IAaptContext* context, ResourceTable* table) {
   for (auto& package : table->packages) {
     for (auto& type : package->types) {
       for (auto& entry : type->entries) {
-        std::vector<ResourceConfigValue*> values =
-            entry->FindValuesIf(IsPseudolocalizable);
-
+        std::vector<ResourceConfigValue*> values = entry->FindValuesIf(IsPseudolocalizable);
         for (ResourceConfigValue* value : values) {
-          PseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value,
-                                 &table->string_pool, entry.get());
-          PseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value,
-                                 &table->string_pool, entry.get());
+          PseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value, &table->string_pool,
+                                 entry.get());
+          PseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value, &table->string_pool,
+                                 entry.get());
         }
       }
     }
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index 4db37db..b08e1da 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -25,7 +25,7 @@
   StringPool pool;
   StyleString original_style;
   original_style.str = "Hello world!";
-  original_style.spans = {Span{"b", 2, 3}, Span{"b", 6, 7}, Span{"i", 1, 10}};
+  original_style.spans = {Span{"i", 1, 10}, Span{"b", 2, 3}, Span{"b", 6, 7}};
 
   std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
       util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
@@ -34,22 +34,19 @@
   EXPECT_EQ(original_style.str, *new_string->value->str);
   ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
 
-  EXPECT_EQ(std::string("He").size(), new_string->value->spans[0].first_char);
-  EXPECT_EQ(std::string("Hel").size(), new_string->value->spans[0].last_char);
-  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
+  EXPECT_EQ(std::string("i"), *new_string->value->spans[0].name);
+  EXPECT_EQ(std::u16string(u"H").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::u16string(u"Hello worl").size(), new_string->value->spans[0].last_char);
 
-  EXPECT_EQ(std::string("Hello ").size(),
-            new_string->value->spans[1].first_char);
-  EXPECT_EQ(std::string("Hello w").size(),
-            new_string->value->spans[1].last_char);
   EXPECT_EQ(std::string("b"), *new_string->value->spans[1].name);
+  EXPECT_EQ(std::u16string(u"He").size(), new_string->value->spans[1].first_char);
+  EXPECT_EQ(std::u16string(u"Hel").size(), new_string->value->spans[1].last_char);
 
-  EXPECT_EQ(std::string("H").size(), new_string->value->spans[2].first_char);
-  EXPECT_EQ(std::string("Hello worl").size(),
-            new_string->value->spans[2].last_char);
-  EXPECT_EQ(std::string("i"), *new_string->value->spans[2].name);
+  EXPECT_EQ(std::string("b"), *new_string->value->spans[2].name);
+  EXPECT_EQ(std::u16string(u"Hello ").size(), new_string->value->spans[2].first_char);
+  EXPECT_EQ(std::u16string(u"Hello w").size(), new_string->value->spans[2].last_char);
 
-  original_style.spans.push_back(Span{"em", 0, 11u});
+  original_style.spans.insert(original_style.spans.begin(), Span{"em", 0, 11u});
 
   new_string = PseudolocalizeStyledString(
       util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
@@ -58,23 +55,128 @@
   EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð¡ one two]"), *new_string->value->str);
   ASSERT_EQ(original_style.spans.size(), new_string->value->spans.size());
 
-  EXPECT_EQ(std::string("[Ĥé").size(), new_string->value->spans[0].first_char);
-  EXPECT_EQ(std::string("[Ĥéļ").size(), new_string->value->spans[0].last_char);
+  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::u16string(u"[Ĥéļļö ŵöŕļð").size(), new_string->value->spans[0].last_char);
 
-  EXPECT_EQ(std::string("[Ĥéļļö ").size(),
+  EXPECT_EQ(std::u16string(u"[Ĥ").size(), new_string->value->spans[1].first_char);
+  EXPECT_EQ(std::u16string(u"[Ĥéļļö ŵöŕļ").size(), new_string->value->spans[1].last_char);
+
+  EXPECT_EQ(std::u16string(u"[Ĥé").size(), new_string->value->spans[2].first_char);
+  EXPECT_EQ(std::u16string(u"[Ĥéļ").size(), new_string->value->spans[2].last_char);
+
+  EXPECT_EQ(std::u16string(u"[Ĥéļļö ").size(), new_string->value->spans[3].first_char);
+  EXPECT_EQ(std::u16string(u"[Ĥéļļö ŵ").size(), new_string->value->spans[3].last_char);
+}
+
+TEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentNestedTags) {
+  StringPool pool;
+  StyleString original_style;
+  original_style.str = "bold";
+  original_style.spans = {Span{"b", 0, 3}, Span{"i", 0, 3}};
+
+  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
+      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
+      Pseudolocalizer::Method::kAccent, &pool);
+  ASSERT_NE(nullptr, new_string);
+  ASSERT_EQ(2u, new_string->value->spans.size());
+  EXPECT_EQ(std::string("[ɓöļð one]"), *new_string->value->str);
+
+  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
+  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::u16string(u"[ɓöļ").size(), new_string->value->spans[0].last_char);
+
+  EXPECT_EQ(std::string("i"), *new_string->value->spans[1].name);
+  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[1].first_char);
+  EXPECT_EQ(std::u16string(u"[ɓöļ").size(), new_string->value->spans[1].last_char);
+}
+
+TEST(PseudolocaleGeneratorTest, PseudolocalizeAdjacentTagsUnsorted) {
+  StringPool pool;
+  StyleString original_style;
+  original_style.str = "bold";
+  original_style.spans = {Span{"i", 2, 3}, Span{"b", 0, 1}};
+
+  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
+      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
+      Pseudolocalizer::Method::kAccent, &pool);
+  ASSERT_NE(nullptr, new_string);
+  ASSERT_EQ(2u, new_string->value->spans.size());
+  EXPECT_EQ(std::string("[ɓöļð one]"), *new_string->value->str);
+
+  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
+  EXPECT_EQ(std::u16string(u"[").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::u16string(u"[ɓ").size(), new_string->value->spans[0].last_char);
+
+  EXPECT_EQ(std::string("i"), *new_string->value->spans[1].name);
+  EXPECT_EQ(std::u16string(u"[ɓö").size(), new_string->value->spans[1].first_char);
+  EXPECT_EQ(std::u16string(u"[ɓöļ").size(), new_string->value->spans[1].last_char);
+}
+
+TEST(PseudolocaleGeneratorTest, PseudolocalizeNestedAndAdjacentTags) {
+  StringPool pool;
+  StyleString original_style;
+  original_style.str = "This sentence is not what you think it is at all.";
+  original_style.spans = {Span{"b", 16u, 19u}, Span{"em", 29u, 47u}, Span{"i", 38u, 40u},
+                          Span{"b", 44u, 47u}};
+
+  std::unique_ptr<StyledString> new_string = PseudolocalizeStyledString(
+      util::make_unique<StyledString>(pool.MakeRef(original_style)).get(),
+      Pseudolocalizer::Method::kAccent, &pool);
+  ASSERT_NE(nullptr, new_string);
+  ASSERT_EQ(4u, new_string->value->spans.size());
+  EXPECT_EQ(std::string(
+                "[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ åļļ. one two three four five six]"),
+            *new_string->value->str);
+
+  EXPECT_EQ(std::string("b"), *new_string->value->spans[0].name);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñö").size(), new_string->value->spans[0].last_char);
+
+  EXPECT_EQ(std::string("em"), *new_string->value->spans[1].name);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû").size(),
             new_string->value->spans[1].first_char);
-  EXPECT_EQ(std::string("[Ĥéļļö ŵ").size(),
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ åļ").size(),
             new_string->value->spans[1].last_char);
 
-  EXPECT_EQ(std::string("[Ĥ").size(), new_string->value->spans[2].first_char);
-  EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļ").size(),
+  EXPECT_EQ(std::string("i"), *new_string->value->spans[2].name);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ").size(),
+            new_string->value->spans[2].first_char);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ î").size(),
             new_string->value->spans[2].last_char);
 
-  EXPECT_EQ(std::string("[").size(), new_string->value->spans[3].first_char);
-  EXPECT_EQ(std::string("[Ĥéļļö ŵöŕļð").size(),
+  EXPECT_EQ(std::string("b"), *new_string->value->spans[3].name);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ").size(),
+            new_string->value->spans[3].first_char);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šéñţéñçé îš ñöţ ŵĥåţ ýöû ţĥîñķ îţ îš åţ åļ").size(),
             new_string->value->spans[3].last_char);
 }
 
+TEST(PseudolocaleGeneratorTest, PseudolocalizePartsOfString) {
+  StringPool pool;
+  StyleString original_style;
+  original_style.str = "This should NOT be pseudolocalized.";
+  original_style.spans = {Span{"em", 4u, 14u}, Span{"i", 18u, 33u}};
+  std::unique_ptr<StyledString> original_string =
+      util::make_unique<StyledString>(pool.MakeRef(original_style));
+  original_string->untranslatable_sections = {UntranslatableSection{11u, 15u}};
+
+  std::unique_ptr<StyledString> new_string =
+      PseudolocalizeStyledString(original_string.get(), Pseudolocalizer::Method::kAccent, &pool);
+  ASSERT_NE(nullptr, new_string);
+  ASSERT_EQ(2u, new_string->value->spans.size());
+  EXPECT_EQ(std::string("[Ţĥîš šĥöûļð NOT ɓé þšéûðöļöçåļîžéð. one two three four]"),
+            *new_string->value->str);
+
+  EXPECT_EQ(std::string("em"), *new_string->value->spans[0].name);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš").size(), new_string->value->spans[0].first_char);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šĥöûļð NO").size(), new_string->value->spans[0].last_char);
+
+  EXPECT_EQ(std::string("i"), *new_string->value->spans[1].name);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šĥöûļð NOT ɓé").size(), new_string->value->spans[1].first_char);
+  EXPECT_EQ(std::u16string(u"[Ţĥîš šĥöûļð NOT ɓé þšéûðöļöçåļîžé").size(),
+            new_string->value->spans[1].last_char);
+}
+
 TEST(PseudolocaleGeneratorTest, PseudolocalizeOnlyDefaultConfigs) {
   std::unique_ptr<ResourceTable> table =
       test::ResourceTableBuilder()
@@ -138,7 +240,7 @@
   {
     StyleString original_style;
     original_style.str = "Hello world!";
-    original_style.spans = {Span{"b", 2, 3}, Span{"b", 6, 7}, Span{"i", 1, 10}};
+    original_style.spans = {Span{"i", 1, 10}, Span{"b", 2, 3}, Span{"b", 6, 7}};
 
     auto styled_string =
         util::make_unique<StyledString>(table->string_pool.MakeRef(original_style));
diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp
index 7f71589..a33fd06 100644
--- a/tools/aapt2/link/Link.cpp
+++ b/tools/aapt2/link/Link.cpp
@@ -1913,7 +1913,7 @@
   std::vector<std::string> overlay_arg_list;
   std::vector<std::string> extra_java_packages;
   Maybe<std::string> package_id;
-  Maybe<std::string> configs;
+  std::vector<std::string> configs;
   Maybe<std::string> preferred_density;
   Maybe<std::string> product_list;
   bool legacy_x_flag = false;
@@ -1971,7 +1971,7 @@
                           &legacy_x_flag)
           .OptionalSwitch("-z", "Require localization of strings marked 'suggested'",
                           &require_localization)
-          .OptionalFlag("-c",
+          .OptionalFlagList("-c",
                         "Comma separated list of configurations to include. The default\n"
                         "is all configurations",
                         &configs)
@@ -2151,28 +2151,29 @@
   }
 
   AxisConfigFilter filter;
-  if (configs) {
-    for (const StringPiece& config_str : util::Tokenize(configs.value(), ',')) {
-      ConfigDescription config;
-      LocaleValue lv;
-      if (lv.InitFromFilterString(config_str)) {
-        lv.WriteTo(&config);
-      } else if (!ConfigDescription::Parse(config_str, &config)) {
-        context.GetDiagnostics()->Error(DiagMessage() << "invalid config '"
-                                                      << config_str
-                                                      << "' for -c option");
-        return 1;
-      }
+  if (configs.empty()) {
+    for (const std::string& config_arg : configs) {
+      for (const StringPiece& config_str : util::Tokenize(config_arg, ',')) {
+        ConfigDescription config;
+        LocaleValue lv;
+        if (lv.InitFromFilterString(config_str)) {
+          lv.WriteTo(&config);
+        } else if (!ConfigDescription::Parse(config_str, &config)) {
+          context.GetDiagnostics()->Error(DiagMessage() << "invalid config '"
+                                                        << config_str
+                                                        << "' for -c option");
+          return 1;
+        }
 
-      if (config.density != 0) {
-        context.GetDiagnostics()->Warn(DiagMessage() << "ignoring density '"
-                                                     << config
-                                                     << "' for -c option");
-      } else {
-        filter.AddConfig(config);
+        if (config.density != 0) {
+          context.GetDiagnostics()->Warn(DiagMessage() << "ignoring density '"
+                                                       << config
+                                                       << "' for -c option");
+        } else {
+          filter.AddConfig(config);
+        }
       }
     }
-
     options.table_splitter_options.config_filter = &filter;
   }