Merge "Pass weight/italic pair instead of style." into oc-dev
diff --git a/Android.mk b/Android.mk
index f1db6b7..e27aa30 100644
--- a/Android.mk
+++ b/Android.mk
@@ -320,6 +320,8 @@
 	core/java/android/service/wallpaper/IWallpaperService.aidl \
 	core/java/android/service/chooser/IChooserTargetService.aidl \
 	core/java/android/service/chooser/IChooserTargetResult.aidl \
+	core/java/android/service/resolver/IResolverRankerService.aidl \
+	core/java/android/service/resolver/IResolverRankerResult.aidl \
 	core/java/android/text/ITextClassificationService.aidl \
 	core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl\
 	core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl\
@@ -728,6 +730,7 @@
 	frameworks/base/core/java/android/service/notification/SnoozeCriterion.aidl \
 	frameworks/base/core/java/android/service/notification/StatusBarNotification.aidl \
 	frameworks/base/core/java/android/service/chooser/ChooserTarget.aidl \
+	frameworks/base/core/java/android/service/resolver/ResolverTarget.aidl \
 	frameworks/base/core/java/android/speech/tts/Voice.aidl \
 	frameworks/base/core/java/android/app/usage/CacheQuotaHint.aidl \
 	frameworks/base/core/java/android/app/usage/ExternalStorageStats.aidl \
@@ -1460,8 +1463,7 @@
 LOCAL_SRC_FILES := \
     $(call all-proto-files-under, core/proto) \
     $(call all-proto-files-under, libs/incident/proto)
-LOCAL_SHARED_LIBRARIES := libprotobuf-cpp-full
-include $(BUILD_SHARED_LIBRARY)
+include $(BUILD_STATIC_LIBRARY)
 
 # ====  c++ proto host library  ==============================
 include $(CLEAR_VARS)
diff --git a/api/current.txt b/api/current.txt
index f26adb9..3c90844 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20913,6 +20913,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 +24556,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 +24642,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 +24780,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
@@ -41213,6 +41323,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 {
@@ -41414,7 +41526,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);
@@ -48618,7 +48730,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();
@@ -48667,7 +48779,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);
@@ -48958,12 +49070,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);
@@ -51224,7 +51336,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();
@@ -51337,7 +51449,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-current.txt b/api/system-current.txt
index efababc..6a14b15 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -53,6 +53,7 @@
     field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
     field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
     field public static final java.lang.String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
+    field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
     field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
     field public static final java.lang.String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
     field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
@@ -4621,6 +4622,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";
@@ -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
@@ -40479,6 +40620,36 @@
 
 }
 
+package android.service.resolver {
+
+  public abstract class ResolverRankerService extends android.app.Service {
+    ctor public ResolverRankerService();
+    method public android.os.IBinder onBind(android.content.Intent);
+    method public void onPredictSharingProbabilities(java.util.List<android.service.resolver.ResolverTarget>);
+    method public void onTrainRankingModel(java.util.List<android.service.resolver.ResolverTarget>, int);
+    field public static final java.lang.String BIND_PERMISSION = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
+    field public static final java.lang.String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService";
+  }
+
+  public final class ResolverTarget implements android.os.Parcelable {
+    ctor public ResolverTarget();
+    method public int describeContents();
+    method public float getChooserScore();
+    method public float getLaunchScore();
+    method public float getRecencyScore();
+    method public float getSelectProbability();
+    method public float getTimeSpentScore();
+    method public void setChooserScore(float);
+    method public void setLaunchScore(float);
+    method public void setRecencyScore(float);
+    method public void setSelectProbability(float);
+    method public void setTimeSpentScore(float);
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final android.os.Parcelable.Creator<android.service.resolver.ResolverTarget> CREATOR;
+  }
+
+}
+
 package android.service.restrictions {
 
   public abstract class RestrictionsReceiver extends android.content.BroadcastReceiver {
@@ -44675,6 +44846,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 {
@@ -44876,7 +45049,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);
@@ -52166,7 +52339,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();
@@ -52221,7 +52394,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);
@@ -52549,12 +52722,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);
@@ -55054,7 +55227,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();
@@ -55167,7 +55340,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-current.txt b/api/test-current.txt
index cf8455c..c5dc584 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -21026,6 +21026,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 +24669,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 +24755,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 +24893,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
@@ -41421,6 +41531,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 {
@@ -41622,7 +41734,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);
@@ -49002,7 +49114,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();
@@ -49051,7 +49163,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);
@@ -49342,12 +49454,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);
@@ -51615,7 +51727,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();
@@ -51728,7 +51840,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/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/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/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 279b900..399987f 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.
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/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/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/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/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index e27fa06..b7a0420 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -78,11 +78,6 @@
     }
 
     /** @hide */
-    public @Nullable RemoteViews getPresentation() {
-        return mPresentation;
-    }
-
-    /** @hide */
     public @Nullable IntentSender getAuthentication() {
         return mAuthentication;
     }
