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>
+ * <service android:name=".MyResolverRankerService"
+ * android:exported="true"
+ * android:priority="100"
+ * android:permission="android.permission.BIND_RESOLVER_RANKER_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.service.resolver.ResolverRankerService" />
+ * </intent-filter>
+ * </service>
+ * </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;
}