summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp8
-rw-r--r--api/current.txt31
-rw-r--r--api/system-current.txt48
-rw-r--r--api/test-current.txt27
-rw-r--r--cmds/statsd/src/atoms.proto154
-rw-r--r--cmds/statsd/src/external/StatsPullerManager.cpp3
-rw-r--r--core/java/android/app/ActivityThread.java7
-rw-r--r--core/java/android/app/ContextImpl.java41
-rw-r--r--core/java/android/app/NotificationManager.java1
-rw-r--r--core/java/android/content/pm/ILauncherApps.aidl10
-rw-r--r--core/java/android/content/pm/LauncherApps.java90
-rw-r--r--core/java/android/content/pm/PackageInstaller.java70
-rw-r--r--core/java/android/net/ConnectivityManager.java28
-rw-r--r--core/java/android/os/OWNERS2
-rw-r--r--core/java/android/provider/DeviceConfig.java23
-rw-r--r--core/java/android/provider/MediaStore.java54
-rw-r--r--core/java/android/provider/Settings.java55
-rw-r--r--core/java/android/service/attention/AttentionService.java4
-rw-r--r--core/java/android/service/dreams/OWNERS2
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java32
-rw-r--r--core/java/android/util/FeatureFlagUtils.java1
-rw-r--r--core/java/android/view/textclassifier/ExtrasUtils.java127
-rw-r--r--core/java/android/view/textclassifier/TextClassification.java37
-rw-r--r--core/java/android/view/textclassifier/TextClassificationSession.java21
-rw-r--r--core/java/android/view/textclassifier/TextClassifier.java7
-rw-r--r--core/java/android/view/textclassifier/TextClassifierEvent.java36
-rw-r--r--core/java/android/view/textclassifier/TextClassifierEventTronLogger.java19
-rw-r--r--core/java/android/view/textclassifier/TextClassifierImpl.java49
-rw-r--r--core/java/android/widget/Editor.java7
-rw-r--r--core/java/android/widget/SelectionActionModeHelper.java118
-rw-r--r--core/java/android/widget/TextView.java21
-rw-r--r--core/java/com/android/internal/os/OWNERS1
-rw-r--r--core/jni/OWNERS3
-rw-r--r--core/jni/android_media_AudioAttributes.cpp2
-rw-r--r--core/jni/android_media_AudioAttributes.h6
-rw-r--r--core/jni/android_os_VintfObject.cpp15
-rw-r--r--core/res/res/values/dimens.xml2
-rw-r--r--core/res/res/values/styles_device_defaults.xml4
-rw-r--r--core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java18
-rw-r--r--data/etc/privapp-permissions-platform.xml1
-rw-r--r--graphics/java/android/graphics/Bitmap.java7
-rw-r--r--graphics/java/android/graphics/Paint.java12
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp4
-rw-r--r--location/java/android/location/LocationManager.java108
-rw-r--r--location/java/android/location/LocationRequest.java5
-rw-r--r--media/Android.bp69
-rw-r--r--media/apex/java/android/media/MediaPlayer2.java40
-rw-r--r--media/java/android/media/MediaCodec.java2
-rw-r--r--media/java/android/media/MediaDescription.aidl (renamed from media/apex/java/android/media/MediaDescription.aidl)0
-rw-r--r--media/java/android/media/MediaDescription.java (renamed from media/apex/java/android/media/MediaDescription.java)0
-rw-r--r--media/java/android/media/MediaParceledListSlice.aidl (renamed from media/apex/java/android/media/MediaParceledListSlice.aidl)0
-rw-r--r--media/java/android/media/MediaParceledListSlice.java (renamed from media/apex/java/android/media/MediaParceledListSlice.java)0
-rw-r--r--media/java/android/media/Rating.aidl (renamed from media/apex/java/android/media/Rating.aidl)0
-rw-r--r--media/java/android/media/Rating.java (renamed from media/apex/java/android/media/Rating.java)0
-rw-r--r--media/java/android/media/VolumeProvider.java (renamed from media/apex/java/android/media/VolumeProvider.java)0
-rw-r--r--media/java/android/media/browse/MediaBrowser.aidl (renamed from media/apex/java/android/media/browse/MediaBrowser.aidl)0
-rw-r--r--media/java/android/media/browse/MediaBrowser.java (renamed from media/apex/java/android/media/browse/MediaBrowser.java)0
-rw-r--r--media/java/android/media/browse/MediaBrowserUtils.java (renamed from media/apex/java/android/media/browse/MediaBrowserUtils.java)0
-rw-r--r--media/java/android/media/session/ControllerCallbackLink.aidl (renamed from media/apex/java/android/media/session/ControllerCallbackLink.aidl)0
-rw-r--r--media/java/android/media/session/ControllerCallbackLink.java (renamed from media/apex/java/android/media/session/ControllerCallbackLink.java)0
-rw-r--r--media/java/android/media/session/ControllerLink.aidl (renamed from media/apex/java/android/media/session/ControllerLink.aidl)0
-rw-r--r--media/java/android/media/session/ControllerLink.java (renamed from media/apex/java/android/media/session/ControllerLink.java)0
-rw-r--r--media/java/android/media/session/ISession.aidl (renamed from media/apex/java/android/media/session/ISession.aidl)0
-rw-r--r--media/java/android/media/session/ISessionCallback.aidl (renamed from media/apex/java/android/media/session/ISessionCallback.aidl)0
-rw-r--r--media/java/android/media/session/ISessionController.aidl (renamed from media/apex/java/android/media/session/ISessionController.aidl)0
-rw-r--r--media/java/android/media/session/ISessionControllerCallback.aidl (renamed from media/apex/java/android/media/session/ISessionControllerCallback.aidl)0
-rw-r--r--media/java/android/media/session/MediaController.aidl (renamed from media/apex/java/android/media/session/MediaController.aidl)0
-rw-r--r--media/java/android/media/session/MediaController.java (renamed from media/apex/java/android/media/session/MediaController.java)0
-rw-r--r--media/java/android/media/session/MediaSession.java5
-rw-r--r--media/java/android/media/session/MediaSessionEngine.java (renamed from media/apex/java/android/media/session/MediaSessionEngine.java)311
-rw-r--r--media/java/android/media/session/MediaSessionProviderService.java (renamed from media/apex/java/android/media/session/MediaSessionProviderService.java)0
-rw-r--r--media/java/android/media/session/PlaybackState.aidl (renamed from media/apex/java/android/media/session/PlaybackState.aidl)0
-rw-r--r--media/java/android/media/session/PlaybackState.java (renamed from media/apex/java/android/media/session/PlaybackState.java)0
-rw-r--r--media/java/android/media/session/SessionCallbackLink.aidl (renamed from media/apex/java/android/media/session/SessionCallbackLink.aidl)0
-rw-r--r--media/java/android/media/session/SessionCallbackLink.java (renamed from media/apex/java/android/media/session/SessionCallbackLink.java)283
-rw-r--r--media/java/android/media/session/SessionLink.aidl (renamed from media/apex/java/android/media/session/SessionLink.aidl)0
-rw-r--r--media/java/android/media/session/SessionLink.java (renamed from media/apex/java/android/media/session/SessionLink.java)0
-rw-r--r--media/java/android/service/media/IMediaBrowserService.aidl (renamed from media/apex/java/android/service/media/IMediaBrowserService.aidl)0
-rw-r--r--media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl (renamed from media/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl)0
-rw-r--r--media/java/android/service/media/MediaBrowserService.java (renamed from media/apex/java/android/service/media/MediaBrowserService.java)0
-rw-r--r--native/webview/plat_support/draw_functor.cpp3
-rw-r--r--packages/CarSystemUI/res/values/integers_car.xml2
-rw-r--r--packages/SettingsLib/OWNERS2
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java2
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/OWNERS2
-rw-r--r--packages/SystemUI/res-keyguard/values/strings.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java100
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java30
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java145
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java4
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java29
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java25
-rw-r--r--services/core/java/com/android/server/ThreadPriorityBooster.java18
-rw-r--r--services/core/java/com/android/server/am/AppCompactor.java54
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java2
-rw-r--r--services/core/java/com/android/server/attention/AttentionManagerService.java8
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceBroker.java2
-rw-r--r--services/core/java/com/android/server/audio/AudioDeviceInventory.java8
-rw-r--r--services/core/java/com/android/server/audio/AudioService.java4
-rw-r--r--services/core/java/com/android/server/audio/RecordingActivityMonitor.java44
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java3
-rw-r--r--services/core/java/com/android/server/dreams/OWNERS2
-rw-r--r--services/core/java/com/android/server/incident/IncidentCompanionService.java403
-rw-r--r--services/core/java/com/android/server/incident/PendingReports.java477
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java93
-rw-r--r--services/core/java/com/android/server/pm/OWNERS2
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java20
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java1
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java18
-rw-r--r--services/core/java/com/android/server/power/AttentionDetector.java19
-rw-r--r--services/core/java/com/android/server/role/RoleManagerService.java29
-rw-r--r--services/core/java/com/android/server/role/RoleManagerServiceInternal.java38
-rw-r--r--services/core/java/com/android/server/role/RoleUserState.java31
-rw-r--r--services/core/java/com/android/server/stats/StatsCompanionService.java61
-rw-r--r--services/core/jni/com_android_server_security_VerityUtils.cpp90
-rw-r--r--services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java84
-rw-r--r--startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java4
-rw-r--r--telephony/java/android/telephony/NetworkService.java5
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java10
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java50
-rw-r--r--telephony/java/android/telephony/data/DataService.java18
-rwxr-xr-xtelephony/java/com/android/internal/telephony/ISub.aidl2
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephony.aidl10
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyProperties.java7
127 files changed, 2362 insertions, 1651 deletions
diff --git a/Android.bp b/Android.bp
index e19ca8465548..9b62b7af4558 100644
--- a/Android.bp
+++ b/Android.bp
@@ -49,8 +49,6 @@ java_defaults {
"rs/java/**/*.java",
":framework-javastream-protos",
- // TODO: Resolve circular library dependency and remove media1-srcs
- ":media1-srcs",
"core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl",
"core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl",
@@ -505,7 +503,11 @@ java_defaults {
"media/java/android/media/session/ICallback.aidl",
"media/java/android/media/session/IOnMediaKeyListener.aidl",
"media/java/android/media/session/IOnVolumeKeyLongPressListener.aidl",
+ "media/java/android/media/session/ISession.aidl",
"media/java/android/media/session/ISession2TokensListener.aidl",
+ "media/java/android/media/session/ISessionCallback.aidl",
+ "media/java/android/media/session/ISessionController.aidl",
+ "media/java/android/media/session/ISessionControllerCallback.aidl",
"media/java/android/media/session/ISessionManager.aidl",
"media/java/android/media/soundtrigger/ISoundTriggerDetectionService.aidl",
"media/java/android/media/soundtrigger/ISoundTriggerDetectionServiceClient.aidl",
@@ -520,6 +522,8 @@ java_defaults {
"media/java/android/media/tv/ITvInputSessionCallback.aidl",
"media/java/android/media/tv/ITvRemoteProvider.aidl",
"media/java/android/media/tv/ITvRemoteServiceInput.aidl",
+ "media/java/android/service/media/IMediaBrowserService.aidl",
+ "media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl",
"telecomm/java/com/android/internal/telecom/ICallRedirectionAdapter.aidl",
"telecomm/java/com/android/internal/telecom/ICallRedirectionService.aidl",
"telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl",
diff --git a/api/current.txt b/api/current.txt
index 3b6cfe3a3cee..4a1fccf0b5ae 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11233,6 +11233,7 @@ package android.content.pm {
public class LauncherApps {
method public java.util.List<android.content.pm.LauncherActivityInfo> getActivityList(String, android.os.UserHandle);
+ method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllPackageInstallerSessions();
method @Nullable public android.content.pm.LauncherApps.AppUsageLimit getAppUsageLimit(String, android.os.UserHandle);
method public android.content.pm.ApplicationInfo getApplicationInfo(@NonNull String, int, @NonNull android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method public android.content.pm.LauncherApps.PinItemRequest getPinItemRequest(android.content.Intent);
@@ -11249,13 +11250,16 @@ package android.content.pm {
method public void pinShortcuts(@NonNull String, @NonNull java.util.List<java.lang.String>, @NonNull android.os.UserHandle);
method public void registerCallback(android.content.pm.LauncherApps.Callback);
method public void registerCallback(android.content.pm.LauncherApps.Callback, android.os.Handler);
+ method public void registerPackageInstallerSessionCallback(@NonNull java.util.concurrent.Executor, @NonNull android.content.pm.PackageInstaller.SessionCallback);
method public android.content.pm.LauncherActivityInfo resolveActivity(android.content.Intent, android.os.UserHandle);
method public boolean shouldHideFromSuggestions(@NonNull String, @NonNull android.os.UserHandle);
method public void startAppDetailsActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
method public void startMainActivity(android.content.ComponentName, android.os.UserHandle, android.graphics.Rect, android.os.Bundle);
+ method public void startPackageInstallerSessionDetailsActivity(android.content.pm.PackageInstaller.SessionInfo, android.graphics.Rect, android.os.Bundle);
method public void startShortcut(@NonNull String, @NonNull String, @Nullable android.graphics.Rect, @Nullable android.os.Bundle, @NonNull android.os.UserHandle);
method public void startShortcut(@NonNull android.content.pm.ShortcutInfo, @Nullable android.graphics.Rect, @Nullable android.os.Bundle);
method public void unregisterCallback(android.content.pm.LauncherApps.Callback);
+ method public void unregisterPackageInstallerSessionCallback(android.content.pm.PackageInstaller.SessionCallback);
field public static final String ACTION_CONFIRM_PIN_APPWIDGET = "android.content.pm.action.CONFIRM_PIN_APPWIDGET";
field public static final String ACTION_CONFIRM_PIN_SHORTCUT = "android.content.pm.action.CONFIRM_PIN_SHORTCUT";
field public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST";
@@ -11445,6 +11449,7 @@ package android.content.pm {
method public long getSize();
method public int getStagedSessionErrorCode();
method public String getStagedSessionErrorMessage();
+ method public android.os.UserHandle getUser();
method public boolean isActive();
method public boolean isMultiPackage();
method public boolean isSealed();
@@ -13552,10 +13557,12 @@ package android.graphics {
method public static android.graphics.Bitmap createScaledBitmap(@NonNull android.graphics.Bitmap, int, int, boolean);
method public int describeContents();
method public void eraseColor(@ColorInt int);
+ method public void eraseColor(@ColorLong long);
method @CheckResult public android.graphics.Bitmap extractAlpha();
method @CheckResult public android.graphics.Bitmap extractAlpha(android.graphics.Paint, int[]);
method public int getAllocationByteCount();
method public int getByteCount();
+ method public android.graphics.Color getColor(int, int);
method @Nullable public android.graphics.ColorSpace getColorSpace();
method public android.graphics.Bitmap.Config getConfig();
method public int getDensity();
@@ -13581,6 +13588,7 @@ package android.graphics {
method public void reconfigure(int, int, android.graphics.Bitmap.Config);
method public void recycle();
method public boolean sameAs(android.graphics.Bitmap);
+ method public void setColorSpace(@NonNull android.graphics.ColorSpace);
method public void setConfig(android.graphics.Bitmap.Config);
method public void setDensity(int);
method public void setHasAlpha(boolean);
@@ -14382,6 +14390,7 @@ package android.graphics {
method @Nullable public android.graphics.BlendMode getBlendMode();
method @ColorInt public int getColor();
method public android.graphics.ColorFilter getColorFilter();
+ method @ColorLong public long getColorLong();
method public boolean getFillPath(android.graphics.Path, android.graphics.Path);
method public int getFlags();
method public String getFontFeatureSettings();
@@ -14402,6 +14411,7 @@ package android.graphics {
method public float getRunAdvance(CharSequence, int, int, int, int, boolean, int);
method public android.graphics.Shader getShader();
method @ColorInt public int getShadowLayerColor();
+ method @ColorLong public long getShadowLayerColorLong();
method public float getShadowLayerDx();
method public float getShadowLayerDy();
method public float getShadowLayerRadius();
@@ -14456,6 +14466,7 @@ package android.graphics {
method public void setAntiAlias(boolean);
method public void setBlendMode(@Nullable android.graphics.BlendMode);
method public void setColor(@ColorInt int);
+ method public void setColor(@ColorLong long);
method public android.graphics.ColorFilter setColorFilter(android.graphics.ColorFilter);
method public void setDither(boolean);
method public void setElegantTextHeight(boolean);
@@ -14472,6 +14483,7 @@ package android.graphics {
method public android.graphics.PathEffect setPathEffect(android.graphics.PathEffect);
method public android.graphics.Shader setShader(android.graphics.Shader);
method public void setShadowLayer(float, float, float, @ColorInt int);
+ method public void setShadowLayer(float, float, float, @ColorLong long);
method public void setStrikeThruText(boolean);
method public void setStrokeCap(android.graphics.Paint.Cap);
method public void setStrokeJoin(android.graphics.Paint.Join);
@@ -25575,6 +25587,14 @@ package android.media {
field public static final int PLAYER_STATE_PAUSED = 1003; // 0x3eb
field public static final int PLAYER_STATE_PLAYING = 1004; // 0x3ec
field public static final int PLAYER_STATE_PREPARED = 1002; // 0x3ea
+ field public static final int PREPARE_DRM_STATUS_KEY_EXCHANGE_ERROR = 7; // 0x7
+ field public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3; // 0x3
+ field public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1; // 0x1
+ field public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2; // 0x2
+ field public static final int PREPARE_DRM_STATUS_RESOURCE_BUSY = 5; // 0x5
+ field public static final int PREPARE_DRM_STATUS_RESTORE_ERROR = 6; // 0x6
+ field public static final int PREPARE_DRM_STATUS_SUCCESS = 0; // 0x0
+ field public static final int PREPARE_DRM_STATUS_UNSUPPORTED_SCHEME = 4; // 0x4
field public static final int SEEK_CLOSEST = 3; // 0x3
field public static final int SEEK_CLOSEST_SYNC = 2; // 0x2
field public static final int SEEK_NEXT_SYNC = 1; // 0x1
@@ -38490,13 +38510,13 @@ package android.provider {
field public static final String BUCKET_ID = "bucket_id";
field public static final String DATE_TAKEN = "datetaken";
field public static final String DESCRIPTION = "description";
+ field public static final String GROUP_ID = "group_id";
field public static final String IS_PRIVATE = "isprivate";
field @Deprecated public static final String LATITUDE = "latitude";
field @Deprecated public static final String LONGITUDE = "longitude";
field @Deprecated public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
field public static final String ORIENTATION = "orientation";
field @Deprecated public static final String PICASA_ID = "picasa_id";
- field public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id";
}
public static final class MediaStore.Images.Media implements android.provider.MediaStore.Images.ImageColumns {
@@ -38550,6 +38570,8 @@ package android.provider {
field public static final String IS_TRASHED = "is_trashed";
field public static final String MIME_TYPE = "mime_type";
field public static final String OWNER_PACKAGE_NAME = "owner_package_name";
+ field public static final String PRIMARY_DIRECTORY = "primary_directory";
+ field public static final String SECONDARY_DIRECTORY = "secondary_directory";
field public static final String SIZE = "_size";
field public static final String TITLE = "title";
field public static final String WIDTH = "width";
@@ -38617,13 +38639,13 @@ package android.provider {
field public static final String DATE_TAKEN = "datetaken";
field public static final String DESCRIPTION = "description";
field public static final String DURATION = "duration";
+ field public static final String GROUP_ID = "group_id";
field public static final String IS_PRIVATE = "isprivate";
field public static final String LANGUAGE = "language";
field @Deprecated public static final String LATITUDE = "latitude";
field @Deprecated public static final String LONGITUDE = "longitude";
field @Deprecated public static final String MINI_THUMB_MAGIC = "mini_thumb_magic";
field public static final String RESOLUTION = "resolution";
- field public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id";
field public static final String TAGS = "tags";
}
@@ -38847,6 +38869,7 @@ package android.provider {
field @Deprecated public static final int LOCATION_MODE_BATTERY_SAVING = 2; // 0x2
field @Deprecated public static final int LOCATION_MODE_HIGH_ACCURACY = 3; // 0x3
field @Deprecated public static final int LOCATION_MODE_OFF = 0; // 0x0
+ field @Deprecated public static final int LOCATION_MODE_ON = 3; // 0x3
field @Deprecated public static final int LOCATION_MODE_SENSORS_ONLY = 1; // 0x1
field @Deprecated public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
field @Deprecated public static final String LOCK_PATTERN_ENABLED = "lock_pattern_autolock";
@@ -41871,10 +41894,6 @@ package android.service.voice {
method public void showSession(android.os.Bundle, int);
field public static final String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
field public static final String SERVICE_META_DATA = "android.voice_interaction";
- field public static final int VOICE_STATE_CONDITIONAL_LISTENING = 1; // 0x1
- field public static final int VOICE_STATE_FULFILLING = 3; // 0x3
- field public static final int VOICE_STATE_LISTENING = 2; // 0x2
- field public static final int VOICE_STATE_NONE = 0; // 0x0
}
public class VoiceInteractionSession implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback {
diff --git a/api/system-current.txt b/api/system-current.txt
index d061d01ac9b4..75f54f9b2301 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3675,7 +3675,7 @@ package android.media.session {
}
public final class MediaSessionEngine implements java.lang.AutoCloseable {
- ctor public MediaSessionEngine(@NonNull android.content.Context, @NonNull android.media.session.SessionLink, @NonNull android.media.session.SessionCallbackLink, @NonNull android.media.session.MediaSessionEngine.CallbackStub);
+ ctor public MediaSessionEngine(@NonNull android.content.Context, @NonNull android.media.session.SessionLink, @NonNull android.media.session.SessionCallbackLink);
method public void close();
method public String getCallingPackage();
method @NonNull public android.media.session.MediaController getController();
@@ -3700,33 +3700,6 @@ package android.media.session {
method public void setSessionActivity(@Nullable android.app.PendingIntent);
}
- public static final class MediaSessionEngine.CallbackStub {
- ctor public MediaSessionEngine.CallbackStub();
- method public void onAdjustVolume(String, int, int, android.media.session.ControllerCallbackLink, int);
- method public void onCommand(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle, android.os.ResultReceiver);
- method public void onCustomAction(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
- method public void onFastForward(String, int, int, android.media.session.ControllerCallbackLink);
- method public void onMediaButton(String, int, int, android.content.Intent, int, android.os.ResultReceiver);
- method public void onMediaButtonFromController(String, int, int, android.media.session.ControllerCallbackLink, android.content.Intent);
- method public void onNext(String, int, int, android.media.session.ControllerCallbackLink);
- method public void onPause(String, int, int, android.media.session.ControllerCallbackLink);
- method public void onPlay(String, int, int, android.media.session.ControllerCallbackLink);
- method public void onPlayFromMediaId(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
- method public void onPlayFromSearch(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
- method public void onPlayFromUri(String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle);
- method public void onPrepare(String, int, int, android.media.session.ControllerCallbackLink);
- method public void onPrepareFromMediaId(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
- method public void onPrepareFromSearch(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
- method public void onPrepareFromUri(String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle);
- method public void onPrevious(String, int, int, android.media.session.ControllerCallbackLink);
- method public void onRate(String, int, int, android.media.session.ControllerCallbackLink, android.media.Rating);
- method public void onRewind(String, int, int, android.media.session.ControllerCallbackLink);
- method public void onSeekTo(String, int, int, android.media.session.ControllerCallbackLink, long);
- method public void onSetVolumeTo(String, int, int, android.media.session.ControllerCallbackLink, int);
- method public void onSkipToTrack(String, int, int, android.media.session.ControllerCallbackLink, long);
- method public void onStop(String, int, int, android.media.session.ControllerCallbackLink);
- }
-
public static interface MediaSessionEngine.MediaButtonEventDelegate {
method public boolean onMediaButtonIntent(android.content.Intent);
}
@@ -5844,6 +5817,7 @@ package android.provider {
public static interface DeviceConfig.ActivityManager {
field public static final String KEY_COMPACT_ACTION_1 = "compact_action_1";
field public static final String KEY_COMPACT_ACTION_2 = "compact_action_2";
+ field public static final String KEY_COMPACT_STATSD_SAMPLE_RATE = "compact_statsd_sample_rate";
field public static final String KEY_COMPACT_THROTTLE_1 = "compact_throttle_1";
field public static final String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2";
field public static final String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3";
@@ -5859,9 +5833,9 @@ package android.provider {
}
public static interface DeviceConfig.AttentionManagerService {
+ field public static final String COMPONENT_NAME = "component_name";
field public static final String NAMESPACE = "attention_manager_service";
- field public static final String PROPERTY_COMPONENT_NAME = "component_name";
- field public static final String PROPERTY_SERVICE_ENABLED = "service_enabled";
+ field public static final String SERVICE_ENABLED = "service_enabled";
}
public static interface DeviceConfig.ContentCapture {
@@ -5875,9 +5849,9 @@ package android.provider {
}
public static interface DeviceConfig.IntelligenceAttention {
+ field public static final String ATTENTION_ENABLED = "attention_enabled";
+ field public static final String ATTENTION_SETTINGS = "attention_settings";
field public static final String NAMESPACE = "intelligence_attention";
- field public static final String PROPERTY_ATTENTION_ENABLED = "attention_enabled";
- field public static final String PROPERTY_ATTENTION_SETTINGS = "attention_settings";
}
public static interface DeviceConfig.NotificationAssistant {
@@ -5892,8 +5866,8 @@ package android.provider {
public static interface DeviceConfig.Privacy {
field public static final String NAMESPACE = "privacy";
- field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "enable_location_access_check";
- field public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "enable_permissions_hub";
+ field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
+ field public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
}
public static interface DeviceConfig.RuntimeNative {
@@ -5907,8 +5881,9 @@ package android.provider {
public static interface DeviceConfig.Telephony {
field public static final String NAMESPACE = "telephony";
- field public static final String PROPERTY_ENABLE_RAMPING_RINGER = "enable_ramping_ringer";
- field public static final String PROPERTY_RAMPING_RINGER_DURATION = "ramping_duration";
+ field public static final String RAMPING_RINGER_DURATION = "ramping_ringer_duration";
+ field public static final String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
+ field public static final String RAMPING_RINGER_VIBRATION_DURATION = "ramping_ringer_vibration_duration";
}
public final class DocumentsContract {
@@ -7931,6 +7906,7 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getEmergencyCallbackMode();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimDomain();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getIsimIst();
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.util.Pair<java.lang.Integer,java.lang.Integer>> getLogicalToPhysicalSlotMapping();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public long getPreferredNetworkTypeBitmap();
method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public int getRadioPowerState();
method public int getSimApplicationState();
diff --git a/api/test-current.txt b/api/test-current.txt
index 76261ddfc191..2f4d45594d89 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -242,6 +242,7 @@ package android.app {
public class NotificationManager {
method public android.content.ComponentName getEffectsSuppressor();
+ method public boolean matchesCallFilter(android.os.Bundle);
}
public final class PictureInPictureParams implements android.os.Parcelable {
@@ -603,23 +604,10 @@ package android.database.sqlite {
package android.graphics {
- public final class Bitmap implements android.os.Parcelable {
- method public void eraseColor(@ColorLong long);
- method public android.graphics.Color getColor(int, int);
- method public void setColorSpace(@NonNull android.graphics.ColorSpace);
- }
-
public final class ImageDecoder implements java.lang.AutoCloseable {
method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(android.content.res.Resources, java.io.InputStream, int);
}
- public class Paint {
- method @ColorLong public long getColorLong();
- method @ColorLong public long getShadowLayerColorLong();
- method public void setColor(@ColorLong long);
- method public void setShadowLayer(float, float, float, @ColorLong long);
- }
-
}
package android.graphics.drawable {
@@ -839,6 +827,17 @@ package android.media {
method public android.media.BufferingParams.Builder setResumePlaybackMarkMs(int);
}
+ public class MediaPlayer2 implements android.media.AudioRouting java.lang.AutoCloseable {
+ method public android.media.MediaPlayer2.DrmInfo getDrmInfo(@NonNull android.media.DataSourceDesc);
+ method public android.media.MediaDrm.KeyRequest getDrmKeyRequest(@NonNull android.media.DataSourceDesc, @Nullable byte[], @Nullable byte[], @Nullable String, int, @Nullable java.util.Map<java.lang.String,java.lang.String>) throws android.media.MediaPlayer2.NoDrmSchemeException;
+ method public String getDrmPropertyString(@NonNull android.media.DataSourceDesc, @NonNull String) throws android.media.MediaPlayer2.NoDrmSchemeException;
+ method public Object prepareDrm(@NonNull android.media.DataSourceDesc, @NonNull java.util.UUID);
+ method public byte[] provideDrmKeyResponse(@NonNull android.media.DataSourceDesc, @Nullable byte[], @NonNull byte[]) throws android.media.DeniedByServerException, android.media.MediaPlayer2.NoDrmSchemeException;
+ method public void releaseDrm(@NonNull android.media.DataSourceDesc) throws android.media.MediaPlayer2.NoDrmSchemeException;
+ method public void restoreDrmKeys(@NonNull android.media.DataSourceDesc, @NonNull byte[]) throws android.media.MediaPlayer2.NoDrmSchemeException;
+ method public void setDrmPropertyString(@NonNull android.media.DataSourceDesc, @NonNull String, @NonNull String) throws android.media.MediaPlayer2.NoDrmSchemeException;
+ }
+
public final class PlaybackParams implements android.os.Parcelable {
method public int getAudioStretchMode();
method public android.media.PlaybackParams setAudioStretchMode(int);
@@ -1745,7 +1744,7 @@ package android.provider {
public static interface DeviceConfig.Privacy {
field public static final String NAMESPACE = "privacy";
- field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "enable_location_access_check";
+ field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
}
public final class MediaStore {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 30df850fd3b3..427662aa9eaa 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -234,6 +234,7 @@ message Atom {
BluetoothBondStateChanged bluetooth_bond_state_changed = 165;
BluetoothClassicPairingEventReported bluetooth_classic_pairing_event_reported = 166;
BluetoothSmpPairingEventReported bluetooth_smp_pairing_event_reported = 167;
+ ScreenTimeoutExtensionReported screen_timeout_extension_reported = 168;
}
// Pulled events will start at field 10000.
@@ -288,6 +289,7 @@ message Atom {
DebugElapsedClock debug_elapsed_clock = 10046;
DebugFailingElapsedClock debug_failing_elapsed_clock = 10047;
NumBiometricsEnrolled num_faces_enrolled = 10048;
+ RoleHolder role_holder = 10049;
}
// DO NOT USE field numbers above 100,000 in AOSP.
@@ -3973,6 +3975,20 @@ message NumBiometricsEnrolled {
optional int32 num_enrolled = 2;
}
+/**
+ * A mapping of role holder -> role
+ */
+message RoleHolder {
+ // uid of the role holder
+ optional int32 uid = 1 [(is_uid) = true];
+
+ // package name of the role holder
+ optional string package_name = 2;
+
+ // the role held
+ optional string role = 3;
+}
+
message AggStats {
optional int64 min = 1;
@@ -4968,17 +4984,17 @@ message GnssConfigurationReported {
* packages/apps/Nfc/src/com/android/nfc/cardemulation/AidRoutingManager.java
*/
message NfcErrorOccurred {
- enum Type {
- UNKNOWN = 0;
- CMD_TIMEOUT = 1;
- ERROR_NOTIFICATION = 2;
- AID_OVERFLOW = 3;
- }
- optional Type type = 1;
- // If it's nci cmd timeout, log the timeout command.
- optional uint32 nci_cmd = 2;
+ enum Type {
+ UNKNOWN = 0;
+ CMD_TIMEOUT = 1;
+ ERROR_NOTIFICATION = 2;
+ AID_OVERFLOW = 3;
+ }
+ optional Type type = 1;
+ // If it's nci cmd timeout, log the timeout command.
+ optional uint32 nci_cmd = 2;
- optional uint32 error_ntf_status_code = 3;
+ optional uint32 error_ntf_status_code = 3;
}
/**
@@ -4987,14 +5003,14 @@ message NfcErrorOccurred {
* packages/apps/Nfc/src/com/android/nfc/NfcService.java
*/
message NfcStateChanged {
- enum State {
- UNKNOWN = 0;
- OFF = 1;
- ON = 2;
- ON_LOCKED = 3; // Secure Nfc enabled.
- CRASH_RESTART = 4; // NfcService watchdog timeout restart.
- }
- optional State state = 1;
+ enum State {
+ UNKNOWN = 0;
+ OFF = 1;
+ ON = 2;
+ ON_LOCKED = 3; // Secure Nfc enabled.
+ CRASH_RESTART = 4; // NfcService watchdog timeout restart.
+ }
+ optional State state = 1;
}
/**
@@ -5003,12 +5019,12 @@ message NfcStateChanged {
* packages/apps/Nfc/src/com/android/nfc/P2pLinkManager.java
*/
message NfcBeamOccurred {
- enum Operation {
- UNKNOWN = 0;
- SEND = 1;
- RECEIVE = 2;
- }
- optional Operation operation = 1;
+ enum Operation {
+ UNKNOWN = 0;
+ SEND = 1;
+ RECEIVE = 2;
+ }
+ optional Operation operation = 1;
}
/**
@@ -5018,16 +5034,16 @@ message NfcBeamOccurred {
* packages/apps/Nfc/src/com/android/nfc/cardemulation/HostNfcFEmulationManager.java
*/
message NfcCardemulationOccurred {
- enum Category {
- UNKNOWN = 0;
- HCE_PAYMENT = 1;
- HCE_OTHER = 2;
- OFFHOST = 3;
- }
- // Transaction belongs to HCE payment or HCE other category, or offhost.
- optional Category category = 1;
- // SeName from transaction: SIMx, eSEx, HCE, HCEF.
- optional string se_name = 2;
+ enum Category {
+ UNKNOWN = 0;
+ HCE_PAYMENT = 1;
+ HCE_OTHER = 2;
+ OFFHOST = 3;
+ }
+ // Transaction belongs to HCE payment or HCE other category, or offhost.
+ optional Category category = 1;
+ // SeName from transaction: SIMx, eSEx, HCE, HCEF.
+ optional string se_name = 2;
}
/**
@@ -5036,16 +5052,16 @@ message NfcCardemulationOccurred {
* packages/apps/Nfc/src/com/android/nfc/NfcDispatcher.java
*/
message NfcTagOccurred {
- enum Type {
- UNKNOWN = 0;
- URL = 1;
- BT_PAIRING = 2;
- PROVISION = 3;
- WIFI_CONNECT = 4;
- APP_LAUNCH = 5;
- OTHERS = 6;
- }
- optional Type type = 1;
+ enum Type {
+ UNKNOWN = 0;
+ URL = 1;
+ BT_PAIRING = 2;
+ PROVISION = 3;
+ WIFI_CONNECT = 4;
+ APP_LAUNCH = 5;
+ OTHERS = 6;
+ }
+ optional Type type = 1;
}
/**
@@ -5065,18 +5081,18 @@ message NfcHceTransactionOccurred {
* packages/apps/SecureElement/src/com/android/se/Terminal.java
*/
message SeStateChanged {
- enum State {
- UNKNOWN = 0;
- INITIALIZED = 1;
- DISCONNECTED = 2;
- CONNECTED = 3;
- HALCRASH = 4;
- }
- optional State state = 1;
+ enum State {
+ UNKNOWN = 0;
+ INITIALIZED = 1;
+ DISCONNECTED = 2;
+ CONNECTED = 3;
+ HALCRASH = 4;
+ }
+ optional State state = 1;
- optional string state_change_reason = 2;
- // SIMx or eSEx.
- optional string terminal = 3;
+ optional string state_change_reason = 2;
+ // SIMx or eSEx.
+ optional string terminal = 3;
}
/**
@@ -5085,15 +5101,15 @@ message SeStateChanged {
* packages/apps/SecureElement/src/com/android/se/Terminal.java
*/
message SeOmapiReported {
- enum Operation {
- UNKNOWN = 0;
- OPEN_CHANNEL = 1;
- }
- optional Operation operation = 1;
- // SIMx or eSEx.
- optional string terminal = 2;
+ enum Operation {
+ UNKNOWN = 0;
+ OPEN_CHANNEL = 1;
+ }
+ optional Operation operation = 1;
+ // SIMx or eSEx.
+ optional string terminal = 2;
- optional string package_name = 3;
+ optional string package_name = 3;
}
/**
@@ -5275,3 +5291,15 @@ message ScheduledJobConstraintChanged {
}
optional State state = 4;
}
+
+/**
+ * Logs PowerManagerService screen timeout resets (extensions) that happen when an attention check
+ * returns true.
+ *
+ * Logged from:
+ * frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
+ */
+message ScreenTimeoutExtensionReported {
+ // Describes how many times in a row did the power manager reset the screen off timeout.
+ optional uint32 consecutive_timeout_extended_count = 1;
+}
diff --git a/cmds/statsd/src/external/StatsPullerManager.cpp b/cmds/statsd/src/external/StatsPullerManager.cpp
index a6ba2cae2889..6f3eeaa71703 100644
--- a/cmds/statsd/src/external/StatsPullerManager.cpp
+++ b/cmds/statsd/src/external/StatsPullerManager.cpp
@@ -220,6 +220,9 @@ const std::map<int, PullAtomInfo> StatsPullerManager::kAllPullAtomInfo = {
// BuildInformation.
{android::util::BUILD_INFORMATION,
{.puller = new StatsCompanionServicePuller(android::util::BUILD_INFORMATION)}},
+ // RoleHolder.
+ {android::util::ROLE_HOLDER,
+ {.puller = new StatsCompanionServicePuller(android::util::ROLE_HOLDER)}},
};
StatsPullerManager::StatsPullerManager() : mNextPullTimeNs(NO_ALARM_UPDATE) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 03a09ee04ea1..4a8566c0072c 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -6083,7 +6083,12 @@ public final class ActivityThread extends ClientTransactionHandler {
instrApp.initForUser(UserHandle.myUserId());
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
- final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
+
+ // The test context's op package name == the target app's op package name, because
+ // the app ops manager checks the op package name against the real calling UID,
+ // which is what the target package name is associated with.
+ final ContextImpl instrContext = ContextImpl.createAppContext(this, pi,
+ appContext.getOpPackageName());
try {
final ClassLoader cl = instrContext.getClassLoader();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 92cdb20c7f4f..1a728c12e138 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2128,7 +2128,7 @@ class ContextImpl extends Context {
flags | CONTEXT_REGISTER_PACKAGE);
if (pi != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, null, mActivityToken,
- new UserHandle(UserHandle.getUserId(application.uid)), flags, null);
+ new UserHandle(UserHandle.getUserId(application.uid)), flags, null, null);
final int displayId = getDisplayId();
@@ -2156,14 +2156,14 @@ class ContextImpl extends Context {
// The system resources are loaded in every application, so we can safely copy
// the context without reloading Resources.
return new ContextImpl(this, mMainThread, mPackageInfo, null, mActivityToken, user,
- flags, null);
+ flags, null, null);
}
LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(),
flags | CONTEXT_REGISTER_PACKAGE, user.getIdentifier());
if (pi != null) {
ContextImpl c = new ContextImpl(this, mMainThread, pi, null, mActivityToken, user,
- flags, null);
+ flags, null, null);
final int displayId = getDisplayId();
@@ -2190,7 +2190,7 @@ class ContextImpl extends Context {
final String[] paths = mPackageInfo.getSplitPaths(splitName);
final ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, splitName,
- mActivityToken, mUser, mFlags, classLoader);
+ mActivityToken, mUser, mFlags, classLoader, null);
final int displayId = getDisplayId();
@@ -2214,7 +2214,7 @@ class ContextImpl extends Context {
}
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mSplitName,
- mActivityToken, mUser, mFlags, mClassLoader);
+ mActivityToken, mUser, mFlags, mClassLoader, null);
final int displayId = getDisplayId();
context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId,
@@ -2229,7 +2229,7 @@ class ContextImpl extends Context {
}
ContextImpl context = new ContextImpl(this, mMainThread, mPackageInfo, mSplitName,
- mActivityToken, mUser, mFlags, mClassLoader);
+ mActivityToken, mUser, mFlags, mClassLoader, null);
final int displayId = display.getDisplayId();
context.setResources(createResources(mActivityToken, mPackageInfo, mSplitName, displayId,
@@ -2243,7 +2243,7 @@ class ContextImpl extends Context {
final int flags = (mFlags & ~Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE)
| Context.CONTEXT_DEVICE_PROTECTED_STORAGE;
return new ContextImpl(this, mMainThread, mPackageInfo, mSplitName, mActivityToken, mUser,
- flags, mClassLoader);
+ flags, mClassLoader, null);
}
@Override
@@ -2251,7 +2251,7 @@ class ContextImpl extends Context {
final int flags = (mFlags & ~Context.CONTEXT_DEVICE_PROTECTED_STORAGE)
| Context.CONTEXT_CREDENTIAL_PROTECTED_STORAGE;
return new ContextImpl(this, mMainThread, mPackageInfo, mSplitName, mActivityToken, mUser,
- flags, mClassLoader);
+ flags, mClassLoader, null);
}
@Override
@@ -2397,7 +2397,7 @@ class ContextImpl extends Context {
static ContextImpl createSystemContext(ActivityThread mainThread) {
LoadedApk packageInfo = new LoadedApk(mainThread);
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
- null);
+ null, null);
context.setResources(packageInfo.getResources());
context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
context.mResourcesManager.getDisplayMetrics());
@@ -2414,7 +2414,7 @@ class ContextImpl extends Context {
static ContextImpl createSystemUiContext(ContextImpl systemContext, int displayId) {
final LoadedApk packageInfo = systemContext.mPackageInfo;
ContextImpl context = new ContextImpl(null, systemContext.mMainThread, packageInfo, null,
- null, null, 0, null);
+ null, null, 0, null, null);
context.setResources(createResources(null, packageInfo, null, displayId, null,
packageInfo.getCompatibilityInfo()));
context.updateDisplay(displayId);
@@ -2431,9 +2431,14 @@ class ContextImpl extends Context {
@UnsupportedAppUsage
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
+ return createAppContext(mainThread, packageInfo, null);
+ }
+
+ static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo,
+ String opPackageName) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
- null);
+ null, opPackageName);
context.setResources(packageInfo.getResources());
return context;
}
@@ -2461,7 +2466,7 @@ class ContextImpl extends Context {
}
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
- activityToken, null, 0, classLoader);
+ activityToken, null, 0, classLoader, null);
// Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
@@ -2491,7 +2496,7 @@ class ContextImpl extends Context {
private ContextImpl(@Nullable ContextImpl container, @NonNull ActivityThread mainThread,
@NonNull LoadedApk packageInfo, @Nullable String splitName,
@Nullable IBinder activityToken, @Nullable UserHandle user, int flags,
- @Nullable ClassLoader classLoader) {
+ @Nullable ClassLoader classLoader, @Nullable String overrideOpPackageName) {
mOuterContext = this;
// If creator didn't specify which storage to use, use the default
@@ -2520,9 +2525,11 @@ class ContextImpl extends Context {
mClassLoader = classLoader;
mResourcesManager = ResourcesManager.getInstance();
+ String opPackageName;
+
if (container != null) {
mBasePackageName = container.mBasePackageName;
- mOpPackageName = container.mOpPackageName;
+ opPackageName = container.mOpPackageName;
setResources(container.mResources);
mDisplay = container.mDisplay;
} else {
@@ -2533,12 +2540,14 @@ class ContextImpl extends Context {
// processes. For purposes of app ops, we must then consider the context as
// belonging to the package of this process, not the system itself, otherwise
// the package+uid verifications in app ops will fail.
- mOpPackageName = ActivityThread.currentPackageName();
+ opPackageName = ActivityThread.currentPackageName();
} else {
- mOpPackageName = mBasePackageName;
+ opPackageName = mBasePackageName;
}
}
+ mOpPackageName = overrideOpPackageName != null ? overrideOpPackageName : opPackageName;
+
mContentResolver = new ApplicationContentResolver(this, mainThread);
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 6a1ff298afdb..8207e0a112c5 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -828,6 +828,7 @@ public class NotificationManager {
/**
* @hide
*/
+ @TestApi
public boolean matchesCallFilter(Bundle extras) {
INotificationManager service = getService();
try {
diff --git a/core/java/android/content/pm/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl
index d1bc37791d40..50bb3c721763 100644
--- a/core/java/android/content/pm/ILauncherApps.aidl
+++ b/core/java/android/content/pm/ILauncherApps.aidl
@@ -24,6 +24,8 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IOnAppsChangedListener;
import android.content.pm.LauncherApps;
+import android.content.pm.IPackageInstallerCallback;
+import android.content.pm.PackageInstaller;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
@@ -44,6 +46,9 @@ interface ILauncherApps {
String callingPackage, String packageName, in UserHandle user);
ActivityInfo resolveActivity(
String callingPackage, in ComponentName component, in UserHandle user);
+ void startSessionDetailsActivityAsUser(in IApplicationThread caller, String callingPackage,
+ in PackageInstaller.SessionInfo sessionInfo, in Rect sourceBounds, in Bundle opts,
+ in UserHandle user);
void startActivityAsUser(in IApplicationThread caller, String callingPackage,
in ComponentName component, in Rect sourceBounds,
in Bundle opts, in UserHandle user);
@@ -79,4 +84,9 @@ interface ILauncherApps {
String callingPackage, String packageName, in UserHandle user);
IntentSender getShortcutConfigActivityIntent(String callingPackage, in ComponentName component,
in UserHandle user);
+
+ // Unregister is performed using package installer
+ void registerPackageInstallerCallback(String callingPackage,
+ in IPackageInstallerCallback callback);
+ ParceledListSlice getAllSessions(String callingPackage);
}
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 98dd9b3aa30b..b0d16cdace21 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -16,6 +16,7 @@
package android.content.pm;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -32,6 +33,9 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
+import android.content.pm.PackageInstaller.SessionCallback;
+import android.content.pm.PackageInstaller.SessionCallbackDelegate;
+import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
@@ -65,7 +69,9 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Class for retrieving a list of launchable activities for the current user and any associated
@@ -154,8 +160,8 @@ public class LauncherApps {
private final PackageManager mPm;
private final UserManager mUserManager;
- private List<CallbackMessageHandler> mCallbacks
- = new ArrayList<CallbackMessageHandler>();
+ private final List<CallbackMessageHandler> mCallbacks = new ArrayList<>();
+ private final List<SessionCallbackDelegate> mDelegates = new ArrayList<>();
/**
* Callbacks for package changes to this and related managed profiles.
@@ -572,6 +578,24 @@ public class LauncherApps {
}
/**
+ * Starts an activity to show the details of the specified session.
+ *
+ * @param sessionInfo The SessionInfo of the session
+ * @param sourceBounds The Rect containing the source bounds of the clicked icon
+ * @param opts Options to pass to startActivity
+ */
+ public void startPackageInstallerSessionDetailsActivity(SessionInfo sessionInfo,
+ Rect sourceBounds, Bundle opts) {
+ try {
+ mService.startSessionDetailsActivityAsUser(mContext.getIApplicationThread(),
+ mContext.getPackageName(), sessionInfo, sourceBounds, opts,
+ sessionInfo.getUser());
+ } catch (RemoteException re) {
+ throw re.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Starts the settings activity to show the application details for a
* package in the specified profile.
*
@@ -1131,7 +1155,7 @@ public class LauncherApps {
}
/**
- * Registers a callback for changes to packages in current and managed profiles.
+ * Registers a callback for changes to packages in this user and managed profiles.
*
* @param callback The callback to register.
*/
@@ -1140,7 +1164,7 @@ public class LauncherApps {
}
/**
- * Registers a callback for changes to packages in current and managed profiles.
+ * Registers a callback for changes to packages in this user and managed profiles.
*
* @param callback The callback to register.
* @param handler that should be used to post callbacks on, may be null.
@@ -1446,6 +1470,64 @@ public class LauncherApps {
}
/**
+ * Register a callback to watch for session lifecycle events in this user and managed profiles.
+ * @param callback The callback to register.
+ * @param executor {@link Executor} to handle the callbacks, cannot be null.
+ *
+ * @see PackageInstaller#registerSessionCallback(SessionCallback)
+ */
+ public void registerPackageInstallerSessionCallback(
+ @NonNull @CallbackExecutor Executor executor, @NonNull SessionCallback callback) {
+ if (executor == null) {
+ throw new NullPointerException("Executor must not be null");
+ }
+
+ synchronized (mDelegates) {
+ final SessionCallbackDelegate delegate = new SessionCallbackDelegate(callback,
+ executor);
+ try {
+ mService.registerPackageInstallerCallback(mContext.getPackageName(),
+ delegate);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ mDelegates.add(delegate);
+ }
+ }
+
+ /**
+ * Unregisters a callback that was previously registered.
+ *
+ * @param callback The callback to unregister.
+ * @see #registerPackageInstallerSessionCallback(Executor, SessionCallback)
+ */
+ public void unregisterPackageInstallerSessionCallback(SessionCallback callback) {
+ synchronized (mDelegates) {
+ for (Iterator<SessionCallbackDelegate> i = mDelegates.iterator(); i.hasNext();) {
+ final SessionCallbackDelegate delegate = i.next();
+ if (delegate.mCallback == callback) {
+ mPm.getPackageInstaller().unregisterSessionCallback(delegate.mCallback);
+ i.remove();
+ }
+ }
+ }
+ }
+
+ /**
+ * Return list of all known install sessions in this user and managed profiles, regardless
+ * of the installer.
+ *
+ * @see PackageInstaller#getAllSessions()
+ */
+ public @NonNull List<SessionInfo> getAllPackageInstallerSessions() {
+ try {
+ return mService.getAllSessions(mContext.getPackageName()).getList();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* A helper method to extract a {@link PinItemRequest} set to
* the {@link #EXTRA_PIN_ITEM_REQUEST} extra.
*/
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 2dc014c45fad..4f674bd378c0 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -36,20 +36,21 @@ import android.net.Uri;
import android.os.Build;
import android.os.FileBridge;
import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
+import android.os.HandlerExecutor;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.SystemProperties;
+import android.os.UserHandle;
import android.system.ErrnoException;
import android.system.Os;
import android.util.ExceptionUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.pooled.PooledLambda;
import java.io.Closeable;
import java.io.IOException;
@@ -61,6 +62,7 @@ import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.Executor;
/**
* Offers the ability to install, upgrade, and remove applications on the
@@ -659,8 +661,7 @@ public class PackageInstaller {
}
/** {@hide} */
- private static class SessionCallbackDelegate extends IPackageInstallerCallback.Stub implements
- Handler.Callback {
+ static class SessionCallbackDelegate extends IPackageInstallerCallback.Stub {
private static final int MSG_SESSION_CREATED = 1;
private static final int MSG_SESSION_BADGING_CHANGED = 2;
private static final int MSG_SESSION_ACTIVE_CHANGED = 3;
@@ -668,63 +669,41 @@ public class PackageInstaller {
private static final int MSG_SESSION_FINISHED = 5;
final SessionCallback mCallback;
- final Handler mHandler;
+ final Executor mExecutor;
- public SessionCallbackDelegate(SessionCallback callback, Looper looper) {
+ SessionCallbackDelegate(SessionCallback callback, Executor executor) {
mCallback = callback;
- mHandler = new Handler(looper, this);
- }
-
- @Override
- public boolean handleMessage(Message msg) {
- final int sessionId = msg.arg1;
- switch (msg.what) {
- case MSG_SESSION_CREATED:
- mCallback.onCreated(sessionId);
- return true;
- case MSG_SESSION_BADGING_CHANGED:
- mCallback.onBadgingChanged(sessionId);
- return true;
- case MSG_SESSION_ACTIVE_CHANGED:
- final boolean active = msg.arg2 != 0;
- mCallback.onActiveChanged(sessionId, active);
- return true;
- case MSG_SESSION_PROGRESS_CHANGED:
- mCallback.onProgressChanged(sessionId, (float) msg.obj);
- return true;
- case MSG_SESSION_FINISHED:
- mCallback.onFinished(sessionId, msg.arg2 != 0);
- return true;
- }
- return false;
+ mExecutor = executor;
}
@Override
public void onSessionCreated(int sessionId) {
- mHandler.obtainMessage(MSG_SESSION_CREATED, sessionId, 0).sendToTarget();
+ mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onCreated, mCallback,
+ sessionId).recycleOnUse());
}
@Override
public void onSessionBadgingChanged(int sessionId) {
- mHandler.obtainMessage(MSG_SESSION_BADGING_CHANGED, sessionId, 0).sendToTarget();
+ mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onBadgingChanged,
+ mCallback, sessionId).recycleOnUse());
}
@Override
public void onSessionActiveChanged(int sessionId, boolean active) {
- mHandler.obtainMessage(MSG_SESSION_ACTIVE_CHANGED, sessionId, active ? 1 : 0)
- .sendToTarget();
+ mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onActiveChanged,
+ mCallback, sessionId, active).recycleOnUse());
}
@Override
public void onSessionProgressChanged(int sessionId, float progress) {
- mHandler.obtainMessage(MSG_SESSION_PROGRESS_CHANGED, sessionId, 0, progress)
- .sendToTarget();
+ mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onProgressChanged,
+ mCallback, sessionId, progress).recycleOnUse());
}
@Override
public void onSessionFinished(int sessionId, boolean success) {
- mHandler.obtainMessage(MSG_SESSION_FINISHED, sessionId, success ? 1 : 0)
- .sendToTarget();
+ mExecutor.execute(PooledLambda.obtainRunnable(SessionCallback::onFinished,
+ mCallback, sessionId, success).recycleOnUse());
}
}
@@ -758,7 +737,7 @@ public class PackageInstaller {
public void registerSessionCallback(@NonNull SessionCallback callback, @NonNull Handler handler) {
synchronized (mDelegates) {
final SessionCallbackDelegate delegate = new SessionCallbackDelegate(callback,
- handler.getLooper());
+ new HandlerExecutor(handler));
try {
mInstaller.registerCallback(delegate, mUserId);
} catch (RemoteException e) {
@@ -1649,6 +1628,8 @@ public class PackageInstaller {
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public int sessionId;
/** {@hide} */
+ public int userId;
+ /** {@hide} */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public String installerPackageName;
/** {@hide} */
@@ -1720,6 +1701,7 @@ public class PackageInstaller {
/** {@hide} */
public SessionInfo(Parcel source) {
sessionId = source.readInt();
+ userId = source.readInt();
installerPackageName = source.readString();
resolvedBaseCodePath = source.readString();
progress = source.readFloat();
@@ -1761,6 +1743,13 @@ public class PackageInstaller {
}
/**
+ * Return the user associated with this session.
+ */
+ public UserHandle getUser() {
+ return new UserHandle(userId);
+ }
+
+ /**
* Return the package name of the app that owns this session.
*/
public @Nullable String getInstallerPackageName() {
@@ -2091,6 +2080,7 @@ public class PackageInstaller {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(sessionId);
+ dest.writeInt(userId);
dest.writeString(installerPackageName);
dest.writeString(resolvedBaseCodePath);
dest.writeFloat(progress);
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index ef8ca9e3cb67..869cf6477df0 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1033,34 +1033,6 @@ public class ConnectivityManager {
}
}
- /**
- * Configures an always-on VPN connection through a specific application.
- * This connection is automatically granted and persisted after a reboot.
- *
- * <p>The designated package should declare a {@link VpnService} in its
- * manifest guarded by {@link android.Manifest.permission.BIND_VPN_SERVICE},
- * otherwise the call will fail.
- *
- * @param userId The identifier of the user to set an always-on VPN for.
- * @param vpnPackage The package name for an installed VPN app on the device, or {@code null}
- * to remove an existing always-on VPN configuration.
- * @param lockdownEnabled {@code true} to disallow networking when the VPN is not connected or
- * {@code false} otherwise.
- * @return {@code true} if the package is set as always-on VPN controller;
- * {@code false} otherwise.
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.CONTROL_ALWAYS_ON_VPN)
- public boolean setAlwaysOnVpnPackageForUser(int userId, @Nullable String vpnPackage,
- boolean lockdownEnabled) {
- try {
- return mService.setAlwaysOnVpnPackage(
- userId, vpnPackage, lockdownEnabled, /* whitelist */ null);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
/**
* Returns the package name of the currently set always-on VPN application.
* If there is no always-on VPN set, or the VPN is provided by the system instead
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
new file mode 100644
index 000000000000..b568f157c01d
--- /dev/null
+++ b/core/java/android/os/OWNERS
@@ -0,0 +1,2 @@
+# Zygote
+per-file ZygoteProcess.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 30c0731870ef..92650e114a66 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -181,10 +181,10 @@ public final class DeviceConfig {
String NAMESPACE = "intelligence_attention";
/** If {@code true}, enables the attention features. */
- String PROPERTY_ATTENTION_ENABLED = "attention_enabled";
+ String ATTENTION_ENABLED = "attention_enabled";
/** Settings for the attention features. */
- String PROPERTY_ATTENTION_SETTINGS = "attention_settings";
+ String ATTENTION_SETTINGS = "attention_settings";
}
/**
@@ -203,12 +203,12 @@ public final class DeviceConfig {
* @hide
*/
@SystemApi
- String PROPERTY_PERMISSIONS_HUB_ENABLED = "enable_permissions_hub";
+ String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
/**
* Whether to show location access check notifications.
*/
- String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "enable_location_access_check";
+ String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
}
/**
@@ -220,13 +220,17 @@ public final class DeviceConfig {
public interface Telephony {
String NAMESPACE = "telephony";
/**
+ * Ringer ramping time in milliseconds.
+ */
+ String RAMPING_RINGER_DURATION = "ramping_ringer_duration";
+ /**
* Whether to apply ramping ringer on incoming phone calls.
*/
- String PROPERTY_ENABLE_RAMPING_RINGER = "enable_ramping_ringer";
+ String RAMPING_RINGER_ENABLED = "ramping_ringer_enabled";
/**
- * Ringer ramping time in milliseconds.
+ * Vibration time in milliseconds before ramping ringer starts.
*/
- String PROPERTY_RAMPING_RINGER_DURATION = "ramping_duration";
+ String RAMPING_RINGER_VIBRATION_DURATION = "ramping_ringer_vibration_duration";
}
/**
@@ -261,6 +265,7 @@ public final class DeviceConfig {
String KEY_COMPACT_THROTTLE_2 = "compact_throttle_2";
String KEY_COMPACT_THROTTLE_3 = "compact_throttle_3";
String KEY_COMPACT_THROTTLE_4 = "compact_throttle_4";
+ String KEY_COMPACT_STATSD_SAMPLE_RATE = "compact_statsd_sample_rate";
/**
* Maximum number of cached processes. See
@@ -279,10 +284,10 @@ public final class DeviceConfig {
String NAMESPACE = "attention_manager_service";
/** If {@code true}, enables {@link AttentionManagerService} features. */
- String PROPERTY_SERVICE_ENABLED = "service_enabled";
+ String SERVICE_ENABLED = "service_enabled";
/** Allows a CTS to inject a fake implementation. */
- String PROPERTY_COMPONENT_NAME = "component_name";
+ String COMPONENT_NAME = "component_name";
}
/**
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 124c50a3393e..0743c23080fd 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -641,6 +641,8 @@ public final class MediaStore {
* location. For example, when this value is left undefined, pending
* {@link MediaStore.Audio.Media} items are stored under
* {@link Environment#DIRECTORY_MUSIC}.
+ *
+ * @see MediaColumns#PRIMARY_DIRECTORY
*/
public void setPrimaryDirectory(@Nullable String primaryDirectory) {
this.primaryDirectory = primaryDirectory;
@@ -652,6 +654,8 @@ public final class MediaStore {
* <p>
* You may leave this value undefined to store the media as a direct
* descendant of the {@link #setPrimaryDirectory(String)} location.
+ *
+ * @see MediaColumns#SECONDARY_DIRECTORY
*/
public void setSecondaryDirectory(@Nullable String secondaryDirectory) {
this.secondaryDirectory = secondaryDirectory;
@@ -980,6 +984,26 @@ public final class MediaStore {
* Type: TEXT
*/
public static final String OWNER_PACKAGE_NAME = "owner_package_name";
+
+ /**
+ * The primary directory name this media exists under. The value may be
+ * {@code NULL} if the media doesn't have a primary directory name.
+ * <p>
+ * Type: TEXT
+ *
+ * @see PendingParams#setPrimaryDirectory(String)
+ */
+ public static final String PRIMARY_DIRECTORY = "primary_directory";
+
+ /**
+ * The secondary directory name this media exists under. The value may
+ * be {@code NULL} if the media doesn't have a secondary directory name.
+ * <p>
+ * Type: TEXT
+ *
+ * @see PendingParams#setSecondaryDirectory(String)
+ */
+ public static final String SECONDARY_DIRECTORY = "secondary_directory";
}
/**
@@ -1428,13 +1452,20 @@ public final class MediaStore {
public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
/**
- * The secondary bucket ID of this media item. This can be useful to
- * present the user a second-level clustering of related media
- * items. This is a read-only column that is automatically computed.
+ * The group ID of this media item. This can be useful to present
+ * the user a grouping of related media items, such a burst of
+ * images, or a {@code JPG} and {@code DNG} version of the same
+ * image.
+ * <p>
+ * This is a read-only column that is automatically computed based
+ * on the first portion of the filename. For example,
+ * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
+ * will have the same {@link #GROUP_ID} because the first portion of
+ * their filenames is identical.
* <p>
* Type: INTEGER
*/
- public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id";
+ public static final String GROUP_ID = "group_id";
}
public static final class Media implements ImageColumns {
@@ -2697,13 +2728,20 @@ public final class MediaStore {
public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
/**
- * The secondary bucket ID of this media item. This can be useful to
- * present the user a second-level clustering of related media
- * items. This is a read-only column that is automatically computed.
+ * The group ID of this media item. This can be useful to present
+ * the user a grouping of related media items, such a burst of
+ * images, or a {@code JPG} and {@code DNG} version of the same
+ * image.
+ * <p>
+ * This is a read-only column that is automatically computed based
+ * on the first portion of the filename. For example,
+ * {@code IMG1024.BURST001.JPG} and {@code IMG1024.BURST002.JPG}
+ * will have the same {@link #GROUP_ID} because the first portion of
+ * their filenames is identical.
* <p>
* Type: INTEGER
*/
- public static final String SECONDARY_BUCKET_ID = "secondary_bucket_id";
+ public static final String GROUP_ID = "group_id";
/**
* The bookmark for the video. Time in ms. Represents the location in the video that the
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ea00698f2001..afa21100f022 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -5874,30 +5874,24 @@ public final class Settings {
"unknown_sources_default_reversed";
/**
- * Comma-separated list of location providers that activities may access. Do not rely on
- * this value being present in settings.db or on ContentObserver notifications on the
+ * Comma-separated list of location providers that are accessible. Do not rely on
+ * this value being present or correct, or on ContentObserver notifications on the
* corresponding Uri.
*
- * @deprecated Providers should not be controlled individually. See {@link #LOCATION_MODE}
- * documentation for information on reading/writing location information.
+ * @deprecated The preferred methods for checking provider status and listening for changes
+ * are via {@link LocationManager#isProviderEnabled(String)} and
+ * {@link LocationManager#PROVIDERS_CHANGED_ACTION}.
*/
@Deprecated
public static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
/**
- * The degree of location access enabled by the user.
- * <p>
- * When used with {@link #putInt(ContentResolver, String, int)}, must be one of {@link
- * #LOCATION_MODE_HIGH_ACCURACY}, {@link #LOCATION_MODE_SENSORS_ONLY}, {@link
- * #LOCATION_MODE_BATTERY_SAVING}, or {@link #LOCATION_MODE_OFF}. When used with {@link
- * #getInt(ContentResolver, String)}, the caller must gracefully handle additional location
- * modes that might be added in the future.
- * <p>
- * Note: do not rely on this value being present in settings.db or on ContentObserver
- * notifications for the corresponding Uri. Use {@link LocationManager#MODE_CHANGED_ACTION}
- * to receive changes in this value.
+ * The current location mode of the device. Do not rely on this value being present or on
+ * ContentObserver notifications on the corresponding Uri.
*
- * @deprecated To check location mode, use {@link LocationManager#isLocationEnabled()}.
+ * @deprecated The preferred methods for checking location mode and listening for changes
+ * are via {@link LocationManager#isLocationEnabled()} and
+ * {@link LocationManager#MODE_CHANGED_ACTION}.
*/
@Deprecated
public static final String LOCATION_MODE = "location_mode";
@@ -5924,7 +5918,7 @@ public final class Settings {
public static final int LOCATION_CHANGER_QUICK_SETTINGS = 2;
/**
- * Location access disabled.
+ * Location mode is off.
*
* @deprecated See {@link #LOCATION_MODE}.
*/
@@ -5932,34 +5926,41 @@ public final class Settings {
public static final int LOCATION_MODE_OFF = 0;
/**
- * Network Location Provider disabled, but GPS and other sensors enabled.
+ * This mode no longer has any distinct meaning, but is interpreted as the location mode is
+ * on.
*
- * @deprecated To check location status, use {@link LocationManager#isLocationEnabled()}. To
- * get the status of a location provider, use
- * {@link LocationManager#isProviderEnabled(String)}.
+ * @deprecated See {@link #LOCATION_MODE_ON}.
*/
@Deprecated
public static final int LOCATION_MODE_SENSORS_ONLY = 1;
/**
- * Reduced power usage, such as limiting the number of GPS updates per hour. Requests
- * with {@link android.location.Criteria#POWER_HIGH} may be downgraded to
- * {@link android.location.Criteria#POWER_MEDIUM}.
+ * This mode no longer has any distinct meaning, but is interpreted as the location mode is
+ * on.
*
- * @deprecated See {@link #LOCATION_MODE}.
+ * @deprecated See {@link #LOCATION_MODE_ON}.
*/
@Deprecated
public static final int LOCATION_MODE_BATTERY_SAVING = 2;
/**
- * Best-effort location computation allowed.
+ * This mode no longer has any distinct meaning, but is interpreted as the location mode is
+ * on.
*
- * @deprecated See {@link #LOCATION_MODE}.
+ * @deprecated See {@link #LOCATION_MODE_ON}.
*/
@Deprecated
public static final int LOCATION_MODE_HIGH_ACCURACY = 3;
/**
+ * Location mode is on.
+ *
+ * @deprecated See {@link #LOCATION_MODE}.
+ */
+ @Deprecated
+ public static final int LOCATION_MODE_ON = LOCATION_MODE_HIGH_ACCURACY;
+
+ /**
* A flag containing settings used for biometric weak
* @hide
*/
diff --git a/core/java/android/service/attention/AttentionService.java b/core/java/android/service/attention/AttentionService.java
index f6e448dc4757..24d74ffd747d 100644
--- a/core/java/android/service/attention/AttentionService.java
+++ b/core/java/android/service/attention/AttentionService.java
@@ -64,10 +64,10 @@ public abstract class AttentionService extends Service {
/** Attention is present. */
public static final int ATTENTION_SUCCESS_PRESENT = 1;
- /** Preempted by other camera user. */
+ /** Preempted by other client. */
public static final int ATTENTION_FAILURE_PREEMPTED = 2;
- /** Preempted by other camera user. */
+ /** Request timed out. */
public static final int ATTENTION_FAILURE_TIMED_OUT = 3;
/** Unknown reasons for failing to determine the attention. */
diff --git a/core/java/android/service/dreams/OWNERS b/core/java/android/service/dreams/OWNERS
index 3c9bbf8797ea..426f002ad236 100644
--- a/core/java/android/service/dreams/OWNERS
+++ b/core/java/android/service/dreams/OWNERS
@@ -1,3 +1,3 @@
-dsandler@google.com
+dsandler@android.com
michaelwr@google.com
roosa@google.com
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 2789651c4eaf..e76e0966b817 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -16,7 +16,6 @@
package android.service.voice;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
@@ -41,8 +40,6 @@ import com.android.internal.util.function.pooled.PooledLambda;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
@@ -80,33 +77,6 @@ public class VoiceInteractionService extends Service {
*/
public static final String SERVICE_META_DATA = "android.voice_interaction";
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"VOICE_STATE_"}, value = {
- VOICE_STATE_NONE,
- VOICE_STATE_CONDITIONAL_LISTENING,
- VOICE_STATE_LISTENING,
- VOICE_STATE_FULFILLING})
- public @interface VoiceState {
- }
-
- /**
- * Voice assistant inactive.
- */
- public static final int VOICE_STATE_NONE = 0;
- /**
- * Voice assistant listening, but will only trigger if it hears a request it can fulfill.
- */
- public static final int VOICE_STATE_CONDITIONAL_LISTENING = 1;
- /**
- * Voice assistant is listening to user speech.
- */
- public static final int VOICE_STATE_LISTENING = 2;
- /**
- * Voice assistant is fulfilling an action requested by the user.
- */
- public static final int VOICE_STATE_FULFILLING = 3;
-
IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
@Override
public void ready() {
@@ -376,7 +346,7 @@ public class VoiceInteractionService extends Service {
*
* @param state value indicating whether the assistant is listening, fulfilling, etc.
*/
- public final void setVoiceState(@VoiceState int state) {
+ public final void setVoiceState(int state) {
try {
mSystemService.setVoiceState(state);
} catch (RemoteException e) {
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index db9351b030df..2e8b7f021ff6 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -57,6 +57,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put("settings_wifi_dpp", "true");
DEFAULT_FLAGS.put("settings_wifi_mac_randomization", "true");
DEFAULT_FLAGS.put("settings_wifi_sharing", "true");
+ DEFAULT_FLAGS.put("settings_mainline_module", "false");
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
DEFAULT_FLAGS.put(SAFETY_HUB, "false");
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
diff --git a/core/java/android/view/textclassifier/ExtrasUtils.java b/core/java/android/view/textclassifier/ExtrasUtils.java
new file mode 100644
index 000000000000..602455c65beb
--- /dev/null
+++ b/core/java/android/view/textclassifier/ExtrasUtils.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.textclassifier;
+
+import android.annotation.Nullable;
+import android.app.RemoteAction;
+import android.content.Intent;
+import android.os.Bundle;
+
+import java.util.ArrayList;
+
+/**
+ * Utility class for inserting and retrieving data in TextClassifier request/response extras.
+ * @hide
+ */
+public final class ExtrasUtils {
+
+ private static final String ACTIONS_INTENTS = "actions-intents";
+ private static final String FOREIGN_LANGUAGE = "foreign-language";
+ private static final String ENTITY_TYPE = "entity-type";
+ private static final String SCORE = "score";
+ private static final String MODEL_VERSION = "model-version";
+ private static final String MODEL_NAME = "model-name";
+
+ private ExtrasUtils() {}
+
+ /**
+ * Bundles and returns foreign language detection information for TextClassifier responses.
+ */
+ static Bundle createForeignLanguageExtra(
+ String language, float score, int modelVersion) {
+ final Bundle bundle = new Bundle();
+ bundle.putString(ENTITY_TYPE, language);
+ bundle.putFloat(SCORE, score);
+ bundle.putInt(MODEL_VERSION, modelVersion);
+ bundle.putString(MODEL_NAME, "langId_v" + modelVersion);
+ return bundle;
+ }
+
+ /**
+ * Stores {@code extra} as foreign language information in TextClassifier response object's
+ * extras {@code container}.
+ */
+ static void putForeignLanguageExtra(Bundle container, Bundle extra) {
+ container.putParcelable(FOREIGN_LANGUAGE, extra);
+ }
+
+ /**
+ * Returns foreign language detection information contained in the TextClassification object.
+ * responses.
+ */
+ @Nullable
+ public static Bundle getForeignLanguageExtra(TextClassification classification) {
+ return classification.getExtras().getBundle(FOREIGN_LANGUAGE);
+ }
+
+ /**
+ * Stores {@code actionIntents} information in TextClassifier response object's extras
+ * {@code container}.
+ */
+ static void putActionsIntents(Bundle container, ArrayList<Intent> actionsIntents) {
+ container.putParcelableArrayList(ACTIONS_INTENTS, actionsIntents);
+ }
+
+ /**
+ * Returns {@code actionIntents} information contained in the TextClassification object.
+ */
+ @Nullable
+ public static ArrayList<Intent> getActionsIntents(TextClassification classification) {
+ return classification.getExtras().getParcelableArrayList(ACTIONS_INTENTS);
+ }
+
+ /**
+ * Returns the first "translate" action found in the {@code classification} object.
+ */
+ @Nullable
+ public static RemoteAction findTranslateAction(TextClassification classification) {
+ final ArrayList<Intent> actionIntents = getActionsIntents(classification);
+ if (actionIntents != null) {
+ final int size = actionIntents.size();
+ for (int i = 0; i < size; i++) {
+ if (Intent.ACTION_TRANSLATE.equals(actionIntents.get(i).getAction())) {
+ return classification.getActions().get(i);
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the entity type contained in the {@code extra}.
+ */
+ @Nullable
+ public static String getEntityType(Bundle extra) {
+ return extra.getString(ENTITY_TYPE);
+ }
+
+ /**
+ * Returns the score contained in the {@code extra}.
+ */
+ @Nullable
+ public static float getScore(Bundle extra) {
+ return extra.getFloat(SCORE, -1);
+ }
+
+ /**
+ * Returns the model name contained in the {@code extra}.
+ */
+ @Nullable
+ public static String getModelName(Bundle extra) {
+ return extra.getString(MODEL_NAME);
+ }
+}
diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java
index d9f79655d588..a05920960dcf 100644
--- a/core/java/android/view/textclassifier/TextClassification.java
+++ b/core/java/android/view/textclassifier/TextClassification.java
@@ -378,6 +378,8 @@ public final class TextClassification implements Parcelable {
@Nullable private OnClickListener mLegacyOnClickListener;
@Nullable private String mId;
@Nullable private Bundle mExtras;
+ @NonNull private final ArrayList<Intent> mActionIntents = new ArrayList<>();
+ @Nullable private Bundle mForeignLanguageExtra;
/**
* Sets the classified text.
@@ -412,8 +414,19 @@ public final class TextClassification implements Parcelable {
*/
@NonNull
public Builder addAction(@NonNull RemoteAction action) {
+ return addAction(action, null);
+ }
+
+ /**
+ * @param intent the intent in the remote action.
+ * @see #addAction(RemoteAction)
+ * @hide
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public Builder addAction(RemoteAction action, @Nullable Intent intent) {
Preconditions.checkArgument(action != null);
mActions.add(action);
+ mActionIntents.add(intent);
return this;
}
@@ -499,13 +512,33 @@ public final class TextClassification implements Parcelable {
}
/**
+ * @see #setExtras(Bundle)
+ * @hide
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public Builder setForeignLanguageExtra(@Nullable Bundle extra) {
+ mForeignLanguageExtra = extra;
+ return this;
+ }
+
+ /**
* Builds and returns a {@link TextClassification} object.
*/
@NonNull
public TextClassification build() {
return new TextClassification(mText, mLegacyIcon, mLegacyLabel, mLegacyIntent,
- mLegacyOnClickListener, mActions, mEntityConfidence, mId,
- mExtras == null ? Bundle.EMPTY : mExtras.deepCopy());
+ mLegacyOnClickListener, mActions, mEntityConfidence, mId, buildExtras());
+ }
+
+ private Bundle buildExtras() {
+ final Bundle extras = mExtras == null ? new Bundle() : mExtras.deepCopy();
+ if (!mActionIntents.isEmpty()) {
+ ExtrasUtils.putActionsIntents(extras, mActionIntents);
+ }
+ if (mForeignLanguageExtra != null) {
+ ExtrasUtils.putForeignLanguageExtra(extras, mForeignLanguageExtra);
+ }
+ return extras.isEmpty() ? Bundle.EMPTY : extras;
}
}
diff --git a/core/java/android/view/textclassifier/TextClassificationSession.java b/core/java/android/view/textclassifier/TextClassificationSession.java
index 45668c01a8d3..ba1287fc6b0f 100644
--- a/core/java/android/view/textclassifier/TextClassificationSession.java
+++ b/core/java/android/view/textclassifier/TextClassificationSession.java
@@ -71,10 +71,23 @@ final class TextClassificationSession implements TextClassifier {
@Override
public void onSelectionEvent(SelectionEvent event) {
- checkDestroyed();
- Preconditions.checkNotNull(event);
- if (mEventHelper.sanitizeEvent(event)) {
- mDelegate.onSelectionEvent(event);
+ try {
+ if (mEventHelper.sanitizeEvent(event)) {
+ mDelegate.onSelectionEvent(event);
+ }
+ } catch (Exception e) {
+ // Avoid crashing for event reporting.
+ Log.e(LOG_TAG, "Error reporting text classifier selection event", e);
+ }
+ }
+
+ @Override
+ public void onTextClassifierEvent(TextClassifierEvent event) {
+ try {
+ mDelegate.onTextClassifierEvent(event);
+ } catch (Exception e) {
+ // Avoid crashing for event reporting.
+ Log.e(LOG_TAG, "Error reporting text classifier event", e);
}
}
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index 8a688d8454e7..e0101556910f 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -161,7 +161,12 @@ public interface TextClassifier {
* No-op TextClassifier.
* This may be used to turn off TextClassifier features.
*/
- TextClassifier NO_OP = new TextClassifier() {};
+ TextClassifier NO_OP = new TextClassifier() {
+ @Override
+ public String toString() {
+ return "TextClassifier.NO_OP";
+ }
+ };
/**
* Extra that is included on activity intents coming from a TextClassifier when
diff --git a/core/java/android/view/textclassifier/TextClassifierEvent.java b/core/java/android/view/textclassifier/TextClassifierEvent.java
index cd13cc0ec577..0d4338b0af6b 100644
--- a/core/java/android/view/textclassifier/TextClassifierEvent.java
+++ b/core/java/android/view/textclassifier/TextClassifierEvent.java
@@ -141,6 +141,8 @@ public final class TextClassifierEvent implements Parcelable {
@Nullable private final String mLanguage;
private final float mScore;
+ @Nullable private final String mModelName;
+
private TextClassifierEvent(
int eventCategory,
int eventType,
@@ -156,7 +158,8 @@ public final class TextClassifierEvent implements Parcelable {
int relativeSuggestedWordEndIndex,
int[] actionIndex,
String language,
- float score) {
+ float score,
+ String modelVersion) {
mEventCategory = eventCategory;
mEventType = eventType;
mEntityTypes = entityTypes;
@@ -172,6 +175,7 @@ public final class TextClassifierEvent implements Parcelable {
mActionIndices = actionIndex;
mLanguage = language;
mScore = score;
+ mModelName = modelVersion;
}
@Override
@@ -196,6 +200,7 @@ public final class TextClassifierEvent implements Parcelable {
dest.writeIntArray(mActionIndices);
dest.writeString(mLanguage);
dest.writeFloat(mScore);
+ dest.writeString(mModelName);
}
private static TextClassifierEvent readFromParcel(Parcel in) {
@@ -214,7 +219,8 @@ public final class TextClassifierEvent implements Parcelable {
/* relativeSuggestedWordEndIndex= */ in.readInt(),
/* actionIndices= */ in.createIntArray(),
/* language= */ in.readString(),
- /* score= */ in.readFloat());
+ /* score= */ in.readFloat(),
+ /* modelVersion= */ in.readString());
}
/**
@@ -264,6 +270,7 @@ public final class TextClassifierEvent implements Parcelable {
return mEventIndex;
}
+ // TODO: Remove this API.
/**
* Returns the time this event occurred. This is the number of milliseconds since
* January 1, 1970, 00:00:00 GMT. 0 indicates not set.
@@ -339,6 +346,15 @@ public final class TextClassifierEvent implements Parcelable {
}
/**
+ * Returns the model name.
+ * @hide
+ */
+ @Nullable
+ public String getModelName() {
+ return mModelName;
+ }
+
+ /**
* Builder to build a text classifier event.
*/
public static final class Builder {
@@ -359,6 +375,8 @@ public final class TextClassifierEvent implements Parcelable {
@Nullable private String mLanguage;
private float mScore;
+ private String mModelName;
+
/**
* Creates a builder for building {@link TextClassifierEvent}s.
*
@@ -407,6 +425,7 @@ public final class TextClassifierEvent implements Parcelable {
return this;
}
+ // TODO: Remove this API.
/**
* Sets the time this event occurred. This is the number of milliseconds since
* January 1, 1970, 00:00:00 GMT. 0 indicates not set.
@@ -501,6 +520,15 @@ public final class TextClassifierEvent implements Parcelable {
}
/**
+ * Sets the model name string.
+ * @hide
+ */
+ public Builder setModelName(@Nullable String modelVersion) {
+ mModelName = modelVersion;
+ return this;
+ }
+
+ /**
* Builds and returns a text classifier event.
*/
@NonNull
@@ -521,7 +549,8 @@ public final class TextClassifierEvent implements Parcelable {
mRelativeSuggestedWordEndIndex,
mActionIndices,
mLanguage,
- mScore);
+ mScore,
+ mModelName);
}
// TODO: Add build(boolean validate).
}
@@ -544,6 +573,7 @@ public final class TextClassifierEvent implements Parcelable {
out.append(", mActionIndices=").append(Arrays.toString(mActionIndices));
out.append(", mLanguage=").append(mLanguage);
out.append(", mScore=").append(mScore);
+ out.append(", mModelName=").append(mModelName);
out.append("}");
return out.toString();
}
diff --git a/core/java/android/view/textclassifier/TextClassifierEventTronLogger.java b/core/java/android/view/textclassifier/TextClassifierEventTronLogger.java
index 5563dfc2eee5..6a122506d0ac 100644
--- a/core/java/android/view/textclassifier/TextClassifierEventTronLogger.java
+++ b/core/java/android/view/textclassifier/TextClassifierEventTronLogger.java
@@ -16,7 +16,6 @@
package android.view.textclassifier;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXTCLASSIFIER_MODEL;
-import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_EVENT_TIME;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_FIRST_ENTITY_TYPE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_SCORE;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TEXT_CLASSIFIER_SECOND_ENTITY_TYPE;
@@ -46,7 +45,7 @@ public final class TextClassifierEventTronLogger {
private final MetricsLogger mMetricsLogger;
public TextClassifierEventTronLogger() {
- mMetricsLogger = new MetricsLogger();
+ this(new MetricsLogger());
}
@VisibleForTesting
@@ -57,6 +56,7 @@ public final class TextClassifierEventTronLogger {
/** Emits a text classifier event to the logs. */
public void writeEvent(TextClassifierEvent event) {
Preconditions.checkNotNull(event);
+
int category = getCategory(event);
if (category == -1) {
Log.w(TAG, "Unknown category: " + event.getEventCategory());
@@ -65,14 +65,12 @@ public final class TextClassifierEventTronLogger {
final LogMaker log = new LogMaker(category)
.setSubtype(getLogType(event))
.addTaggedData(FIELD_TEXT_CLASSIFIER_SESSION_ID, event.getResultId())
- .addTaggedData(FIELD_TEXT_CLASSIFIER_EVENT_TIME, event.getEventTime())
- .addTaggedData(FIELD_TEXTCLASSIFIER_MODEL,
- SelectionSessionLogger.SignatureParser.getModelName(event.getResultId()))
+ .addTaggedData(FIELD_TEXTCLASSIFIER_MODEL, getModelName(event))
.addTaggedData(FIELD_TEXT_CLASSIFIER_SCORE, event.getScore());
String[] entityTypes = event.getEntityTypes();
- // TRON does not support a field of list type, and thus workaround by store them
- // in three separate fields. This is no longer an issue once we have moved to Westworld.
+ // The old logger does not support a field of list type, and thus workaround by store them
+ // in three separate fields. This is not an issue with the new logger.
if (entityTypes.length >= 1) {
log.addTaggedData(FIELD_TEXT_CLASSIFIER_FIRST_ENTITY_TYPE, entityTypes[0]);
}
@@ -93,6 +91,13 @@ public final class TextClassifierEventTronLogger {
debugLog(log);
}
+ private static String getModelName(TextClassifierEvent event) {
+ if (event.getModelName() != null) {
+ return event.getModelName();
+ }
+ return SelectionSessionLogger.SignatureParser.getModelName(event.getResultId());
+ }
+
private static int getCategory(TextClassifierEvent event) {
switch (event.getEventCategory()) {
case TextClassifierEvent.CATEGORY_CONVERSATION_ACTIONS:
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index c297928ae5f6..14afa339f192 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -65,9 +65,6 @@ import java.util.Objects;
*/
public final class TextClassifierImpl implements TextClassifier {
- /** @hide */
- public static final String ACTIONS_INTENTS = "actions-intents";
-
private static final String LOG_TAG = DEFAULT_LOG_TAG;
private static final boolean DEBUG = false;
@@ -343,7 +340,11 @@ public final class TextClassifierImpl implements TextClassifier {
if (DEBUG) {
Log.d(DEFAULT_LOG_TAG, "onTextClassifierEvent() called with: event = [" + event + "]");
}
- mTextClassifierEventTronLogger.writeEvent(event);
+ try {
+ mTextClassifierEventTronLogger.writeEvent(event);
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Error writing event", e);
+ }
}
/** @inheritDoc */
@@ -566,12 +567,16 @@ public final class TextClassifierImpl implements TextClassifier {
final float foreignTextThreshold = mSettings.getLangIdThresholdOverride() >= 0
? mSettings.getLangIdThresholdOverride()
: 0.5f /* TODO: Load this from the langId model. */;
+ final Bundle foreignLanguageBundle =
+ detectForeignLanguage(classifiedText, foreignTextThreshold);
+ builder.setForeignLanguageExtra(foreignLanguageBundle);
+
boolean isPrimaryAction = true;
final ArrayList<Intent> sourceIntents = new ArrayList<>();
List<LabeledIntent> labeledIntents = mIntentFactory.create(
mContext,
classifiedText,
- isForeignText(classifiedText, foreignTextThreshold),
+ foreignLanguageBundle != null,
referenceTime,
highestScoringResult);
for (LabeledIntent labeledIntent : labeledIntents) {
@@ -590,28 +595,28 @@ public final class TextClassifierImpl implements TextClassifier {
labeledIntent.getIntent(), labeledIntent.getRequestCode())));
isPrimaryAction = false;
}
- builder.addAction(action);
- sourceIntents.add(labeledIntent.getIntent());
+ builder.addAction(action, labeledIntent.getIntent());
}
- final Bundle extras = new Bundle();
- extras.putParcelableArrayList(ACTIONS_INTENTS, sourceIntents);
-
- return builder.setId(createId(text, start, end))
- .setExtras(extras)
- .build();
+ return builder.setId(createId(text, start, end)).build();
}
- private boolean isForeignText(String text, float threshold) {
+ /**
+ * Returns a bundle with the language and confidence score if it finds the text to be
+ * in a foreign language. Otherwise returns null.
+ */
+ @Nullable
+ private Bundle detectForeignLanguage(String text, float threshold) {
if (threshold > 1) {
- return false;
+ return null;
}
// TODO: Revisit this algorithm.
try {
- final LangIdModel.LanguageResult[] langResults = getLangIdImpl().detectLanguages(text);
+ final LangIdModel langId = getLangIdImpl();
+ final LangIdModel.LanguageResult[] langResults = langId.detectLanguages(text);
if (langResults.length <= 0) {
- return false;
+ return null;
}
LangIdModel.LanguageResult highestScoringResult = langResults[0];
@@ -621,7 +626,7 @@ public final class TextClassifierImpl implements TextClassifier {
}
}
if (highestScoringResult.getScore() < threshold) {
- return false;
+ return null;
}
// TODO: Remove
Log.d(LOG_TAG, String.format("Language detected: <%s:%s>",
@@ -632,14 +637,15 @@ public final class TextClassifierImpl implements TextClassifier {
final int size = deviceLocales.size();
for (int i = 0; i < size; i++) {
if (deviceLocales.get(i).getLanguage().equals(detected.getLanguage())) {
- return false;
+ return null;
}
}
- return true;
+ return ExtrasUtils.createForeignLanguageExtra(
+ detected.getLanguage(), highestScoringResult.getScore(), langId.getVersion());
} catch (Throwable t) {
Log.e(LOG_TAG, "Error detecting foreign text. Ignored.", t);
}
- return false;
+ return null;
}
@Override
@@ -773,3 +779,4 @@ public final class TextClassifierImpl implements TextClassifier {
}
}
}
+
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 4a60b6a8185a..c38566b87d9c 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4112,9 +4112,9 @@ public class Editor {
}
}
- private MenuItem addAssistMenuItem(Menu menu, RemoteAction action, int intemId, int order,
+ private MenuItem addAssistMenuItem(Menu menu, RemoteAction action, int itemId, int order,
int showAsAction) {
- final MenuItem item = menu.add(TextView.ID_ASSIST, intemId, order, action.getTitle())
+ final MenuItem item = menu.add(TextView.ID_ASSIST, itemId, order, action.getTitle())
.setContentDescription(action.getContentDescription());
if (action.shouldShowIcon()) {
item.setIcon(action.getIcon().loadDrawable(mTextView.getContext()));
@@ -4188,7 +4188,8 @@ public class Editor {
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- getSelectionActionModeHelper().onSelectionAction(item.getItemId());
+ getSelectionActionModeHelper()
+ .onSelectionAction(item.getItemId(), item.getTitle().toString());
if (mProcessTextIntentActionsHandler.performMenuItemAction(item)) {
return true;
diff --git a/core/java/android/widget/SelectionActionModeHelper.java b/core/java/android/widget/SelectionActionModeHelper.java
index 4caf28881edc..564cfdd20d76 100644
--- a/core/java/android/widget/SelectionActionModeHelper.java
+++ b/core/java/android/widget/SelectionActionModeHelper.java
@@ -20,12 +20,14 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.annotation.WorkerThread;
+import android.app.RemoteAction;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PointF;
import android.graphics.RectF;
import android.os.AsyncTask;
import android.os.Build;
+import android.os.Bundle;
import android.os.LocaleList;
import android.text.Layout;
import android.text.Selection;
@@ -34,13 +36,16 @@ import android.text.TextUtils;
import android.text.util.Linkify;
import android.util.Log;
import android.view.ActionMode;
+import android.view.textclassifier.ExtrasUtils;
import android.view.textclassifier.SelectionEvent;
import android.view.textclassifier.SelectionEvent.InvocationMethod;
import android.view.textclassifier.SelectionSessionLogger;
import android.view.textclassifier.TextClassification;
import android.view.textclassifier.TextClassificationConstants;
+import android.view.textclassifier.TextClassificationContext;
import android.view.textclassifier.TextClassificationManager;
import android.view.textclassifier.TextClassifier;
+import android.view.textclassifier.TextClassifierEvent;
import android.view.textclassifier.TextSelection;
import android.widget.Editor.SelectionModifierCursorController;
@@ -166,16 +171,17 @@ public final class SelectionActionModeHelper {
}
}
- public void onSelectionAction(int menuItemId) {
+ /** Reports a selection action event. */
+ public void onSelectionAction(int menuItemId, @Nullable String actionLabel) {
mSelectionTracker.onSelectionAction(
mTextView.getSelectionStart(), mTextView.getSelectionEnd(),
- getActionType(menuItemId), mTextClassification);
+ getActionType(menuItemId), actionLabel, mTextClassification);
}
public void onSelectionDrag() {
mSelectionTracker.onSelectionAction(
mTextView.getSelectionStart(), mTextView.getSelectionEnd(),
- SelectionEvent.ACTION_DRAG, mTextClassification);
+ SelectionEvent.ACTION_DRAG, /* actionLabel= */ null, mTextClassification);
}
public void onTextChanged(int start, int end) {
@@ -511,8 +517,11 @@ public final class SelectionActionModeHelper {
mOriginalEnd = mSelectionEnd = selectionEnd;
mAllowReset = false;
maybeInvalidateLogger();
- mLogger.logSelectionStarted(mTextView.getTextClassificationSession(),
- text, selectionStart,
+ mLogger.logSelectionStarted(
+ mTextView.getTextClassificationSession(),
+ mTextView.getTextClassificationContext(),
+ text,
+ selectionStart,
isLink ? SelectionEvent.INVOCATION_LINK : SelectionEvent.INVOCATION_MANUAL);
}
@@ -570,10 +579,12 @@ public final class SelectionActionModeHelper {
public void onSelectionAction(
int selectionStart, int selectionEnd,
@SelectionEvent.ActionType int action,
+ @Nullable String actionLabel,
@Nullable TextClassification classification) {
if (isSelectionStarted()) {
mAllowReset = false;
- mLogger.logSelectionAction(selectionStart, selectionEnd, action, classification);
+ mLogger.logSelectionAction(
+ selectionStart, selectionEnd, action, actionLabel, classification);
}
}
@@ -596,7 +607,8 @@ public final class SelectionActionModeHelper {
mSelectionEnd = editor.getTextView().getSelectionEnd();
mLogger.logSelectionAction(
textView.getSelectionStart(), textView.getSelectionEnd(),
- SelectionEvent.ACTION_RESET, null /* classification */);
+ SelectionEvent.ACTION_RESET,
+ /* actionLabel= */ null, /* classification= */ null);
}
return selected;
}
@@ -605,7 +617,9 @@ public final class SelectionActionModeHelper {
public void onTextChanged(int start, int end, TextClassification classification) {
if (isSelectionStarted() && start == mSelectionStart && end == mSelectionEnd) {
- onSelectionAction(start, end, SelectionEvent.ACTION_OVERTYPE, classification);
+ onSelectionAction(
+ start, end, SelectionEvent.ACTION_OVERTYPE,
+ /* actionLabel= */ null, classification);
}
}
@@ -644,7 +658,8 @@ public final class SelectionActionModeHelper {
if (mIsPending) {
mLogger.logSelectionAction(
mSelectionStart, mSelectionEnd,
- SelectionEvent.ACTION_ABANDON, null /* classification */);
+ SelectionEvent.ACTION_ABANDON,
+ /* actionLabel= */ null, /* classification= */ null);
mSelectionStart = mSelectionEnd = -1;
mLogger.endTextClassificationSession();
mIsPending = false;
@@ -679,6 +694,11 @@ public final class SelectionActionModeHelper {
private final BreakIterator mTokenIterator;
@Nullable private TextClassifier mClassificationSession;
+ @Nullable private TextClassificationContext mClassificationContext;
+
+ @Nullable private TextClassifierEvent mTranslateViewEvent;
+ @Nullable private TextClassifierEvent mTranslateClickEvent;
+
private int mStartIndex;
private String mText;
@@ -690,6 +710,7 @@ public final class SelectionActionModeHelper {
public void logSelectionStarted(
TextClassifier classificationSession,
+ TextClassificationContext classificationContext,
CharSequence text, int index,
@InvocationMethod int invocationMethod) {
try {
@@ -701,6 +722,7 @@ public final class SelectionActionModeHelper {
mTokenIterator.setText(mText);
mStartIndex = index;
mClassificationSession = classificationSession;
+ mClassificationContext = classificationContext;
if (hasActiveClassificationSession()) {
mClassificationSession.onSelectionEvent(
SelectionEvent.createSelectionStartedEvent(invocationMethod, 0));
@@ -731,6 +753,7 @@ public final class SelectionActionModeHelper {
SelectionEvent.createSelectionModifiedEvent(
wordIndices[0], wordIndices[1]));
}
+ maybeGenerateTranslateViewEvent(classification);
}
} catch (Exception e) {
// Avoid crashes due to logging.
@@ -741,6 +764,7 @@ public final class SelectionActionModeHelper {
public void logSelectionAction(
int start, int end,
@SelectionEvent.ActionType int action,
+ @Nullable String actionLabel,
@Nullable TextClassification classification) {
try {
if (hasActiveClassificationSession()) {
@@ -757,6 +781,9 @@ public final class SelectionActionModeHelper {
SelectionEvent.createSelectionActionEvent(
wordIndices[0], wordIndices[1], action));
}
+
+ maybeGenerateTranslateClickEvent(classification, actionLabel);
+
if (SelectionEvent.isTerminal(action)) {
endTextClassificationSession();
}
@@ -773,6 +800,7 @@ public final class SelectionActionModeHelper {
public void endTextClassificationSession() {
if (hasActiveClassificationSession()) {
+ maybeReportTranslateEvents();
mClassificationSession.destroy();
}
}
@@ -843,6 +871,78 @@ public final class SelectionActionModeHelper {
private boolean isWhitespace(int start, int end) {
return PATTERN_WHITESPACE.matcher(mText.substring(start, end)).matches();
}
+
+ private void maybeGenerateTranslateViewEvent(@Nullable TextClassification classification) {
+ if (classification != null) {
+ final TextClassifierEvent event = generateTranslateEvent(
+ TextClassifierEvent.TYPE_ACTIONS_SHOWN,
+ classification, mClassificationContext, /* actionLabel= */null);
+ mTranslateViewEvent = (event != null) ? event : mTranslateViewEvent;
+ }
+ }
+
+ private void maybeGenerateTranslateClickEvent(
+ @Nullable TextClassification classification, String actionLabel) {
+ if (classification != null) {
+ mTranslateClickEvent = generateTranslateEvent(
+ TextClassifierEvent.TYPE_SMART_ACTION,
+ classification, mClassificationContext, actionLabel);
+ }
+ }
+
+ private void maybeReportTranslateEvents() {
+ // Translate view and click events should only be logged once per selection session.
+ if (mTranslateViewEvent != null) {
+ mClassificationSession.onTextClassifierEvent(mTranslateViewEvent);
+ mTranslateViewEvent = null;
+ }
+ if (mTranslateClickEvent != null) {
+ mClassificationSession.onTextClassifierEvent(mTranslateClickEvent);
+ mTranslateClickEvent = null;
+ }
+ }
+
+ @Nullable
+ private static TextClassifierEvent generateTranslateEvent(
+ int eventType, TextClassification classification,
+ TextClassificationContext classificationContext, @Nullable String actionLabel) {
+
+ // The platform attempts to log "views" and "clicks" of the "Translate" action.
+ // Views are logged if a user is presented with the translate action during a selection
+ // session.
+ // Clicks are logged if the user clicks on the translate action.
+ // The index of the translate action is also logged to indicate whether it might have
+ // been in the main panel or overflow panel of the selection toolbar.
+ // NOTE that the "views" metric may be flawed if a TextView removes the translate menu
+ // item via a custom action mode callback or does not show a selection menu item.
+
+ final RemoteAction translateAction = ExtrasUtils.findTranslateAction(classification);
+ if (translateAction == null) {
+ // No translate action present. Nothing to log. Exit.
+ return null;
+ }
+
+ if (eventType == TextClassifierEvent.TYPE_SMART_ACTION
+ && !translateAction.getTitle().toString().equals(actionLabel)) {
+ // Clicked action is not a translate action. Nothing to log. Exit.
+ // Note that we don't expect an actionLabel for "view" events.
+ return null;
+ }
+
+ final Bundle foreignLanguageExtra = ExtrasUtils.getForeignLanguageExtra(classification);
+ final String language = ExtrasUtils.getEntityType(foreignLanguageExtra);
+ final float score = ExtrasUtils.getScore(foreignLanguageExtra);
+ final String model = ExtrasUtils.getModelName(foreignLanguageExtra);
+ return new TextClassifierEvent.Builder(
+ TextClassifierEvent.CATEGORY_LANGUAGE_DETECTION, eventType)
+ .setEventContext(classificationContext)
+ .setResultId(classification.getId())
+ .setEntityTypes(language)
+ .setScore(score)
+ .setActionIndices(classification.getActions().indexOf(translateAction))
+ .setModelName(model)
+ .build();
+ }
}
/**
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2b45c0697155..8029cf0eb50e 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -456,6 +456,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
private TextClassifier mTextClassifier;
private TextClassifier mTextClassificationSession;
+ private TextClassificationContext mTextClassificationContext;
// A flag to prevent repeated movements from escaping the enclosing text view. The idea here is
// that if a user is holding down a movement key to traverse text, we shouldn't also traverse
@@ -12068,16 +12069,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} else {
widgetType = TextClassifier.WIDGET_TYPE_UNSELECTABLE_TEXTVIEW;
}
- final TextClassificationContext textClassificationContext =
- new TextClassificationContext.Builder(
- mContext.getPackageName(), widgetType)
- .build();
+ mTextClassificationContext = new TextClassificationContext.Builder(
+ mContext.getPackageName(), widgetType)
+ .build();
if (mTextClassifier != null) {
mTextClassificationSession = tcm.createTextClassificationSession(
- textClassificationContext, mTextClassifier);
+ mTextClassificationContext, mTextClassifier);
} else {
mTextClassificationSession = tcm.createTextClassificationSession(
- textClassificationContext);
+ mTextClassificationContext);
}
} else {
mTextClassificationSession = TextClassifier.NO_OP;
@@ -12087,6 +12087,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Returns the {@link TextClassificationContext} for the current TextClassifier session.
+ * @see #getTextClassificationSession()
+ */
+ @Nullable
+ TextClassificationContext getTextClassificationContext() {
+ return mTextClassificationContext;
+ }
+
+ /**
* Returns true if this TextView uses a no-op TextClassifier.
*/
boolean usesNoOpTextClassifier() {
diff --git a/core/java/com/android/internal/os/OWNERS b/core/java/com/android/internal/os/OWNERS
new file mode 100644
index 000000000000..928310549e6e
--- /dev/null
+++ b/core/java/com/android/internal/os/OWNERS
@@ -0,0 +1 @@
+per-file ZygoteArguments.java,ZygoteConnection.java,ZygoteInit.java,Zygote.java,ZygoteServer.java = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
diff --git a/core/jni/OWNERS b/core/jni/OWNERS
index a365a566f038..86342c47c455 100644
--- a/core/jni/OWNERS
+++ b/core/jni/OWNERS
@@ -4,3 +4,6 @@ per-file *Camera*,*camera* = shuzhenwang@google.com, yinchiayeh@google.com, zhij
# Connectivity
per-file android_net_* = ek@google.com, lorenzo@google.com, satk@google.com
+
+# Zygote
+per-file com_android_inernal_os_Zygote.*,fd_utils.* = chriswailes@google.com, ngeoffray@google.com, sehr@google.com, narayan@google.com, maco@google.com
diff --git a/core/jni/android_media_AudioAttributes.cpp b/core/jni/android_media_AudioAttributes.cpp
index 4be4def4a87b..b87a34d6c7aa 100644
--- a/core/jni/android_media_AudioAttributes.cpp
+++ b/core/jni/android_media_AudioAttributes.cpp
@@ -135,7 +135,7 @@ JNIAudioAttributeHelper::UniqueAaPtr JNIAudioAttributeHelper::makeUnique()
{
audio_attributes_t *aa = new (calloc(1, sizeof(audio_attributes_t)))
audio_attributes_t{AUDIO_ATTRIBUTES_INITIALIZER};
- return UniqueAaPtr{aa, free};
+ return UniqueAaPtr{aa};
}
jint JNIAudioAttributeHelper::nativeFromJava(JNIEnv* env, jobject jAudioAttributes,
diff --git a/core/jni/android_media_AudioAttributes.h b/core/jni/android_media_AudioAttributes.h
index c55835222086..628f7e3469e8 100644
--- a/core/jni/android_media_AudioAttributes.h
+++ b/core/jni/android_media_AudioAttributes.h
@@ -27,7 +27,11 @@ namespace android {
class JNIAudioAttributeHelper
{
public:
- using UniqueAaPtr = std::unique_ptr<audio_attributes_t, decltype(free)*>;
+ struct FreeDeleter {
+ void operator()(void *p) const { ::free(p); }
+ };
+
+ using UniqueAaPtr = std::unique_ptr<audio_attributes_t, FreeDeleter>;
/**
* @brief makeUnique helper to prevent leak
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index e64d2afe7bf3..ee11b6162db0 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -96,7 +96,7 @@ static jobjectArray android_os_VintfObject_report(JNIEnv* env, jclass)
return toJavaStringArray(env, cStrings);
}
-static jint verify(JNIEnv* env, jobjectArray packageInfo, android::vintf::CheckFlags::Type checks) {
+static jint android_os_VintfObject_verify(JNIEnv* env, jclass, jobjectArray packageInfo) {
std::vector<std::string> cPackageInfo;
if (packageInfo) {
size_t count = env->GetArrayLength(packageInfo);
@@ -109,18 +109,19 @@ static jint verify(JNIEnv* env, jobjectArray packageInfo, android::vintf::CheckF
}
}
std::string error;
- int32_t status = VintfObject::CheckCompatibility(cPackageInfo, &error, checks);
+ int32_t status = VintfObject::CheckCompatibility(cPackageInfo, &error);
if (status)
LOG(WARNING) << "VintfObject.verify() returns " << status << ": " << error;
return status;
}
-static jint android_os_VintfObject_verify(JNIEnv* env, jclass, jobjectArray packageInfo) {
- return verify(env, packageInfo, ::android::vintf::CheckFlags::ENABLE_ALL_CHECKS);
-}
-
static jint android_os_VintfObject_verifyWithoutAvb(JNIEnv* env, jclass) {
- return verify(env, nullptr, ::android::vintf::CheckFlags::DISABLE_AVB_CHECK);
+ std::string error;
+ int32_t status = VintfObject::CheckCompatibility({}, &error,
+ ::android::vintf::CheckFlags::DISABLE_AVB_CHECK);
+ if (status)
+ LOG(WARNING) << "VintfObject.verifyWithoutAvb() returns " << status << ": " << error;
+ return status;
}
static jobjectArray android_os_VintfObject_getHalNamesAndVersions(JNIEnv* env, jclass) {
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index ef3834cccc15..baf758752abe 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -240,7 +240,7 @@
<dimen name="notification_header_icon_size">18dp</dimen>
<!-- size (width and height) of the icon in the notification header -->
- <dimen name="notification_header_icon_size_ambient">20dp</dimen>
+ <dimen name="notification_header_icon_size_ambient">18dp</dimen>
<!-- The margin before the start of the app name in the header. -->
<dimen name="notification_header_app_name_margin_start">3dp</dimen>
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index 79afe697c504..0dc54e091f9d 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -374,7 +374,9 @@ easier.
<style name="TextAppearance.DeviceDefault.Caption" parent="TextAppearance.Material.Caption">
<item name="fontFamily">@string/config_bodyFontFamily</item>
</style>
- <style name="TextAppearance.DeviceDefault.ListItem" parent="TextAppearance.DeviceDefault.Subhead"/>
+ <style name="TextAppearance.DeviceDefault.ListItem" parent="TextAppearance.DeviceDefault.Subhead">
+ <item name="fontFamily">@string/config_headlineFontFamily</item>
+ </style>
<style name="TextAppearance.DeviceDefault.ListItemSecondary" parent="TextAppearance.DeviceDefault.Body1"/>
<!-- Preference Styles -->
diff --git a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
index 5e58f82038f1..582be9d51731 100644
--- a/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/TextClassifierTest.java
@@ -21,8 +21,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
+import android.app.RemoteAction;
import android.content.Context;
import android.content.Intent;
+import android.os.Bundle;
import android.os.LocaleList;
import android.text.Spannable;
import android.text.SpannableString;
@@ -246,25 +248,31 @@ public class TextClassifierTest {
public void testClassifyText_foreignText() {
LocaleList originalLocales = LocaleList.getDefault();
LocaleList.setDefault(LocaleList.forLanguageTags("en"));
- String foreignText = "これは日本語のテキストです";
+ String japaneseText = "これは日本語のテキストです";
Context context = new FakeContextBuilder()
.setIntentComponent(Intent.ACTION_TRANSLATE, FakeContextBuilder.DEFAULT_COMPONENT)
.build();
TextClassifier classifier = new TextClassifierImpl(context, TC_CONSTANTS);
TextClassification.Request request = new TextClassification.Request.Builder(
- foreignText, 0, foreignText.length())
+ japaneseText, 0, japaneseText.length())
.setDefaultLocales(LOCALES)
.build();
TextClassification classification = classifier.classifyText(request);
+ RemoteAction translateAction = classification.getActions().get(0);
assertEquals(1, classification.getActions().size());
assertEquals(
context.getString(com.android.internal.R.string.translate),
- classification.getActions().get(0).getTitle());
- Intent intent = (Intent) classification.getExtras()
- .getParcelableArrayList(TextClassifierImpl.ACTIONS_INTENTS).get(0);
+ translateAction.getTitle());
+
+ assertEquals(translateAction, ExtrasUtils.findTranslateAction(classification));
+ Intent intent = ExtrasUtils.getActionsIntents(classification).get(0);
assertEquals(Intent.ACTION_TRANSLATE, intent.getAction());
+ Bundle foreignLanguageInfo = ExtrasUtils.getForeignLanguageExtra(classification);
+ assertEquals("ja", ExtrasUtils.getEntityType(foreignLanguageInfo));
+ assertTrue(ExtrasUtils.getScore(foreignLanguageInfo) >= 0);
+ assertTrue(ExtrasUtils.getScore(foreignLanguageInfo) <= 1);
LocaleList.setDefault(originalLocales);
}
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a47ab875804f..bcac5fd63930 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -329,6 +329,7 @@ applications that come with the platform
<permission name="android.permission.USE_RESERVED_DISK"/>
<permission name="android.permission.WRITE_MEDIA_STORAGE"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ <permission name="android.permission.STATUS_BAR_SERVICE"/>
<permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/>
</privapp-permissions>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 97cb2ec2b4f7..f9e7dd177342 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -21,7 +21,6 @@ import android.annotation.ColorInt;
import android.annotation.ColorLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.annotation.WorkerThread;
import android.content.res.ResourcesImpl;
@@ -1762,9 +1761,7 @@ public final class Bitmap implements Parcelable {
* previously assigned color space.
*
* @param colorSpace to assign to the bitmap
- * @hide
*/
- @TestApi
public void setColorSpace(@NonNull ColorSpace colorSpace) {
checkRecycled("setColorSpace called on a recycled bitmap");
if (colorSpace == null) {
@@ -1815,9 +1812,7 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if the color space encoded in the long
* is invalid or unknown.
*
- * @hide pending API approval
*/
- @TestApi
public void eraseColor(@ColorLong long c) {
checkRecycled("Can't erase a recycled bitmap");
if (!isMutable()) {
@@ -1864,9 +1859,7 @@ public final class Bitmap implements Parcelable {
* @throws IllegalArgumentException if x, y exceed the bitmap's bounds
* @throws IllegalStateException if the bitmap's config is {@link Config#HARDWARE}
*
- * @hide pending API approval
*/
- @TestApi
public Color getColor(int x, int y) {
checkRecycled("Can't call getColor() on a recycled bitmap");
checkHardware("unable to getColor(), "
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 7eee6f4bf37d..73442db1c143 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -24,7 +24,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Px;
import android.annotation.Size;
-import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontVariationAxis;
import android.os.Build;
@@ -974,10 +973,7 @@ public class Paint {
* @see Color for APIs that help manipulate a color long.
*
* @return the paint's color (and alpha).
- *
- * @hide pending API approval
*/
- @TestApi
@ColorLong
public long getColorLong() {
return mColor;
@@ -1006,10 +1002,7 @@ public class Paint {
* to set in the paint.
* @throws IllegalArgumentException if the color space encoded in the long
* is invalid or unknown.
- *
- * @hide pending API approval
*/
- @TestApi
public void setColor(@ColorLong long color) {
ColorSpace cs = Color.colorSpace(color);
float r = Color.red(color);
@@ -1445,10 +1438,7 @@ public class Paint {
*
* @throws IllegalArgumentException if the color space encoded in the long
* is invalid or unknown.
- *
- * @hide pending API approval
*/
- @TestApi
public void setShadowLayer(float radius, float dx, float dy, @ColorLong long shadowColor) {
ColorSpace cs = Color.colorSpace(shadowColor);
float r = Color.red(shadowColor);
@@ -1517,9 +1507,7 @@ public class Paint {
* Returns the color of the shadow layer.
* @see #setShadowLayer(float,float,float,int)
* @see #setShadowLayer(float,float,float,long)
- * @hide pending API approval
*/
- @TestApi
public @ColorLong long getShadowLayerColorLong() {
return mShadowLayerColor;
}
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index b67aea224055..d9456355cb88 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -142,10 +142,8 @@ void SkiaRecordingCanvas::callDrawGLFunction(Functor* functor,
void SkiaRecordingCanvas::drawWebViewFunctor(int functor) {
FunctorDrawable* functorDrawable;
if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
- // TODO(cblume) use VkFunctorDrawable instead of VkInteropFunctorDrawable here when the
- // interop is disabled.
functorDrawable =
- mDisplayList->allocateDrawable<VkInteropFunctorDrawable>(functor, asSkCanvas());
+ mDisplayList->allocateDrawable<VkFunctorDrawable>(functor, asSkCanvas());
} else {
functorDrawable = mDisplayList->allocateDrawable<GLFunctorDrawable>(functor, asSkCanvas());
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 59c6a0a21cd1..63b57d166f1f 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -181,22 +181,14 @@ public class LocationManager {
"android.location.GPS_ENABLED_CHANGE";
/**
- * Broadcast intent action when the configured location providers
- * change. For use with {@link #isProviderEnabled(String)}. If you're interacting with the
- * {@link android.provider.Settings.Secure#LOCATION_MODE} API, use {@link #MODE_CHANGED_ACTION}
- * instead.
+ * Broadcast intent action when the set of enabled location providers changes. To check the
+ * status of a provider, use {@link #isProviderEnabled(String)}.
*/
- public static final String PROVIDERS_CHANGED_ACTION =
- "android.location.PROVIDERS_CHANGED";
+ public static final String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED";
/**
- * Broadcast intent action when {@link android.provider.Settings.Secure#LOCATION_MODE} changes.
- * For use with the {@link android.provider.Settings.Secure#LOCATION_MODE} API.
- * If you're interacting with {@link #isProviderEnabled(String)}, use
- * {@link #PROVIDERS_CHANGED_ACTION} instead.
- *
- * In the future, there may be mode changes that do not result in
- * {@link #PROVIDERS_CHANGED_ACTION} broadcasts.
+ * Broadcast intent action when the device location mode changes. To check the location mode,
+ * use {@link #isLocationEnabled()}.
*/
public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED";
@@ -207,8 +199,10 @@ public class LocationManager {
* If you're interacting with {@link #isProviderEnabled(String)}, use
* {@link #PROVIDERS_CHANGED_ACTION} instead.
*
+ * @deprecated Do not use.
* @hide
*/
+ @Deprecated
public static final String MODE_CHANGING_ACTION = "com.android.settings.location.MODE_CHANGING";
/**
@@ -299,7 +293,7 @@ public class LocationManager {
"com.android.settings.location.FOOTER_STRING";
// Map from LocationListeners to their associated ListenerTransport objects
- private HashMap<LocationListener,ListenerTransport> mListeners =
+ private final HashMap<LocationListener, ListenerTransport> mListeners =
new HashMap<LocationListener,ListenerTransport>();
private class ListenerTransport extends ILocationListener.Stub {
@@ -1264,39 +1258,20 @@ public class LocationManager {
}
/**
- * Returns the current enabled/disabled status of location
+ * Returns the current enabled/disabled state of location. To listen for changes, see
+ * {@link #MODE_CHANGED_ACTION}.
*
- * @return true if location is enabled. false if location is disabled.
+ * @return true if location is enabled and false if location is disabled.
*/
public boolean isLocationEnabled() {
return isLocationEnabledForUser(Process.myUserHandle());
}
/**
- * Method for enabling or disabling location.
- *
- * @param enabled true to enable location. false to disable location
- * @param userHandle the user to set
- *
- * @hide
- */
- @SystemApi
- @RequiresPermission(WRITE_SECURE_SETTINGS)
- public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
- Settings.Secure.putIntForUser(
- mContext.getContentResolver(),
- Settings.Secure.LOCATION_MODE,
- enabled
- ? Settings.Secure.LOCATION_MODE_HIGH_ACCURACY
- : Settings.Secure.LOCATION_MODE_OFF,
- userHandle.getIdentifier());
- }
-
- /**
- * Returns the current enabled/disabled status of location
+ * Returns the current enabled/disabled state of location.
*
* @param userHandle the user to query
- * @return true location is enabled. false if location is disabled.
+ * @return true if location is enabled and false if location is disabled.
*
* @hide
*/
@@ -1310,19 +1285,32 @@ public class LocationManager {
}
/**
- * Returns the current enabled/disabled status of the given provider.
+ * Enables or disables the location setting.
*
- * <p>If the user has enabled this provider in the Settings menu, true
- * is returned otherwise false is returned
+ * @param enabled true to enable location and false to disable location.
+ * @param userHandle the user to set
*
- * <p>Callers should instead use {@link #isLocationEnabled()}
- * unless they depend on provider-specific APIs such as
- * {@link #requestLocationUpdates(String, long, float, LocationListener)}.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(WRITE_SECURE_SETTINGS)
+ public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
+ Settings.Secure.putIntForUser(
+ mContext.getContentResolver(),
+ Settings.Secure.LOCATION_MODE,
+ enabled
+ ? Settings.Secure.LOCATION_MODE_ON
+ : Settings.Secure.LOCATION_MODE_OFF,
+ userHandle.getIdentifier());
+ }
+
+ /**
+ * Returns the current enabled/disabled status of the given provider. To listen for changes, see
+ * {@link #PROVIDERS_CHANGED_ACTION}.
*
- * <p>
- * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this
- * method would throw {@link SecurityException} if the location permissions
- * were not sufficient to use the specified provider.
+ * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw
+ * {@link SecurityException} if the location permissions were not sufficient to use the
+ * specified provider.
*
* @param provider the name of the provider
* @return true if the provider exists and is enabled
@@ -1334,19 +1322,13 @@ public class LocationManager {
}
/**
- * Returns the current enabled/disabled status of the given provider and user.
- *
- * <p>If the user has enabled this provider in the Settings menu, true
- * is returned otherwise false is returned
- *
- * <p>Callers should instead use {@link #isLocationEnabled()}
- * unless they depend on provider-specific APIs such as
- * {@link #requestLocationUpdates(String, long, float, LocationListener)}.
+ * Returns the current enabled/disabled status of the given provider and user. Callers should
+ * prefer {@link #isLocationEnabledForUser(UserHandle)} unless they depend on provider-specific
+ * APIs.
*
- * <p>
- * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this
- * method would throw {@link SecurityException} if the location permissions
- * were not sufficient to use the specified provider.
+ * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw
+ * {@link SecurityException} if the location permissions were not sufficient to use the
+ * specified provider.
*
* @param provider the name of the provider
* @param userHandle the user to query
@@ -1367,12 +1349,14 @@ public class LocationManager {
}
/**
- * Method for enabling or disabling a single location provider.
+ * Method for enabling or disabling a single location provider. This method is deprecated and
+ * functions as a best effort. It should not be relied on in any meaningful sense as providers
+ * may no longer be enabled or disabled by clients.
*
* @param provider the name of the provider
* @param enabled true to enable the provider. false to disable the provider
* @param userHandle the user to set
- * @return true if the value was set, false on database errors
+ * @return true if the value was set, false otherwise
*
* @throws IllegalArgumentException if provider is null
* @deprecated Do not manipulate providers individually, use
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 3d0afb098697..0480eab580ac 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -683,6 +683,7 @@ public final class LocationRequest implements Parcelable {
request.setSmallestDisplacement(in.readFloat());
request.setHideFromAppOps(in.readInt() != 0);
request.setLowPowerMode(in.readInt() != 0);
+ request.setLocationSettingsIgnored(in.readInt() != 0);
String provider = in.readString();
if (provider != null) request.setProvider(provider);
WorkSource workSource = in.readParcelable(null);
@@ -711,6 +712,7 @@ public final class LocationRequest implements Parcelable {
parcel.writeFloat(mSmallestDisplacement);
parcel.writeInt(mHideFromAppOps ? 1 : 0);
parcel.writeInt(mLowPowerMode ? 1 : 0);
+ parcel.writeInt(mLocationSettingsIgnored ? 1 : 0);
parcel.writeString(mProvider);
parcel.writeParcelable(mWorkSource, 0);
}
@@ -755,6 +757,9 @@ public final class LocationRequest implements Parcelable {
s.append(" num=").append(mNumUpdates);
}
s.append(" lowPowerMode=").append(mLowPowerMode);
+ if (mLocationSettingsIgnored) {
+ s.append(" ignoreSettings");
+ }
s.append(']');
return s.toString();
}
diff --git a/media/Android.bp b/media/Android.bp
index e7d5faf52d69..d7b8dd23bd6b 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -1,30 +1,4 @@
java_library {
- name: "updatable-media1",
-
- srcs: [
- ":media1-srcs",
- ":framework-media-annotation-srcs",
- ],
-
- aidl: {
- export_include_dirs: [
- "apex/java",
- ],
-
- // TODO: find out a way to include only the necessary aidl files instead of dirs.
- include_dirs: [
- "frameworks/base/core/java",
- "frameworks/base/media/java",
- ],
- },
-
- installable: true,
-
- // Make sure that the implementaion only relies on SDK or system APIs.
- sdk_version: "system_current",
-}
-
-java_library {
name: "updatable-media",
srcs: [
@@ -57,55 +31,12 @@ java_library {
filegroup {
name: "media-srcs-without-aidls",
srcs : [
- ":media1-srcs-without-aidls",
":mediasession2-srcs-without-aidls",
":mediaplayer2-srcs",
],
}
filegroup {
- name: "media1-srcs",
- srcs: [
- "apex/java/android/media/MediaDescription.java",
- "apex/java/android/media/MediaParceledListSlice.java",
- "apex/java/android/media/Rating.java",
- "apex/java/android/media/VolumeProvider.java",
- "apex/java/android/media/browse/MediaBrowser.java",
- "apex/java/android/media/browse/MediaBrowserUtils.java",
- "apex/java/android/media/session/ControllerCallbackLink.java",
- "apex/java/android/media/session/ControllerLink.java",
- "apex/java/android/media/session/ISession.aidl",
- "apex/java/android/media/session/ISessionCallback.aidl",
- "apex/java/android/media/session/ISessionController.aidl",
- "apex/java/android/media/session/ISessionControllerCallback.aidl",
- "apex/java/android/media/session/MediaController.java",
- "apex/java/android/media/session/MediaSessionEngine.java",
- "apex/java/android/media/session/MediaSessionProviderService.java",
- "apex/java/android/media/session/PlaybackState.java",
- "apex/java/android/media/session/SessionCallbackLink.java",
- "apex/java/android/media/session/SessionLink.java",
- "apex/java/android/service/media/IMediaBrowserService.aidl",
- "apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl",
- "apex/java/android/service/media/MediaBrowserService.java",
- ],
-}
-
-filegroup {
- name: "media1-srcs-without-aidls",
- srcs: [
- ":media1-srcs",
- ],
- exclude_srcs: [
- "apex/java/android/media/session/ISession.aidl",
- "apex/java/android/media/session/ISessionCallback.aidl",
- "apex/java/android/media/session/ISessionController.aidl",
- "apex/java/android/media/session/ISessionControllerCallback.aidl",
- "apex/java/android/service/media/IMediaBrowserService.aidl",
- "apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl",
- ],
-}
-
-filegroup {
name: "mediasession2-srcs",
srcs: [
"apex/java/android/media/Controller2Link.java",
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
index 1a1f6fb4457a..0fd496bda251 100644
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ b/media/apex/java/android/media/MediaPlayer2.java
@@ -21,6 +21,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
+import android.annotation.TestApi;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
@@ -3667,53 +3668,66 @@ public class MediaPlayer2 implements AutoCloseable
}
/**
- * The status codes for {@link DrmEventCallback#onDrmPrepared} listener.
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
* <p>
*
* DRM preparation has succeeded.
- * @hide
*/
public static final int PREPARE_DRM_STATUS_SUCCESS = 0;
/**
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
+ * <p>
+ *
* The device required DRM provisioning but couldn't reach the provisioning server.
- * @hide
*/
public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1;
/**
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
+ * <p>
+ *
* The device required DRM provisioning but the provisioning server denied the request.
- * @hide
*/
public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2;
/**
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
+ * <p>
+ *
* The DRM preparation has failed .
- * @hide
*/
public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3;
/**
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
+ * <p>
+ *
* The crypto scheme UUID is not supported by the device.
- * @hide
*/
public static final int PREPARE_DRM_STATUS_UNSUPPORTED_SCHEME = 4;
/**
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
+ * <p>
+ *
* The hardware resources are not available, due to being in use.
- * @hide
*/
public static final int PREPARE_DRM_STATUS_RESOURCE_BUSY = 5;
/**
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
+ * <p>
+ *
* Restoring persisted offline keys failed.
- * @hide
*/
public static final int PREPARE_DRM_STATUS_RESTORE_ERROR = 6;
/**
+ * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
+ * <p>
+ *
* Error during key request/response exchange with license server.
- * @hide
*/
public static final int PREPARE_DRM_STATUS_KEY_EXCHANGE_ERROR = 7;
@@ -3758,6 +3772,7 @@ public class MediaPlayer2 implements AutoCloseable
* @throws IllegalStateException if called before being prepared
* @hide
*/
+ @TestApi
public DrmInfo getDrmInfo(@NonNull DataSourceDesc dsd) {
final SourceInfo sourceInfo = getSourceInfo(dsd);
if (sourceInfo != null) {
@@ -3814,6 +3829,7 @@ public class MediaPlayer2 implements AutoCloseable
* @hide
*/
// This is an asynchronous call.
+ @TestApi
public Object prepareDrm(@NonNull DataSourceDesc dsd, @NonNull UUID uuid) {
return addTask(newPrepareDrmTask(dsd, uuid));
}
@@ -3905,6 +3921,7 @@ public class MediaPlayer2 implements AutoCloseable
* @hide
*/
// This is a synchronous call.
+ @TestApi
public void releaseDrm(@NonNull DataSourceDesc dsd)
throws NoDrmSchemeException {
final SourceInfo sourceInfo = getSourceInfo(dsd);
@@ -3955,6 +3972,7 @@ public class MediaPlayer2 implements AutoCloseable
* @throws NoDrmSchemeException if there is no active DRM session
* @hide
*/
+ @TestApi
public MediaDrm.KeyRequest getDrmKeyRequest(
@NonNull DataSourceDesc dsd,
@Nullable byte[] keySetId, @Nullable byte[] initData,
@@ -3997,6 +4015,7 @@ public class MediaPlayer2 implements AutoCloseable
* @hide
*/
// This is a synchronous call.
+ @TestApi
public byte[] provideDrmKeyResponse(
@NonNull DataSourceDesc dsd,
@Nullable byte[] keySetId, @NonNull byte[] response)
@@ -4023,6 +4042,7 @@ public class MediaPlayer2 implements AutoCloseable
* @hide
*/
// This is a synchronous call.
+ @TestApi
public void restoreDrmKeys(
@NonNull DataSourceDesc dsd,
@NonNull byte[] keySetId)
@@ -4050,6 +4070,7 @@ public class MediaPlayer2 implements AutoCloseable
* @throws NoDrmSchemeException if there is no active DRM session
* @hide
*/
+ @TestApi
public String getDrmPropertyString(
@NonNull DataSourceDesc dsd,
@NonNull @MediaDrmStringProperty String propertyName)
@@ -4078,6 +4099,7 @@ public class MediaPlayer2 implements AutoCloseable
* @hide
*/
// This is a synchronous call.
+ @TestApi
public void setDrmPropertyString(
@NonNull DataSourceDesc dsd,
@NonNull @MediaDrmStringProperty String propertyName, @NonNull String value)
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index f756658b4fa8..0c3d6255f871 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -3314,7 +3314,7 @@ final public class MediaCodec {
*/
public void setAudioPresentation(@NonNull AudioPresentation presentation) {
if (presentation == null) {
- throw new IllegalArgumentException("audio presentation is null");
+ throw new NullPointerException("audio presentation is null");
}
native_setAudioPresentation(presentation.getPresentationId(), presentation.getProgramId());
}
diff --git a/media/apex/java/android/media/MediaDescription.aidl b/media/java/android/media/MediaDescription.aidl
index 6f934f75aa28..6f934f75aa28 100644
--- a/media/apex/java/android/media/MediaDescription.aidl
+++ b/media/java/android/media/MediaDescription.aidl
diff --git a/media/apex/java/android/media/MediaDescription.java b/media/java/android/media/MediaDescription.java
index 39eeb3eae49f..39eeb3eae49f 100644
--- a/media/apex/java/android/media/MediaDescription.java
+++ b/media/java/android/media/MediaDescription.java
diff --git a/media/apex/java/android/media/MediaParceledListSlice.aidl b/media/java/android/media/MediaParceledListSlice.aidl
index 5c0e5bc84720..5c0e5bc84720 100644
--- a/media/apex/java/android/media/MediaParceledListSlice.aidl
+++ b/media/java/android/media/MediaParceledListSlice.aidl
diff --git a/media/apex/java/android/media/MediaParceledListSlice.java b/media/java/android/media/MediaParceledListSlice.java
index 16a37d99fb86..16a37d99fb86 100644
--- a/media/apex/java/android/media/MediaParceledListSlice.java
+++ b/media/java/android/media/MediaParceledListSlice.java
diff --git a/media/apex/java/android/media/Rating.aidl b/media/java/android/media/Rating.aidl
index 1dc336aeb79d..1dc336aeb79d 100644
--- a/media/apex/java/android/media/Rating.aidl
+++ b/media/java/android/media/Rating.aidl
diff --git a/media/apex/java/android/media/Rating.java b/media/java/android/media/Rating.java
index ffe7e48f25e4..ffe7e48f25e4 100644
--- a/media/apex/java/android/media/Rating.java
+++ b/media/java/android/media/Rating.java
diff --git a/media/apex/java/android/media/VolumeProvider.java b/media/java/android/media/VolumeProvider.java
index 49202eecef19..49202eecef19 100644
--- a/media/apex/java/android/media/VolumeProvider.java
+++ b/media/java/android/media/VolumeProvider.java
diff --git a/media/apex/java/android/media/browse/MediaBrowser.aidl b/media/java/android/media/browse/MediaBrowser.aidl
index 782e09471a56..782e09471a56 100644
--- a/media/apex/java/android/media/browse/MediaBrowser.aidl
+++ b/media/java/android/media/browse/MediaBrowser.aidl
diff --git a/media/apex/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java
index 2dffef9fb40a..2dffef9fb40a 100644
--- a/media/apex/java/android/media/browse/MediaBrowser.java
+++ b/media/java/android/media/browse/MediaBrowser.java
diff --git a/media/apex/java/android/media/browse/MediaBrowserUtils.java b/media/java/android/media/browse/MediaBrowserUtils.java
index 19d9f008d3db..19d9f008d3db 100644
--- a/media/apex/java/android/media/browse/MediaBrowserUtils.java
+++ b/media/java/android/media/browse/MediaBrowserUtils.java
diff --git a/media/apex/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/session/ControllerCallbackLink.aidl
index 8ee8c7d00148..8ee8c7d00148 100644
--- a/media/apex/java/android/media/session/ControllerCallbackLink.aidl
+++ b/media/java/android/media/session/ControllerCallbackLink.aidl
diff --git a/media/apex/java/android/media/session/ControllerCallbackLink.java b/media/java/android/media/session/ControllerCallbackLink.java
index adc14a550b7d..adc14a550b7d 100644
--- a/media/apex/java/android/media/session/ControllerCallbackLink.java
+++ b/media/java/android/media/session/ControllerCallbackLink.java
diff --git a/media/apex/java/android/media/session/ControllerLink.aidl b/media/java/android/media/session/ControllerLink.aidl
index 532df59d16cf..532df59d16cf 100644
--- a/media/apex/java/android/media/session/ControllerLink.aidl
+++ b/media/java/android/media/session/ControllerLink.aidl
diff --git a/media/apex/java/android/media/session/ControllerLink.java b/media/java/android/media/session/ControllerLink.java
index f60ec000f2d2..f60ec000f2d2 100644
--- a/media/apex/java/android/media/session/ControllerLink.java
+++ b/media/java/android/media/session/ControllerLink.java
diff --git a/media/apex/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index 9b1ad7bcf77c..9b1ad7bcf77c 100644
--- a/media/apex/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
diff --git a/media/apex/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index 9b86bfced340..9b86bfced340 100644
--- a/media/apex/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
diff --git a/media/apex/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index e697c65e11c0..e697c65e11c0 100644
--- a/media/apex/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
diff --git a/media/apex/java/android/media/session/ISessionControllerCallback.aidl b/media/java/android/media/session/ISessionControllerCallback.aidl
index 56ae852d6f50..56ae852d6f50 100644
--- a/media/apex/java/android/media/session/ISessionControllerCallback.aidl
+++ b/media/java/android/media/session/ISessionControllerCallback.aidl
diff --git a/media/apex/java/android/media/session/MediaController.aidl b/media/java/android/media/session/MediaController.aidl
index 17167f45d0e3..17167f45d0e3 100644
--- a/media/apex/java/android/media/session/MediaController.aidl
+++ b/media/java/android/media/session/MediaController.aidl
diff --git a/media/apex/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 1333ab097219..1333ab097219 100644
--- a/media/apex/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index ca3346c9a8c4..03627de9343c 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -142,10 +142,9 @@ public final class MediaSession {
MediaSessionManager manager = (MediaSessionManager) context
.getSystemService(Context.MEDIA_SESSION_SERVICE);
try {
- MediaSessionEngine.CallbackStub cbStub = new MediaSessionEngine.CallbackStub();
- SessionCallbackLink cbLink = new SessionCallbackLink(context, cbStub);
+ SessionCallbackLink cbLink = new SessionCallbackLink(context);
SessionLink sessionLink = manager.createSession(cbLink, tag);
- mImpl = new MediaSessionEngine(context, sessionLink, cbLink, cbStub);
+ mImpl = new MediaSessionEngine(context, sessionLink, cbLink);
mMaxBitmapSize = context.getResources().getDimensionPixelSize(
android.R.dimen.config_mediaMetadataBitmapMaxSize);
} catch (RuntimeException e) {
diff --git a/media/apex/java/android/media/session/MediaSessionEngine.java b/media/java/android/media/session/MediaSessionEngine.java
index 31714e1bde7f..7fea90dd0c43 100644
--- a/media/apex/java/android/media/session/MediaSessionEngine.java
+++ b/media/java/android/media/session/MediaSessionEngine.java
@@ -19,7 +19,6 @@ package android.media.session;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.annotation.UnsupportedAppUsage;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
@@ -44,7 +43,6 @@ import android.util.Pair;
import android.view.KeyEvent;
import android.view.ViewConfiguration;
-import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Objects;
@@ -60,10 +58,7 @@ public final class MediaSessionEngine implements AutoCloseable {
private final MediaSession.Token mSessionToken;
private final MediaController mController;
private final SessionLink mSessionLink;
- private final SessionCallbackLink mCbLink;
- // Do not change the name of mCallbackWrapper. Support lib accesses this by using reflection.
- @UnsupportedAppUsage
private CallbackMessageHandler mCallbackHandler;
private VolumeProvider mVolumeProvider;
private PlaybackState mPlaybackState;
@@ -78,14 +73,12 @@ public final class MediaSessionEngine implements AutoCloseable {
*
* @param context The context to use to create the session.
* @param sessionLink A session link for the binder of MediaSessionRecord
- * @param cbStub A callback link that handles incoming command to {@link MediaSession.Callback}.
*/
public MediaSessionEngine(@NonNull Context context, @NonNull SessionLink sessionLink,
- @NonNull SessionCallbackLink cbLink, @NonNull CallbackStub cbStub) {
+ @NonNull SessionCallbackLink cbLink) {
mSessionLink = sessionLink;
- mCbLink = cbLink;
- cbStub.setSessionImpl(this);
+ cbLink.setSessionEngine(this);
mSessionToken = new MediaSession.Token(mSessionLink.getController());
mController = new MediaController(context, mSessionToken);
}
@@ -479,97 +472,97 @@ public final class MediaSessionEngine implements AutoCloseable {
}
}
- private void dispatchPrepare(RemoteUserInfo caller) {
+ void dispatchPrepare(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null);
}
- private void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
+ void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras);
}
- private void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
+ void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras);
}
- private void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
+ void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras);
}
- private void dispatchPlay(RemoteUserInfo caller) {
+ void dispatchPlay(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null);
}
- private void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
+ void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras);
}
- private void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
+ void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
}
- private void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
+ void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras);
}
- private void dispatchSkipToItem(RemoteUserInfo caller, long id) {
+ void dispatchSkipToItem(RemoteUserInfo caller, long id) {
postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null);
}
- private void dispatchPause(RemoteUserInfo caller) {
+ void dispatchPause(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null);
}
- private void dispatchStop(RemoteUserInfo caller) {
+ void dispatchStop(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null);
}
- private void dispatchNext(RemoteUserInfo caller) {
+ void dispatchNext(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null);
}
- private void dispatchPrevious(RemoteUserInfo caller) {
+ void dispatchPrevious(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null);
}
- private void dispatchFastForward(RemoteUserInfo caller) {
+ void dispatchFastForward(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null);
}
- private void dispatchRewind(RemoteUserInfo caller) {
+ void dispatchRewind(RemoteUserInfo caller) {
postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null);
}
- private void dispatchSeekTo(RemoteUserInfo caller, long pos) {
+ void dispatchSeekTo(RemoteUserInfo caller, long pos) {
postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null);
}
- private void dispatchRate(RemoteUserInfo caller, Rating rating) {
+ void dispatchRate(RemoteUserInfo caller, Rating rating) {
postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null);
}
- private void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) {
+ void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) {
postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
}
- private void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) {
+ void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) {
postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null);
}
- private void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent,
+ void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent,
long delay) {
postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
mediaButtonIntent, null, delay);
}
- private void dispatchAdjustVolume(RemoteUserInfo caller, int direction) {
+ void dispatchAdjustVolume(RemoteUserInfo caller, int direction) {
postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null);
}
- private void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) {
+ void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) {
postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null);
}
- private void dispatchCommand(RemoteUserInfo caller, String command, Bundle args,
+ void dispatchCommand(RemoteUserInfo caller, String command, Bundle args,
ResultReceiver resultCb) {
Command cmd = new Command(command, args, resultCb);
postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null);
@@ -979,259 +972,7 @@ public final class MediaSessionEngine implements AutoCloseable {
}
}
- /**
- * @hide
- */
- @SystemApi
- public static final class CallbackStub extends SessionCallbackLink.CallbackStub {
- private WeakReference<MediaSessionEngine> mSessionImpl;
-
- private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid) {
- return new RemoteUserInfo(packageName, pid, uid);
- }
-
- public CallbackStub() {
- }
-
- @Override
- public void onCommand(String packageName, int pid, int uid,
- ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchCommand(createRemoteUserInfo(packageName, pid, uid),
- command, args, cb);
- }
- }
-
- @Override
- public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent,
- int sequenceNumber, ResultReceiver cb) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- try {
- if (sessionImpl != null) {
- sessionImpl.dispatchMediaButton(
- createRemoteUserInfo(packageName, pid, uid), mediaButtonIntent);
- }
- } finally {
- if (cb != null) {
- cb.send(sequenceNumber, null);
- }
- }
- }
-
- @Override
- public void onMediaButtonFromController(String packageName, int pid, int uid,
- ControllerCallbackLink caller, Intent mediaButtonIntent) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid),
- mediaButtonIntent);
- }
- }
-
- @Override
- public void onPrepare(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onPrepareFromMediaId(String packageName, int pid, int uid,
- ControllerCallbackLink caller, String mediaId,
- Bundle extras) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPrepareFromMediaId(
- createRemoteUserInfo(packageName, pid, uid), mediaId, extras);
- }
- }
-
- @Override
- public void onPrepareFromSearch(String packageName, int pid, int uid,
- ControllerCallbackLink caller, String query,
- Bundle extras) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPrepareFromSearch(
- createRemoteUserInfo(packageName, pid, uid), query, extras);
- }
- }
-
- @Override
- public void onPrepareFromUri(String packageName, int pid, int uid,
- ControllerCallbackLink caller, Uri uri, Bundle extras) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPrepareFromUri(
- createRemoteUserInfo(packageName, pid, uid), uri, extras);
- }
- }
-
- @Override
- public void onPlay(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPlay(createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onPlayFromMediaId(String packageName, int pid, int uid,
- ControllerCallbackLink caller, String mediaId,
- Bundle extras) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPlayFromMediaId(
- createRemoteUserInfo(packageName, pid, uid), mediaId, extras);
- }
- }
-
- @Override
- public void onPlayFromSearch(String packageName, int pid, int uid,
- ControllerCallbackLink caller, String query,
- Bundle extras) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPlayFromSearch(
- createRemoteUserInfo(packageName, pid, uid), query, extras);
- }
- }
-
- @Override
- public void onPlayFromUri(String packageName, int pid, int uid,
- ControllerCallbackLink caller, Uri uri, Bundle extras) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPlayFromUri(
- createRemoteUserInfo(packageName, pid, uid), uri, extras);
- }
- }
-
- @Override
- public void onSkipToTrack(String packageName, int pid, int uid,
- ControllerCallbackLink caller, long id) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchSkipToItem(
- createRemoteUserInfo(packageName, pid, uid), id);
- }
- }
-
- @Override
- public void onPause(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPause(createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onStop(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchStop(createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onNext(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchNext(createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onPrevious(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onFastForward(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchFastForward(
- createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onRewind(String packageName, int pid, int uid,
- ControllerCallbackLink caller) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchRewind(createRemoteUserInfo(packageName, pid, uid));
- }
- }
-
- @Override
- public void onSeekTo(String packageName, int pid, int uid,
- ControllerCallbackLink caller, long pos) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchSeekTo(
- createRemoteUserInfo(packageName, pid, uid), pos);
- }
- }
-
- @Override
- public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller,
- Rating rating) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchRate(
- createRemoteUserInfo(packageName, pid, uid), rating);
- }
- }
-
- @Override
- public void onCustomAction(String packageName, int pid, int uid,
- ControllerCallbackLink caller, String action, Bundle args) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchCustomAction(
- createRemoteUserInfo(packageName, pid, uid), action, args);
- }
- }
-
- @Override
- public void onAdjustVolume(String packageName, int pid, int uid,
- ControllerCallbackLink caller, int direction) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchAdjustVolume(
- createRemoteUserInfo(packageName, pid, uid), direction);
- }
- }
-
- @Override
- public void onSetVolumeTo(String packageName, int pid, int uid,
- ControllerCallbackLink caller, int value) {
- MediaSessionEngine sessionImpl = mSessionImpl.get();
- if (sessionImpl != null) {
- sessionImpl.dispatchSetVolumeTo(
- createRemoteUserInfo(packageName, pid, uid), value);
- }
- }
-
- void setSessionImpl(MediaSessionEngine sessionImpl) {
- mSessionImpl = new WeakReference<>(sessionImpl);
- }
- }
-
- /**
+ /**
* A single item that is part of the play queue. It contains a description
* of the item and its id in the queue.
*/
diff --git a/media/apex/java/android/media/session/MediaSessionProviderService.java b/media/java/android/media/session/MediaSessionProviderService.java
index 9a346ff4a12e..9a346ff4a12e 100644
--- a/media/apex/java/android/media/session/MediaSessionProviderService.java
+++ b/media/java/android/media/session/MediaSessionProviderService.java
diff --git a/media/apex/java/android/media/session/PlaybackState.aidl b/media/java/android/media/session/PlaybackState.aidl
index 0876ebd2d4d2..0876ebd2d4d2 100644
--- a/media/apex/java/android/media/session/PlaybackState.aidl
+++ b/media/java/android/media/session/PlaybackState.aidl
diff --git a/media/apex/java/android/media/session/PlaybackState.java b/media/java/android/media/session/PlaybackState.java
index 6b28c976c710..6b28c976c710 100644
--- a/media/apex/java/android/media/session/PlaybackState.java
+++ b/media/java/android/media/session/PlaybackState.java
diff --git a/media/apex/java/android/media/session/SessionCallbackLink.aidl b/media/java/android/media/session/SessionCallbackLink.aidl
index c489e5bee6e2..c489e5bee6e2 100644
--- a/media/apex/java/android/media/session/SessionCallbackLink.aidl
+++ b/media/java/android/media/session/SessionCallbackLink.aidl
diff --git a/media/apex/java/android/media/session/SessionCallbackLink.java b/media/java/android/media/session/SessionCallbackLink.java
index 3bcb65c42010..4c2918a0fa94 100644
--- a/media/apex/java/android/media/session/SessionCallbackLink.java
+++ b/media/java/android/media/session/SessionCallbackLink.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.Rating;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -35,6 +36,8 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
+import java.lang.ref.WeakReference;
+
/**
* Handles incoming commands to {@link MediaSession.Callback}.
* @hide
@@ -42,16 +45,15 @@ import android.os.ResultReceiver;
@SystemApi
public final class SessionCallbackLink implements Parcelable {
final Context mContext;
- final CallbackStub mCallbackStub;
final ISessionCallback mISessionCallback;
/**
* Constructor for stub (Callee)
+ * @hide
*/
- SessionCallbackLink(@NonNull Context context, @NonNull CallbackStub callbackStub) {
+ public SessionCallbackLink(@NonNull Context context) {
mContext = context;
- mCallbackStub = callbackStub;
- mISessionCallback = new CallbackStubProxy();
+ mISessionCallback = new CallbackStub();
}
/**
@@ -59,11 +61,19 @@ public final class SessionCallbackLink implements Parcelable {
*/
public SessionCallbackLink(IBinder binder) {
mContext = null;
- mCallbackStub = null;
mISessionCallback = ISessionCallback.Stub.asInterface(binder);
}
/**
+ * Set {@link MediaSessionEngine} which will be used by {@link CallbackStub}.
+ */
+ void setSessionEngine(@Nullable MediaSessionEngine sessionImpl) {
+ if (mISessionCallback instanceof CallbackStub) {
+ ((CallbackStub) mISessionCallback).mSessionImpl = new WeakReference<>(sessionImpl);
+ }
+ }
+
+ /**
* Notify session that a controller sends a command.
*
* @param packageName the package name of the controller
@@ -540,139 +550,24 @@ public final class SessionCallbackLink implements Parcelable {
}
};
- /**
- * Class for Stub implementation
- */
- abstract static class CallbackStub {
- /** Stub method for ISessionCallback.notifyCommand */
- public void onCommand(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull String command,
- @Nullable Bundle args, @Nullable ResultReceiver cb) {
- }
-
- /** Stub method for ISessionCallback.notifyMediaButton */
- public void onMediaButton(@NonNull String packageName, int pid, int uid,
- @NonNull Intent mediaButtonIntent, int sequenceNumber,
- @Nullable ResultReceiver cb) {
- }
-
- /** Stub method for ISessionCallback.notifyMediaButtonFromController */
- public void onMediaButtonFromController(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull Intent mediaButtonIntent) {
- }
-
- /** Stub method for ISessionCallback.notifyPrepare */
- public void onPrepare(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
-
- /** Stub method for ISessionCallback.notifyPrepareFromMediaId */
- public void onPrepareFromMediaId(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
- @Nullable Bundle extras) {
- }
-
- /** Stub method for ISessionCallback.notifyPrepareFromSearch */
- public void onPrepareFromSearch(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, String query, @Nullable Bundle extras) {
- }
-
- /** Stub method for ISessionCallback.notifyPrepareFromUri */
- public void onPrepareFromUri(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) {
- }
-
- /** Stub method for ISessionCallback.notifyPlay */
- public void onPlay(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
-
- /** Stub method for ISessionCallback.notifyPlayFromMediaId */
- public void onPlayFromMediaId(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull String mediaId,
- @Nullable Bundle extras) {
- }
-
- /** Stub method for ISessionCallback.notifyPlayFromSearch */
- public void onPlayFromSearch(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, String query, @Nullable Bundle extras) {
- }
-
- /** Stub method for ISessionCallback.notifyPlayFromUri */
- public void onPlayFromUri(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull Uri uri, @Nullable Bundle extras) {
- }
-
- /** Stub method for ISessionCallback.notifySkipToTrack */
- public void onSkipToTrack(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, long id) {
- }
-
- /** Stub method for ISessionCallback.notifyPause */
- public void onPause(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
-
- /** Stub method for ISessionCallback.notifyStop */
- public void onStop(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
-
- /** Stub method for ISessionCallback.notifyNext */
- public void onNext(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
-
- /** Stub method for ISessionCallback.notifyPrevious */
- public void onPrevious(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
-
- /** Stub method for ISessionCallback.notifyFastForward */
- public void onFastForward(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
-
- /** Stub method for ISessionCallback.notifyRewind */
- public void onRewind(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller) {
- }
+ private class CallbackStub extends ISessionCallback.Stub {
+ private WeakReference<MediaSessionEngine> mSessionImpl;
- /** Stub method for ISessionCallback.notifySeekTo */
- public void onSeekTo(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, long pos) {
+ private RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid) {
+ return new RemoteUserInfo(packageName, pid, uid);
}
- /** Stub method for ISessionCallback.notifyRate */
- public void onRate(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull Rating rating) {
- }
-
- /** Stub method for ISessionCallback.notifyCustomAction */
- public void onCustomAction(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, @NonNull String action,
- @Nullable Bundle args) {
- }
-
- /** Stub method for ISessionCallback.notifyAdjustVolume */
- public void onAdjustVolume(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, int direction) {
- }
-
- /** Stub method for ISessionCallback.notifySetVolumeTo */
- public void onSetVolumeTo(@NonNull String packageName, int pid, int uid,
- @NonNull ControllerCallbackLink caller, int value) {
- }
- }
-
- private class CallbackStubProxy extends ISessionCallback.Stub {
@Override
public void notifyCommand(String packageName, int pid, int uid,
ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onCommand(packageName, pid, uid, caller, command, args, cb);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchCommand(createRemoteUserInfo(packageName, pid, uid),
+ command, args, cb);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -684,9 +579,15 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onMediaButton(packageName, pid, uid, mediaButtonIntent,
- sequenceNumber, cb);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchMediaButton(
+ createRemoteUserInfo(packageName, pid, uid), mediaButtonIntent);
+ }
} finally {
+ if (cb != null) {
+ cb.send(sequenceNumber, null);
+ }
Binder.restoreCallingIdentity(token);
}
}
@@ -697,8 +598,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onMediaButtonFromController(packageName, pid, uid, caller,
- mediaButtonIntent);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid),
+ mediaButtonIntent);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -710,7 +614,10 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPrepare(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -722,7 +629,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPrepareFromMediaId(
+ createRemoteUserInfo(packageName, pid, uid), mediaId, extras);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -734,7 +645,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPrepareFromSearch(packageName, pid, uid, caller, query, extras);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPrepareFromSearch(
+ createRemoteUserInfo(packageName, pid, uid), query, extras);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -746,7 +661,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPrepareFromUri(packageName, pid, uid, caller, uri, extras);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPrepareFromUri(
+ createRemoteUserInfo(packageName, pid, uid), uri, extras);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -758,7 +677,10 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPlay(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPlay(createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -770,7 +692,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPlayFromMediaId(
+ createRemoteUserInfo(packageName, pid, uid), mediaId, extras);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -782,7 +708,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPlayFromSearch(packageName, pid, uid, caller, query, extras);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPlayFromSearch(
+ createRemoteUserInfo(packageName, pid, uid), query, extras);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -794,7 +724,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPlayFromUri(packageName, pid, uid, caller, uri, extras);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPlayFromUri(
+ createRemoteUserInfo(packageName, pid, uid), uri, extras);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -806,7 +740,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onSkipToTrack(packageName, pid, uid, caller, id);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchSkipToItem(
+ createRemoteUserInfo(packageName, pid, uid), id);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -818,7 +756,10 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPause(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPause(createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -830,7 +771,10 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onStop(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchStop(createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -842,7 +786,10 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onNext(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchNext(createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -854,7 +801,10 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onPrevious(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -866,7 +816,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onFastForward(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchFastForward(
+ createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -878,7 +832,10 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onRewind(packageName, pid, uid, caller);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchRewind(createRemoteUserInfo(packageName, pid, uid));
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -890,7 +847,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onSeekTo(packageName, pid, uid, caller, pos);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchSeekTo(
+ createRemoteUserInfo(packageName, pid, uid), pos);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -902,7 +863,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onRate(packageName, pid, uid, caller, rating);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchRate(
+ createRemoteUserInfo(packageName, pid, uid), rating);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -913,7 +878,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onCustomAction(packageName, pid, uid, caller, action, args);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchCustomAction(
+ createRemoteUserInfo(packageName, pid, uid), action, args);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -925,7 +894,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onAdjustVolume(packageName, pid, uid, caller, direction);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchAdjustVolume(
+ createRemoteUserInfo(packageName, pid, uid), direction);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -937,7 +910,11 @@ public final class SessionCallbackLink implements Parcelable {
ensureMediaControlPermission();
final long token = Binder.clearCallingIdentity();
try {
- mCallbackStub.onSetVolumeTo(packageName, pid, uid, caller, value);
+ MediaSessionEngine sessionImpl = mSessionImpl.get();
+ if (sessionImpl != null) {
+ sessionImpl.dispatchSetVolumeTo(
+ createRemoteUserInfo(packageName, pid, uid), value);
+ }
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/media/apex/java/android/media/session/SessionLink.aidl b/media/java/android/media/session/SessionLink.aidl
index c3be23e8f6b7..c3be23e8f6b7 100644
--- a/media/apex/java/android/media/session/SessionLink.aidl
+++ b/media/java/android/media/session/SessionLink.aidl
diff --git a/media/apex/java/android/media/session/SessionLink.java b/media/java/android/media/session/SessionLink.java
index 4ea762367010..4ea762367010 100644
--- a/media/apex/java/android/media/session/SessionLink.java
+++ b/media/java/android/media/session/SessionLink.java
diff --git a/media/apex/java/android/service/media/IMediaBrowserService.aidl b/media/java/android/service/media/IMediaBrowserService.aidl
index 1c50ec7ac421..1c50ec7ac421 100644
--- a/media/apex/java/android/service/media/IMediaBrowserService.aidl
+++ b/media/java/android/service/media/IMediaBrowserService.aidl
diff --git a/media/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
index 507a8f72ea57..507a8f72ea57 100644
--- a/media/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ b/media/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
diff --git a/media/apex/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java
index d9ef6ae40dfb..d9ef6ae40dfb 100644
--- a/media/apex/java/android/service/media/MediaBrowserService.java
+++ b/media/java/android/service/media/MediaBrowserService.java
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index 6deb47f09347..e43a60c3f396 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -177,9 +177,6 @@ int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
webview_functor_callbacks.vk.initialize = &initializeVk;
webview_functor_callbacks.vk.draw = &drawVk;
webview_functor_callbacks.vk.postDraw = &postDrawVk;
- // TODO(boliu): Remove this once SkiaRecordingCanvas::drawWebViewFunctor
- // no longer uses GL interop.
- webview_functor_callbacks.gles.draw = &draw_gl;
break;
}
callbacks_initialized = true;
diff --git a/packages/CarSystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml
index 777283d6bf92..be2cb0d8d900 100644
--- a/packages/CarSystemUI/res/values/integers_car.xml
+++ b/packages/CarSystemUI/res/values/integers_car.xml
@@ -23,7 +23,7 @@
<!-- Number of milliseconds user can spend driving with the keyguard up. After that, we switch to Guest. -->
<!-- If the number is negative, the feature is disabled.
If it's zero, we switch to guest immediately as we start driving. -->
- <integer name="driving_on_keyguard_timeout_ms">30000</integer>
+ <integer name="driving_on_keyguard_timeout_ms">-1</integer>
<!--Percentage of the screen height, from the bottom, that a notification panel being
partially closed at will result in it remaining open if released-->
diff --git a/packages/SettingsLib/OWNERS b/packages/SettingsLib/OWNERS
index d188c65be883..d87908738b56 100644
--- a/packages/SettingsLib/OWNERS
+++ b/packages/SettingsLib/OWNERS
@@ -4,7 +4,7 @@ asargent@google.com
dehboxturtle@google.com
dhnishi@google.com
dling@google.com
-dsandler@google.com
+dsandler@android.com
evanlaird@google.com
jackqdyulei@google.com
jmonk@google.com
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 445312168eba..23e5f0eea46d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -4231,7 +4231,7 @@ public class SettingsProvider extends ContentProvider {
String defLocationMode = Integer.toString(
!TextUtils.isEmpty(locationProvidersAllowed.getValue())
- ? Secure.LOCATION_MODE_HIGH_ACCURACY
+ ? Secure.LOCATION_MODE_ON
: Secure.LOCATION_MODE_OFF);
secureSettings.insertSettingLocked(
Secure.LOCATION_MODE, defLocationMode,
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index c3c3f25a9f03..c03268381367 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -145,6 +145,7 @@
<uses-permission android:name="android.permission.SET_TIME_ZONE" />
<uses-permission android:name="android.permission.DISABLE_HIDDEN_API_CHECKS" />
<uses-permission android:name="android.permission.MANAGE_ROLE_HOLDERS" />
+ <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
<!-- Permission needed to rename bugreport notifications (so they're not shown as Shell) -->
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
<!-- Permission needed to hold a wakelock in dumpstate.cpp (drop_root_user()) -->
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index 2f6e32b2c6d2..e7e2c1aafa78 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -1,6 +1,6 @@
set noparent
-dsandler@google.com
+dsandler@android.com
adamcohen@google.com
asc@google.com
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 7432f9cde639..41acf82a4567 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -405,7 +405,7 @@ number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.
<!-- Header for typographic clock face. [CHAR LIMIT=8] -->
<string name="type_clock_header">It\u2019s</string>
- <!-- Hour displayed in words on the typographic clock face. [CHAR LIMIT=8] -->
+ <!-- Hour displayed in words on the typographic clock face. [CHAR LIMIT=12] -->
<string-array name="type_clock_hours">
<item>Twelve</item>
<item>One</item>
@@ -421,7 +421,7 @@ number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable.
<item>Eleven</item>
</string-array>
- <!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=16] -->
+ <!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=20] -->
<string-array name="type_clock_minutes">
<item>O\u2019Clock</item>
<item>O\u2019One</item>
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java
index 71ae1f8620f6..231e725057d0 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedViewContainer.java
@@ -19,6 +19,7 @@ package com.android.systemui.bubbles;
import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
+import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ShapeDrawable;
import android.text.TextUtils;
@@ -68,9 +69,15 @@ public class BubbleExpandedViewContainer extends LinearLayout {
mPointerView = findViewById(R.id.pointer_view);
int width = res.getDimensionPixelSize(R.dimen.bubble_pointer_width);
int height = res.getDimensionPixelSize(R.dimen.bubble_pointer_height);
+
+ TypedArray ta = getContext().obtainStyledAttributes(
+ new int[] {android.R.attr.colorBackgroundFloating});
+ int bgColor = ta.getColor(0, Color.WHITE);
+ ta.recycle();
+
ShapeDrawable triangleDrawable = new ShapeDrawable(
TriangleShape.create(width, height, true /* pointUp */));
- triangleDrawable.setTint(Color.WHITE); // TODO: dark mode
+ triangleDrawable.setTint(bgColor);
mPointerView.setBackground(triangleDrawable);
mHeaderView = findViewById(R.id.bubble_content_header);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index cb1384cacec8..aa221993cd82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -25,7 +25,6 @@ import android.app.NotificationChannel;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.metrics.LogMaker;
import android.net.Uri;
import android.os.ServiceManager;
import android.os.UserHandle;
@@ -392,12 +391,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
return false;
}
- LogMaker logMaker = (row.getStatusBarNotification() == null)
- ? new LogMaker(MetricsProto.MetricsEvent.ACTION_NOTE_CONTROLS)
- : row.getStatusBarNotification().getLogMaker();
- mMetricsLogger.write(logMaker.setCategory(MetricsProto.MetricsEvent.ACTION_NOTE_CONTROLS)
- .setType(MetricsProto.MetricsEvent.TYPE_ACTION));
-
// ensure that it's laid but not visible until actually laid out
guts.setVisibility(View.INVISIBLE);
// Post to ensure the the guts are properly laid out.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 359bc6ec71d8..b6948fc4bd1f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -126,18 +126,23 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private OnClickListener mOnKeepShowing = v -> {
mExitReason = NotificationCounters.BLOCKING_HELPER_KEEP_SHOWING;
closeControls(v);
- mMetricsLogger.write(getLogMaker().setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT));
+ if (mIsForBlockingHelper) {
+ mMetricsLogger.write(getLogMaker().setCategory(
+ MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_STAY_SILENT));
+ }
};
private OnClickListener mOnToggleSilent = v -> {
Runnable saveImportance = () -> {
swapContent(ACTION_TOGGLE_SILENT, true /* animate */);
- mMetricsLogger.write(getLogMaker()
- .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_ALERT_ME));
+ if (mIsForBlockingHelper) {
+ mMetricsLogger.write(getLogMaker()
+ .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_ALERT_ME));
+ }
};
if (mCheckSaveListener != null) {
mCheckSaveListener.checkSave(saveImportance, mSbn);
@@ -149,10 +154,12 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private OnClickListener mOnStopOrMinimizeNotifications = v -> {
Runnable saveImportance = () -> {
swapContent(ACTION_BLOCK, true /* animate */);
- mMetricsLogger.write(getLogMaker()
- .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED));
+ if (mIsForBlockingHelper) {
+ mMetricsLogger.write(getLogMaker()
+ .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_BLOCKED));
+ }
};
if (mCheckSaveListener != null) {
mCheckSaveListener.checkSave(saveImportance, mSbn);
@@ -164,12 +171,16 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private OnClickListener mOnUndo = v -> {
// Reset exit counter that we'll log and record an undo event separately (not an exit event)
mExitReason = NotificationCounters.BLOCKING_HELPER_DISMISSED;
- logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO);
- mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS));
+ if (mIsForBlockingHelper) {
+ logBlockingHelperCounter(NotificationCounters.BLOCKING_HELPER_UNDO);
+ mMetricsLogger.write(getLogMaker().setCategory(
+ MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
+ .setType(MetricsEvent.TYPE_DISMISS)
+ .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_UNDO));
+ } else {
+ mMetricsLogger.write(importanceChangeLogMaker().setType(MetricsEvent.TYPE_DISMISS));
+ }
swapContent(ACTION_UNDO, true /* animate */);
- mMetricsLogger.write(getLogMaker().setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_DISMISS)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_CLICK_UNDO));
};
public NotificationInfo(Context context, AttributeSet attrs) {
@@ -269,11 +280,11 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
bindPrompt();
bindButtons();
- mMetricsLogger.write(getLogMaker().setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_OPEN)
- .setSubtype(MetricsEvent.BLOCKING_HELPER_DISPLAY));
+ mMetricsLogger.write(notificationControlsLogMaker());
}
+
+
private void bindHeader() throws RemoteException {
// Package name
Drawable pkgicon = null;
@@ -404,19 +415,6 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
}
}
- /**
- * Returns an initialized LogMaker for logging importance changes.
- * The caller may override the type (to DISMISS) before passing it to mMetricsLogger.
- * @return new LogMaker
- */
- private LogMaker importanceChangeLogMaker() {
- Integer chosenImportance =
- mChosenImportance != null ? mChosenImportance : mStartingChannelImportance;
- return new LogMaker(MetricsEvent.ACTION_SAVE_IMPORTANCE)
- .setType(MetricsEvent.TYPE_ACTION)
- .setSubtype(chosenImportance - mStartingChannelImportance);
- }
-
private boolean hasImportanceChanged() {
return mSingleNotificationChannel != null
&& mChosenImportance != null
@@ -616,8 +614,8 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
confirmation.setAlpha(1f);
header.setVisibility(VISIBLE);
header.setAlpha(1f);
- mMetricsLogger.write(getLogMaker().setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
- .setType(MetricsEvent.TYPE_CLOSE));
+
+ mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE));
}
@Override
@@ -764,7 +762,39 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
}
}
+ /**
+ * Returns a LogMaker with all available notification information.
+ * Caller should set category, type, and maybe subtype, before passing it to mMetricsLogger.
+ * @return LogMaker
+ */
private LogMaker getLogMaker() {
- return mSbn.getLogMaker();
+ // The constructor requires a category, so also do it in the other branch for consistency.
+ return mSbn == null ? new LogMaker(MetricsEvent.NOTIFICATION_BLOCKING_HELPER)
+ : mSbn.getLogMaker().setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER);
+ }
+
+ /**
+ * Returns an initialized LogMaker for logging importance changes.
+ * The caller may override the type before passing it to mMetricsLogger.
+ * @return LogMaker
+ */
+ private LogMaker importanceChangeLogMaker() {
+ Integer chosenImportance =
+ mChosenImportance != null ? mChosenImportance : mStartingChannelImportance;
+ return getLogMaker().setCategory(MetricsEvent.ACTION_SAVE_IMPORTANCE)
+ .setType(MetricsEvent.TYPE_ACTION)
+ .setSubtype(chosenImportance - mStartingChannelImportance);
+ }
+
+ /**
+ * Returns an initialized LogMaker for logging open/close of the info display.
+ * The caller may override the type before passing it to mMetricsLogger.
+ * @return LogMaker
+ */
+ private LogMaker notificationControlsLogMaker() {
+ return getLogMaker().setCategory(MetricsEvent.ACTION_NOTE_CONTROLS)
+ .setType(MetricsEvent.TYPE_OPEN)
+ .setSubtype(mIsForBlockingHelper ? MetricsEvent.BLOCKING_HELPER_DISPLAY
+ : MetricsEvent.BLOCKING_HELPER_UNKNOWN);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index fdc9e0c4d7e4..727e9af94146 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -45,7 +45,6 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.metrics.LogMaker;
import android.os.Binder;
import android.os.Handler;
import android.provider.Settings;
@@ -57,7 +56,6 @@ import android.util.ArraySet;
import android.view.View;
import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.NotificationPresenter;
@@ -220,34 +218,6 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
}
@Test
- public void testOpenGutsLogging() {
- NotificationGutsManager gutsManager = spy(mGutsManager);
- doReturn(true).when(gutsManager).bindGuts(any(), any());
-
- NotificationGuts guts = spy(new NotificationGuts(mContext));
- doReturn(true).when(guts).post(any());
-
- ExpandableNotificationRow realRow = createTestNotificationRow();
- NotificationMenuRowPlugin.MenuItem menuItem = createTestMenuItem(realRow);
-
- ExpandableNotificationRow row = spy(realRow);
- when(row.getWindowToken()).thenReturn(new Binder());
- when(row.getGuts()).thenReturn(guts);
- StatusBarNotification notification = spy(realRow.getStatusBarNotification());
- when(row.getStatusBarNotification()).thenReturn(notification);
-
- assertTrue(gutsManager.openGuts(row, 0, 0, menuItem));
-
- ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
- verify(notification).getLogMaker();
- verify(mMetricsLogger).write(logMakerCaptor.capture());
- assertEquals(MetricsProto.MetricsEvent.ACTION_NOTE_CONTROLS,
- logMakerCaptor.getValue().getCategory());
- assertEquals(MetricsProto.MetricsEvent.TYPE_ACTION,
- logMakerCaptor.getValue().getType());
- }
-
- @Test
public void testAppOpsSettingsIntent_camera() {
ArraySet<Integer> ops = new ArraySet<>();
ops.add(OP_CAMERA);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
index 554baaf1ab9e..2a64445f342a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.java
@@ -83,7 +83,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -107,11 +106,16 @@ public class NotificationInfoTest extends SysuiTestCase {
private NotificationChannel mDefaultNotificationChannel;
private StatusBarNotification mSbn;
- @Rule public MockitoRule mockito = MockitoJUnit.rule();
- @Mock private MetricsLogger mMetricsLogger;
- @Mock private INotificationManager mMockINotificationManager;
- @Mock private PackageManager mMockPackageManager;
- @Mock private NotificationBlockingHelperManager mBlockingHelperManager;
+ @Rule
+ public MockitoRule mockito = MockitoJUnit.rule();
+ @Mock
+ private MetricsLogger mMetricsLogger;
+ @Mock
+ private INotificationManager mMockINotificationManager;
+ @Mock
+ private PackageManager mMockPackageManager;
+ @Mock
+ private NotificationBlockingHelperManager mBlockingHelperManager;
@Before
public void setUp() throws Exception {
@@ -172,44 +176,25 @@ public class NotificationInfoTest extends SysuiTestCase {
PollingCheck.waitFor(1000,
() -> VISIBLE == mNotificationInfo.findViewById(R.id.confirmation).getVisibility());
}
+
private void ensureNoUndoButton() {
PollingCheck.waitFor(1000,
() -> GONE == mNotificationInfo.findViewById(R.id.confirmation).getVisibility()
&& !mNotificationInfo.isAnimating());
}
+
private void waitForStopButton() {
PollingCheck.waitFor(1000,
() -> VISIBLE == mNotificationInfo.findViewById(R.id.prompt).getVisibility());
}
- class ImportanceChangeLogMaker implements ArgumentMatcher<LogMaker> {
- private static final int CATEGORY = MetricsProto.MetricsEvent.ACTION_SAVE_IMPORTANCE;
- private int mType, mSubtype;
-
- ImportanceChangeLogMaker(int type, int subtype) {
- mType = type;
- mSubtype = subtype;
- }
- public boolean matches(LogMaker l) {
- return (l.getCategory() == CATEGORY)
- && (l.getType() == mType)
- && (l.getSubtype() == mSubtype);
- }
-
- public String toString() {
- return String.format("LogMaker(%d, %d, %d)", CATEGORY, mType, mSubtype);
- }
- }
-
- private LogMaker importanceChangeLog(int type, int subtype) {
- return argThat(new ImportanceChangeLogMaker(type, subtype));
- }
-
@Test
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
+ null, null, null,
+ true, false,
IMPORTANCE_DEFAULT, true);
final TextView textView = mNotificationInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
@@ -330,9 +315,9 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testBindNotification_BlockButton() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
- IMPORTANCE_DEFAULT, true);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ IMPORTANCE_DEFAULT, true);
final View block = mNotificationInfo.findViewById(R.id.int_block);
final View minimize = mNotificationInfo.findViewById(R.id.block_or_minimize);
assertEquals(VISIBLE, block.getVisibility());
@@ -340,7 +325,7 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testBindNotification_BlockButton_BlockHelper() throws Exception {
+ public void testBindNotification_BlockButton_BlockingHelper() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
true /* isBlockingHelper */, false, IMPORTANCE_DEFAULT, true);
@@ -498,13 +483,29 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testLogBlockingHelperCounter_logGutsViewDisplayed() throws Exception {
+ public void testBindNotificationLogging_notBlockingHelper() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
+ null, null, null,
+ true, false,
+ IMPORTANCE_DEFAULT, true);
+ verify(mMetricsLogger).write(argThat(logMaker ->
+ logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
+ && logMaker.getType() == MetricsEvent.TYPE_OPEN
+ && logMaker.getSubtype() == MetricsEvent.BLOCKING_HELPER_UNKNOWN
+ ));
+ }
+
+ @Test
+ public void testBindNotificationLogging_BlockingHelper() throws Exception {
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
+ null, null, null,
+ false, true,
+ true, true,
IMPORTANCE_DEFAULT, true);
- mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
verify(mMetricsLogger).write(argThat(logMaker ->
- logMaker.getCategory() == MetricsEvent.NOTIFICATION_BLOCKING_HELPER
+ logMaker.getCategory() == MetricsEvent.ACTION_NOTE_CONTROLS
&& logMaker.getType() == MetricsEvent.TYPE_OPEN
&& logMaker.getSubtype() == MetricsEvent.BLOCKING_HELPER_DISPLAY
));
@@ -513,8 +514,11 @@ public class NotificationInfoTest extends SysuiTestCase {
@Test
public void testLogBlockingHelperCounter_logsForBlockingHelper() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, false, true,
- true, true, IMPORTANCE_DEFAULT, true);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
+ null, null, null,
+ false, true,
+ true, true,
+ IMPORTANCE_DEFAULT, true);
mNotificationInfo.logBlockingHelperCounter("HowCanNotifsBeRealIfAppsArent");
verify(mMetricsLogger).count(eq("HowCanNotifsBeRealIfAppsArent"), eq(1));
}
@@ -680,7 +684,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */,
- null /* onSettingsClick */, null /* onAppSettingsClick */ ,
+ null /* onSettingsClick */, null /* onAppSettingsClick */,
true, false /* isNonblockable */, IMPORTANCE_DEFAULT, false
);
@@ -722,7 +726,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
10 /* numUniqueChannelsInRow */, mSbn, null /* checkSaveListener */,
- null /* onSettingsClick */, null /* onAppSettingsClick */ ,
+ null /* onSettingsClick */, null /* onAppSettingsClick */,
true /* provisioned */,
false /* isNonblockable */, true /* isForBlockingHelper */,
true /* isUserSentimentNegative */, IMPORTANCE_DEFAULT, true);
@@ -744,14 +748,14 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testCloseControls_nonNullCheckSaveListenerDoesntDelayKeepShowing()
+ public void testCloseControls_nonNullCheckSaveListenerDoesntDelayKeepShowing_BlockingHelper()
throws Exception {
NotificationInfo.CheckSaveListener listener =
mock(NotificationInfo.CheckSaveListener.class);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */,
- null /* onSettingsClick */, null /* onAppSettingsClick */ , true /* provisioned */,
+ null /* onSettingsClick */, null /* onAppSettingsClick */, true /* provisioned */,
false /* isNonblockable */, true /* isForBlockingHelper */,
true /* isUserSentimentNegative */, IMPORTANCE_DEFAULT, true);
@@ -772,14 +776,14 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testCloseControls_nonNullCheckSaveListenerDoesntDelayDismiss()
+ public void testCloseControls_nonNullCheckSaveListenerDoesntDelayDismiss_BlockingHelper()
throws Exception {
NotificationInfo.CheckSaveListener listener =
mock(NotificationInfo.CheckSaveListener.class);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel /* notificationChannel */,
10 /* numUniqueChannelsInRow */, mSbn, listener /* checkSaveListener */,
- null /* onSettingsClick */, null /* onAppSettingsClick */ ,
+ null /* onSettingsClick */, null /* onAppSettingsClick */,
false /* isNonblockable */, true /* isForBlockingHelper */,
true, true /* isUserSentimentNegative */, /* isNoisy */
IMPORTANCE_DEFAULT, true);
@@ -791,7 +795,7 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testCloseControls_checkSaveListenerDelaysStopNotifications()
+ public void testCloseControls_checkSaveListenerDelaysStopNotifications_BlockingHelper()
throws Exception {
NotificationInfo.CheckSaveListener listener =
mock(NotificationInfo.CheckSaveListener.class);
@@ -849,18 +853,25 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testBlockChangedCallsUpdateNotificationChannel() throws Exception {
+ public void testBlockChangedCallsUpdateNotificationChannel_notBlockingHelper()
+ throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
+ null, null, null,
+ true, false,
IMPORTANCE_DEFAULT, false);
mNotificationInfo.findViewById(R.id.int_block).performClick();
waitForUndoButton();
mNotificationInfo.handleCloseControls(true, false);
- verify(mMetricsLogger).write(importanceChangeLog(
- MetricsProto.MetricsEvent.TYPE_ACTION, IMPORTANCE_NONE - IMPORTANCE_LOW));
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ verify(mMetricsLogger, times(2)).write(logMakerCaptor.capture());
+ assertEquals(MetricsProto.MetricsEvent.TYPE_ACTION,
+ logMakerCaptor.getValue().getType());
+ assertEquals(IMPORTANCE_NONE - IMPORTANCE_LOW,
+ logMakerCaptor.getValue().getSubtype());
mTestableLooper.processAllMessages();
ArgumentCaptor<NotificationChannel> updated =
@@ -896,8 +907,12 @@ public class NotificationInfoTest extends SysuiTestCase {
waitForUndoButton();
mNotificationInfo.handleCloseControls(true, false);
- verify(mMetricsLogger).write(importanceChangeLog(
- MetricsProto.MetricsEvent.TYPE_ACTION, IMPORTANCE_NONE - IMPORTANCE_LOW));
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ verify(mMetricsLogger, times(3)).write(logMakerCaptor.capture());
+ assertEquals(MetricsProto.MetricsEvent.TYPE_ACTION,
+ logMakerCaptor.getValue().getType());
+ assertEquals(IMPORTANCE_NONE - IMPORTANCE_LOW,
+ logMakerCaptor.getValue().getSubtype());
mTestableLooper.processAllMessages();
ArgumentCaptor<NotificationChannel> updated =
@@ -965,10 +980,12 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testBlockUndoDoesNotBlockNotificationChannel() throws Exception {
+ public void testBlockUndoDoesNotBlockNotificationChannel_notBlockingHelper() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, false,
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
+ null, null, null,
+ true, false,
IMPORTANCE_DEFAULT, false);
mNotificationInfo.findViewById(R.id.int_block).performClick();
@@ -977,8 +994,15 @@ public class NotificationInfoTest extends SysuiTestCase {
waitForStopButton();
// mNotificationInfo.handleCloseControls doesn't get called by this interaction.
- verify(mMetricsLogger).write(importanceChangeLog(
- MetricsProto.MetricsEvent.TYPE_DISMISS, IMPORTANCE_NONE - IMPORTANCE_LOW));
+ ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
+ verify(mMetricsLogger, times(2)).write(logMakerCaptor.capture());
+ assertEquals(MetricsEvent.ACTION_SAVE_IMPORTANCE,
+ logMakerCaptor.getValue().getCategory());
+ assertEquals(MetricsEvent.TYPE_DISMISS,
+ logMakerCaptor.getValue().getType());
+ assertEquals(IMPORTANCE_NONE - IMPORTANCE_LOW,
+ logMakerCaptor.getValue().getSubtype());
+
mTestableLooper.processAllMessages();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -986,11 +1010,12 @@ public class NotificationInfoTest extends SysuiTestCase {
}
@Test
- public void testMinUndoDoesNotMinNotificationChannel() throws Exception {
+ public void testMinUndoDoesNotMinNotificationChannel_notBlockingHelper() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null, null, true, true,
- IMPORTANCE_DEFAULT, false);
+ TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn,
+ null, null, null, true,
+ true, IMPORTANCE_DEFAULT, false);
mNotificationInfo.findViewById(R.id.minimize).performClick();
waitForUndoButton();
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index f4ac13074903..fc43882b4ffd 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -348,8 +348,8 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
}
int getRelevantEventTypes() {
- return (mUsesAccessibilityCache ? AccessibilityCache.CACHE_CRITICAL_EVENTS_MASK : 0)
- | mEventTypes;
+ return (mUsesAccessibilityCache ? AccessibilityCache.CACHE_CRITICAL_EVENTS_MASK
+ : AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) | mEventTypes;
}
@Override
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index d2c6354e91b8..33c6dd24012a 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -405,6 +405,7 @@ public class LocationManagerService extends ILocationManager.Stub {
// initialize in-memory settings values
onBackgroundThrottleWhitelistChangedLocked();
+ onIgnoreSettingsWhitelistChangedLocked();
}
@GuardedBy("mLock")
@@ -547,18 +548,17 @@ public class LocationManagerService extends ILocationManager.Stub {
@GuardedBy("mLock")
private void onBackgroundThrottleWhitelistChangedLocked() {
+ mBackgroundThrottlePackageWhitelist.clear();
+ mBackgroundThrottlePackageWhitelist.addAll(
+ SystemConfig.getInstance().getAllowUnthrottledLocation());
+
String setting = Settings.Global.getString(
mContext.getContentResolver(),
Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST);
- if (setting == null) {
- setting = "";
+ if (!TextUtils.isEmpty(setting)) {
+ mBackgroundThrottlePackageWhitelist.addAll(Arrays.asList(setting.split(",")));
}
- mBackgroundThrottlePackageWhitelist.clear();
- mBackgroundThrottlePackageWhitelist.addAll(
- SystemConfig.getInstance().getAllowUnthrottledLocation());
- mBackgroundThrottlePackageWhitelist.addAll(Arrays.asList(setting.split(",")));
-
for (LocationProvider p : mProviders) {
applyRequirementsLocked(p);
}
@@ -566,18 +566,17 @@ public class LocationManagerService extends ILocationManager.Stub {
@GuardedBy("lock")
private void onIgnoreSettingsWhitelistChangedLocked() {
+ mIgnoreSettingsPackageWhitelist.clear();
+ mIgnoreSettingsPackageWhitelist.addAll(
+ SystemConfig.getInstance().getAllowIgnoreLocationSettings());
+
String setting = Settings.Global.getString(
mContext.getContentResolver(),
Settings.Global.LOCATION_IGNORE_SETTINGS_PACKAGE_WHITELIST);
- if (setting == null) {
- setting = "";
+ if (!TextUtils.isEmpty(setting)) {
+ mIgnoreSettingsPackageWhitelist.addAll(Arrays.asList(setting.split(",")));
}
- mIgnoreSettingsPackageWhitelist.clear();
- mIgnoreSettingsPackageWhitelist.addAll(
- SystemConfig.getInstance().getAllowIgnoreLocationSettings());
- mIgnoreSettingsPackageWhitelist.addAll(Arrays.asList(setting.split(",")));
-
for (LocationProvider p : mProviders) {
applyRequirementsLocked(p);
}
@@ -2200,7 +2199,7 @@ public class LocationManagerService extends ILocationManager.Stub {
return false;
}
- if (mBackgroundThrottlePackageWhitelist.contains(record.mReceiver.mIdentity.mPackageName)) {
+ if (mIgnoreSettingsPackageWhitelist.contains(record.mReceiver.mIdentity.mPackageName)) {
return true;
}
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index cecd55a325d3..f2329d3ebf8e 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -1541,10 +1541,6 @@ class StorageManagerService extends IStorageManager.Stub
mCallbacks = new Callbacks(FgThread.get().getLooper());
mLockPatternUtils = new LockPatternUtils(mContext);
- mPmInternal = LocalServices.getService(PackageManagerInternal.class);
- mUmInternal = LocalServices.getService(UserManagerInternal.class);
- mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
-
HandlerThread hthread = new HandlerThread(TAG);
hthread.start();
mHandler = new StorageManagerServiceHandler(hthread.getLooper());
@@ -1662,6 +1658,19 @@ class StorageManagerService extends IStorageManager.Stub
}
private void servicesReady() {
+ mPmInternal = LocalServices.getService(PackageManagerInternal.class);
+ mUmInternal = LocalServices.getService(UserManagerInternal.class);
+ mAmInternal = LocalServices.getService(ActivityManagerInternal.class);
+
+ mIPackageManager = IPackageManager.Stub.asInterface(
+ ServiceManager.getService("package"));
+ mIAppOpsService = IAppOpsService.Stub.asInterface(
+ ServiceManager.getService(Context.APP_OPS_SERVICE));
+ try {
+ mIAppOpsService.startWatchingMode(OP_REQUEST_INSTALL_PACKAGES, null, mAppOpsCallback);
+ } catch (RemoteException e) {
+ }
+
synchronized (mLock) {
final boolean thisIsolatedStorage = StorageManager.hasIsolatedStorage();
if (mLastIsolatedStorage == thisIsolatedStorage) {
@@ -1734,14 +1743,6 @@ class StorageManagerService extends IStorageManager.Stub
.registerScreenObserver(this);
mSystemReady = true;
- mIPackageManager = IPackageManager.Stub.asInterface(
- ServiceManager.getService("package"));
- mIAppOpsService = IAppOpsService.Stub.asInterface(
- ServiceManager.getService(Context.APP_OPS_SERVICE));
- try {
- mIAppOpsService.startWatchingMode(OP_REQUEST_INSTALL_PACKAGES, null, mAppOpsCallback);
- } catch (RemoteException e) {
- }
mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
}
diff --git a/services/core/java/com/android/server/ThreadPriorityBooster.java b/services/core/java/com/android/server/ThreadPriorityBooster.java
index 53e8ce43fff8..f74a438509c2 100644
--- a/services/core/java/com/android/server/ThreadPriorityBooster.java
+++ b/services/core/java/com/android/server/ThreadPriorityBooster.java
@@ -43,9 +43,9 @@ public class ThreadPriorityBooster {
public void boost() {
final int tid = myTid();
- final int prevPriority = getThreadPriority(tid);
final PriorityState state = mThreadState.get();
if (state.regionCounter == 0) {
+ final int prevPriority = getThreadPriority(tid);
state.prevPriority = prevPriority;
if (prevPriority > mBoostToPriority) {
setThreadPriority(tid, mBoostToPriority);
@@ -60,9 +60,11 @@ public class ThreadPriorityBooster {
public void reset() {
final PriorityState state = mThreadState.get();
state.regionCounter--;
- final int currentPriority = getThreadPriority(myTid());
- if (state.regionCounter == 0 && state.prevPriority != currentPriority) {
- setThreadPriority(myTid(), state.prevPriority);
+ if (state.regionCounter == 0) {
+ final int currentPriority = getThreadPriority(myTid());
+ if (state.prevPriority != currentPriority) {
+ setThreadPriority(myTid(), state.prevPriority);
+ }
}
}
@@ -77,9 +79,11 @@ public class ThreadPriorityBooster {
mBoostToPriority = priority;
final PriorityState state = mThreadState.get();
final int tid = myTid();
- final int prevPriority = getThreadPriority(tid);
- if (state.regionCounter != 0 && prevPriority != priority) {
- setThreadPriority(tid, priority);
+ if (state.regionCounter != 0) {
+ final int prevPriority = getThreadPriority(tid);
+ if (prevPriority != priority) {
+ setThreadPriority(tid, priority);
+ }
}
}
diff --git a/services/core/java/com/android/server/am/AppCompactor.java b/services/core/java/com/android/server/am/AppCompactor.java
index bb55ec3100c0..1118014dab96 100644
--- a/services/core/java/com/android/server/am/AppCompactor.java
+++ b/services/core/java/com/android/server/am/AppCompactor.java
@@ -19,6 +19,7 @@ package com.android.server.am;
import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_1;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_2;
+import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_STATSD_SAMPLE_RATE;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_1;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_2;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_3;
@@ -45,6 +46,7 @@ import com.android.server.ServiceThread;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Random;
public final class AppCompactor {
@@ -65,6 +67,8 @@ public final class AppCompactor {
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_2 = 10_000;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_3 = 500;
@VisibleForTesting static final long DEFAULT_COMPACT_THROTTLE_4 = 10_000;
+ // The sampling rate to push app compaction events into statsd for upload.
+ @VisibleForTesting static final float DEFAULT_STATSD_SAMPLE_RATE = 0.1f;
@VisibleForTesting
interface PropertyChangedCallbackForTest {
@@ -104,6 +108,8 @@ public final class AppCompactor {
|| KEY_COMPACT_THROTTLE_3.equals(name)
|| KEY_COMPACT_THROTTLE_4.equals(name)) {
updateCompactionThrottles();
+ } else if (KEY_COMPACT_STATSD_SAMPLE_RATE.equals(name)) {
+ updateStatsdSampleRate();
}
}
if (mTestCallback != null) {
@@ -116,21 +122,25 @@ public final class AppCompactor {
// Configured by phenotype. Updates from the server take effect immediately.
@GuardedBy("mPhenotypeFlagLock")
- @VisibleForTesting String mCompactActionSome =
+ @VisibleForTesting volatile String mCompactActionSome =
compactActionIntToString(DEFAULT_COMPACT_ACTION_1);
@GuardedBy("mPhenotypeFlagLock")
- @VisibleForTesting String mCompactActionFull =
+ @VisibleForTesting volatile String mCompactActionFull =
compactActionIntToString(DEFAULT_COMPACT_ACTION_2);
@GuardedBy("mPhenotypeFlagLock")
- @VisibleForTesting long mCompactThrottleSomeSome = DEFAULT_COMPACT_THROTTLE_1;
+ @VisibleForTesting volatile long mCompactThrottleSomeSome = DEFAULT_COMPACT_THROTTLE_1;
@GuardedBy("mPhenotypeFlagLock")
- @VisibleForTesting long mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2;
+ @VisibleForTesting volatile long mCompactThrottleSomeFull = DEFAULT_COMPACT_THROTTLE_2;
@GuardedBy("mPhenotypeFlagLock")
- @VisibleForTesting long mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3;
+ @VisibleForTesting volatile long mCompactThrottleFullSome = DEFAULT_COMPACT_THROTTLE_3;
@GuardedBy("mPhenotypeFlagLock")
- @VisibleForTesting long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4;
+ @VisibleForTesting volatile long mCompactThrottleFullFull = DEFAULT_COMPACT_THROTTLE_4;
@GuardedBy("mPhenotypeFlagLock")
- private boolean mUseCompaction = DEFAULT_USE_COMPACTION;
+ private volatile boolean mUseCompaction = DEFAULT_USE_COMPACTION;
+
+ private final Random mRandom = new Random();
+ @GuardedBy("mPhenotypeFlagLock")
+ @VisibleForTesting volatile float mStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE;
// Handler on which compaction runs.
private Handler mCompactionHandler;
@@ -158,6 +168,7 @@ public final class AppCompactor {
updateUseCompaction();
updateCompactionActions();
updateCompactionThrottles();
+ updateStatsdSampleRate();
}
}
@@ -181,6 +192,7 @@ public final class AppCompactor {
pw.println(" " + KEY_COMPACT_THROTTLE_2 + "=" + mCompactThrottleSomeFull);
pw.println(" " + KEY_COMPACT_THROTTLE_3 + "=" + mCompactThrottleFullSome);
pw.println(" " + KEY_COMPACT_THROTTLE_4 + "=" + mCompactThrottleFullFull);
+ pw.println(" " + KEY_COMPACT_STATSD_SAMPLE_RATE + "=" + mStatsdSampleRate);
}
}
@@ -289,6 +301,19 @@ public final class AppCompactor {
}
}
+ @GuardedBy("mPhenotypeFlagLock")
+ private void updateStatsdSampleRate() {
+ String sampleRateFlag = DeviceConfig.getProperty(DeviceConfig.ActivityManager.NAMESPACE,
+ KEY_COMPACT_STATSD_SAMPLE_RATE);
+ try {
+ mStatsdSampleRate = TextUtils.isEmpty(sampleRateFlag)
+ ? DEFAULT_STATSD_SAMPLE_RATE : Float.parseFloat(sampleRateFlag);
+ } catch (NumberFormatException e) {
+ mStatsdSampleRate = DEFAULT_STATSD_SAMPLE_RATE;
+ }
+ mStatsdSampleRate = Math.min(1.0f, Math.max(0.0f, mStatsdSampleRate));
+ }
+
@VisibleForTesting
static String compactActionIntToString(int action) {
switch(action) {
@@ -385,11 +410,16 @@ public final class AppCompactor {
rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3],
rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time,
lastCompactAction, lastCompactTime, msg.arg1, msg.arg2);
- StatsLog.write(StatsLog.APP_COMPACTED, pid, name, pendingAction,
- rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3],
- rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time,
- lastCompactAction, lastCompactTime, msg.arg1,
- ActivityManager.processStateAmToProto(msg.arg2));
+ // Note that as above not taking mPhenoTypeFlagLock here to avoid locking
+ // on every single compaction for a flag that will seldom change and the
+ // impact of reading the wrong value here is low.
+ if (mRandom.nextFloat() < mStatsdSampleRate) {
+ StatsLog.write(StatsLog.APP_COMPACTED, pid, name, pendingAction,
+ rssBefore[0], rssBefore[1], rssBefore[2], rssBefore[3],
+ rssAfter[0], rssAfter[1], rssAfter[2], rssAfter[3], time,
+ lastCompactAction, lastCompactTime, msg.arg1,
+ ActivityManager.processStateAmToProto(msg.arg2));
+ }
synchronized (mAm) {
proc.lastCompactTime = end;
proc.lastCompactAction = pendingAction;
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 64a36ef66f12..1fb11baab2e4 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -450,7 +450,7 @@ public final class BroadcastQueue {
if (state == BroadcastRecord.IDLE) {
Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
}
- if (r.allowBackgroundActivityStarts) {
+ if (r.allowBackgroundActivityStarts && r.curApp != null) {
r.curApp.removeAllowBackgroundActivityStartsToken(r);
}
// If we're abandoning this broadcast before any receivers were actually spun up,
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 5b469fe2dc7a..2061b2681268 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -16,9 +16,9 @@
package com.android.server.attention;
+import static android.provider.DeviceConfig.AttentionManagerService.COMPONENT_NAME;
import static android.provider.DeviceConfig.AttentionManagerService.NAMESPACE;
-import static android.provider.DeviceConfig.AttentionManagerService.PROPERTY_COMPONENT_NAME;
-import static android.provider.DeviceConfig.AttentionManagerService.PROPERTY_SERVICE_ENABLED;
+import static android.provider.DeviceConfig.AttentionManagerService.SERVICE_ENABLED;
import android.Manifest;
import android.annotation.Nullable;
@@ -129,7 +129,7 @@ public class AttentionManagerService extends SystemService {
}
private boolean isServiceEnabled() {
- final String enabled = DeviceConfig.getProperty(NAMESPACE, PROPERTY_SERVICE_ENABLED);
+ final String enabled = DeviceConfig.getProperty(NAMESPACE, SERVICE_ENABLED);
return enabled == null ? DEFAULT_SERVICE_ENABLED : "true".equals(enabled);
}
@@ -279,7 +279,7 @@ public class AttentionManagerService extends SystemService {
* system.
*/
private static ComponentName resolveAttentionService(Context context) {
- final String flag = DeviceConfig.getProperty(NAMESPACE, PROPERTY_COMPONENT_NAME);
+ final String flag = DeviceConfig.getProperty(NAMESPACE, COMPONENT_NAME);
final String componentNameString = flag != null ? flag : context.getString(
R.string.config_defaultAttentionService);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index d652f93ccf04..deaa9313fadd 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -600,7 +600,7 @@ import java.util.ArrayList;
break;
case MSG_IL_SET_A2DP_SINK_CONNECTION_STATE:
mDeviceInventory.onSetA2dpSinkConnectionState(
- (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1, msg.arg2);
+ (BtHelper.BluetoothA2dpDeviceInfo) msg.obj, msg.arg1);
break;
case MSG_IL_SET_A2DP_SOURCE_CONNECTION_STATE:
mDeviceInventory.onSetA2dpSourceConnectionState(
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index eb76e6e02edc..97649a741f62 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -147,18 +147,20 @@ public final class AudioDeviceInventory {
}
/*package*/ void onSetA2dpSinkConnectionState(@NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo,
- @AudioService.BtProfileConnectionState int state, int a2dpVolume) {
+ @AudioService.BtProfileConnectionState int state) {
final BluetoothDevice btDevice = btInfo.getBtDevice();
+ int a2dpVolume = btInfo.getVolume();
if (AudioService.DEBUG_DEVICES) {
Log.d(TAG, "onSetA2dpSinkConnectionState btDevice=" + btDevice + " state="
- + state + " is dock=" + btDevice.isBluetoothDock());
+ + state + " is dock=" + btDevice.isBluetoothDock() + " vol=" + a2dpVolume);
}
String address = btDevice.getAddress();
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
address = "";
}
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
- "A2DP sink connected: device addr=" + address + " state=" + state));
+ "A2DP sink connected: device addr=" + address + " state=" + state
+ + " vol=" + a2dpVolume));
final int a2dpCodec;
synchronized (mDeviceBroker.mA2dpAvrcpLock) {
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index df33bf249133..1723163a132d 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -392,12 +392,14 @@ public class AudioService extends IAudioService.Stub
* e.g. user on homescreen, no app playing anything, presses hardware volume buttons, this
* stream type is controlled.
*/
- protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
+ protected static final int DEFAULT_VOL_STREAM_NO_PLAYBACK = AudioSystem.STREAM_MUSIC;
private final AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
case AudioSystem.AUDIO_STATUS_SERVER_DIED:
+ mRecordMonitor.clear();
+
sendMsg(mAudioHandler, MSG_AUDIO_SERVER_DIED,
SENDMSG_NOOP, 0, 0, null, 0);
sendMsg(mAudioHandler, MSG_DISPATCH_AUDIO_SERVER_STATE,
diff --git a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
index 9d6628cf0c40..b2c7ff3bfdf6 100644
--- a/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
+++ b/services/core/java/com/android/server/audio/RecordingActivityMonitor.java
@@ -78,24 +78,27 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
updateSnapshot(event, uid, session, source, recordingInfo,
portId, silenced, activeSource, clientEffects, effects);
if (configsSystem != null){
- synchronized (mClients) {
- // list of recording configurations for "public consumption". It is only computed if
- // there are non-system recording activity listeners.
- final List<AudioRecordingConfiguration> configsPublic = mHasPublicClients ?
- anonymizeForPublicConsumption(configsSystem) :
- new ArrayList<AudioRecordingConfiguration>();
- final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
- while (clientIterator.hasNext()) {
- final RecMonitorClient rmc = clientIterator.next();
- try {
- if (rmc.mIsPrivileged) {
- rmc.mDispatcherCb.dispatchRecordingConfigChange(configsSystem);
- } else {
- rmc.mDispatcherCb.dispatchRecordingConfigChange(configsPublic);
- }
- } catch (RemoteException e) {
- Log.w(TAG, "Could not call dispatchRecordingConfigChange() on client", e);
+ dispatchCallbacks(configsSystem);
+ }
+ }
+ private void dispatchCallbacks(List<AudioRecordingConfiguration> configs) {
+ synchronized (mClients) {
+ // list of recording configurations for "public consumption". It is only computed if
+ // there are non-system recording activity listeners.
+ final List<AudioRecordingConfiguration> configsPublic = mHasPublicClients
+ ? anonymizeForPublicConsumption(configs) :
+ new ArrayList<AudioRecordingConfiguration>();
+ final Iterator<RecMonitorClient> clientIterator = mClients.iterator();
+ while (clientIterator.hasNext()) {
+ final RecMonitorClient rmc = clientIterator.next();
+ try {
+ if (rmc.mIsPrivileged) {
+ rmc.mDispatcherCb.dispatchRecordingConfigChange(configs);
+ } else {
+ rmc.mDispatcherCb.dispatchRecordingConfigChange(configsPublic);
}
+ } catch (RemoteException e) {
+ Log.w(TAG, "Could not call dispatchRecordingConfigChange() on client", e);
}
}
}
@@ -130,6 +133,13 @@ public final class RecordingActivityMonitor implements AudioSystem.AudioRecordin
AudioSystem.setRecordingCallback(this);
}
+ void clear() {
+ synchronized (mRecordConfigs) {
+ mRecordConfigs.clear();
+ }
+ dispatchCallbacks(new ArrayList<AudioRecordingConfiguration>());
+ }
+
void registerRecordingCallback(IRecordingConfigDispatcher rcdb, boolean isPrivileged) {
if (rcdb == null) {
return;
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index db3928ec5fde..2a8462bc03f7 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -592,6 +592,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
public BrightnessConfiguration getDefaultBrightnessConfiguration() {
+ if (mAutomaticBrightnessController == null) {
+ return null;
+ }
return mAutomaticBrightnessController.getDefaultConfig();
}
diff --git a/services/core/java/com/android/server/dreams/OWNERS b/services/core/java/com/android/server/dreams/OWNERS
index 3c9bbf8797ea..426f002ad236 100644
--- a/services/core/java/com/android/server/dreams/OWNERS
+++ b/services/core/java/com/android/server/dreams/OWNERS
@@ -1,3 +1,3 @@
-dsandler@google.com
+dsandler@android.com
michaelwr@google.com
roosa@google.com
diff --git a/services/core/java/com/android/server/incident/IncidentCompanionService.java b/services/core/java/com/android/server/incident/IncidentCompanionService.java
index 3ebba0074a1c..6f2bfc3cd8d2 100644
--- a/services/core/java/com/android/server/incident/IncidentCompanionService.java
+++ b/services/core/java/com/android/server/incident/IncidentCompanionService.java
@@ -16,38 +16,18 @@
package com.android.server.incident;
-import android.app.ActivityManager;
-import android.app.AppOpsManager;
-import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.net.Uri;
import android.os.Binder;
-import android.os.Handler;
import android.os.IIncidentAuthListener;
import android.os.IIncidentCompanion;
-import android.os.IncidentManager;
-import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
import com.android.internal.util.DumpUtils;
import com.android.server.SystemService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
import java.util.List;
-// TODO: User changes should deny everything that's pending.
-
/**
* Helper service for incidentd and dumpstated to provide user feedback
* and authorization for bug and inicdent reports to be taken.
@@ -55,83 +35,26 @@ import java.util.List;
public class IncidentCompanionService extends SystemService {
static final String TAG = "IncidentCompanionService";
- private final Handler mHandler = new Handler();
- private final RequestQueue mRequestQueue = new RequestQueue(mHandler);
- private final PackageManager mPackageManager;
- private final AppOpsManager mAppOpsManager;
-
- //
- // All fields below must be protected by mLock
- //
- private final Object mLock = new Object();
- private final ArrayList<PendingReportRec> mPending = new ArrayList();
-
/**
- * The next ID we'll use when we make a PendingReportRec.
+ * Tracker for reports pending approval.
*/
- private int mNextPendingId = 1;
-
- /**
- * One for each authorization that's pending.
- */
- private final class PendingReportRec {
- public int id;
- public String callingPackage;
- public int flags;
- public IIncidentAuthListener listener;
- public long addedRealtime;
- public long addedWalltime;
-
- /**
- * Construct a PendingReportRec, with an auto-incremented id.
- */
- PendingReportRec(String callingPackage, int flags, IIncidentAuthListener listener) {
- this.id = mNextPendingId++;
- this.callingPackage = callingPackage;
- this.flags = flags;
- this.listener = listener;
- this.addedRealtime = SystemClock.elapsedRealtime();
- this.addedWalltime = System.currentTimeMillis();
- }
-
- /**
- * Get the Uri that contains the flattened data.
- */
- Uri getUri() {
- return (new Uri.Builder())
- .scheme(IncidentManager.URI_SCHEME)
- .authority(IncidentManager.URI_AUTHORITY)
- .path(IncidentManager.URI_PATH)
- .appendQueryParameter(IncidentManager.URI_PARAM_ID, Integer.toString(id))
- .appendQueryParameter(IncidentManager.URI_PARAM_CALLING_PACKAGE, callingPackage)
- .appendQueryParameter(IncidentManager.URI_PARAM_FLAGS, Integer.toString(flags))
- .appendQueryParameter(IncidentManager.URI_PARAM_TIMESTAMP,
- Long.toString(addedWalltime))
- .build();
- }
- }
+ private PendingReports mPendingReports;
/**
* Implementation of the IIncidentCompanion binder interface.
*/
private final class BinderService extends IIncidentCompanion.Stub {
/**
- * ONEWAY binder call to initiate authorizing the report. The actual logic is posted
- * to mRequestQueue, and may happen later. The security checks need to happen here.
+ * ONEWAY binder call to initiate authorizing the report.
*/
@Override
- public void authorizeReport(int callingUid, final String callingPackage, final int flags,
+ public void authorizeReport(int callingUid, final String callingPackage, int flags,
final IIncidentAuthListener listener) {
enforceRequestAuthorizationPermission();
final long ident = Binder.clearCallingIdentity();
try {
- // Starting the system server is complicated, and rather than try to
- // have a complicated lifecycle that we share with dumpstated and incidentd,
- // we will accept the request, and then display it whenever it becomes possible to.
- mRequestQueue.enqueue(listener.asBinder(), true, () -> {
- authorizeReportImpl(callingUid, callingPackage, flags, listener);
- });
+ mPendingReports.authorizeReport(callingUid, callingPackage, flags, listener);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -152,9 +75,7 @@ public class IncidentCompanionService extends SystemService {
// authorize/cancel pairs.
final long ident = Binder.clearCallingIdentity();
try {
- mRequestQueue.enqueue(listener.asBinder(), false, () -> {
- cancelReportImpl(listener);
- });
+ mPendingReports.cancelAuthorization(listener);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -167,19 +88,11 @@ public class IncidentCompanionService extends SystemService {
@Override
public List<String> getPendingReports() {
enforceAuthorizePermission();
-
- synchronized (mLock) {
- final int size = mPending.size();
- final ArrayList<String> result = new ArrayList(size);
- for (int i = 0; i < size; i++) {
- result.add(mPending.get(i).getUri().toString());
- }
- return result;
- }
+ return mPendingReports.getPendingReports();
}
/**
- * ONEWAY binder call to mark a report as approved.
+ * SYNCHRONOUS binder call to mark a report as approved.
*/
@Override
public void approveReport(String uri) {
@@ -187,32 +100,14 @@ public class IncidentCompanionService extends SystemService {
final long ident = Binder.clearCallingIdentity();
try {
- final PendingReportRec rec;
- synchronized (mLock) {
- rec = findAndRemovePendingReportRecLocked(uri);
- if (rec == null) {
- Log.e(TAG, "confirmApproved: Couldn't find record for uri: " + uri);
- return;
- }
- }
-
- // Re-do the broadcast, so whoever is listening knows the list changed,
- // in case another one was added in the meantime.
- sendBroadcast();
-
- Log.i(TAG, "Approved report: " + uri);
- try {
- rec.listener.onReportApproved();
- } catch (RemoteException ex) {
- Log.w(TAG, "Failed calling back for approval for: " + uri, ex);
- }
+ mPendingReports.approveReport(uri);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
/**
- * ONEWAY binder call to mark a report as NOT approved.
+ * SYNCHRONOUS binder call to mark a report as NOT approved.
*/
@Override
public void denyReport(String uri) {
@@ -220,25 +115,7 @@ public class IncidentCompanionService extends SystemService {
final long ident = Binder.clearCallingIdentity();
try {
- final PendingReportRec rec;
- synchronized (mLock) {
- rec = findAndRemovePendingReportRecLocked(uri);
- if (rec == null) {
- Log.e(TAG, "confirmDenied: Couldn't find record for uri: " + uri);
- return;
- }
- }
-
- // Re-do the broadcast, so whoever is listening knows the list changed,
- // in case another one was added in the meantime.
- sendBroadcast();
-
- Log.i(TAG, "Denied report: " + uri);
- try {
- rec.listener.onReportDenied();
- } catch (RemoteException ex) {
- Log.w(TAG, "Failed calling back for denial for: " + uri, ex);
- }
+ mPendingReports.denyReport(uri);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -252,27 +129,22 @@ public class IncidentCompanionService extends SystemService {
if (!DumpUtils.checkDumpPermission(getContext(), TAG, writer)) {
return;
}
- if (args.length == 0) {
- // Standard text dumpsys
- final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
- synchronized (mLock) {
- final int size = mPending.size();
- writer.println("mPending: (" + size + ")");
- for (int i = 0; i < size; i++) {
- final PendingReportRec entry = mPending.get(i);
- writer.println(String.format(" %11d %s: %s", entry.addedRealtime,
- df.format(new Date(entry.addedWalltime)),
- entry.getUri().toString()));
- }
- }
- }
+ mPendingReports.dump(fd, writer, args);
}
+ /**
+ * Inside the binder interface class because we want to do all of the authorization
+ * here, before calling out to the helper objects.
+ */
private void enforceRequestAuthorizationPermission() {
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.REQUEST_INCIDENT_REPORT_APPROVAL, null);
}
+ /**
+ * Inside the binder interface class because we want to do all of the authorization
+ * here, before calling out to the helper objects.
+ */
private void enforceAuthorizePermission() {
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.APPROVE_INCIDENT_REPORTS, null);
@@ -285,8 +157,7 @@ public class IncidentCompanionService extends SystemService {
*/
public IncidentCompanionService(Context context) {
super(context);
- mPackageManager = context.getPackageManager();
- mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ mPendingReports = new PendingReports(context);
}
/**
@@ -307,239 +178,9 @@ public class IncidentCompanionService extends SystemService {
super.onBootPhase(phase);
switch (phase) {
case SystemService.PHASE_BOOT_COMPLETED:
- // Release the enqueued work.
- mRequestQueue.start();
+ mPendingReports.onBootCompleted();
break;
}
}
-
- /**
- * Start the confirmation process.
- */
- private void authorizeReportImpl(int callingUid, final String callingPackage, int flags,
- final IIncidentAuthListener listener) {
- // Enforce that the calling package pertains to the callingUid.
- if (!isPackageInUid(callingUid, callingPackage)) {
- Log.w(TAG, "Calling uid " + callingUid + " doesn't match package "
- + callingPackage);
- denyReportBeforeAddingRec(listener, callingPackage);
- return;
- }
-
- // Find the primary user of this device.
- final int primaryUser = getAndValidateUser();
- if (primaryUser == UserHandle.USER_NULL) {
- denyReportBeforeAddingRec(listener, callingPackage);
- return;
- }
-
- // Find the approver app (hint: it's PermissionController).
- final ComponentName receiver = getApproverComponent(primaryUser);
- if (receiver == null) {
- // We couldn't find an approver... so deny the request here and now, before we
- // do anything else.
- denyReportBeforeAddingRec(listener, callingPackage);
- return;
- }
-
- // Save the record for when the PermissionController comes back to authorize it.
- PendingReportRec rec = null;
- synchronized (mLock) {
- rec = new PendingReportRec(callingPackage, flags, listener);
- mPending.add(rec);
- }
-
- try {
- listener.asBinder().linkToDeath(() -> {
- Log.i(TAG, "Got death notification listener=" + listener);
- cancelReportImpl(listener, receiver, primaryUser);
- }, 0);
- } catch (RemoteException ex) {
- Log.e(TAG, "Remote died while trying to register death listener: " + rec.getUri());
- // First, remove from our list.
- cancelReportImpl(listener, receiver, primaryUser);
- }
-
- // Go tell Permission controller to start asking the user.
- sendBroadcast(receiver, primaryUser);
- }
-
- /**
- * Cancel a pending report request (because of an explicit call to cancel)
- */
- private void cancelReportImpl(IIncidentAuthListener listener) {
- final int primaryUser = getAndValidateUser();
- final ComponentName receiver = getApproverComponent(primaryUser);
- if (primaryUser != UserHandle.USER_NULL && receiver != null) {
- cancelReportImpl(listener, receiver, primaryUser);
- }
- }
-
- /**
- * Cancel a pending report request (either because of an explicit call to cancel
- * by the calling app, or because of a binder death).
- */
- private void cancelReportImpl(IIncidentAuthListener listener, ComponentName receiver,
- int primaryUser) {
- // First, remove from our list.
- synchronized (mLock) {
- removePendingReportRecLocked(listener);
- }
- // Second, call back to PermissionController to say it's canceled.
- sendBroadcast(receiver, primaryUser);
- }
-
- /**
- * Send an extra copy of the broadcast, to tell them that the list has changed
- * because of an addition or removal. This function is less aggressive than
- * authorizeReportImpl in logging about failures, because this is for use in
- * cleanup cases to keep the apps' list in sync with ours.
- */
- private void sendBroadcast() {
- final int primaryUser = getAndValidateUser();
- if (primaryUser == UserHandle.USER_NULL) {
- return;
- }
- final ComponentName receiver = getApproverComponent(primaryUser);
- if (receiver == null) {
- return;
- }
- sendBroadcast(receiver, primaryUser);
- }
-
- /**
- * Send the confirmation broadcast.
- */
- private void sendBroadcast(ComponentName receiver, int primaryUser) {
- final Intent intent = new Intent(Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED);
- intent.setComponent(receiver);
-
- // Send it to the primary user.
- getContext().sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(primaryUser),
- android.Manifest.permission.APPROVE_INCIDENT_REPORTS);
- }
-
- /**
- * Remove a PendingReportRec keyed by uri, and return it.
- */
- private PendingReportRec findAndRemovePendingReportRecLocked(String uriString) {
- final Uri uri = Uri.parse(uriString);
- final int id;
- try {
- final String idStr = uri.getQueryParameter(IncidentManager.URI_PARAM_ID);
- id = Integer.parseInt(idStr);
- } catch (NumberFormatException ex) {
- Log.w(TAG, "Can't parse id from: " + uriString);
- return null;
- }
- final int size = mPending.size();
- for (int i = 0; i < size; i++) {
- final PendingReportRec rec = mPending.get(i);
- if (rec.id == id) {
- mPending.remove(i);
- return rec;
- }
- }
- return null;
- }
-
- /**
- * Remove a PendingReportRec keyed by listener.
- */
- private void removePendingReportRecLocked(IIncidentAuthListener listener) {
- final int size = mPending.size();
- for (int i = 0; i < size; i++) {
- final PendingReportRec rec = mPending.get(i);
- if (rec.listener.asBinder() == listener.asBinder()) {
- Log.i(TAG, " ...Removed PendingReportRec index=" + i + ": " + rec.getUri());
- mPending.remove(i);
- }
- }
- }
-
- /**
- * Just call listener.deny() (wrapping the RemoteException), without try to
- * add it to the list.
- */
- private void denyReportBeforeAddingRec(IIncidentAuthListener listener, String pkg) {
- try {
- listener.onReportDenied();
- } catch (RemoteException ex) {
- Log.w(TAG, "Failed calling back for denial for " + pkg, ex);
- }
- }
-
- /**
- * Check whether the current user is the primary user, and return the user id if they are.
- * Returns UserHandle.USER_NULL if not valid.
- */
- private int getAndValidateUser() {
- // Current user
- UserInfo currentUser;
- try {
- currentUser = ActivityManager.getService().getCurrentUser();
- } catch (RemoteException ex) {
- // We're already inside the system process.
- throw new RuntimeException(ex);
- }
-
- // Primary user
- final UserManager um = UserManager.get(getContext());
- final UserInfo primaryUser = um.getPrimaryUser();
-
- // Check that we're using the right user.
- if (currentUser == null) {
- Log.w(TAG, "No current user. Nobody to approve the report."
- + " The report will be denied.");
- return UserHandle.USER_NULL;
- }
- if (primaryUser == null) {
- Log.w(TAG, "No primary user. Nobody to approve the report."
- + " The report will be denied.");
- return UserHandle.USER_NULL;
- }
- if (primaryUser.id != currentUser.id) {
- Log.w(TAG, "Only the primary user can approve bugreports, but they are not"
- + " the current user. The report will be denied.");
- return UserHandle.USER_NULL;
- }
-
- return primaryUser.id;
- }
-
- /**
- * Return the ComponentName of the BroadcastReceiver that will approve reports.
- * The system must have zero or one of these installed. We only look on the
- * system partition. When the broadcast happens, the component will also need
- * have the APPROVE_INCIDENT_REPORTS permission.
- */
- private ComponentName getApproverComponent(int userId) {
- // Find the one true BroadcastReceiver
- final Intent intent = new Intent(Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED);
- final List<ResolveInfo> matches = mPackageManager.queryBroadcastReceiversAsUser(intent,
- PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DIRECT_BOOT_AWARE
- | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId);
- if (matches.size() == 1) {
- return matches.get(0).getComponentInfo().getComponentName();
- } else {
- Log.w(TAG, "Didn't find exactly one BroadcastReceiver to handle "
- + Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED
- + ". The report will be denied. size="
- + matches.size() + ": matches=" + matches);
- return null;
- }
- }
-
- /**
- * Return whether the package is one of the packages installed for the uid.
- */
- private boolean isPackageInUid(int uid, String packageName) {
- try {
- mAppOpsManager.checkPackage(uid, packageName);
- return true;
- } catch (SecurityException ex) {
- return false;
- }
- }
}
diff --git a/services/core/java/com/android/server/incident/PendingReports.java b/services/core/java/com/android/server/incident/PendingReports.java
new file mode 100644
index 000000000000..519ed41670f6
--- /dev/null
+++ b/services/core/java/com/android/server/incident/PendingReports.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.incident;
+
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.IIncidentAuthListener;
+import android.os.IncidentManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+// TODO: User changes should deny everything that's pending.
+
+/**
+ * Tracker for reports pending approval.
+ */
+class PendingReports {
+ static final String TAG = IncidentCompanionService.TAG;
+
+ private final Handler mHandler = new Handler();
+ private final RequestQueue mRequestQueue = new RequestQueue(mHandler);
+ private final Context mContext;
+ private final PackageManager mPackageManager;
+ private final AppOpsManager mAppOpsManager;
+
+ //
+ // All fields below must be protected by mLock
+ //
+ private final Object mLock = new Object();
+ private final ArrayList<PendingReportRec> mPending = new ArrayList();
+
+ /**
+ * The next ID we'll use when we make a PendingReportRec.
+ */
+ private int mNextPendingId = 1;
+
+ /**
+ * One for each authorization that's pending.
+ */
+ private final class PendingReportRec {
+ public int id;
+ public String callingPackage;
+ public int flags;
+ public IIncidentAuthListener listener;
+ public long addedRealtime;
+ public long addedWalltime;
+
+ /**
+ * Construct a PendingReportRec, with an auto-incremented id.
+ */
+ PendingReportRec(String callingPackage, int flags, IIncidentAuthListener listener) {
+ this.id = mNextPendingId++;
+ this.callingPackage = callingPackage;
+ this.flags = flags;
+ this.listener = listener;
+ this.addedRealtime = SystemClock.elapsedRealtime();
+ this.addedWalltime = System.currentTimeMillis();
+ }
+
+ /**
+ * Get the Uri that contains the flattened data.
+ */
+ Uri getUri() {
+ return (new Uri.Builder())
+ .scheme(IncidentManager.URI_SCHEME)
+ .authority(IncidentManager.URI_AUTHORITY)
+ .path(IncidentManager.URI_PATH)
+ .appendQueryParameter(IncidentManager.URI_PARAM_ID, Integer.toString(id))
+ .appendQueryParameter(IncidentManager.URI_PARAM_CALLING_PACKAGE, callingPackage)
+ .appendQueryParameter(IncidentManager.URI_PARAM_FLAGS, Integer.toString(flags))
+ .appendQueryParameter(IncidentManager.URI_PARAM_TIMESTAMP,
+ Long.toString(addedWalltime))
+ .build();
+ }
+ }
+
+ /**
+ * Construct new PendingReports with the context.
+ */
+ PendingReports(Context context) {
+ mContext = context;
+ mPackageManager = context.getPackageManager();
+ mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ }
+
+ /**
+ * ONEWAY binder call to initiate authorizing the report. The actual logic is posted
+ * to mRequestQueue, and may happen later.
+ * <p>
+ * The security checks are handled by IncidentCompanionService.
+ */
+ public void authorizeReport(int callingUid, final String callingPackage, final int flags,
+ final IIncidentAuthListener listener) {
+ // Starting the system server is complicated, and rather than try to
+ // have a complicated lifecycle that we share with dumpstated and incidentd,
+ // we will accept the request, and then display it whenever it becomes possible to.
+ mRequestQueue.enqueue(listener.asBinder(), true, () -> {
+ authorizeReportImpl(callingUid, callingPackage, flags, listener);
+ });
+ }
+
+ /**
+ * ONEWAY binder call to cancel the inbound authorization request.
+ * <p>
+ * This is a oneway call, and so is authorizeReport, so the
+ * caller's ordering is preserved. The other calls on this object are synchronous, so
+ * their ordering is not guaranteed with respect to these calls. So the implementation
+ * sends out extra broadcasts to allow for eventual consistency.
+ * <p>
+ * The security checks are handled by IncidentCompanionService.
+ */
+ public void cancelAuthorization(final IIncidentAuthListener listener) {
+ mRequestQueue.enqueue(listener.asBinder(), false, () -> {
+ cancelReportImpl(listener);
+ });
+ }
+
+ /**
+ * SYNCHRONOUS binder call to get the list of reports that are pending confirmation
+ * by the user.
+ * <p>
+ * The security checks are handled by IncidentCompanionService.
+ */
+ public List<String> getPendingReports() {
+ synchronized (mLock) {
+ final int size = mPending.size();
+ final ArrayList<String> result = new ArrayList(size);
+ for (int i = 0; i < size; i++) {
+ result.add(mPending.get(i).getUri().toString());
+ }
+ return result;
+ }
+ }
+
+ /**
+ * SYNCHRONOUS binder call to mark a report as approved.
+ * <p>
+ * The security checks are handled by IncidentCompanionService.
+ */
+ public void approveReport(String uri) {
+ final PendingReportRec rec;
+ synchronized (mLock) {
+ rec = findAndRemovePendingReportRecLocked(uri);
+ if (rec == null) {
+ Log.e(TAG, "confirmApproved: Couldn't find record for uri: " + uri);
+ return;
+ }
+ }
+
+ // Re-do the broadcast, so whoever is listening knows the list changed,
+ // in case another one was added in the meantime.
+ sendBroadcast();
+
+ Log.i(TAG, "Approved report: " + uri);
+ try {
+ rec.listener.onReportApproved();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Failed calling back for approval for: " + uri, ex);
+ }
+ }
+
+ /**
+ * SYNCHRONOUS binder call to mark a report as NOT approved.
+ */
+ public void denyReport(String uri) {
+ final PendingReportRec rec;
+ synchronized (mLock) {
+ rec = findAndRemovePendingReportRecLocked(uri);
+ if (rec == null) {
+ Log.e(TAG, "confirmDenied: Couldn't find record for uri: " + uri);
+ return;
+ }
+ }
+
+ // Re-do the broadcast, so whoever is listening knows the list changed,
+ // in case another one was added in the meantime.
+ sendBroadcast();
+
+ Log.i(TAG, "Denied report: " + uri);
+ try {
+ rec.listener.onReportDenied();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Failed calling back for denial for: " + uri, ex);
+ }
+ }
+
+ /**
+ * Implementation of adb shell dumpsys debugreportcompanion.
+ */
+ protected void dump(FileDescriptor fd, final PrintWriter writer, String[] args) {
+ if (args.length == 0) {
+ // Standard text dumpsys
+ final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+ synchronized (mLock) {
+ final int size = mPending.size();
+ writer.println("mPending: (" + size + ")");
+ for (int i = 0; i < size; i++) {
+ final PendingReportRec entry = mPending.get(i);
+ writer.println(String.format(" %11d %s: %s", entry.addedRealtime,
+ df.format(new Date(entry.addedWalltime)),
+ entry.getUri().toString()));
+ }
+ }
+ }
+ }
+
+ /**
+ * Handle the boot process... Starts everything running once the system is
+ * up enough for us to do UI.
+ */
+ public void onBootCompleted() {
+ // Release the enqueued work.
+ mRequestQueue.start();
+ }
+
+ /**
+ * Start the confirmation process.
+ */
+ private void authorizeReportImpl(int callingUid, final String callingPackage, int flags,
+ final IIncidentAuthListener listener) {
+ // Enforce that the calling package pertains to the callingUid.
+ if (!isPackageInUid(callingUid, callingPackage)) {
+ Log.w(TAG, "Calling uid " + callingUid + " doesn't match package "
+ + callingPackage);
+ denyReportBeforeAddingRec(listener, callingPackage);
+ return;
+ }
+
+ // Find the primary user of this device.
+ final int primaryUser = getAndValidateUser();
+ if (primaryUser == UserHandle.USER_NULL) {
+ denyReportBeforeAddingRec(listener, callingPackage);
+ return;
+ }
+
+ // Find the approver app (hint: it's PermissionController).
+ final ComponentName receiver = getApproverComponent(primaryUser);
+ if (receiver == null) {
+ // We couldn't find an approver... so deny the request here and now, before we
+ // do anything else.
+ denyReportBeforeAddingRec(listener, callingPackage);
+ return;
+ }
+
+ // Save the record for when the PermissionController comes back to authorize it.
+ PendingReportRec rec = null;
+ synchronized (mLock) {
+ rec = new PendingReportRec(callingPackage, flags, listener);
+ mPending.add(rec);
+ }
+
+ try {
+ listener.asBinder().linkToDeath(() -> {
+ Log.i(TAG, "Got death notification listener=" + listener);
+ cancelReportImpl(listener, receiver, primaryUser);
+ }, 0);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Remote died while trying to register death listener: " + rec.getUri());
+ // First, remove from our list.
+ cancelReportImpl(listener, receiver, primaryUser);
+ }
+
+ // Go tell Permission controller to start asking the user.
+ sendBroadcast(receiver, primaryUser);
+ }
+
+ /**
+ * Cancel a pending report request (because of an explicit call to cancel)
+ */
+ private void cancelReportImpl(IIncidentAuthListener listener) {
+ final int primaryUser = getAndValidateUser();
+ final ComponentName receiver = getApproverComponent(primaryUser);
+ if (primaryUser != UserHandle.USER_NULL && receiver != null) {
+ cancelReportImpl(listener, receiver, primaryUser);
+ }
+ }
+
+ /**
+ * Cancel a pending report request (either because of an explicit call to cancel
+ * by the calling app, or because of a binder death).
+ */
+ private void cancelReportImpl(IIncidentAuthListener listener, ComponentName receiver,
+ int primaryUser) {
+ // First, remove from our list.
+ synchronized (mLock) {
+ removePendingReportRecLocked(listener);
+ }
+ // Second, call back to PermissionController to say it's canceled.
+ sendBroadcast(receiver, primaryUser);
+ }
+
+ /**
+ * Send an extra copy of the broadcast, to tell them that the list has changed
+ * because of an addition or removal. This function is less aggressive than
+ * authorizeReportImpl in logging about failures, because this is for use in
+ * cleanup cases to keep the apps' list in sync with ours.
+ */
+ private void sendBroadcast() {
+ final int primaryUser = getAndValidateUser();
+ if (primaryUser == UserHandle.USER_NULL) {
+ return;
+ }
+ final ComponentName receiver = getApproverComponent(primaryUser);
+ if (receiver == null) {
+ return;
+ }
+ sendBroadcast(receiver, primaryUser);
+ }
+
+ /**
+ * Send the confirmation broadcast.
+ */
+ private void sendBroadcast(ComponentName receiver, int primaryUser) {
+ final Intent intent = new Intent(Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED);
+ intent.setComponent(receiver);
+
+ // Send it to the primary user.
+ mContext.sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(primaryUser),
+ android.Manifest.permission.APPROVE_INCIDENT_REPORTS);
+ }
+
+ /**
+ * Remove a PendingReportRec keyed by uri, and return it.
+ */
+ private PendingReportRec findAndRemovePendingReportRecLocked(String uriString) {
+ final Uri uri = Uri.parse(uriString);
+ final int id;
+ try {
+ final String idStr = uri.getQueryParameter(IncidentManager.URI_PARAM_ID);
+ id = Integer.parseInt(idStr);
+ } catch (NumberFormatException ex) {
+ Log.w(TAG, "Can't parse id from: " + uriString);
+ return null;
+ }
+ final int size = mPending.size();
+ for (int i = 0; i < size; i++) {
+ final PendingReportRec rec = mPending.get(i);
+ if (rec.id == id) {
+ mPending.remove(i);
+ return rec;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Remove a PendingReportRec keyed by listener.
+ */
+ private void removePendingReportRecLocked(IIncidentAuthListener listener) {
+ final int size = mPending.size();
+ for (int i = 0; i < size; i++) {
+ final PendingReportRec rec = mPending.get(i);
+ if (rec.listener.asBinder() == listener.asBinder()) {
+ Log.i(TAG, " ...Removed PendingReportRec index=" + i + ": " + rec.getUri());
+ mPending.remove(i);
+ }
+ }
+ }
+
+ /**
+ * Just call listener.deny() (wrapping the RemoteException), without try to
+ * add it to the list.
+ */
+ private void denyReportBeforeAddingRec(IIncidentAuthListener listener, String pkg) {
+ try {
+ listener.onReportDenied();
+ } catch (RemoteException ex) {
+ Log.w(TAG, "Failed calling back for denial for " + pkg, ex);
+ }
+ }
+
+ /**
+ * Check whether the current user is the primary user, and return the user id if they are.
+ * Returns UserHandle.USER_NULL if not valid.
+ */
+ private int getAndValidateUser() {
+ // Current user
+ UserInfo currentUser;
+ try {
+ currentUser = ActivityManager.getService().getCurrentUser();
+ } catch (RemoteException ex) {
+ // We're already inside the system process.
+ throw new RuntimeException(ex);
+ }
+
+ // Primary user
+ final UserManager um = UserManager.get(mContext);
+ final UserInfo primaryUser = um.getPrimaryUser();
+
+ // Check that we're using the right user.
+ if (currentUser == null) {
+ Log.w(TAG, "No current user. Nobody to approve the report."
+ + " The report will be denied.");
+ return UserHandle.USER_NULL;
+ }
+ if (primaryUser == null) {
+ Log.w(TAG, "No primary user. Nobody to approve the report."
+ + " The report will be denied.");
+ return UserHandle.USER_NULL;
+ }
+ if (primaryUser.id != currentUser.id) {
+ Log.w(TAG, "Only the primary user can approve bugreports, but they are not"
+ + " the current user. The report will be denied.");
+ return UserHandle.USER_NULL;
+ }
+
+ return primaryUser.id;
+ }
+
+ /**
+ * Return the ComponentName of the BroadcastReceiver that will approve reports.
+ * The system must have zero or one of these installed. We only look on the
+ * system partition. When the broadcast happens, the component will also need
+ * have the APPROVE_INCIDENT_REPORTS permission.
+ */
+ private ComponentName getApproverComponent(int userId) {
+ // Find the one true BroadcastReceiver
+ final Intent intent = new Intent(Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED);
+ final List<ResolveInfo> matches = mPackageManager.queryBroadcastReceiversAsUser(intent,
+ PackageManager.MATCH_SYSTEM_ONLY | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId);
+ if (matches.size() == 1) {
+ return matches.get(0).getComponentInfo().getComponentName();
+ } else {
+ Log.w(TAG, "Didn't find exactly one BroadcastReceiver to handle "
+ + Intent.ACTION_PENDING_INCIDENT_REPORTS_CHANGED
+ + ". The report will be denied. size="
+ + matches.size() + ": matches=" + matches);
+ return null;
+ }
+ }
+
+ /**
+ * Return whether the package is one of the packages installed for the uid.
+ */
+ private boolean isPackageInUid(int uid, String packageName) {
+ try {
+ mAppOpsManager.checkPackage(uid, packageName);
+ return true;
+ } catch (SecurityException ex) {
+ return false;
+ }
+ }
+}
+
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index c2ac27a5b737..62c4815a7de0 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -34,9 +34,11 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ILauncherApps;
import android.content.pm.IOnAppsChangedListener;
+import android.content.pm.IPackageInstallerCallback;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
@@ -56,6 +58,7 @@ import android.os.IInterface;
import android.os.ParcelFileDescriptor;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
@@ -153,6 +156,8 @@ public class LauncherAppsService extends SystemService {
private final Object mVouchedSignaturesLocked = new Object();
+ private PackageInstallerService mPackageInstallerService;
+
public LauncherAppsImpl(Context context) {
mContext = context;
mUm = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
@@ -204,8 +209,7 @@ public class LauncherAppsService extends SystemService {
}
/*
- * @see android.content.pm.ILauncherApps#addOnAppsChangedListener(
- * android.content.pm.IOnAppsChangedListener)
+ * @see android.content.pm.ILauncherApps#addOnAppsChangedListener
*/
@Override
public void addOnAppsChangedListener(String callingPackage, IOnAppsChangedListener listener)
@@ -228,8 +232,7 @@ public class LauncherAppsService extends SystemService {
}
/*
- * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener(
- * android.content.pm.IOnAppsChangedListener)
+ * @see android.content.pm.ILauncherApps#removeOnAppsChangedListener
*/
@Override
public void removeOnAppsChangedListener(IOnAppsChangedListener listener)
@@ -246,6 +249,44 @@ public class LauncherAppsService extends SystemService {
}
/**
+ * @see android.content.pm.ILauncherApps#registerPackageInstallerCallback
+ */
+ @Override
+ public void registerPackageInstallerCallback(String callingPackage,
+ IPackageInstallerCallback callback) {
+ verifyCallingPackage(callingPackage);
+ UserHandle callingIdUserHandle = new UserHandle(getCallingUserId());
+ getPackageInstallerService().registerCallback(callback, eventUserId ->
+ isEnabledProfileOf(callingIdUserHandle,
+ new UserHandle(eventUserId), "shouldReceiveEvent"));
+ }
+
+ @Override
+ public ParceledListSlice<SessionInfo> getAllSessions(String callingPackage) {
+ verifyCallingPackage(callingPackage);
+ List<SessionInfo> sessionInfos = new ArrayList<>();
+ int[] userIds = mUm.getEnabledProfileIds(getCallingUserId());
+ long token = Binder.clearCallingIdentity();
+ try {
+ for (int userId : userIds) {
+ sessionInfos.addAll(getPackageInstallerService().getAllSessions(userId)
+ .getList());
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return new ParceledListSlice<>(sessionInfos);
+ }
+
+ private PackageInstallerService getPackageInstallerService() {
+ if (mPackageInstallerService == null) {
+ mPackageInstallerService = ((PackageInstallerService) ((PackageManagerService)
+ ServiceManager.getService("package")).getPackageInstaller());
+ }
+ return mPackageInstallerService;
+ }
+
+ /**
* Register a receiver to watch for package broadcasts
*/
private void startWatchingPackageBroadcasts() {
@@ -430,6 +471,9 @@ public class LauncherAppsService extends SystemService {
if (!mVouchedSignaturesByUser.containsKey(user)) {
initVouchedSignatures(user);
}
+ if (isManagedProfileAdmin(user, appInfo.packageName)) {
+ return false;
+ }
if (mVouchProviders.contains(appInfo.packageName)) {
// If it's a vouching packages then we must show hidden app
return true;
@@ -453,6 +497,24 @@ public class LauncherAppsService extends SystemService {
return true;
}
+ private boolean isManagedProfileAdmin(UserHandle user, String packageName) {
+ final List<UserInfo> userInfoList = mUm.getProfiles(user.getIdentifier());
+ for (int i = 0; i < userInfoList.size(); i++) {
+ UserInfo userInfo = userInfoList.get(i);
+ if (!userInfo.isManagedProfile()) {
+ continue;
+ }
+ ComponentName componentName = mDpm.getProfileOwnerAsUser(userInfo.getUserHandle());
+ if (componentName == null) {
+ continue;
+ }
+ if (componentName.getPackageName().equals(packageName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@VisibleForTesting
static String computePackageCertDigest(Signature signature) {
MessageDigest messageDigest;
@@ -848,6 +910,29 @@ public class LauncherAppsService extends SystemService {
}
@Override
+ public void startSessionDetailsActivityAsUser(IApplicationThread caller,
+ String callingPackage, SessionInfo sessionInfo, Rect sourceBounds,
+ Bundle opts, UserHandle userHandle) throws RemoteException {
+ int userId = userHandle.getIdentifier();
+ if (!canAccessProfile(userId, "Cannot start details activity")) {
+ return;
+ }
+
+ Intent i = new Intent(Intent.ACTION_VIEW)
+ .setData(new Uri.Builder()
+ .scheme("market")
+ .authority("details")
+ .appendQueryParameter("id", sessionInfo.appPackageName)
+ .build())
+ .putExtra(Intent.EXTRA_REFERRER, new Uri.Builder().scheme("android-app")
+ .authority(callingPackage).build());
+ i.setSourceBounds(sourceBounds);
+
+ mActivityTaskManagerInternal.startActivityAsUser(caller, callingPackage, i, opts,
+ userId);
+ }
+
+ @Override
public void startActivityAsUser(IApplicationThread caller, String callingPackage,
ComponentName component, Rect sourceBounds,
Bundle opts, UserHandle user) throws RemoteException {
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 60d792530101..33b8641c145e 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -51,6 +51,8 @@ per-file UserManagerService.java = omakoto@google.com
per-file UserManagerService.java = yamasani@google.com
per-file UserRestrictionsUtils.java = omakoto@google.com
per-file UserRestrictionsUtils.java = yamasani@google.com
+per-file UserRestrictionsUtils.java = rubinxu@google.com
+per-file UserRestrictionsUtils.java = sandness@google.com
# security
per-file KeySetHandle.java = cbrubaker@google.com
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 146a2f3d8433..a3e0d8db8ad5 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -59,7 +59,6 @@ import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SELinux;
-import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.system.ErrnoException;
@@ -107,6 +106,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Random;
+import java.util.function.IntPredicate;
/** The service responsible for installing packages. */
public class PackageInstallerService extends IPackageInstaller.Stub implements
@@ -804,7 +804,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
public void registerCallback(IPackageInstallerCallback callback, int userId) {
mPermissionManager.enforceCrossUserPermission(
Binder.getCallingUid(), userId, true, false, "registerCallback");
- mCallbacks.register(callback, userId);
+ registerCallback(callback, eventUserId -> userId == eventUserId);
+ }
+
+ /**
+ * Assume permissions already checked and caller's identity cleared
+ */
+ public void registerCallback(IPackageInstallerCallback callback, IntPredicate userCheck) {
+ mCallbacks.register(callback, userCheck);
}
@Override
@@ -1026,8 +1033,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
super(looper);
}
- public void register(IPackageInstallerCallback callback, int userId) {
- mCallbacks.register(callback, new UserHandle(userId));
+ public void register(IPackageInstallerCallback callback, IntPredicate userCheck) {
+ mCallbacks.register(callback, userCheck);
}
public void unregister(IPackageInstallerCallback callback) {
@@ -1040,9 +1047,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
final int n = mCallbacks.beginBroadcast();
for (int i = 0; i < n; i++) {
final IPackageInstallerCallback callback = mCallbacks.getBroadcastItem(i);
- final UserHandle user = (UserHandle) mCallbacks.getBroadcastCookie(i);
- // TODO: dispatch notifications for slave profiles
- if (userId == user.getIdentifier()) {
+ final IntPredicate userCheck = (IntPredicate) mCallbacks.getBroadcastCookie(i);
+ if (userCheck.test(userId)) {
try {
invokeCallback(callback, msg);
} catch (RemoteException ignored) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 494ec3ff67aa..de0849fa9951 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -473,6 +473,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
final SessionInfo info = new SessionInfo();
synchronized (mLock) {
info.sessionId = sessionId;
+ info.userId = userId;
info.installerPackageName = mInstallerPackageName;
info.resolvedBaseCodePath = (mResolvedBaseFile != null) ?
mResolvedBaseFile.getAbsolutePath() : null;
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 4f20590a47ff..d0f192d597c6 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1109,14 +1109,7 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public int getManagedProfileBadge(@UserIdInt int userId) {
- int callingUserId = UserHandle.getCallingUserId();
- if (callingUserId != userId && !hasManageUsersPermission()) {
- if (!isSameProfileGroupNoChecks(callingUserId, userId)) {
- throw new SecurityException(
- "You need MANAGE_USERS permission to: check if specified user a " +
- "managed profile outside your profile group");
- }
- }
+ checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getManagedProfileBadge");
synchronized (mUsersLock) {
UserInfo userInfo = getUserInfoLU(userId);
return userInfo != null ? userInfo.profileBadge : 0;
@@ -1125,14 +1118,7 @@ public class UserManagerService extends IUserManager.Stub {
@Override
public boolean isManagedProfile(int userId) {
- int callingUserId = UserHandle.getCallingUserId();
- if (callingUserId != userId && !hasManageUsersPermission()) {
- if (!isSameProfileGroupNoChecks(callingUserId, userId)) {
- throw new SecurityException(
- "You need MANAGE_USERS permission to: check if specified user a " +
- "managed profile outside your profile group");
- }
- }
+ checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "isManagedProfile");
synchronized (mUsersLock) {
UserInfo userInfo = getUserInfoLU(userId);
return userInfo != null && userInfo.isManagedProfile();
diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java
index a2c8dace9510..4186154016e2 100644
--- a/services/core/java/com/android/server/power/AttentionDetector.java
+++ b/services/core/java/com/android/server/power/AttentionDetector.java
@@ -24,11 +24,13 @@ import android.os.PowerManagerInternal;
import android.os.SystemClock;
import android.service.attention.AttentionService;
import android.util.Slog;
+import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicLong;
/**
* Class responsible for checking if the user is currently paying attention to the phone and
@@ -79,6 +81,11 @@ public class AttentionDetector {
*/
private int mWakefulness;
+ /**
+ * Describes how many times in a row was the timeout extended.
+ */
+ private AtomicLong mConsecutiveTimeoutExtendedCount = new AtomicLong(0);
+
@VisibleForTesting
final AttentionCallbackInternal mCallback = new AttentionCallbackInternal() {
@@ -95,6 +102,8 @@ public class AttentionDetector {
}
if (result == AttentionService.ATTENTION_SUCCESS_PRESENT) {
mOnUserAttention.run();
+ } else {
+ resetConsecutiveExtensionCount();
}
}
}
@@ -176,6 +185,7 @@ public class AttentionDetector {
public int onUserActivity(long eventTime, int event) {
switch (event) {
case PowerManager.USER_ACTIVITY_EVENT_ATTENTION:
+ mConsecutiveTimeoutExtendedCount.incrementAndGet();
return 0;
case PowerManager.USER_ACTIVITY_EVENT_OTHER:
case PowerManager.USER_ACTIVITY_EVENT_BUTTON:
@@ -183,6 +193,7 @@ public class AttentionDetector {
case PowerManager.USER_ACTIVITY_EVENT_ACCESSIBILITY:
cancelCurrentRequestIfAny();
mLastUserActivityTime = eventTime;
+ resetConsecutiveExtensionCount();
return 1;
default:
if (DEBUG) {
@@ -196,6 +207,7 @@ public class AttentionDetector {
mWakefulness = wakefulness;
if (wakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
cancelCurrentRequestIfAny();
+ resetConsecutiveExtensionCount();
}
}
@@ -206,6 +218,13 @@ public class AttentionDetector {
}
}
+ private void resetConsecutiveExtensionCount() {
+ final long previousCount = mConsecutiveTimeoutExtendedCount.getAndSet(0);
+ if (previousCount > 0) {
+ StatsLog.write(StatsLog.SCREEN_TIMEOUT_EXTENSION_REPORTED, previousCount);
+ }
+ }
+
@VisibleForTesting
int getRequestCode() {
return (int) (mLastUserActivityTime % Integer.MAX_VALUE);
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index 03ec57b45acf..d72270e3f36d 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -52,6 +52,7 @@ import android.os.UserManagerInternal;
import android.service.sms.FinancialSmsService;
import android.telephony.IFinancialSmsCallback;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.PackageUtils;
import android.util.Slog;
@@ -145,6 +146,9 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
mAppOpsManager = context.getSystemService(AppOpsManager.class);
+ LocalServices.addService(RoleManagerServiceInternal.class,
+ new RoleManagerServiceInternalImpl());
+
registerUserRemovedReceiver();
}
@@ -382,6 +386,19 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
}
}
+ /**
+ * Get all roles and packages hold them.
+ *
+ * @param user The user to query to roles for
+ *
+ * @return The roles and their holders
+ */
+ @NonNull
+ private ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(@NonNull UserHandle user) {
+ RoleUserState userState = getOrCreateUserState(user.getIdentifier());
+ return userState.getRoleHolders();
+ }
+
private class Stub extends IRoleManager.Stub {
@Override
@@ -676,4 +693,16 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
}
}
}
+
+ /**
+ * Entry point for internal calls into role manager
+ */
+ private final class RoleManagerServiceInternalImpl extends RoleManagerServiceInternal {
+
+ @NonNull
+ @Override
+ public ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(@NonNull UserHandle user) {
+ return RoleManagerService.this.getRoleHoldersAsUser(user);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/role/RoleManagerServiceInternal.java b/services/core/java/com/android/server/role/RoleManagerServiceInternal.java
new file mode 100644
index 000000000000..3afc3f731eb9
--- /dev/null
+++ b/services/core/java/com/android/server/role/RoleManagerServiceInternal.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.role;
+
+import android.annotation.NonNull;
+import android.os.UserHandle;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+
+/**
+ * Internal calls into {@link RoleManagerService}
+ */
+public abstract class RoleManagerServiceInternal {
+ /**
+ * Get all roles and packages hold them.
+ *
+ * @param user The user to query to roles for
+ *
+ * @return The roles and their holders
+ */
+ @NonNull
+ public abstract ArrayMap<String, ArraySet<String>> getRoleHoldersAsUser(
+ @NonNull UserHandle user);
+}
diff --git a/services/core/java/com/android/server/role/RoleUserState.java b/services/core/java/com/android/server/role/RoleUserState.java
index 02dcc4945664..bc68dded2dfe 100644
--- a/services/core/java/com/android/server/role/RoleUserState.java
+++ b/services/core/java/com/android/server/role/RoleUserState.java
@@ -376,7 +376,7 @@ public class RoleUserState {
version = mVersion;
packagesHash = mPackagesHash;
- roles = snapshotRolesLocked();
+ roles = getRoleHolders();
}
AtomicFile atomicFile = new AtomicFile(getFile(mUserId), "roles-" + mUserId);
@@ -541,7 +541,7 @@ public class RoleUserState {
version = mVersion;
packagesHash = mPackagesHash;
- roles = snapshotRolesLocked();
+ roles = getRoleHolders();
}
long fieldToken = dumpOutputStream.start(fieldName, fieldId);
@@ -570,17 +570,24 @@ public class RoleUserState {
dumpOutputStream.end(fieldToken);
}
- @GuardedBy("mLock")
- private ArrayMap<String, ArraySet<String>> snapshotRolesLocked() {
- ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
- for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
- String roleName = mRoles.keyAt(i);
- ArraySet<String> roleHolders = mRoles.valueAt(i);
-
- roleHolders = new ArraySet<>(roleHolders);
- roles.put(roleName, roleHolders);
+ /**
+ * Get the roles and their holders.
+ *
+ * @return A copy of the roles and their holders
+ */
+ @NonNull
+ public ArrayMap<String, ArraySet<String>> getRoleHolders() {
+ synchronized (mLock) {
+ ArrayMap<String, ArraySet<String>> roles = new ArrayMap<>();
+ for (int i = 0, size = CollectionUtils.size(mRoles); i < size; ++i) {
+ String roleName = mRoles.keyAt(i);
+ ArraySet<String> roleHolders = mRoles.valueAt(i);
+
+ roleHolders = new ArraySet<>(roleHolders);
+ roles.put(roleName, roleHolders);
+ }
+ return roles;
}
- return roles;
}
/**
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index c6d2870a24c9..2be78fe32f68 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -23,6 +23,7 @@ import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import static com.android.server.am.MemoryStatUtil.readRssHighWaterMarkFromProcfs;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManagerInternal;
import android.app.AlarmManager;
@@ -83,6 +84,7 @@ import android.os.storage.StorageManager;
import android.telephony.ModemActivityInfo;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.util.StatsLog;
@@ -112,6 +114,7 @@ import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.am.MemoryStatUtil.MemoryStat;
+import com.android.server.role.RoleManagerServiceInternal;
import com.android.server.storage.DiskStatsFileLogger;
import com.android.server.storage.DiskStatsLoggingService;
@@ -1781,6 +1784,60 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
}
/**
+ * Add a RoleHolder atom for each package that holds a role.
+ *
+ * @param elapsedNanos the time since boot
+ * @param wallClockNanos the time on the clock
+ * @param pulledData the data sink to write to
+ */
+ private void pullRoleHolders(long elapsedNanos, final long wallClockNanos,
+ @NonNull List<StatsLogEventWrapper> pulledData) {
+ long callingToken = Binder.clearCallingIdentity();
+ try {
+ PackageManager pm = mContext.getPackageManager();
+ RoleManagerServiceInternal rm =
+ LocalServices.getService(RoleManagerServiceInternal.class);
+
+ List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers();
+
+ int numUsers = users.size();
+ for (int userNum = 0; userNum < numUsers; userNum++) {
+ UserHandle user = users.get(userNum).getUserHandle();
+
+ ArrayMap<String, ArraySet<String>> roles = rm.getRoleHoldersAsUser(user);
+
+ int numRoles = roles.size();
+ for (int roleNum = 0; roleNum < numRoles; roleNum++) {
+ String roleName = roles.keyAt(roleNum);
+ ArraySet<String> holders = roles.valueAt(roleNum);
+
+ int numHolders = holders.size();
+ for (int holderNum = 0; holderNum < numHolders; holderNum++) {
+ String holderName = holders.valueAt(holderNum);
+
+ PackageInfo pkg;
+ try {
+ pkg = pm.getPackageInfoAsUser(holderName, 0, user.getIdentifier());
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Role holder " + holderName + " not found");
+ return;
+ }
+
+ StatsLogEventWrapper e = new StatsLogEventWrapper(StatsLog.ROLE_HOLDER,
+ elapsedNanos, wallClockNanos);
+ e.writeInt(pkg.applicationInfo.uid);
+ e.writeString(holderName);
+ e.writeString(roleName);
+ pulledData.add(e);
+ }
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingToken);
+ }
+ }
+
+ /**
* Pulls various data.
*/
@Override // Binder call
@@ -1954,6 +2011,10 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
pullDebugFailingElapsedClock(tagId, elapsedNanos, wallClockNanos, ret);
break;
}
+ case StatsLog.ROLE_HOLDER: {
+ pullRoleHolders(elapsedNanos, wallClockNanos, ret);
+ break;
+ }
default:
Slog.w(TAG, "No such tagId data as " + tagId);
return null;
diff --git a/services/core/jni/com_android_server_security_VerityUtils.cpp b/services/core/jni/com_android_server_security_VerityUtils.cpp
index 0d888dc41719..988d75cfb984 100644
--- a/services/core/jni/com_android_server_security_VerityUtils.cpp
+++ b/services/core/jni/com_android_server_security_VerityUtils.cpp
@@ -32,9 +32,67 @@
// TODO(112037636): Always include once fsverity.h is upstreamed.
#if __has_include(<linux/fsverity.h>)
#include <linux/fsverity.h>
-const int kSha256Bytes = 32;
+#else
+
+// Before fs-verity is upstreamed, use the current snapshot for development.
+// https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git/tree/include/uapi/linux/fsverity.h?h=fsverity
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
+
+struct fsverity_digest {
+ __u16 digest_algorithm;
+ __u16 digest_size; /* input/output */
+ __u8 digest[];
+};
+
+#define FS_IOC_ENABLE_VERITY _IO('f', 133)
+#define FS_IOC_MEASURE_VERITY _IOWR('f', 134, struct fsverity_digest)
+
+#define FS_VERITY_MAGIC "FSVerity"
+
+#define FS_VERITY_ALG_SHA256 1
+
+struct fsverity_descriptor {
+ __u8 magic[8]; /* must be FS_VERITY_MAGIC */
+ __u8 major_version; /* must be 1 */
+ __u8 minor_version; /* must be 0 */
+ __u8 log_data_blocksize;/* log2(data-bytes-per-hash), e.g. 12 for 4KB */
+ __u8 log_tree_blocksize;/* log2(tree-bytes-per-hash), e.g. 12 for 4KB */
+ __le16 data_algorithm; /* hash algorithm for data blocks */
+ __le16 tree_algorithm; /* hash algorithm for tree blocks */
+ __le32 flags; /* flags */
+ __le32 __reserved1; /* must be 0 */
+ __le64 orig_file_size; /* size of the original file data */
+ __le16 auth_ext_count; /* number of authenticated extensions */
+ __u8 __reserved2[30]; /* must be 0 */
+};
+
+#define FS_VERITY_EXT_ROOT_HASH 1
+#define FS_VERITY_EXT_PKCS7_SIGNATURE 3
+
+struct fsverity_extension {
+ __le32 length;
+ __le16 type; /* Type of this extension (see codes above) */
+ __le16 __reserved; /* Reserved, must be 0 */
+};
+
+struct fsverity_digest_disk {
+ __le16 digest_algorithm;
+ __le16 digest_size;
+ __u8 digest[];
+};
+
+struct fsverity_footer {
+ __le32 desc_reverse_offset; /* distance to fsverity_descriptor */
+ __u8 magic[8]; /* FS_VERITY_MAGIC */
+} __packed;
+
#endif
+const int kSha256Bytes = 32;
+
namespace android {
namespace {
@@ -73,7 +131,6 @@ class JavaByteArrayHolder {
};
int enableFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath) {
-#if __has_include(<linux/fsverity.h>)
const char* path = env->GetStringUTFChars(filePath, nullptr);
::android::base::unique_fd rfd(open(path, O_RDONLY | O_CLOEXEC));
if (rfd.get() < 0) {
@@ -83,14 +140,9 @@ int enableFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath) {
return errno;
}
return 0;
-#else
- LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
- return ENOSYS;
-#endif
}
int measureFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath) {
-#if __has_include(<linux/fsverity.h>)
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_digest) + kSha256Bytes);
fsverity_digest* data = reinterpret_cast<fsverity_digest*>(raii->getRaw());
data->digest_size = kSha256Bytes; // the only input/output parameter
@@ -104,14 +156,9 @@ int measureFsverity(JNIEnv* env, jobject /* clazz */, jstring filePath) {
return errno;
}
return 0;
-#else
- LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
- return ENOSYS;
-#endif
}
jbyteArray constructFsveritySignedData(JNIEnv* env, jobject /* clazz */, jbyteArray digest) {
-#if __has_include(<linux/fsverity.h>)
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_digest_disk) + kSha256Bytes);
fsverity_digest_disk* data = reinterpret_cast<fsverity_digest_disk*>(raii->getRaw());
@@ -126,15 +173,10 @@ jbyteArray constructFsveritySignedData(JNIEnv* env, jobject /* clazz */, jbyteAr
memcpy(data->digest, src, kSha256Bytes);
return raii->release();
-#else
- LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
- return 0;
-#endif
}
jbyteArray constructFsverityDescriptor(JNIEnv* env, jobject /* clazz */, jlong fileSize) {
-#if __has_include(<linux/fsverity.h>)
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_descriptor));
fsverity_descriptor* desc = reinterpret_cast<fsverity_descriptor*>(raii->getRaw());
@@ -150,15 +192,10 @@ jbyteArray constructFsverityDescriptor(JNIEnv* env, jobject /* clazz */, jlong f
desc->auth_ext_count = 1;
return raii->release();
-#else
- LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
- return 0;
-#endif
}
jbyteArray constructFsverityExtension(JNIEnv* env, jobject /* clazz */, jshort extensionId,
jint extensionDataSize) {
-#if __has_include(<linux/fsverity.h>)
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_extension));
fsverity_extension* ext = reinterpret_cast<fsverity_extension*>(raii->getRaw());
@@ -166,15 +203,10 @@ jbyteArray constructFsverityExtension(JNIEnv* env, jobject /* clazz */, jshort e
ext->type = extensionId;
return raii->release();
-#else
- LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
- return 0;
-#endif
}
jbyteArray constructFsverityFooter(JNIEnv* env, jobject /* clazz */,
jint offsetToDescriptorHead) {
-#if __has_include(<linux/fsverity.h>)
auto raii = JavaByteArrayHolder::newArray(env, sizeof(fsverity_footer));
fsverity_footer* footer = reinterpret_cast<fsverity_footer*>(raii->getRaw());
@@ -182,10 +214,6 @@ jbyteArray constructFsverityFooter(JNIEnv* env, jobject /* clazz */,
memcpy(footer->magic, FS_VERITY_MAGIC, sizeof(footer->magic));
return raii->release();
-#else
- LOG_ALWAYS_FATAL("fs-verity is used while not enabled");
- return 0;
-#endif
}
const JNINativeMethod sMethods[] = {
diff --git a/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java b/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java
index 1a231cf56921..2f8e5456a695 100644
--- a/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/AppCompactorTest.java
@@ -18,6 +18,7 @@ package com.android.server.am;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_1;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_ACTION_2;
+import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_STATSD_SAMPLE_RATE;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_1;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_2;
import static android.provider.DeviceConfig.ActivityManager.KEY_COMPACT_THROTTLE_3;
@@ -61,6 +62,9 @@ import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
public final class AppCompactorTest {
+ private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
+ "device_config delete activity_manager";
+
@Mock private AppOpsService mAppOpsService;
private AppCompactor mCompactorUnderTest;
private HandlerThread mHandlerThread;
@@ -70,19 +74,21 @@ public final class AppCompactorTest {
private static void clearDeviceConfig() throws IOException {
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
uiDevice.executeShellCommand(
- "device_config delete activity_manager " + KEY_USE_COMPACTION);
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_USE_COMPACTION);
+ uiDevice.executeShellCommand(
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_1);
uiDevice.executeShellCommand(
- "device_config delete activity_manager " + KEY_COMPACT_ACTION_1);
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_ACTION_2);
uiDevice.executeShellCommand(
- "device_config delete activity_manager " + KEY_COMPACT_ACTION_2);
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_1);
uiDevice.executeShellCommand(
- "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_1);
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_2);
uiDevice.executeShellCommand(
- "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_2);
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_3);
uiDevice.executeShellCommand(
- "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_3);
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_THROTTLE_4);
uiDevice.executeShellCommand(
- "device_config delete activity_manager " + KEY_COMPACT_THROTTLE_4);
+ CLEAR_DEVICE_CONFIG_KEY_CMD + " " + KEY_COMPACT_STATSD_SAMPLE_RATE);
}
@Before
@@ -128,6 +134,8 @@ public final class AppCompactorTest {
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3));
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4));
+ assertThat(mCompactorUnderTest.mStatsdSampleRate,
+ is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE));
}
@Test
@@ -155,6 +163,9 @@ public final class AppCompactorTest {
DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
KEY_COMPACT_THROTTLE_4,
Long.toString(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1), false);
+ DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
+ KEY_COMPACT_STATSD_SAMPLE_RATE,
+ Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false);
// Then calling init will read and set that flag.
mCompactorUnderTest.init();
@@ -173,6 +184,8 @@ public final class AppCompactorTest {
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_3 + 1));
assertThat(mCompactorUnderTest.mCompactThrottleFullFull,
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4 + 1));
+ assertThat(mCompactorUnderTest.mStatsdSampleRate,
+ is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f));
}
@Test
@@ -365,6 +378,63 @@ public final class AppCompactorTest {
is(AppCompactor.DEFAULT_COMPACT_THROTTLE_4));
}
+ @Test
+ public void statsdSampleRate_listensToDeviceConfigChanges() throws InterruptedException {
+ mCompactorUnderTest.init();
+
+ // When we override mStatsdSampleRate with a reasonable values ...
+ mCountDown = new CountDownLatch(1);
+ DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
+ KEY_COMPACT_STATSD_SAMPLE_RATE,
+ Float.toString(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f), false);
+ assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
+
+ // Then that override is reflected in the compactor.
+ assertThat(mCompactorUnderTest.mStatsdSampleRate,
+ is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE + 0.1f));
+ }
+
+ @Test
+ public void statsdSanokeRate_listensToDeviceConfigChangesBadValues()
+ throws InterruptedException {
+ mCompactorUnderTest.init();
+
+ // When we override mStatsdSampleRate with a reasonable values ...
+ mCountDown = new CountDownLatch(1);
+ DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
+ KEY_COMPACT_STATSD_SAMPLE_RATE, "foo", false);
+ assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
+
+ // Then that override is reflected in the compactor.
+ assertThat(mCompactorUnderTest.mStatsdSampleRate,
+ is(AppCompactor.DEFAULT_STATSD_SAMPLE_RATE));
+ }
+
+ @Test
+ public void statsdSanokeRate_listensToDeviceConfigChangesOutOfRangeValues()
+ throws InterruptedException {
+ mCompactorUnderTest.init();
+
+ // When we override mStatsdSampleRate with an value outside of [0..1]...
+ mCountDown = new CountDownLatch(1);
+ DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
+ KEY_COMPACT_STATSD_SAMPLE_RATE,
+ Float.toString(-1.0f), false);
+ assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
+
+ // Then the values is capped in the range.
+ assertThat(mCompactorUnderTest.mStatsdSampleRate, is(0.0f));
+
+ mCountDown = new CountDownLatch(1);
+ DeviceConfig.setProperty(DeviceConfig.ActivityManager.NAMESPACE,
+ KEY_COMPACT_STATSD_SAMPLE_RATE,
+ Float.toString(1.01f), false);
+ assertThat(mCountDown.await(5, TimeUnit.SECONDS), is(true));
+
+ // Then the values is capped in the range.
+ assertThat(mCompactorUnderTest.mStatsdSampleRate, is(1.0f));
+ }
+
private class TestInjector extends Injector {
@Override
public AppOpsService getAppOpsService(File file, Handler handler) {
diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
index 9a30b35f02a2..22fc15985b05 100644
--- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
+++ b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
@@ -50,8 +50,8 @@ public class IorapForwardingService extends SystemService {
public static final String TAG = "IorapForwardingService";
/** $> adb shell 'setprop log.tag.IorapdForwardingService VERBOSE' */
public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- /** $> adb shell 'setprop iorapd.enable true' */
- private static boolean IS_ENABLED = SystemProperties.getBoolean("iorapd.enable", true);
+ /** $> adb shell 'setprop ro.iorapd.enable true' */
+ private static boolean IS_ENABLED = SystemProperties.getBoolean("ro.iorapd.enable", true);
/** $> adb shell 'setprop iorapd.forwarding_service.wtf_crash true' */
private static boolean WTF_CRASH = SystemProperties.getBoolean(
"iorapd.forwarding_service.wtf_crash", false);
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index 4bca404d9444..6c45cc4ef3b8 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
@@ -112,13 +113,13 @@ public abstract class NetworkService extends Service {
mSlotId, 0, null).sendToTarget();
}
- private void registerForStateChanged(INetworkServiceCallback callback) {
+ private void registerForStateChanged(@NonNull INetworkServiceCallback callback) {
synchronized (mNetworkRegistrationStateChangedCallbacks) {
mNetworkRegistrationStateChangedCallbacks.add(callback);
}
}
- private void unregisterForStateChanged(INetworkServiceCallback callback) {
+ private void unregisterForStateChanged(@NonNull INetworkServiceCallback callback) {
synchronized (mNetworkRegistrationStateChangedCallbacks) {
mNetworkRegistrationStateChangedCallbacks.remove(callback);
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 869cf1cf9e14..dfe36efcd5d1 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2577,8 +2577,14 @@ public class SubscriptionManager {
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setPreferredDataSubscriptionId(int subId) {
if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
- setSubscriptionPropertyHelper(DEFAULT_SUBSCRIPTION_ID, "setPreferredDataSubscriptionId",
- (iSub)-> iSub.setPreferredDataSubscriptionId(subId));
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ iSub.setPreferredDataSubscriptionId(subId);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
}
/**
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index dfdec4db0c91..a1fb09017bcd 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -72,6 +72,7 @@ import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import com.android.ims.internal.IImsServiceFeatureCallback;
import com.android.internal.annotations.VisibleForTesting;
@@ -3264,6 +3265,35 @@ public class TelephonyManager {
}
}
+ /**
+ * Get the mapping from logical slots to physical slots. The mapping represent by a pair list.
+ * The key of the piar is the logical slot id and the value of the pair is the physical
+ * slots id mapped to this logical slot id.
+ *
+ * @return an pair list indicates the mapping from logical slots to physical slots. The size of
+ * the list should be {@link #getPhoneCount()} if success, otherwise return an empty list.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @NonNull
+ public List<Pair<Integer, Integer>> getLogicalToPhysicalSlotMapping() {
+ List<Pair<Integer, Integer>> slotMapping = new ArrayList<>();
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ int[] slotMappingArray = telephony.getSlotsMapping();
+ for (int i = 0; i < slotMappingArray.length; i++) {
+ slotMapping.add(new Pair(i, slotMappingArray[i]));
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "getSlotsMapping RemoteException", e);
+ }
+ return slotMapping;
+ }
+
//
//
// Subscriber Info
@@ -10239,4 +10269,24 @@ public class TelephonyManager {
Rlog.e(TAG, "switchMultiSimConfig RemoteException", ex);
}
}
+
+ /**
+ * Get whether reboot is required or not after making changes to modem configurations.
+ * @Return {@code True} if reboot is required after making changes to modem configurations,
+ * otherwise return {@code False}.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public boolean isRebootRequiredForModemConfigChange() {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.isRebootRequiredForModemConfigChange();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "isRebootRequiredForModemConfigChange RemoteException", e);
+ }
+ return false;
+ }
}
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index 74d1e838f186..79572b9706a9 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -157,7 +157,10 @@ public abstract class DataService extends Service {
@Nullable LinkProperties linkProperties,
@Nullable DataServiceCallback callback) {
// The default implementation is to return unsupported.
- callback.onSetupDataCallComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED, null);
+ if (callback != null) {
+ callback.onSetupDataCallComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED,
+ null);
+ }
}
/**
@@ -176,7 +179,9 @@ public abstract class DataService extends Service {
public void deactivateDataCall(int cid, @DeactivateDataReason int reason,
@Nullable DataServiceCallback callback) {
// The default implementation is to return unsupported.
- callback.onDeactivateDataCallComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED);
+ if (callback != null) {
+ callback.onDeactivateDataCallComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED);
+ }
}
/**
@@ -190,7 +195,10 @@ public abstract class DataService extends Service {
public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming,
@Nullable DataServiceCallback callback) {
// The default implementation is to return unsupported.
- callback.onSetInitialAttachApnComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED);
+ if (callback != null) {
+ callback.onSetInitialAttachApnComplete(
+ DataServiceCallback.RESULT_ERROR_UNSUPPORTED);
+ }
}
/**
@@ -206,7 +214,9 @@ public abstract class DataService extends Service {
public void setDataProfile(List<DataProfile> dps, boolean isRoaming,
@Nullable DataServiceCallback callback) {
// The default implementation is to return unsupported.
- callback.onSetDataProfileComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED);
+ if (callback != null) {
+ callback.onSetDataProfileComplete(DataServiceCallback.RESULT_ERROR_UNSUPPORTED);
+ }
}
/**
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index a49d2d976d16..6ce9de4ca677 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -220,7 +220,7 @@ interface ISub {
* @hide
*
*/
- int setPreferredDataSubscriptionId(int subId);
+ void setPreferredDataSubscriptionId(int subId);
/**
* Get which subscription is preferred for cellular data.
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 927c676aefe6..762d8860afcd 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1848,4 +1848,14 @@ interface ITelephony {
* @hide
*/
int getNumOfActiveSims();
+
+ /**
+ * Get if reboot is required upon altering modems configurations
+ */
+ boolean isRebootRequiredForModemConfigChange();
+
+ /**
+ * Get the mapping from logical slots to physical slots.
+ */
+ int[] getSlotsMapping();
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index 6567ea764b50..603c4c2870d7 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -194,6 +194,13 @@ public interface TelephonyProperties
*/
static final String PROPERTY_MULTI_SIM_CONFIG = "persist.radio.multisim.config";
+ /**
+ * Property to indicate if reboot is required when changing modems configurations
+ * Type: String(true, false) default is false; most devices don't need reboot
+ */
+ String PROPERTY_REBOOT_REQUIRED_ON_MODEM_CHANGE =
+ "persist.radio.reboot_on_modem_change";
+
/**
* Property to store default subscription.
*/