diff --git a/core/java/android/service/resolver/IResolverRankerResult.aidl b/core/java/android/service/resolver/IResolverRankerResult.aidl
new file mode 100644
index 0000000..bda3154
--- /dev/null
+++ b/core/java/android/service/resolver/IResolverRankerResult.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.service.resolver;
+
+import android.service.resolver.ResolverTarget;
+
+/**
+ * @hide
+ */
+oneway interface IResolverRankerResult
+{
+    void sendResult(in List<ResolverTarget> results);
+}
\ No newline at end of file
diff --git a/core/java/android/service/resolver/IResolverRankerService.aidl b/core/java/android/service/resolver/IResolverRankerService.aidl
new file mode 100644
index 0000000..f0d747d
--- /dev/null
+++ b/core/java/android/service/resolver/IResolverRankerService.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.service.resolver;
+
+import android.service.resolver.IResolverRankerResult;
+import android.service.resolver.ResolverTarget;
+
+/**
+ * @hide
+ */
+oneway interface IResolverRankerService
+{
+    void predict(in List<ResolverTarget> targets, IResolverRankerResult result);
+    void train(in List<ResolverTarget> targets, int selectedPosition);
+}
\ No newline at end of file
diff --git a/core/java/android/service/resolver/ResolverRankerService.java b/core/java/android/service/resolver/ResolverRankerService.java
new file mode 100644
index 0000000..0506747
--- /dev/null
+++ b/core/java/android/service/resolver/ResolverRankerService.java
@@ -0,0 +1,187 @@
+/*
+ * 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.service.resolver;
+
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.RemoteException;
+import android.service.resolver.ResolverTarget;
+import android.util.Log;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A service to rank apps according to usage stats of apps, when the system is resolving targets for
+ * an Intent.
+ *
+ * <p>To extend this class, you must declare the service in your manifest file with the
+ * {@link android.Manifest.permission#BIND_RESOLVER_RANKER_SERVICE} permission, and include an
+ * intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
+ * <pre>
+ *     &lt;service android:name=".MyResolverRankerService"
+ *             android:exported="true"
+ *             android:priority="100"
+ *             android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"&gt;
+ *         &lt;intent-filter&gt;
+ *             &lt;action android:name="android.service.resolver.ResolverRankerService" /&gt;
+ *         &lt;/intent-filter&gt;
+ *     &lt;/service&gt;
+ * </pre>
+ * @hide
+ */
+@SystemApi
+public abstract class ResolverRankerService extends Service {
+
+    private static final String TAG = "ResolverRankerService";
+
+    private static final boolean DEBUG = false;
+
+    /**
+     * The Intent action that a service must respond to. Add it to the intent filter of the service
+     * in its manifest.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE = "android.service.resolver.ResolverRankerService";
+
+    /**
+     * The permission that a service must require to ensure that only Android system can bind to it.
+     * If this permission is not enforced in the AndroidManifest of the service, the system will
+     * skip that service.
+     */
+    public static final String BIND_PERMISSION = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
+
+    private ResolverRankerServiceWrapper mWrapper = null;
+
+    /**
+     * Called by the system to retrieve a list of probabilities to rank apps/options. To implement
+     * it, set selectProbability of each input {@link ResolverTarget}. The higher the
+     * selectProbability is, the more likely the {@link ResolverTarget} will be selected by the
+     * user. Override this function to provide prediction results.
+     *
+     * @param targets a list of {@link ResolverTarget}, for the list of apps to be ranked.
+     *
+     * @throws Exception when the prediction task fails.
+     */
+    public void onPredictSharingProbabilities(final List<ResolverTarget> targets) {}
+
+    /**
+     * Called by the system to train/update a ranking service, after the user makes a selection from
+     * the ranked list of apps. Override this function to enable model updates.
+     *
+     * @param targets a list of {@link ResolverTarget}, for the list of apps to be ranked.
+     * @param selectedPosition the position of the selected app in the list.
+     *
+     * @throws Exception when the training task fails.
+     */
+    public void onTrainRankingModel(
+            final List<ResolverTarget> targets, final int selectedPosition) {}
+
+    private static final String HANDLER_THREAD_NAME = "RESOLVER_RANKER_SERVICE";
+    private volatile Handler mHandler;
+    private HandlerThread mHandlerThread;
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (DEBUG) Log.d(TAG, "onBind " + intent);
+        if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+            if (DEBUG) Log.d(TAG, "bad intent action " + intent.getAction() + "; returning null");
+            return null;
+        }
+        if (mHandlerThread == null) {
+            mHandlerThread = new HandlerThread(HANDLER_THREAD_NAME);
+            mHandlerThread.start();
+            mHandler = new Handler(mHandlerThread.getLooper());
+        }
+        if (mWrapper == null) {
+            mWrapper = new ResolverRankerServiceWrapper();
+        }
+        return mWrapper;
+    }
+
+    @Override
+    public void onDestroy() {
+        mHandler = null;
+        if (mHandlerThread != null) {
+            mHandlerThread.quitSafely();
+        }
+        super.onDestroy();
+    }
+
+    private static void sendResult(List<ResolverTarget> targets, IResolverRankerResult result) {
+        try {
+            result.sendResult(targets);
+        } catch (Exception e) {
+            Log.e(TAG, "failed to send results: " + e);
+        }
+    }
+
+    private class ResolverRankerServiceWrapper extends IResolverRankerService.Stub {
+
+        @Override
+        public void predict(final List<ResolverTarget> targets, final IResolverRankerResult result)
+                throws RemoteException {
+            Runnable predictRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) {
+                            Log.d(TAG, "predict calls onPredictSharingProbabilities.");
+                        }
+                        onPredictSharingProbabilities(targets);
+                        sendResult(targets, result);
+                    } catch (Exception e) {
+                        Log.e(TAG, "onPredictSharingProbabilities failed; send null results: " + e);
+                        sendResult(null, result);
+                    }
+                }
+            };
+            final Handler h = mHandler;
+            if (h != null) {
+                h.post(predictRunnable);
+            }
+        }
+
+        @Override
+        public void train(final List<ResolverTarget> targets, final int selectedPosition)
+                throws RemoteException {
+            Runnable trainRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) {
+                            Log.d(TAG, "train calls onTranRankingModel");
+                        }
+                        onTrainRankingModel(targets, selectedPosition);
+                    } catch (Exception e) {
+                        Log.e(TAG, "onTrainRankingModel failed; skip train: " + e);
+                    }
+                }
+            };
+            final Handler h = mHandler;
+            if (h != null) {
+                h.post(trainRunnable);
+            }
+        }
+    }
+}
diff --git a/core/java/android/service/resolver/ResolverTarget.aidl b/core/java/android/service/resolver/ResolverTarget.aidl
new file mode 100644
index 0000000..6cab2d4
--- /dev/null
+++ b/core/java/android/service/resolver/ResolverTarget.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.service.resolver;
+
+/**
+ * @hide
+ */
+parcelable ResolverTarget;
diff --git a/core/java/android/service/resolver/ResolverTarget.java b/core/java/android/service/resolver/ResolverTarget.java
new file mode 100644
index 0000000..fb3e2d7
--- /dev/null
+++ b/core/java/android/service/resolver/ResolverTarget.java
@@ -0,0 +1,216 @@
+/*
+ * 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.service.resolver;
+
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArrayMap;
+
+import java.util.Map;
+
+/**
+ * A ResolverTarget contains features by which an app or option will be ranked, in
+ * {@link ResolverRankerService}.
+ * @hide
+ */
+@SystemApi
+public final class ResolverTarget implements Parcelable {
+    private static final String TAG = "ResolverTarget";
+
+    /**
+     * a float score for recency of last use.
+     */
+    private float mRecencyScore;
+
+    /**
+     * a float score for total time spent.
+     */
+    private float mTimeSpentScore;
+
+    /**
+     * a float score for number of launches.
+     */
+    private float mLaunchScore;
+
+    /**
+     * a float score for number of selected.
+     */
+    private float mChooserScore;
+
+    /**
+     * a float score for the probability to be selected.
+     */
+    private float mSelectProbability;
+
+    // constructor for the class.
+    public ResolverTarget() {}
+
+    ResolverTarget(Parcel in) {
+        mRecencyScore = in.readFloat();
+        mTimeSpentScore = in.readFloat();
+        mLaunchScore = in.readFloat();
+        mChooserScore = in.readFloat();
+        mSelectProbability = in.readFloat();
+    }
+
+    /**
+     * Gets the score for how recently the target was used in the foreground.
+     *
+     * @return a float score whose range is [0, 1]. The higher the score is, the more recently the
+     * target was used.
+     */
+    public float getRecencyScore() {
+        return mRecencyScore;
+    }
+
+    /**
+     * Sets the score for how recently the target was used in the foreground.
+     *
+     * @param recencyScore a float score whose range is [0, 1]. The higher the score is, the more
+     *                     recently the target was used.
+     */
+    public void setRecencyScore(float recencyScore) {
+        this.mRecencyScore = recencyScore;
+    }
+
+    /**
+     * Gets the score for how long the target has been used in the foreground.
+     *
+     * @return a float score whose range is [0, 1]. The higher the score is, the longer the target
+     * has been used for.
+     */
+    public float getTimeSpentScore() {
+        return mTimeSpentScore;
+    }
+
+    /**
+     * Sets the score for how long the target has been used in the foreground.
+     *
+     * @param timeSpentScore a float score whose range is [0, 1]. The higher the score is, the
+     *                       longer the target has been used for.
+     */
+    public void setTimeSpentScore(float timeSpentScore) {
+        this.mTimeSpentScore = timeSpentScore;
+    }
+
+    /**
+     * Gets the score for how many times the target has been launched to the foreground.
+     *
+     * @return a float score whose range is [0, 1]. The higher the score is, the more times the
+     * target has been launched.
+     */
+    public float getLaunchScore() {
+        return mLaunchScore;
+    }
+
+    /**
+     * Sets the score for how many times the target has been launched to the foreground.
+     *
+     * @param launchScore a float score whose range is [0, 1]. The higher the score is, the more
+     *                    times the target has been launched.
+     */
+    public void setLaunchScore(float launchScore) {
+        this.mLaunchScore = launchScore;
+    }
+
+    /**
+     * Gets the score for how many times the target has been selected by the user to share the same
+     * types of content.
+     *
+     * @return a float score whose range is [0, 1]. The higher the score is, the
+     * more times the target has been selected by the user to share the same types of content for.
+     */
+    public float getChooserScore() {
+        return mChooserScore;
+    }
+
+    /**
+     * Sets the score for how many times the target has been selected by the user to share the same
+     * types of content.
+     *
+     * @param chooserScore a float score whose range is [0, 1]. The higher the score is, the more
+     *                     times the target has been selected by the user to share the same types
+     *                     of content for.
+     */
+    public void setChooserScore(float chooserScore) {
+        this.mChooserScore = chooserScore;
+    }
+
+    /**
+     * Gets the probability of how likely this target will be selected by the user.
+     *
+     * @return a float score whose range is [0, 1]. The higher the score is, the more likely the
+     * user is going to select this target.
+     */
+    public float getSelectProbability() {
+        return mSelectProbability;
+    }
+
+    /**
+     * Sets the probability for how like this target will be selected by the user.
+     *
+     * @param selectProbability a float score whose range is [0, 1]. The higher the score is, the
+     *                          more likely tht user is going to select this target.
+     */
+    public void setSelectProbability(float selectProbability) {
+        this.mSelectProbability = selectProbability;
+    }
+
+    // serialize the class to a string.
+    @Override
+    public String toString() {
+        return "ResolverTarget{"
+                + mRecencyScore + ", "
+                + mTimeSpentScore + ", "
+                + mLaunchScore + ", "
+                + mChooserScore + ", "
+                + mSelectProbability + "}";
+    }
+
+    // describes the kinds of special objects contained in this Parcelable instance's marshaled
+    // representation.
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    // flattens this object in to a Parcel.
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeFloat(mRecencyScore);
+        dest.writeFloat(mTimeSpentScore);
+        dest.writeFloat(mLaunchScore);
+        dest.writeFloat(mChooserScore);
+        dest.writeFloat(mSelectProbability);
+    }
+
+    // creator definition for the class.
+    public static final Creator<ResolverTarget> CREATOR
+            = new Creator<ResolverTarget>() {
+        @Override
+        public ResolverTarget createFromParcel(Parcel source) {
+            return new ResolverTarget(source);
+        }
+
+        @Override
+        public ResolverTarget[] newArray(int size) {
+            return new ResolverTarget[size];
+        }
+    };
+}
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..0221040 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();
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/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 b383663..1b60ebc 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -610,7 +610,7 @@
 
     private int mBreakStrategy;
     private int mHyphenationFrequency;
-    private boolean mJustify;
+    private int mJustificationMode;
 
     private int mMaximum = Integer.MAX_VALUE;
     private int mMaxMode = LINES;
@@ -821,7 +821,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();
 
@@ -3738,14 +3738,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();
@@ -3754,12 +3755,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;
     }
 
     /**
@@ -7683,7 +7684,7 @@
                         .setIncludePad(mIncludePad)
                         .setBreakStrategy(mBreakStrategy)
                         .setHyphenationFrequency(mHyphenationFrequency)
-                        .setJustify(mJustify)
+                        .setJustificationMode(mJustificationMode)
                         .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
                 if (shouldEllipsize) {
                     builder.setEllipsize(mEllipsize)
@@ -7725,7 +7726,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) {
@@ -7775,7 +7776,7 @@
                     .setIncludePad(mIncludePad)
                     .setBreakStrategy(mBreakStrategy)
                     .setHyphenationFrequency(mHyphenationFrequency)
-                    .setJustify(mJustify)
+                    .setJustificationMode(mJustificationMode)
                     .setMaxLines(mMaxMode == LINES ? mMaximum : Integer.MAX_VALUE);
             if (shouldEllipsize) {
                 builder.setEllipsize(effectiveEllipsize)
@@ -8115,7 +8116,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/app/LRResolverRankerService.java b/core/java/com/android/internal/app/LRResolverRankerService.java
new file mode 100644
index 0000000..1cad7c7
--- /dev/null
+++ b/core/java/com/android/internal/app/LRResolverRankerService.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Environment;
+import android.os.IBinder;
+import android.os.storage.StorageManager;
+import android.service.resolver.ResolverRankerService;
+import android.service.resolver.ResolverTarget;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A Logistic Regression based {@link android.service.resolver.ResolverRankerService}, to be used
+ * in {@link ResolverComparator}.
+ */
+public final class LRResolverRankerService extends ResolverRankerService {
+    private static final String TAG = "LRResolverRankerService";
+
+    private static final boolean DEBUG = false;
+
+    private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params";
+    private static final String BIAS_PREF_KEY = "bias";
+    private static final String VERSION_PREF_KEY = "version";
+
+    private static final String LAUNCH_SCORE = "launch";
+    private static final String TIME_SPENT_SCORE = "timeSpent";
+    private static final String RECENCY_SCORE = "recency";
+    private static final String CHOOSER_SCORE = "chooser";
+
+    // parameters for a pre-trained model, to initialize the app ranker. When updating the
+    // pre-trained model, please update these params, as well as initModel().
+    private static final int CURRENT_VERSION = 1;
+    private static final float LEARNING_RATE = 0.0001f;
+    private static final float REGULARIZER_PARAM = 0.0001f;
+
+    private SharedPreferences mParamSharedPref;
+    private ArrayMap<String, Float> mFeatureWeights;
+    private float mBias;
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        initModel();
+        return super.onBind(intent);
+    }
+
+    @Override
+    public void onPredictSharingProbabilities(List<ResolverTarget> targets) {
+        final int size = targets.size();
+        for (int i = 0; i < size; ++i) {
+            ResolverTarget target = targets.get(i);
+            ArrayMap<String, Float> features = getFeatures(target);
+            target.setSelectProbability(predict(features));
+        }
+    }
+
+    @Override
+    public void onTrainRankingModel(List<ResolverTarget> targets, int selectedPosition) {
+        final int size = targets.size();
+        if (selectedPosition < 0 || selectedPosition >= size) {
+            if (DEBUG) {
+                Log.d(TAG, "Invalid Position of Selected App " + selectedPosition);
+            }
+            return;
+        }
+        final ArrayMap<String, Float> positive = getFeatures(targets.get(selectedPosition));
+        final float positiveProbability = targets.get(selectedPosition).getSelectProbability();
+        final int targetSize = targets.size();
+        for (int i = 0; i < targetSize; ++i) {
+            if (i == selectedPosition) {
+                continue;
+            }
+            final ArrayMap<String, Float> negative = getFeatures(targets.get(i));
+            final float negativeProbability = targets.get(i).getSelectProbability();
+            if (negativeProbability > positiveProbability) {
+                update(negative, negativeProbability, false);
+                update(positive, positiveProbability, true);
+            }
+        }
+        commitUpdate();
+    }
+
+    private void initModel() {
+        mParamSharedPref = getParamSharedPref();
+        mFeatureWeights = new ArrayMap<>(4);
+        if (mParamSharedPref == null ||
+                mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) {
+            // Initializing the app ranker to a pre-trained model. When updating the pre-trained
+            // model, please increment CURRENT_VERSION, and update LEARNING_RATE and
+            // REGULARIZER_PARAM.
+            mBias = -1.6568f;
+            mFeatureWeights.put(LAUNCH_SCORE, 2.5543f);
+            mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f);
+            mFeatureWeights.put(RECENCY_SCORE, 0.269f);
+            mFeatureWeights.put(CHOOSER_SCORE, 4.2222f);
+        } else {
+            mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f);
+            mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f));
+            mFeatureWeights.put(
+                    TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f));
+            mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f));
+            mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f));
+        }
+    }
+
+    private ArrayMap<String, Float> getFeatures(ResolverTarget target) {
+        ArrayMap<String, Float> features = new ArrayMap<>(4);
+        features.put(RECENCY_SCORE, target.getRecencyScore());
+        features.put(TIME_SPENT_SCORE, target.getTimeSpentScore());
+        features.put(LAUNCH_SCORE, target.getLaunchScore());
+        features.put(CHOOSER_SCORE, target.getChooserScore());
+        return features;
+    }
+
+    private float predict(ArrayMap<String, Float> target) {
+        if (target == null) {
+            return 0.0f;
+        }
+        final int featureSize = target.size();
+        float sum = 0.0f;
+        for (int i = 0; i < featureSize; i++) {
+            String featureName = target.keyAt(i);
+            float weight = mFeatureWeights.getOrDefault(featureName, 0.0f);
+            sum += weight * target.valueAt(i);
+        }
+        return (float) (1.0 / (1.0 + Math.exp(-mBias - sum)));
+    }
+
+    private void update(ArrayMap<String, Float> target, float predict, boolean isSelected) {
+        if (target == null) {
+            return;
+        }
+        final int featureSize = target.size();
+        float error = isSelected ? 1.0f - predict : -predict;
+        for (int i = 0; i < featureSize; i++) {
+            String featureName = target.keyAt(i);
+            float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f);
+            mBias += LEARNING_RATE * error;
+            currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight +
+                    LEARNING_RATE * error * target.valueAt(i);
+            mFeatureWeights.put(featureName, currentWeight);
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias);
+        }
+    }
+
+    private void commitUpdate() {
+        try {
+            SharedPreferences.Editor editor = mParamSharedPref.edit();
+            editor.putFloat(BIAS_PREF_KEY, mBias);
+            final int size = mFeatureWeights.size();
+            for (int i = 0; i < size; i++) {
+                editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i));
+            }
+            editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION);
+            editor.apply();
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to commit update" + e);
+        }
+    }
+
+    private SharedPreferences getParamSharedPref() {
+        // The package info in the context isn't initialized in the way it is for normal apps,
+        // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
+        // build the path manually below using the same policy that appears in ContextImpl.
+        if (DEBUG) {
+            Log.d(TAG, "Context Package Name: " + getPackageName());
+        }
+        final File prefsFile = new File(new File(
+                Environment.getDataUserCePackageDirectory(
+                        StorageManager.UUID_PRIVATE_INTERNAL, getUserId(), getPackageName()),
+                "shared_prefs"),
+                PARAM_SHARED_PREF_NAME + ".xml");
+        return getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
+    }
+}
\ No newline at end of file
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 3f1c9ad..622b708 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -530,6 +530,9 @@
             getMainThreadHandler().removeCallbacks(mPostListReadyRunnable);
             mPostListReadyRunnable = null;
         }
+        if (mAdapter != null && mAdapter.mResolverListController != null) {
+            mAdapter.mResolverListController.destroy();
+        }
     }
 
     @Override
diff --git a/core/java/com/android/internal/app/ResolverComparator.java b/core/java/com/android/internal/app/ResolverComparator.java
index 096fcb8..73b62a5 100644
--- a/core/java/com/android/internal/app/ResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverComparator.java
@@ -26,20 +26,34 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.ComponentInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.SharedPreferences;
+import android.content.ServiceConnection;
 import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
 import android.os.storage.StorageManager;
 import android.os.UserHandle;
+import android.service.resolver.IResolverRankerService;
+import android.service.resolver.IResolverRankerResult;
+import android.service.resolver.ResolverRankerService;
+import android.service.resolver.ResolverTarget;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
 
 import java.io.File;
+import java.lang.InterruptedException;
 import java.text.Collator;
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -61,11 +75,15 @@
 
     private static final float RECENCY_MULTIPLIER = 2.f;
 
-    // feature names used in ranking.
-    private static final String LAUNCH_SCORE = "launch";
-    private static final String TIME_SPENT_SCORE = "timeSpent";
-    private static final String RECENCY_SCORE = "recency";
-    private static final String CHOOSER_SCORE = "chooser";
+    // message types
+    private static final int RESOLVER_RANKER_SERVICE_RESULT = 0;
+    private static final int RESOLVER_RANKER_RESULT_TIMEOUT = 1;
+
+    // timeout for establishing connections with a ResolverRankerService.
+    private static final int CONNECTION_COST_TIMEOUT_MILLIS = 200;
+    // timeout for establishing connections with a ResolverRankerService, collecting features and
+    // predicting ranking scores.
+    private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
 
     private final Collator mCollator;
     private final boolean mHttp;
@@ -74,18 +92,74 @@
     private final Map<String, UsageStats> mStats;
     private final long mCurrentTime;
     private final long mSinceTime;
-    private final LinkedHashMap<ComponentName, ScoredTarget> mScoredTargets = new LinkedHashMap<>();
+    private final LinkedHashMap<ComponentName, ResolverTarget> mTargetsDict = new LinkedHashMap<>();
     private final String mReferrerPackage;
+    private final Object mLock = new Object();
+    private ArrayList<ResolverTarget> mTargets;
     private String mContentType;
     private String[] mAnnotations;
     private String mAction;
-    private LogisticRegressionAppRanker mRanker;
+    private IResolverRankerService mRanker;
+    private ResolverRankerServiceConnection mConnection;
+    private AfterCompute mAfterCompute;
+    private Context mContext;
+    private CountDownLatch mConnectSignal;
 
-    public ResolverComparator(Context context, Intent intent, String referrerPackage) {
+    private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case RESOLVER_RANKER_SERVICE_RESULT:
+                    if (DEBUG) {
+                        Log.d(TAG, "RESOLVER_RANKER_SERVICE_RESULT");
+                    }
+                    if (mHandler.hasMessages(RESOLVER_RANKER_RESULT_TIMEOUT)) {
+                        if (msg.obj != null) {
+                            final List<ResolverTarget> receivedTargets =
+                                    (List<ResolverTarget>) msg.obj;
+                            if (receivedTargets != null && mTargets != null
+                                    && receivedTargets.size() == mTargets.size()) {
+                                final int size = mTargets.size();
+                                for (int i = 0; i < size; ++i) {
+                                    mTargets.get(i).setSelectProbability(
+                                            receivedTargets.get(i).getSelectProbability());
+                                }
+                            } else {
+                                Log.e(TAG, "Sizes of sent and received ResolverTargets diff.");
+                            }
+                        } else {
+                            Log.e(TAG, "Receiving null prediction results.");
+                        }
+                        mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT);
+                        mAfterCompute.afterCompute();
+                    }
+                    break;
+
+                case RESOLVER_RANKER_RESULT_TIMEOUT:
+                    if (DEBUG) {
+                        Log.d(TAG, "RESOLVER_RANKER_RESULT_TIMEOUT; unbinding services");
+                    }
+                    mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT);
+                    mAfterCompute.afterCompute();
+                    break;
+
+                default:
+                    super.handleMessage(msg);
+            }
+        }
+    };
+
+    public interface AfterCompute {
+        public void afterCompute ();
+    }
+
+    public ResolverComparator(Context context, Intent intent, String referrerPackage,
+                              AfterCompute afterCompute) {
         mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
         String scheme = intent.getScheme();
         mHttp = "http".equals(scheme) || "https".equals(scheme);
         mReferrerPackage = referrerPackage;
+        mAfterCompute = afterCompute;
+        mContext = context;
 
         mPm = context.getPackageManager();
         mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
@@ -96,9 +170,9 @@
         mContentType = intent.getType();
         getContentAnnotations(intent);
         mAction = intent.getAction();
-        mRanker = new LogisticRegressionAppRanker(context);
     }
 
+    // get annotations of content from intent.
     public void getContentAnnotations(Intent intent) {
         ArrayList<String> annotations = intent.getStringArrayListExtra(
                 Intent.EXTRA_CONTENT_ANNOTATIONS);
@@ -114,20 +188,24 @@
         }
     }
 
+    public void setCallBack(AfterCompute afterCompute) {
+        mAfterCompute = afterCompute;
+    }
+
+    // compute features for each target according to usage stats of targets.
     public void compute(List<ResolvedComponentInfo> targets) {
-        mScoredTargets.clear();
+        reset();
 
         final long recentSinceTime = mCurrentTime - RECENCY_TIME_PERIOD;
 
-        long mostRecentlyUsedTime = recentSinceTime + 1;
-        long mostTimeSpent = 1;
-        int mostLaunched = 1;
-        int mostSelected = 1;
+        float mostRecencyScore = 1.0f;
+        float mostTimeSpentScore = 1.0f;
+        float mostLaunchScore = 1.0f;
+        float mostChooserScore = 1.0f;
 
         for (ResolvedComponentInfo target : targets) {
-            final ScoredTarget scoredTarget
-                    = new ScoredTarget(target.getResolveInfoAt(0).activityInfo);
-            mScoredTargets.put(target.name, scoredTarget);
+            final ResolverTarget resolverTarget = new ResolverTarget();
+            mTargetsDict.put(target.name, resolverTarget);
             final UsageStats pkStats = mStats.get(target.name.getPackageName());
             if (pkStats != null) {
                 // Only count recency for apps that weren't the caller
@@ -135,31 +213,33 @@
                 // Persistent processes muck this up, so omit them too.
                 if (!target.name.getPackageName().equals(mReferrerPackage)
                         && !isPersistentProcess(target)) {
-                    final long lastTimeUsed = pkStats.getLastTimeUsed();
-                    scoredTarget.lastTimeUsed = lastTimeUsed;
-                    if (lastTimeUsed > mostRecentlyUsedTime) {
-                        mostRecentlyUsedTime = lastTimeUsed;
+                    final float recencyScore =
+                            (float) Math.max(pkStats.getLastTimeUsed() - recentSinceTime, 0);
+                    resolverTarget.setRecencyScore(recencyScore);
+                    if (recencyScore > mostRecencyScore) {
+                        mostRecencyScore = recencyScore;
                     }
                 }
-                final long timeSpent = pkStats.getTotalTimeInForeground();
-                scoredTarget.timeSpent = timeSpent;
-                if (timeSpent > mostTimeSpent) {
-                    mostTimeSpent = timeSpent;
+                final float timeSpentScore = (float) pkStats.getTotalTimeInForeground();
+                resolverTarget.setTimeSpentScore(timeSpentScore);
+                if (timeSpentScore > mostTimeSpentScore) {
+                    mostTimeSpentScore = timeSpentScore;
                 }
-                final int launched = pkStats.mLaunchCount;
-                scoredTarget.launchCount = launched;
-                if (launched > mostLaunched) {
-                    mostLaunched = launched;
+                final float launchScore = (float) pkStats.mLaunchCount;
+                resolverTarget.setLaunchScore(launchScore);
+                if (launchScore > mostLaunchScore) {
+                    mostLaunchScore = launchScore;
                 }
 
-                int selected = 0;
+                float chooserScore = 0.0f;
                 if (pkStats.mChooserCounts != null && mAction != null
                         && pkStats.mChooserCounts.get(mAction) != null) {
-                    selected = pkStats.mChooserCounts.get(mAction).getOrDefault(mContentType, 0);
+                    chooserScore = (float) pkStats.mChooserCounts.get(mAction)
+                            .getOrDefault(mContentType, 0);
                     if (mAnnotations != null) {
                         final int size = mAnnotations.length;
                         for (int i = 0; i < size; i++) {
-                            selected += pkStats.mChooserCounts.get(mAction)
+                            chooserScore += (float) pkStats.mChooserCounts.get(mAction)
                                     .getOrDefault(mAnnotations[i], 0);
                         }
                     }
@@ -169,44 +249,37 @@
                         Log.d(TAG, "Action type is null");
                     } else {
                         Log.d(TAG, "Chooser Count of " + mAction + ":" +
-                                target.name.getPackageName() + " is " + Integer.toString(selected));
+                                target.name.getPackageName() + " is " +
+                                Float.toString(chooserScore));
                     }
                 }
-                scoredTarget.chooserCount = selected;
-                if (selected > mostSelected) {
-                    mostSelected = selected;
+                resolverTarget.setChooserScore(chooserScore);
+                if (chooserScore > mostChooserScore) {
+                    mostChooserScore = chooserScore;
                 }
             }
         }
 
-
         if (DEBUG) {
-            Log.d(TAG, "compute - mostRecentlyUsedTime: " + mostRecentlyUsedTime
-                    + " mostTimeSpent: " + mostTimeSpent
-                    + " recentSinceTime: " + recentSinceTime
-                    + " mostLaunched: " + mostLaunched);
+            Log.d(TAG, "compute - mostRecencyScore: " + mostRecencyScore
+                    + " mostTimeSpentScore: " + mostTimeSpentScore
+                    + " mostLaunchScore: " + mostLaunchScore
+                    + " mostChooserScore: " + mostChooserScore);
         }
 
-        for (ScoredTarget target : mScoredTargets.values()) {
-            final float recency = (float) Math.max(target.lastTimeUsed - recentSinceTime, 0)
-                    / (mostRecentlyUsedTime - recentSinceTime);
-            target.setFeatures((float) target.launchCount / mostLaunched,
-                    (float) target.timeSpent / mostTimeSpent,
-                    recency * recency * RECENCY_MULTIPLIER,
-                    (float) target.chooserCount / mostSelected);
-            target.selectProb = mRanker.predict(target.getFeatures());
+        mTargets = new ArrayList<>(mTargetsDict.values());
+        for (ResolverTarget target : mTargets) {
+            final float recency = target.getRecencyScore() / mostRecencyScore;
+            setFeatures(target, recency * recency * RECENCY_MULTIPLIER,
+                    target.getLaunchScore() / mostLaunchScore,
+                    target.getTimeSpentScore() / mostTimeSpentScore,
+                    target.getChooserScore() / mostChooserScore);
+            addDefaultSelectProbability(target);
             if (DEBUG) {
                 Log.d(TAG, "Scores: " + target);
             }
         }
-    }
-
-    static boolean isPersistentProcess(ResolvedComponentInfo rci) {
-        if (rci != null && rci.getCount() > 0) {
-            return (rci.getResolveInfoAt(0).activityInfo.applicationInfo.flags &
-                    ApplicationInfo.FLAG_PERSISTENT) != 0;
-        }
-        return false;
+        predictSelectProbabilities(mTargets);
     }
 
     @Override
@@ -245,16 +318,16 @@
         // Pinned items stay stable within a normal lexical sort and ignore scoring.
         if (!lPinned && !rPinned) {
             if (mStats != null) {
-                final ScoredTarget lhsTarget = mScoredTargets.get(new ComponentName(
+                final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
                         lhs.activityInfo.packageName, lhs.activityInfo.name));
-                final ScoredTarget rhsTarget = mScoredTargets.get(new ComponentName(
+                final ResolverTarget rhsTarget = mTargetsDict.get(new ComponentName(
                         rhs.activityInfo.packageName, rhs.activityInfo.name));
 
-                final int selectProbDiff = Float.compare(
-                        rhsTarget.selectProb, lhsTarget.selectProb);
+                final int selectProbabilityDiff = Float.compare(
+                        rhsTarget.getSelectProbability(), lhsTarget.getSelectProbability());
 
-                if (selectProbDiff != 0) {
-                    return selectProbDiff > 0 ? 1 : -1;
+                if (selectProbabilityDiff != 0) {
+                    return selectProbabilityDiff > 0 ? 1 : -1;
                 }
             }
         }
@@ -268,177 +341,234 @@
     }
 
     public float getScore(ComponentName name) {
-        final ScoredTarget target = mScoredTargets.get(name);
+        final ResolverTarget target = mTargetsDict.get(name);
         if (target != null) {
-            return target.selectProb;
+            return target.getSelectProbability();
         }
         return 0;
     }
 
-    static class ScoredTarget {
-        public final ComponentInfo componentInfo;
-        public long lastTimeUsed;
-        public long timeSpent;
-        public long launchCount;
-        public long chooserCount;
-        public ArrayMap<String, Float> features;
-        public float selectProb;
-
-        public ScoredTarget(ComponentInfo ci) {
-            componentInfo = ci;
-            features = new ArrayMap<>(5);
-        }
-
-        @Override
-        public String toString() {
-            return "ScoredTarget{" + componentInfo
-                    + " lastTimeUsed: " + lastTimeUsed
-                    + " timeSpent: " + timeSpent
-                    + " launchCount: " + launchCount
-                    + " chooserCount: " + chooserCount
-                    + " selectProb: " + selectProb
-                    + "}";
-        }
-
-        public void setFeatures(float launchCountScore, float usageTimeScore, float recencyScore,
-                                float chooserCountScore) {
-            features.put(LAUNCH_SCORE, launchCountScore);
-            features.put(TIME_SPENT_SCORE, usageTimeScore);
-            features.put(RECENCY_SCORE, recencyScore);
-            features.put(CHOOSER_SCORE, chooserCountScore);
-        }
-
-        public ArrayMap<String, Float> getFeatures() {
-            return features;
-        }
-    }
-
     public void updateChooserCounts(String packageName, int userId, String action) {
         if (mUsm != null) {
             mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
         }
     }
 
+    // update ranking model when the connection to it is valid.
     public void updateModel(ComponentName componentName) {
-        if (mScoredTargets == null || componentName == null ||
-                !mScoredTargets.containsKey(componentName)) {
-            return;
-        }
-        ScoredTarget selected = mScoredTargets.get(componentName);
-        for (ComponentName targetComponent : mScoredTargets.keySet()) {
-            if (targetComponent.equals(componentName)) {
-                continue;
-            }
-            ScoredTarget target = mScoredTargets.get(targetComponent);
-            // A potential point of optimization. Save updates or derive a closed form for the
-            // positive case, to avoid calculating them repeatedly.
-            if (target.selectProb >= selected.selectProb) {
-                mRanker.update(target.getFeatures(), target.selectProb, false);
-                mRanker.update(selected.getFeatures(), selected.selectProb, true);
+        synchronized (mLock) {
+            if (mRanker != null) {
+                try {
+                    int selectedPos = new ArrayList<ComponentName>(mTargetsDict.keySet())
+                            .indexOf(componentName);
+                    if (selectedPos > 0) {
+                        mRanker.train(mTargets, selectedPos);
+                    } else {
+                        if (DEBUG) {
+                            Log.d(TAG, "Selected a unknown component: " + componentName);
+                        }
+                    }
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in Train: " + e);
+                }
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, "Ranker is null; skip updateModel.");
+                }
             }
         }
-        mRanker.commitUpdate();
     }
 
-    class LogisticRegressionAppRanker {
-        private static final String PARAM_SHARED_PREF_NAME = "resolver_ranker_params";
-        private static final String BIAS_PREF_KEY = "bias";
-        private static final String VERSION_PREF_KEY = "version";
-
-        // parameters for a pre-trained model, to initialize the app ranker. When updating the
-        // pre-trained model, please update these params, as well as initModel().
-        private static final int CURRENT_VERSION = 1;
-        private static final float LEARNING_RATE = 0.0001f;
-        private static final float REGULARIZER_PARAM = 0.0001f;
-
-        private SharedPreferences mParamSharedPref;
-        private ArrayMap<String, Float> mFeatureWeights;
-        private float mBias;
-
-        public LogisticRegressionAppRanker(Context context) {
-            mParamSharedPref = getParamSharedPref(context);
-            initModel();
+    // unbind the service and clear unhandled messges.
+    public void destroy() {
+        mHandler.removeMessages(RESOLVER_RANKER_SERVICE_RESULT);
+        mHandler.removeMessages(RESOLVER_RANKER_RESULT_TIMEOUT);
+        if (mConnection != null) {
+            mContext.unbindService(mConnection);
+            mConnection.destroy();
         }
-
-        public float predict(ArrayMap<String, Float> target) {
-            if (target == null) {
-                return 0.0f;
-            }
-            final int featureSize = target.size();
-            float sum = 0.0f;
-            for (int i = 0; i < featureSize; i++) {
-                String featureName = target.keyAt(i);
-                float weight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-                sum += weight * target.valueAt(i);
-            }
-            return (float) (1.0 / (1.0 + Math.exp(-mBias - sum)));
+        if (DEBUG) {
+            Log.d(TAG, "Unbinded Resolver Ranker.");
         }
+    }
 
-        public void update(ArrayMap<String, Float> target, float predict, boolean isSelected) {
-            if (target == null) {
+    // connect to a ranking service.
+    private void initRanker(Context context) {
+        synchronized (mLock) {
+            if (mConnection != null && mRanker != null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Ranker still exists; reusing the existing one.");
+                }
                 return;
             }
-            final int featureSize = target.size();
-            float error = isSelected ? 1.0f - predict : -predict;
-            for (int i = 0; i < featureSize; i++) {
-                String featureName = target.keyAt(i);
-                float currentWeight = mFeatureWeights.getOrDefault(featureName, 0.0f);
-                mBias += LEARNING_RATE * error;
-                currentWeight = currentWeight - LEARNING_RATE * REGULARIZER_PARAM * currentWeight +
-                        LEARNING_RATE * error * target.valueAt(i);
-                mFeatureWeights.put(featureName, currentWeight);
+        }
+        Intent intent = resolveRankerService();
+        if (intent == null) {
+            return;
+        }
+        mConnectSignal = new CountDownLatch(1);
+        mConnection = new ResolverRankerServiceConnection(mConnectSignal);
+        context.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM);
+    }
+
+    // resolve the service for ranking.
+    private Intent resolveRankerService() {
+        Intent intent = new Intent(ResolverRankerService.SERVICE_INTERFACE);
+        final List<ResolveInfo> resolveInfos = mPm.queryIntentServices(intent, 0);
+        for (ResolveInfo resolveInfo : resolveInfos) {
+            if (resolveInfo == null || resolveInfo.serviceInfo == null
+                    || resolveInfo.serviceInfo.applicationInfo == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Failed to retrieve a ranker: " + resolveInfo);
+                }
+                continue;
+            }
+            ComponentName componentName = new ComponentName(
+                    resolveInfo.serviceInfo.applicationInfo.packageName,
+                    resolveInfo.serviceInfo.name);
+            try {
+                final String perm = mPm.getServiceInfo(componentName, 0).permission;
+                if (!ResolverRankerService.BIND_PERMISSION.equals(perm)) {
+                    Log.w(TAG, "ResolverRankerService " + componentName + " does not require"
+                            + " permission " + ResolverRankerService.BIND_PERMISSION
+                            + " - this service will not be queried for ResolverComparator."
+                            + " add android:permission=\""
+                            + ResolverRankerService.BIND_PERMISSION + "\""
+                            + " to the <service> tag for " + componentName
+                            + " in the manifest.");
+                    continue;
+                }
+            } catch (NameNotFoundException e) {
+                Log.e(TAG, "Could not look up service " + componentName
+                        + "; component name not found");
+                continue;
             }
             if (DEBUG) {
-                Log.d(TAG, "Weights: " + mFeatureWeights + " Bias: " + mBias);
+                Log.d(TAG, "Succeeded to retrieve a ranker: " + componentName);
             }
+            intent.setComponent(componentName);
+            return intent;
+        }
+        return null;
+    }
+
+    // set a watchdog, to avoid waiting for ranking service for too long.
+    private void startWatchDog(int timeOutLimit) {
+        if (DEBUG) Log.d(TAG, "Setting watchdog timer for " + timeOutLimit + "ms");
+        if (mHandler == null) {
+            Log.d(TAG, "Error: Handler is Null; Needs to be initialized.");
+        }
+        mHandler.sendEmptyMessageDelayed(RESOLVER_RANKER_RESULT_TIMEOUT, timeOutLimit);
+    }
+
+    private class ResolverRankerServiceConnection implements ServiceConnection {
+        private final CountDownLatch mConnectSignal;
+
+        public ResolverRankerServiceConnection(CountDownLatch connectSignal) {
+            mConnectSignal = connectSignal;
         }
 
-        public void commitUpdate() {
-            SharedPreferences.Editor editor = mParamSharedPref.edit();
-            editor.putFloat(BIAS_PREF_KEY, mBias);
-            final int size = mFeatureWeights.size();
-            for (int i = 0; i < size; i++) {
-                editor.putFloat(mFeatureWeights.keyAt(i), mFeatureWeights.valueAt(i));
+        public final IResolverRankerResult resolverRankerResult =
+                new IResolverRankerResult.Stub() {
+            @Override
+            public void sendResult(List<ResolverTarget> targets) throws RemoteException {
+                if (DEBUG) {
+                    Log.d(TAG, "Sending Result back to Resolver: " + targets);
+                }
+                synchronized (mLock) {
+                    final Message msg = Message.obtain();
+                    msg.what = RESOLVER_RANKER_SERVICE_RESULT;
+                    msg.obj = targets;
+                    mHandler.sendMessage(msg);
+                }
             }
-            editor.putInt(VERSION_PREF_KEY, CURRENT_VERSION);
-            editor.apply();
-        }
+        };
 
-        private SharedPreferences getParamSharedPref(Context context) {
-            // The package info in the context isn't initialized in the way it is for normal apps,
-            // so the standard, name-based context.getSharedPreferences doesn't work. Instead, we
-            // build the path manually below using the same policy that appears in ContextImpl.
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
             if (DEBUG) {
-                Log.d(TAG, "Context Package Name: " + context.getPackageName());
+                Log.d(TAG, "onServiceConnected: " + name);
             }
-            final File prefsFile = new File(new File(
-                    Environment.getDataUserCePackageDirectory(StorageManager.UUID_PRIVATE_INTERNAL,
-                            context.getUserId(), context.getPackageName()),
-                    "shared_prefs"),
-                    PARAM_SHARED_PREF_NAME + ".xml");
-            return context.getSharedPreferences(prefsFile, Context.MODE_PRIVATE);
+            synchronized (mLock) {
+                mRanker = IResolverRankerService.Stub.asInterface(service);
+                mConnectSignal.countDown();
+            }
         }
 
-        private void initModel() {
-            mFeatureWeights = new ArrayMap<>(4);
-            if (mParamSharedPref == null ||
-                    mParamSharedPref.getInt(VERSION_PREF_KEY, 0) < CURRENT_VERSION) {
-                // Initializing the app ranker to a pre-trained model. When updating the pre-trained
-                // model, please increment CURRENT_VERSION, and update LEARNING_RATE and
-                // REGULARIZER_PARAM.
-                mBias = -1.6568f;
-                mFeatureWeights.put(LAUNCH_SCORE, 2.5543f);
-                mFeatureWeights.put(TIME_SPENT_SCORE, 2.8412f);
-                mFeatureWeights.put(RECENCY_SCORE, 0.269f);
-                mFeatureWeights.put(CHOOSER_SCORE, 4.2222f);
-            } else {
-                mBias = mParamSharedPref.getFloat(BIAS_PREF_KEY, 0.0f);
-                mFeatureWeights.put(LAUNCH_SCORE, mParamSharedPref.getFloat(LAUNCH_SCORE, 0.0f));
-                mFeatureWeights.put(
-                        TIME_SPENT_SCORE, mParamSharedPref.getFloat(TIME_SPENT_SCORE, 0.0f));
-                mFeatureWeights.put(RECENCY_SCORE, mParamSharedPref.getFloat(RECENCY_SCORE, 0.0f));
-                mFeatureWeights.put(CHOOSER_SCORE, mParamSharedPref.getFloat(CHOOSER_SCORE, 0.0f));
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            if (DEBUG) {
+                Log.d(TAG, "onServiceDisconnected: " + name);
+            }
+            synchronized (mLock) {
+                destroy();
             }
         }
+
+        public void destroy() {
+            synchronized (mLock) {
+                mRanker = null;
+            }
+        }
+    }
+
+    private void reset() {
+        mTargetsDict.clear();
+        mTargets = null;
+        startWatchDog(WATCHDOG_TIMEOUT_MILLIS);
+        initRanker(mContext);
+    }
+
+    // predict select probabilities if ranking service is valid.
+    private void predictSelectProbabilities(List<ResolverTarget> targets) {
+        if (mConnection == null) {
+            if (DEBUG) {
+                Log.d(TAG, "Has not found valid ResolverRankerService; Skip Prediction");
+            }
+            return;
+        } else {
+            try {
+                mConnectSignal.await(CONNECTION_COST_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
+                synchronized (mLock) {
+                    if (mRanker != null) {
+                        mRanker.predict(targets, mConnection.resolverRankerResult);
+                        return;
+                    } else {
+                        if (DEBUG) {
+                            Log.d(TAG, "Ranker has not been initialized; skip predict.");
+                        }
+                    }
+                }
+            } catch (InterruptedException e) {
+                Log.e(TAG, "Error in Wait for Service Connection.");
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error in Predict: " + e);
+            }
+        }
+        mAfterCompute.afterCompute();
+    }
+
+    // adds select prob as the default values, according to a pre-trained Logistic Regression model.
+    private void addDefaultSelectProbability(ResolverTarget target) {
+        float sum = 2.5543f * target.getLaunchScore() + 2.8412f * target.getTimeSpentScore() +
+                0.269f * target.getRecencyScore() + 4.2222f * target.getChooserScore();
+        target.setSelectProbability((float) (1.0 / (1.0 + Math.exp(1.6568f - sum))));
+    }
+
+    // sets features for each target
+    private void setFeatures(ResolverTarget target, float recencyScore, float launchScore,
+                             float timeSpentScore, float chooserScore) {
+        target.setRecencyScore(recencyScore);
+        target.setLaunchScore(launchScore);
+        target.setTimeSpentScore(timeSpentScore);
+        target.setChooserScore(chooserScore);
+    }
+
+    static boolean isPersistentProcess(ResolvedComponentInfo rci) {
+        if (rci != null && rci.getCount() > 0) {
+            return (rci.getResolveInfoAt(0).activityInfo.applicationInfo.flags &
+                    ApplicationInfo.FLAG_PERSISTENT) != 0;
+        }
+        return false;
     }
 }
diff --git a/core/java/com/android/internal/app/ResolverListController.java b/core/java/com/android/internal/app/ResolverListController.java
index 4071ff4..e8bebb7 100644
--- a/core/java/com/android/internal/app/ResolverListController.java
+++ b/core/java/com/android/internal/app/ResolverListController.java
@@ -32,8 +32,10 @@
 import android.util.Log;
 import com.android.internal.annotations.VisibleForTesting;
 
+import java.lang.InterruptedException;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.concurrent.CountDownLatch;
 import java.util.List;
 
 /**
@@ -205,14 +207,42 @@
         return listToReturn;
     }
 
+    private class ComputeCallback implements ResolverComparator.AfterCompute {
+
+        private CountDownLatch mFinishComputeSignal;
+
+        public ComputeCallback(CountDownLatch finishComputeSignal) {
+            mFinishComputeSignal = finishComputeSignal;
+        }
+
+        public void afterCompute () {
+            mFinishComputeSignal.countDown();
+        }
+    }
+
     @VisibleForTesting
     @WorkerThread
     public void sort(List<ResolverActivity.ResolvedComponentInfo> inputList) {
+        final CountDownLatch finishComputeSignal = new CountDownLatch(1);
+        ComputeCallback callback = new ComputeCallback(finishComputeSignal);
         if (mResolverComparator == null) {
-            mResolverComparator = new ResolverComparator(mContext, mTargetIntent, mReferrerPackage);
+            mResolverComparator =
+                    new ResolverComparator(mContext, mTargetIntent, mReferrerPackage, callback);
+        } else {
+            mResolverComparator.setCallBack(callback);
         }
-        mResolverComparator.compute(inputList);
-        Collections.sort(inputList, mResolverComparator);
+        try {
+            long beforeRank = System.currentTimeMillis();
+            mResolverComparator.compute(inputList);
+            finishComputeSignal.await();
+            Collections.sort(inputList, mResolverComparator);
+            long afterRank = System.currentTimeMillis();
+            if (DEBUG) {
+                Log.d(TAG, "Time Cost: " + Long.toString(afterRank - beforeRank));
+            }
+        } catch (InterruptedException e) {
+            Log.e(TAG, "Compute & Sort was interrupted: " + e);
+        }
     }
 
     private static boolean isSameResolvedComponent(ResolveInfo a,
@@ -233,7 +263,7 @@
     @VisibleForTesting
     public float getScore(ResolverActivity.DisplayResolveInfo target) {
         if (mResolverComparator == null) {
-            mResolverComparator = new ResolverComparator(mContext, mTargetIntent, mReferrerPackage);
+            return 0.0f;
         }
         return mResolverComparator.getScore(target.getResolvedComponentName());
     }
@@ -249,4 +279,10 @@
             mResolverComparator.updateChooserCounts(packageName, userId, action);
         }
     }
+
+    public void destroy() {
+        if (mResolverComparator != null) {
+            mResolverComparator.destroy();
+        }
+    }
 }
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..1a35330 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);
@@ -89,7 +97,7 @@
 
     SkShader* shader = 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, matrix).release();
 
     env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
     ThrowIAE_IfNull(env, shader);
@@ -109,7 +117,7 @@
     colors[1] = color1;
 
     SkShader* s = SkGradientShader::MakeLinear(pts, colors, NULL, 2,
-            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();
+            static_cast<SkShader::TileMode>(tileMode), sGradientShaderFlags, matrix).release();
 
     ThrowIAE_IfNull(env, s);
     return reinterpret_cast<jlong>(s);
@@ -135,7 +143,7 @@
 
     SkShader* shader = 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, matrix).release();
     env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues),
                                  JNI_ABORT);
 
@@ -154,7 +162,7 @@
     colors[1] = color1;
 
     SkShader* s = SkGradientShader::MakeRadial(center, radius, colors, NULL, 2,
-            (SkShader::TileMode)tileMode, /* flags */ 0, matrix).release();
+            static_cast<SkShader::TileMode>(tileMode), sGradientShaderFlags, matrix).release();
     ThrowIAE_IfNull(env, s);
     return reinterpret_cast<jlong>(s);
 }
@@ -174,8 +182,8 @@
     #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();
+    SkShader* shader = SkGradientShader::MakeSweep(x, y, reinterpret_cast<const SkColor*>(colors),
+            pos, count, sGradientShaderFlags, matrix).release();
     env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors),
                                  JNI_ABORT);
     ThrowIAE_IfNull(env, shader);
@@ -189,7 +197,7 @@
     colors[0] = color0;
     colors[1] = color1;
     SkShader* s = SkGradientShader::MakeSweep(x, y, colors, NULL, 2,
-            /* flags */ 0, matrix).release();
+            sGradientShaderFlags, matrix).release();
     ThrowIAE_IfNull(env, s);
     return reinterpret_cast<jlong>(s);
 }
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..a73f543 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" />
@@ -3129,6 +3130,15 @@
     <permission android:name="android.permission.BIND_CHOOSER_TARGET_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- @SystemApi Must be required by services that extend
+         {@link android.service.resolver.ResolverRankerService}, to ensure that only the system can
+         bind to them.
+         <p>Protection level: signature
+         @hide
+    -->
+    <permission android:name="android.permission.BIND_RESOLVER_RANKER_SERVICE"
+        android:protectionLevel="signature" />
+
     <!-- Must be required by a {@link
          android.service.notification.ConditionProviderService},
          to ensure that only the system can bind to it.
@@ -3640,6 +3650,14 @@
                  android:permission="android.permission.BIND_JOB_SERVICE" >
         </service>
 
+        <service android:name="com.android.internal.app.LRResolverRankerService"
+            android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE"
+            android:exported="false"
+            android:priority="-1" >
+            <intent-filter>
+                <action android:name="android.service.resolver.ResolverRankerService" />
+            </intent-filter>
+        </service>
     </application>
 
 </manifest>
diff --git a/core/res/res/layout/notification_template_material_ambient.xml b/core/res/res/layout/notification_template_material_ambient.xml
index e2c68b5..f3aa048 100644
--- a/core/res/res/layout/notification_template_material_ambient.xml
+++ b/core/res/res/layout/notification_template_material_ambient.xml
@@ -20,6 +20,8 @@
     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" />
 
@@ -52,7 +54,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 +65,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/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..b82542a 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>
 
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/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/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/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index 7f06421..8826cfc 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -27,5 +27,7 @@
     libft2 \
     libminikin \
     libandroidfw \
-    libRScpp \
+    libRScpp
+
+LOCAL_STATIC_LIBRARIES += \
     libplatformprotos
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/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/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/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/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 8da17fa..a0f2891 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -167,7 +167,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;
@@ -602,6 +602,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/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..9dc0ceb 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;
@@ -5015,16 +5013,20 @@
                     if (!mHeadsUpManager.getAllEntries().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(true);
                     }
                 }
 
                 @Override
                 public void onPulseFinished() {
                     callback.onPulseFinished();
-                    mStackScroller.setPulsing(false);
-                    mVisualStabilityManager.setPulsing(false);
+                    setPulsing(false);
+                }
+
+                private void setPulsing(boolean pulsing) {
+                    mStackScroller.setPulsing(pulsing);
+                    mNotificationPanel.setPulsing(pulsing);
+                    mVisualStabilityManager.setPulsing(pulsing);
                 }
             }, reason);
         }
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..5bead73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -4060,9 +4060,11 @@
             return;
         }
         mPulsing = pulsing;
+        mAmbientState.setPulsing(pulsing);
         updateNotificationAnimationStates();
         updateContentHeight();
         notifyHeightChangeListener(mShelf);
+        requestChildrenUpdate();
     }
 
     public void setFadingOut(boolean fadingOut) {
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/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..e127eb9 100644
--- a/services/core/java/com/android/server/NetworkScorerAppManager.java
+++ b/services/core/java/com/android/server/NetworkScorerAppManager.java
@@ -42,7 +42,6 @@
  *
  * @hide
  */
-@VisibleForTesting
 public class NetworkScorerAppManager {
     private static final String TAG = "NetworkScorerAppManager";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -64,8 +63,7 @@
      * Returns the list of available scorer apps. The list will be empty if there are
      * no valid scorers.
      */
-    @VisibleForTesting
-    public List<NetworkScorerAppData> getAllValidScorers() {
+    List<NetworkScorerAppData> getAllValidScorers() {
         if (VERBOSE) Log.v(TAG, "getAllValidScorers()");
         final PackageManager pm = mContext.getPackageManager();
         final Intent serviceIntent = new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS);
@@ -170,8 +168,7 @@
      *     it was disabled or uninstalled).
      */
     @Nullable
-    @VisibleForTesting
-    public NetworkScorerAppData getActiveScorer() {
+    NetworkScorerAppData getActiveScorer() {
         final int enabledSetting = getNetworkRecommendationsEnabledSetting();
         if (enabledSetting == NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF) {
             return null;
@@ -214,8 +211,7 @@
      * @return true if the scorer was changed, or false if the package is not a valid scorer or
      *         a valid network recommendation provider exists.
      */
-    @VisibleForTesting
-    public boolean setActiveScorer(String packageName) {
+    boolean setActiveScorer(String packageName) {
         final String oldPackageName = getNetworkRecommendationsPackage();
 
         if (TextUtils.equals(oldPackageName, packageName)) {
@@ -250,8 +246,7 @@
      * is no longer valid then {@link Settings.Global#NETWORK_RECOMMENDATIONS_ENABLED} will be set
      * to <code>0</code> (disabled).
      */
-    @VisibleForTesting
-    public void updateState() {
+    void updateState() {
         final int enabledSetting = getNetworkRecommendationsEnabledSetting();
         if (enabledSetting == NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF) {
             // Don't change anything if it's forced off.
@@ -286,6 +281,56 @@
         }
     }
 
+    /**
+     * Migrates the NETWORK_SCORER_APP Setting to the USE_OPEN_WIFI_PACKAGE Setting.
+     */
+    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/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/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d89b12e..3303081 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -842,11 +842,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 +2717,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 +2816,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,7 +3056,7 @@
                 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 Intent resolverIntent = new Intent(Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE);
         final List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
                 resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
 
@@ -3087,7 +3098,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);
 
@@ -3119,35 +3130,18 @@
         }
     }
 
-    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;
-                }
-            }
-            iter.remove();
-        }
-        if (matches.size() == 0) {
+    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;
+        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
+                UserHandle.USER_SYSTEM);
+        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) {
@@ -16965,6 +16959,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 +17016,7 @@
                         args.user, installerPackageName, volumeUuid, res, args.installReason);
             }
         }
+
         synchronized (mPackages) {
             final PackageSetting ps = mSettings.mPackages.get(pkgName);
             if (ps != null) {
@@ -17639,6 +17643,7 @@
         int removedAppId = -1;
         int[] origUsers;
         int[] removedUsers = null;
+        int[] broadcastUsers = null;
         SparseArray<Integer> installReasons;
         boolean isRemovedPackageSystemUpdate = false;
         boolean isUpdate;
@@ -17712,16 +17717,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 +17755,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 +20877,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 +20947,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/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/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
index 54ecab3..af3201c 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java
@@ -33,7 +33,8 @@
  *  bit FrameworksServicesTests:com.android.server.am.ActivityRecordTests
  */
 @MediumTest
-@Presubmit
+// TODO(b/36916522): Currently failing in CI.
+// @Presubmit
 @RunWith(AndroidJUnit4.class)
 public class ActivityRecordTests extends ActivityTestsBase {
     private final ComponentName testActivityComponent =
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/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;
   }