Merge "Use an external GlobalActionsPanelPlugin if available"
diff --git a/Android.bp b/Android.bp
index 9497085..ebd964ae 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1441,29 +1441,6 @@
" --show-annotation android.annotation.TestApi ",
}
-filegroup {
- name: "apache-http-stubs-sources",
- srcs: [
- "core/java/org/apache/http/conn/ConnectTimeoutException.java",
- "core/java/org/apache/http/conn/scheme/HostNameResolver.java",
- "core/java/org/apache/http/conn/scheme/LayeredSocketFactory.java",
- "core/java/org/apache/http/conn/scheme/SocketFactory.java",
- "core/java/org/apache/http/conn/ssl/AbstractVerifier.java",
- "core/java/org/apache/http/conn/ssl/AllowAllHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/AndroidDistinguishedNameParser.java",
- "core/java/org/apache/http/conn/ssl/BrowserCompatHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/SSLSocketFactory.java",
- "core/java/org/apache/http/conn/ssl/StrictHostnameVerifier.java",
- "core/java/org/apache/http/conn/ssl/X509HostnameVerifier.java",
- "core/java/org/apache/http/params/CoreConnectionPNames.java",
- "core/java/org/apache/http/params/HttpConnectionParams.java",
- "core/java/org/apache/http/params/HttpParams.java",
- "core/java/android/net/http/SslCertificate.java",
- "core/java/android/net/http/SslError.java",
- "core/java/com/android/internal/util/HexDump.java",
- ],
-}
-
droidstubs {
name: "api-stubs-docs",
defaults: ["metalava-api-stubs-default"],
@@ -1539,6 +1516,10 @@
api_file: "api/test-current.txt",
removed_api_file: "api/test-removed.txt",
},
+ api_lint: {
+ enabled: true,
+ baseline_file: "api/test-lint-baseline.txt",
+ },
},
}
diff --git a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
index 5b14056..cb1e6d9 100644
--- a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
@@ -32,7 +32,7 @@
public class DeviceIdleFrameworkInitializer {
private static IDeviceIdleController sIDeviceIdleController;
- static {
+ public static void initialize() {
SystemServiceRegistry.registerCachedService(
Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class,
(context, b) -> new DeviceIdleManager(
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
index c90b872..cc6ca3d 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java
@@ -28,7 +28,7 @@
* @hide
*/
public class JobSchedulerFrameworkInitializer {
- static {
+ public static void initialize() {
SystemServiceRegistry.registerStaticService(
Context.JOB_SCHEDULER_SERVICE, JobScheduler.class,
(b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b)));
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index a1734d8..eb22d09 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -899,7 +899,8 @@
}
final private IUidObserver mUidObserver = new IUidObserver.Stub() {
- @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) {
mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index cda5244..3aef5d1 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -466,7 +466,7 @@
private final IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override
- public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
mHandler.obtainMessage(MSG_UID_PROCESS_STATE_CHANGED, uid, procState).sendToTarget();
}
diff --git a/api/current.txt b/api/current.txt
index e31aed0..276fddc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2827,7 +2827,7 @@
method public android.view.accessibility.AccessibilityNodeInfo findFocus(int);
method @NonNull public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController();
method @NonNull public final android.accessibilityservice.AccessibilityButtonController getAccessibilityButtonController(int);
- method @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) @NonNull public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
+ method @NonNull @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public final android.accessibilityservice.FingerprintGestureController getFingerprintGestureController();
method @NonNull public final android.accessibilityservice.AccessibilityService.MagnificationController getMagnificationController();
method public android.view.accessibility.AccessibilityNodeInfo getRootInActiveWindow();
method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
@@ -3541,11 +3541,11 @@
package android.annotation {
- @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface SuppressLint {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) public @interface SuppressLint {
method public abstract String[] value();
}
- @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface TargetApi {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD}) public @interface TargetApi {
method public abstract int value();
}
@@ -3758,7 +3758,7 @@
method public void onContentChanged();
method public boolean onContextItemSelected(@NonNull android.view.MenuItem);
method public void onContextMenuClosed(@NonNull android.view.Menu);
- method @MainThread @CallSuper protected void onCreate(@Nullable android.os.Bundle);
+ method @CallSuper @MainThread protected void onCreate(@Nullable android.os.Bundle);
method public void onCreate(@Nullable android.os.Bundle, @Nullable android.os.PersistableBundle);
method public void onCreateContextMenu(android.view.ContextMenu, android.view.View, android.view.ContextMenu.ContextMenuInfo);
method @Nullable public CharSequence onCreateDescription();
@@ -3901,8 +3901,8 @@
method @Deprecated public void startActivityFromChild(@NonNull android.app.Activity, @RequiresPermission android.content.Intent, int, @Nullable android.os.Bundle);
method @Deprecated public void startActivityFromFragment(@NonNull android.app.Fragment, @RequiresPermission android.content.Intent, int);
method @Deprecated public void startActivityFromFragment(@NonNull android.app.Fragment, @RequiresPermission android.content.Intent, int, @Nullable android.os.Bundle);
- method public boolean startActivityIfNeeded(@RequiresPermission @NonNull android.content.Intent, int);
- method public boolean startActivityIfNeeded(@RequiresPermission @NonNull android.content.Intent, int, @Nullable android.os.Bundle);
+ method public boolean startActivityIfNeeded(@NonNull @RequiresPermission android.content.Intent, int);
+ method public boolean startActivityIfNeeded(@NonNull @RequiresPermission android.content.Intent, int, @Nullable android.os.Bundle);
method public void startIntentSenderForResult(android.content.IntentSender, int, @Nullable android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSenderForResult(android.content.IntentSender, int, @Nullable android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
method @Deprecated public void startIntentSenderFromChild(android.app.Activity, android.content.IntentSender, int, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
@@ -3910,8 +3910,8 @@
method public void startLocalVoiceInteraction(android.os.Bundle);
method public void startLockTask();
method @Deprecated public void startManagingCursor(android.database.Cursor);
- method public boolean startNextMatchingActivity(@RequiresPermission @NonNull android.content.Intent);
- method public boolean startNextMatchingActivity(@RequiresPermission @NonNull android.content.Intent, @Nullable android.os.Bundle);
+ method public boolean startNextMatchingActivity(@NonNull @RequiresPermission android.content.Intent);
+ method public boolean startNextMatchingActivity(@NonNull @RequiresPermission android.content.Intent, @Nullable android.os.Bundle);
method public void startPostponedEnterTransition();
method public void startSearch(@Nullable String, boolean, @Nullable android.os.Bundle, boolean);
method public void stopLocalVoiceInteraction();
@@ -6714,7 +6714,7 @@
method @NonNull public java.util.Set<java.lang.String> getAffiliationIds(@NonNull android.content.ComponentName);
method @Nullable public java.util.Set<java.lang.String> getAlwaysOnVpnLockdownWhitelist(@NonNull android.content.ComponentName);
method @Nullable public String getAlwaysOnVpnPackage(@NonNull android.content.ComponentName);
- method @WorkerThread @NonNull public android.os.Bundle getApplicationRestrictions(@Nullable android.content.ComponentName, String);
+ method @NonNull @WorkerThread public android.os.Bundle getApplicationRestrictions(@Nullable android.content.ComponentName, String);
method @Deprecated @Nullable public String getApplicationRestrictionsManagingPackage(@NonNull android.content.ComponentName);
method public boolean getAutoTimeRequired();
method @NonNull public java.util.List<android.os.UserHandle> getBindDeviceAdminTargetUsers(@NonNull android.content.ComponentName);
@@ -7640,7 +7640,7 @@
method public int checkSlicePermission(@NonNull android.net.Uri, int, int);
method @NonNull public java.util.List<android.net.Uri> getPinnedSlices();
method @NonNull public java.util.Set<android.app.slice.SliceSpec> getPinnedSpecs(android.net.Uri);
- method @WorkerThread @NonNull public java.util.Collection<android.net.Uri> getSliceDescendants(@NonNull android.net.Uri);
+ method @NonNull @WorkerThread public java.util.Collection<android.net.Uri> getSliceDescendants(@NonNull android.net.Uri);
method public void grantSlicePermission(@NonNull String, @NonNull android.net.Uri);
method @Nullable public android.net.Uri mapIntentToUri(@NonNull android.content.Intent);
method public void pinSlice(@NonNull android.net.Uri, @NonNull java.util.Set<android.app.slice.SliceSpec>);
@@ -7796,10 +7796,10 @@
public class StorageStatsManager {
method @WorkerThread public long getFreeBytes(@NonNull java.util.UUID) throws java.io.IOException;
method @WorkerThread public long getTotalBytes(@NonNull java.util.UUID) throws java.io.IOException;
- method @WorkerThread @NonNull public android.app.usage.ExternalStorageStats queryExternalStatsForUser(@NonNull java.util.UUID, @NonNull android.os.UserHandle) throws java.io.IOException;
- method @WorkerThread @NonNull public android.app.usage.StorageStats queryStatsForPackage(@NonNull java.util.UUID, @NonNull String, @NonNull android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
- method @WorkerThread @NonNull public android.app.usage.StorageStats queryStatsForUid(@NonNull java.util.UUID, int) throws java.io.IOException;
- method @WorkerThread @NonNull public android.app.usage.StorageStats queryStatsForUser(@NonNull java.util.UUID, @NonNull android.os.UserHandle) throws java.io.IOException;
+ method @NonNull @WorkerThread public android.app.usage.ExternalStorageStats queryExternalStatsForUser(@NonNull java.util.UUID, @NonNull android.os.UserHandle) throws java.io.IOException;
+ method @NonNull @WorkerThread public android.app.usage.StorageStats queryStatsForPackage(@NonNull java.util.UUID, @NonNull String, @NonNull android.os.UserHandle) throws java.io.IOException, android.content.pm.PackageManager.NameNotFoundException;
+ method @NonNull @WorkerThread public android.app.usage.StorageStats queryStatsForUid(@NonNull java.util.UUID, int) throws java.io.IOException;
+ method @NonNull @WorkerThread public android.app.usage.StorageStats queryStatsForUser(@NonNull java.util.UUID, @NonNull android.os.UserHandle) throws java.io.IOException;
}
public final class UsageEvents implements android.os.Parcelable {
@@ -8059,9 +8059,9 @@
method public boolean isMultipleAdvertisementSupported();
method public boolean isOffloadedFilteringSupported();
method public boolean isOffloadedScanBatchingSupported();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingInsecureL2capChannel() throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingInsecureRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingL2capChannel() throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothServerSocket listenUsingRfcommWithServiceRecord(String, java.util.UUID) throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setName(String);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean startDiscovery();
@@ -8429,9 +8429,9 @@
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean createBond();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createInsecureL2capChannel(int) throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH) @NonNull public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createL2capChannel(int) throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
method public int describeContents();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public boolean fetchUuidsWithSdp();
@@ -9616,14 +9616,14 @@
method public static void addPeriodicSync(android.accounts.Account, String, android.os.Bundle, long);
method public static Object addStatusChangeListener(int, android.content.SyncStatusObserver);
method @NonNull public android.content.ContentProviderResult[] applyBatch(@NonNull String, @NonNull java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException, android.os.RemoteException;
- method public final int bulkInsert(@RequiresPermission.Write @NonNull android.net.Uri, @NonNull android.content.ContentValues[]);
+ method public final int bulkInsert(@NonNull @RequiresPermission.Write android.net.Uri, @NonNull android.content.ContentValues[]);
method @Nullable public final android.os.Bundle call(@NonNull android.net.Uri, @NonNull String, @Nullable String, @Nullable android.os.Bundle);
method @Nullable public final android.os.Bundle call(@NonNull String, @NonNull String, @Nullable String, @Nullable android.os.Bundle);
method @Deprecated public void cancelSync(android.net.Uri);
method public static void cancelSync(android.accounts.Account, String);
method public static void cancelSync(android.content.SyncRequest);
method @Nullable public final android.net.Uri canonicalize(@NonNull android.net.Uri);
- method public final int delete(@RequiresPermission.Write @NonNull android.net.Uri, @Nullable String, @Nullable String[]);
+ method public final int delete(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable String, @Nullable String[]);
method @Deprecated public static android.content.SyncInfo getCurrentSync();
method public static java.util.List<android.content.SyncInfo> getCurrentSyncs();
method public static int getIsSyncable(android.accounts.Account, String);
@@ -9636,7 +9636,7 @@
method public static boolean getSyncAutomatically(android.accounts.Account, String);
method @Nullable public final String getType(@NonNull android.net.Uri);
method @NonNull public final android.content.ContentResolver.MimeTypeInfo getTypeInfo(@NonNull String);
- method @Nullable public final android.net.Uri insert(@RequiresPermission.Write @NonNull android.net.Uri, @Nullable android.content.ContentValues);
+ method @Nullable public final android.net.Uri insert(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues);
method public static boolean isSyncActive(android.accounts.Account, String);
method public static boolean isSyncPending(android.accounts.Account, String);
method @NonNull public android.graphics.Bitmap loadThumbnail(@NonNull android.net.Uri, @NonNull android.util.Size, @Nullable android.os.CancellationSignal) throws java.io.IOException;
@@ -9655,9 +9655,9 @@
method @Nullable public final android.content.res.AssetFileDescriptor openTypedAssetFile(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;
method @Nullable public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.Bundle) throws java.io.FileNotFoundException;
method @Nullable public final android.content.res.AssetFileDescriptor openTypedAssetFileDescriptor(@NonNull android.net.Uri, @NonNull String, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;
- method @Nullable public final android.database.Cursor query(@RequiresPermission.Read @NonNull android.net.Uri, @Nullable String[], @Nullable String, @Nullable String[], @Nullable String);
- method @Nullable public final android.database.Cursor query(@RequiresPermission.Read @NonNull android.net.Uri, @Nullable String[], @Nullable String, @Nullable String[], @Nullable String, @Nullable android.os.CancellationSignal);
- method @Nullable public final android.database.Cursor query(@RequiresPermission.Read @NonNull android.net.Uri, @Nullable String[], @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal);
+ method @Nullable public final android.database.Cursor query(@NonNull @RequiresPermission.Read android.net.Uri, @Nullable String[], @Nullable String, @Nullable String[], @Nullable String);
+ method @Nullable public final android.database.Cursor query(@NonNull @RequiresPermission.Read android.net.Uri, @Nullable String[], @Nullable String, @Nullable String[], @Nullable String, @Nullable android.os.CancellationSignal);
+ method @Nullable public final android.database.Cursor query(@NonNull @RequiresPermission.Read android.net.Uri, @Nullable String[], @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal);
method public final boolean refresh(@NonNull android.net.Uri, @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal);
method public final void registerContentObserver(@NonNull android.net.Uri, boolean, @NonNull android.database.ContentObserver);
method public void releasePersistableUriPermission(@NonNull android.net.Uri, int);
@@ -9672,7 +9672,7 @@
method public void takePersistableUriPermission(@NonNull android.net.Uri, int);
method @Nullable public final android.net.Uri uncanonicalize(@NonNull android.net.Uri);
method public final void unregisterContentObserver(@NonNull android.database.ContentObserver);
- method public final int update(@RequiresPermission.Write @NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]);
+ method public final int update(@NonNull @RequiresPermission.Write android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]);
method public static void validateSyncExtrasBundle(android.os.Bundle);
method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProvider);
method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProviderClient);
@@ -9770,9 +9770,9 @@
public abstract class Context {
ctor public Context();
- method public boolean bindIsolatedService(@RequiresPermission @NonNull android.content.Intent, int, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
+ method public boolean bindIsolatedService(@NonNull @RequiresPermission android.content.Intent, int, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
method public abstract boolean bindService(@RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, int);
- method public boolean bindService(@RequiresPermission @NonNull android.content.Intent, int, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
+ method public boolean bindService(@NonNull @RequiresPermission android.content.Intent, int, @NonNull java.util.concurrent.Executor, @NonNull android.content.ServiceConnection);
method @CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)") public abstract int checkCallingOrSelfPermission(@NonNull String);
method @CheckResult(suggest="#enforceCallingOrSelfUriPermission(Uri,int,String)") public abstract int checkCallingOrSelfUriPermission(android.net.Uri, int);
method @CheckResult(suggest="#enforceCallingPermission(String,String)") public abstract int checkCallingPermission(@NonNull String);
@@ -9871,7 +9871,7 @@
method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String);
method public abstract void sendOrderedBroadcast(@RequiresPermission android.content.Intent, @Nullable String);
- method public abstract void sendOrderedBroadcast(@RequiresPermission @NonNull android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
+ method public abstract void sendOrderedBroadcast(@NonNull @RequiresPermission android.content.Intent, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission("android.permission.INTERACT_ACROSS_USERS") public abstract void sendOrderedBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
method @Deprecated @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY) public abstract void sendStickyBroadcast(@RequiresPermission android.content.Intent);
method @Deprecated @RequiresPermission(allOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.BROADCAST_STICKY}) public abstract void sendStickyBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle);
@@ -11725,7 +11725,7 @@
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedDrawableForDensity(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle, @Nullable android.graphics.Rect, int);
method @NonNull public abstract android.graphics.drawable.Drawable getUserBadgedIcon(@NonNull android.graphics.drawable.Drawable, @NonNull android.os.UserHandle);
method @NonNull public abstract CharSequence getUserBadgedLabel(@NonNull CharSequence, @NonNull android.os.UserHandle);
- method @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions(@NonNull String, int);
+ method @NonNull @RequiresPermission(value="android.permission.WHITELIST_RESTRICTED_PERMISSIONS", conditional=true) public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions(@NonNull String, int);
method @Nullable public abstract android.content.res.XmlResourceParser getXml(@NonNull String, @XmlRes int, @Nullable android.content.pm.ApplicationInfo);
method public boolean hasSigningCertificate(@NonNull String, @NonNull byte[], int);
method public boolean hasSigningCertificate(int, @NonNull byte[], int);
@@ -12419,7 +12419,7 @@
method public int addLoader(@NonNull android.content.res.loader.ResourceLoader, @NonNull android.content.res.loader.ResourcesProvider);
method public final void finishPreloading();
method public final void flushLayoutCache();
- method @NonNull public android.content.res.XmlResourceParser getAnimation(@AnimatorRes @AnimRes int) throws android.content.res.Resources.NotFoundException;
+ method @NonNull public android.content.res.XmlResourceParser getAnimation(@AnimRes @AnimatorRes int) throws android.content.res.Resources.NotFoundException;
method public final android.content.res.AssetManager getAssets();
method @AnyRes public static int getAttributeSetSourceResId(@Nullable android.util.AttributeSet);
method public boolean getBoolean(@BoolRes int) throws android.content.res.Resources.NotFoundException;
@@ -13725,10 +13725,10 @@
method public static android.graphics.Bitmap createBitmap(int, int, @NonNull android.graphics.Bitmap.Config, boolean, @NonNull android.graphics.ColorSpace);
method public static android.graphics.Bitmap createBitmap(@Nullable android.util.DisplayMetrics, int, int, @NonNull android.graphics.Bitmap.Config, boolean);
method public static android.graphics.Bitmap createBitmap(@Nullable android.util.DisplayMetrics, int, int, @NonNull android.graphics.Bitmap.Config, boolean, @NonNull android.graphics.ColorSpace);
- method public static android.graphics.Bitmap createBitmap(@NonNull @ColorInt int[], int, int, int, int, @NonNull android.graphics.Bitmap.Config);
- method public static android.graphics.Bitmap createBitmap(@NonNull android.util.DisplayMetrics, @NonNull @ColorInt int[], int, int, int, int, @NonNull android.graphics.Bitmap.Config);
- method public static android.graphics.Bitmap createBitmap(@NonNull @ColorInt int[], int, int, android.graphics.Bitmap.Config);
- method public static android.graphics.Bitmap createBitmap(@Nullable android.util.DisplayMetrics, @NonNull @ColorInt int[], int, int, @NonNull android.graphics.Bitmap.Config);
+ method public static android.graphics.Bitmap createBitmap(@ColorInt @NonNull int[], int, int, int, int, @NonNull android.graphics.Bitmap.Config);
+ method public static android.graphics.Bitmap createBitmap(@NonNull android.util.DisplayMetrics, @ColorInt @NonNull int[], int, int, int, int, @NonNull android.graphics.Bitmap.Config);
+ method public static android.graphics.Bitmap createBitmap(@ColorInt @NonNull int[], int, int, android.graphics.Bitmap.Config);
+ method public static android.graphics.Bitmap createBitmap(@Nullable android.util.DisplayMetrics, @ColorInt @NonNull int[], int, int, @NonNull android.graphics.Bitmap.Config);
method @NonNull public static android.graphics.Bitmap createBitmap(@NonNull android.graphics.Picture);
method @NonNull public static android.graphics.Bitmap createBitmap(@NonNull android.graphics.Picture, int, int, @NonNull android.graphics.Bitmap.Config);
method public static android.graphics.Bitmap createScaledBitmap(@NonNull android.graphics.Bitmap, int, int, boolean);
@@ -13961,8 +13961,8 @@
method public void drawDoubleRoundRect(@NonNull android.graphics.RectF, float, float, @NonNull android.graphics.RectF, float, float, @NonNull android.graphics.Paint);
method public void drawDoubleRoundRect(@NonNull android.graphics.RectF, @NonNull float[], @NonNull android.graphics.RectF, @NonNull float[], @NonNull android.graphics.Paint);
method public void drawLine(float, float, float, float, @NonNull android.graphics.Paint);
- method public void drawLines(@Size(multiple=4) @NonNull float[], int, int, @NonNull android.graphics.Paint);
- method public void drawLines(@Size(multiple=4) @NonNull float[], @NonNull android.graphics.Paint);
+ method public void drawLines(@NonNull @Size(multiple=4) float[], int, int, @NonNull android.graphics.Paint);
+ method public void drawLines(@NonNull @Size(multiple=4) float[], @NonNull android.graphics.Paint);
method public void drawOval(@NonNull android.graphics.RectF, @NonNull android.graphics.Paint);
method public void drawOval(float, float, float, float, @NonNull android.graphics.Paint);
method public void drawPaint(@NonNull android.graphics.Paint);
@@ -13972,7 +13972,7 @@
method public void drawPicture(@NonNull android.graphics.Picture, @NonNull android.graphics.Rect);
method public void drawPoint(float, float, @NonNull android.graphics.Paint);
method public void drawPoints(@Size(multiple=2) float[], int, int, @NonNull android.graphics.Paint);
- method public void drawPoints(@Size(multiple=2) @NonNull float[], @NonNull android.graphics.Paint);
+ method public void drawPoints(@NonNull @Size(multiple=2) float[], @NonNull android.graphics.Paint);
method @Deprecated public void drawPosText(@NonNull char[], int, int, @NonNull @Size(multiple=2) float[], @NonNull android.graphics.Paint);
method @Deprecated public void drawPosText(@NonNull String, @NonNull @Size(multiple=2) float[], @NonNull android.graphics.Paint);
method public void drawRGB(int, int, int);
@@ -14333,10 +14333,10 @@
method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(@NonNull java.nio.ByteBuffer);
method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(@NonNull java.io.File);
method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(@NonNull java.util.concurrent.Callable<android.content.res.AssetFileDescriptor>);
- method @WorkerThread @NonNull public static android.graphics.Bitmap decodeBitmap(@NonNull android.graphics.ImageDecoder.Source, @NonNull android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
- method @WorkerThread @NonNull public static android.graphics.Bitmap decodeBitmap(@NonNull android.graphics.ImageDecoder.Source) throws java.io.IOException;
- method @WorkerThread @NonNull public static android.graphics.drawable.Drawable decodeDrawable(@NonNull android.graphics.ImageDecoder.Source, @NonNull android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
- method @WorkerThread @NonNull public static android.graphics.drawable.Drawable decodeDrawable(@NonNull android.graphics.ImageDecoder.Source) throws java.io.IOException;
+ method @NonNull @WorkerThread public static android.graphics.Bitmap decodeBitmap(@NonNull android.graphics.ImageDecoder.Source, @NonNull android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
+ method @NonNull @WorkerThread public static android.graphics.Bitmap decodeBitmap(@NonNull android.graphics.ImageDecoder.Source) throws java.io.IOException;
+ method @NonNull @WorkerThread public static android.graphics.drawable.Drawable decodeDrawable(@NonNull android.graphics.ImageDecoder.Source, @NonNull android.graphics.ImageDecoder.OnHeaderDecodedListener) throws java.io.IOException;
+ method @NonNull @WorkerThread public static android.graphics.drawable.Drawable decodeDrawable(@NonNull android.graphics.ImageDecoder.Source) throws java.io.IOException;
method public int getAllocator();
method @Nullable public android.graphics.Rect getCrop();
method public int getMemorySizePolicy();
@@ -14355,7 +14355,7 @@
method public void setPostProcessor(@Nullable android.graphics.PostProcessor);
method public void setTargetColorSpace(android.graphics.ColorSpace);
method public void setTargetSampleSize(@IntRange(from=1) int);
- method public void setTargetSize(@Px @IntRange(from=1) int, @Px @IntRange(from=1) int);
+ method public void setTargetSize(@IntRange(from=1) @Px int, @IntRange(from=1) @Px int);
method public void setUnpremultipliedRequired(boolean);
field public static final int ALLOCATOR_DEFAULT = 0; // 0x0
field public static final int ALLOCATOR_HARDWARE = 3; // 0x3
@@ -14462,8 +14462,8 @@
}
public class LinearGradient extends android.graphics.Shader {
- ctor public LinearGradient(float, float, float, float, @NonNull @ColorInt int[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
- ctor public LinearGradient(float, float, float, float, @NonNull @ColorLong long[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
+ ctor public LinearGradient(float, float, float, float, @ColorInt @NonNull int[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
+ ctor public LinearGradient(float, float, float, float, @ColorLong @NonNull long[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
ctor public LinearGradient(float, float, float, float, @ColorInt int, @ColorInt int, @NonNull android.graphics.Shader.TileMode);
ctor public LinearGradient(float, float, float, float, @ColorLong long, @ColorLong long, @NonNull android.graphics.Shader.TileMode);
}
@@ -15006,8 +15006,8 @@
}
public class RadialGradient extends android.graphics.Shader {
- ctor public RadialGradient(float, float, float, @NonNull @ColorInt int[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
- ctor public RadialGradient(float, float, float, @NonNull @ColorLong long[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
+ ctor public RadialGradient(float, float, float, @ColorInt @NonNull int[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
+ ctor public RadialGradient(float, float, float, @ColorLong @NonNull long[], @Nullable float[], @NonNull android.graphics.Shader.TileMode);
ctor public RadialGradient(float, float, float, @ColorInt int, @ColorInt int, @NonNull android.graphics.Shader.TileMode);
ctor public RadialGradient(float, float, float, @ColorLong long, @ColorLong long, @NonNull android.graphics.Shader.TileMode);
}
@@ -15265,8 +15265,8 @@
}
public class SweepGradient extends android.graphics.Shader {
- ctor public SweepGradient(float, float, @NonNull @ColorInt int[], @Nullable float[]);
- ctor public SweepGradient(float, float, @NonNull @ColorLong long[], @Nullable float[]);
+ ctor public SweepGradient(float, float, @ColorInt @NonNull int[], @Nullable float[]);
+ ctor public SweepGradient(float, float, @ColorLong @NonNull long[], @Nullable float[]);
ctor public SweepGradient(float, float, @ColorInt int, @ColorInt int);
ctor public SweepGradient(float, float, @ColorLong long, @ColorLong long);
}
@@ -15659,8 +15659,8 @@
method public void setColor(@ColorInt int);
method public void setColor(@Nullable android.content.res.ColorStateList);
method public void setColorFilter(@Nullable android.graphics.ColorFilter);
- method public void setColors(@Nullable @ColorInt int[]);
- method public void setColors(@Nullable @ColorInt int[], @Nullable float[]);
+ method public void setColors(@ColorInt @Nullable int[]);
+ method public void setColors(@ColorInt @Nullable int[], @Nullable float[]);
method public void setCornerRadii(@Nullable float[]);
method public void setCornerRadius(float);
method public void setDither(boolean);
@@ -16108,14 +16108,14 @@
public static class LineBreaker.ParagraphConstraints {
ctor public LineBreaker.ParagraphConstraints();
- method @Px @FloatRange(from=0) public float getDefaultTabStop();
- method @Px @FloatRange(from=0.0f) public float getFirstWidth();
- method @Px @IntRange(from=0) public int getFirstWidthLineCount();
+ method @FloatRange(from=0) @Px public float getDefaultTabStop();
+ method @FloatRange(from=0.0f) @Px public float getFirstWidth();
+ method @IntRange(from=0) @Px public int getFirstWidthLineCount();
method @Nullable public float[] getTabStops();
- method @Px @FloatRange(from=0.0f) public float getWidth();
- method public void setIndent(@Px @FloatRange(from=0.0f) float, @Px @IntRange(from=0) int);
- method public void setTabStops(@Nullable float[], @Px @FloatRange(from=0) float);
- method public void setWidth(@Px @FloatRange(from=0.0f) float);
+ method @FloatRange(from=0.0f) @Px public float getWidth();
+ method public void setIndent(@FloatRange(from=0.0f) @Px float, @IntRange(from=0) @Px int);
+ method public void setTabStops(@Nullable float[], @FloatRange(from=0) @Px float);
+ method public void setWidth(@FloatRange(from=0.0f) @Px float);
}
public static class LineBreaker.Result {
@@ -16138,7 +16138,7 @@
public static final class MeasuredText.Builder {
ctor public MeasuredText.Builder(@NonNull char[]);
ctor public MeasuredText.Builder(@NonNull android.graphics.text.MeasuredText);
- method @NonNull public android.graphics.text.MeasuredText.Builder appendReplacementRun(@NonNull android.graphics.Paint, @IntRange(from=0) int, @Px @FloatRange(from=0) float);
+ method @NonNull public android.graphics.text.MeasuredText.Builder appendReplacementRun(@NonNull android.graphics.Paint, @IntRange(from=0) int, @FloatRange(from=0) @Px float);
method @NonNull public android.graphics.text.MeasuredText.Builder appendStyleRun(@NonNull android.graphics.Paint, @IntRange(from=0) int, boolean);
method @NonNull public android.graphics.text.MeasuredText build();
method @NonNull public android.graphics.text.MeasuredText.Builder setComputeHyphenation(boolean);
@@ -23157,7 +23157,7 @@
method @Nullable public String getGnssHardwareModelName();
method public int getGnssYearOfHardware();
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(@Nullable android.location.GpsStatus);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) @Nullable public android.location.Location getLastKnownLocation(@NonNull String);
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.location.Location getLastKnownLocation(@NonNull String);
method @Nullable public android.location.LocationProvider getProvider(@NonNull String);
method @NonNull public java.util.List<java.lang.String> getProviders(boolean);
method @NonNull public java.util.List<java.lang.String> getProviders(@NonNull android.location.Criteria, boolean);
@@ -28628,17 +28628,17 @@
method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
method public boolean bindProcessToNetwork(@Nullable android.net.Network);
method @NonNull public android.net.SocketKeepalive createSocketKeepalive(@NonNull android.net.Network, @NonNull android.net.IpSecManager.UdpEncapsulationSocket, @NonNull java.net.InetAddress, @NonNull java.net.InetAddress, @NonNull java.util.concurrent.Executor, @NonNull android.net.SocketKeepalive.Callback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @Nullable public android.net.Network getActiveNetwork();
+ method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network getActiveNetwork();
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getActiveNetworkInfo();
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo[] getAllNetworkInfo();
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @NonNull public android.net.Network[] getAllNetworks();
+ method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.Network[] getAllNetworks();
method @Deprecated public boolean getBackgroundDataSetting();
method @Nullable public android.net.Network getBoundNetworkForProcess();
method public int getConnectionOwnerUid(int, @NonNull java.net.InetSocketAddress, @NonNull java.net.InetSocketAddress);
method @Nullable public android.net.ProxyInfo getDefaultProxy();
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @Nullable public android.net.LinkProperties getLinkProperties(@Nullable android.net.Network);
+ method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.LinkProperties getLinkProperties(@Nullable android.net.Network);
method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getMultipathPreference(@Nullable android.net.Network);
- method @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) @Nullable public android.net.NetworkCapabilities getNetworkCapabilities(@Nullable android.net.Network);
+ method @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkCapabilities getNetworkCapabilities(@Nullable android.net.Network);
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(int);
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public android.net.NetworkInfo getNetworkInfo(@Nullable android.net.Network);
method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE) public int getNetworkPreference();
@@ -30010,7 +30010,7 @@
method public android.net.wifi.WifiInfo getConnectionInfo();
method public android.net.DhcpInfo getDhcpInfo();
method public int getMaxNumberOfNetworkSuggestionsPerApp();
- method @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) @NonNull public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
+ method @NonNull @RequiresPermission(android.Manifest.permission.ACCESS_WIFI_STATE) public java.util.List<android.net.wifi.WifiNetworkSuggestion> getNetworkSuggestions();
method @Deprecated @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", "android.permission.NETWORK_SETUP_WIZARD"}) public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
method public java.util.List<android.net.wifi.ScanResult> getScanResults();
method public int getWifiState();
@@ -30961,10 +30961,10 @@
method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
method public boolean removeAidsForService(android.content.ComponentName, String);
- method @RequiresPermission(android.Manifest.permission.NFC) @NonNull public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean setOffHostForService(@NonNull android.content.ComponentName, @NonNull String);
method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
method public boolean supportsAidPrefixRegistration();
- method @RequiresPermission(android.Manifest.permission.NFC) @NonNull public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
+ method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
method public boolean unsetPreferredService(android.app.Activity);
field public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
field public static final String CATEGORY_OTHER = "other";
@@ -34620,7 +34620,7 @@
method public void addData(String, byte[], int);
method public void addFile(String, java.io.File, int) throws java.io.IOException;
method public void addText(String, String);
- method @RequiresPermission(allOf={android.Manifest.permission.READ_LOGS, android.Manifest.permission.PACKAGE_USAGE_STATS}) @Nullable public android.os.DropBoxManager.Entry getNextEntry(String, long);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_LOGS, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.DropBoxManager.Entry getNextEntry(String, long);
method public boolean isTagEnabled(String);
field public static final String ACTION_DROPBOX_ENTRY_ADDED = "android.intent.action.DROPBOX_ENTRY_ADDED";
field public static final String EXTRA_DROPPED_COUNT = "android.os.extra.DROPPED_COUNT";
@@ -35506,7 +35506,7 @@
method public String getUserName();
method public java.util.List<android.os.UserHandle> getUserProfiles();
method public android.os.Bundle getUserRestrictions();
- method public android.os.Bundle getUserRestrictions(android.os.UserHandle);
+ method @RequiresPermission(anyOf={"android.permission.MANAGE_USERS", "android.permission.INTERACT_ACROSS_USERS"}, conditional=true) public android.os.Bundle getUserRestrictions(android.os.UserHandle);
method public boolean hasUserRestriction(String);
method public boolean isDemoUser();
method public boolean isQuietModeEnabled(android.os.UserHandle);
@@ -38491,7 +38491,11 @@
method @NonNull public static String getVersion(@NonNull android.content.Context, @NonNull String);
method @NonNull public static String getVolumeName(@NonNull android.net.Uri);
method @NonNull public static android.net.Uri setIncludePending(@NonNull android.net.Uri);
+ method @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
method @NonNull public static android.net.Uri setRequireOriginal(@NonNull android.net.Uri);
+ method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);
+ method public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long);
+ method public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri);
field public static final String ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE";
field public static final String ACTION_IMAGE_CAPTURE_SECURE = "android.media.action.IMAGE_CAPTURE_SECURE";
field public static final String ACTION_REVIEW = "android.provider.action.REVIEW";
@@ -38584,14 +38588,11 @@
}
public static interface MediaStore.Audio.AudioColumns extends android.provider.MediaStore.MediaColumns {
- field public static final String ALBUM = "album";
field public static final String ALBUM_ID = "album_id";
field @Deprecated public static final String ALBUM_KEY = "album_key";
- field public static final String ARTIST = "artist";
field public static final String ARTIST_ID = "artist_id";
field @Deprecated public static final String ARTIST_KEY = "artist_key";
field public static final String BOOKMARK = "bookmark";
- field public static final String COMPOSER = "composer";
field public static final String GENRE = "genre";
field public static final String GENRE_ID = "genre_id";
field @Deprecated public static final String GENRE_KEY = "genre_key";
@@ -38706,7 +38707,6 @@
field public static final int MEDIA_TYPE_VIDEO = 3; // 0x3
field public static final String MIME_TYPE = "mime_type";
field public static final String PARENT = "parent";
- field public static final String TITLE = "title";
}
public static final class MediaStore.Images {
@@ -38715,6 +38715,9 @@
public static interface MediaStore.Images.ImageColumns extends android.provider.MediaStore.MediaColumns {
field public static final String DESCRIPTION = "description";
+ field public static final String EXPOSURE_TIME = "exposure_time";
+ field public static final String F_NUMBER = "f_number";
+ field public static final String ISO = "iso";
field public static final String IS_PRIVATE = "isprivate";
field @Deprecated public static final String LATITUDE = "latitude";
field @Deprecated public static final String LONGITUDE = "longitude";
@@ -38763,28 +38766,45 @@
}
public static interface MediaStore.MediaColumns extends android.provider.BaseColumns {
+ field public static final String ALBUM = "album";
+ field public static final String ALBUM_ARTIST = "album_artist";
+ field public static final String ARTIST = "artist";
+ field public static final String AUTHOR = "author";
+ field public static final String BITRATE = "bitrate";
field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
field public static final String BUCKET_ID = "bucket_id";
+ field public static final String CAPTURE_FRAMERATE = "capture_framerate";
+ field public static final String CD_TRACK_NUMBER = "cd_track_number";
+ field public static final String COMPILATION = "compilation";
+ field public static final String COMPOSER = "composer";
field @Deprecated public static final String DATA = "_data";
field public static final String DATE_ADDED = "date_added";
field public static final String DATE_EXPIRES = "date_expires";
field public static final String DATE_MODIFIED = "date_modified";
field public static final String DATE_TAKEN = "datetaken";
+ field public static final String DISC_NUMBER = "disc_number";
field public static final String DISPLAY_NAME = "_display_name";
field public static final String DOCUMENT_ID = "document_id";
field public static final String DURATION = "duration";
+ field public static final String GENRE = "genre";
field public static final String HEIGHT = "height";
field public static final String INSTANCE_ID = "instance_id";
+ field public static final String IS_FAVORITE = "is_favorite";
field public static final String IS_PENDING = "is_pending";
+ field public static final String IS_TRASHED = "is_trashed";
field public static final String MIME_TYPE = "mime_type";
+ field public static final String NUM_TRACKS = "num_tracks";
field public static final String ORIENTATION = "orientation";
field public static final String ORIGINAL_DOCUMENT_ID = "original_document_id";
field public static final String OWNER_PACKAGE_NAME = "owner_package_name";
field public static final String RELATIVE_PATH = "relative_path";
+ field public static final String RESOLUTION = "resolution";
field public static final String SIZE = "_size";
field public static final String TITLE = "title";
field public static final String VOLUME_NAME = "volume_name";
field public static final String WIDTH = "width";
+ field public static final String WRITER = "writer";
+ field public static final String YEAR = "year";
}
public static final class MediaStore.Video {
@@ -38824,8 +38844,6 @@
}
public static interface MediaStore.Video.VideoColumns extends android.provider.MediaStore.MediaColumns {
- field public static final String ALBUM = "album";
- field public static final String ARTIST = "artist";
field public static final String BOOKMARK = "bookmark";
field public static final String CATEGORY = "category";
field public static final String COLOR_RANGE = "color_range";
@@ -38837,7 +38855,6 @@
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 TAGS = "tags";
}
@@ -44020,7 +44037,7 @@
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.List<android.telecom.PhoneAccountHandle> getSelfManagedPhoneAccounts();
method public android.telecom.PhoneAccountHandle getSimCallManager();
method @Nullable public String getSystemDialerPackage();
- method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @Nullable public android.telecom.PhoneAccountHandle getUserSelectedOutgoingPhoneAccount();
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public android.telecom.PhoneAccountHandle getUserSelectedOutgoingPhoneAccount();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber(android.telecom.PhoneAccountHandle);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean handleMmi(String, android.telecom.PhoneAccountHandle);
@@ -44949,6 +44966,7 @@
method public static int getDefaultSmsSubscriptionId();
method public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) public void getSmsMessagesForFinancialApp(android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.SmsManager.FinancialSmsCallback);
+ method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSmscAddress();
method public int getSubscriptionId();
method public void injectSmsPdu(byte[], String, android.app.PendingIntent);
method public void sendDataMessage(String, String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
@@ -44956,6 +44974,7 @@
method public void sendMultipartTextMessage(String, String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
method public void sendTextMessage(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.SEND_SMS}) public void sendTextMessageWithoutPersisting(String, String, String, android.app.PendingIntent, android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSmscAddress(@NonNull String);
field public static final String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA";
field public static final String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS";
field public static final String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
@@ -45256,9 +45275,9 @@
method public int getDataState();
method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getDeviceId();
method @Deprecated @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getDeviceId(int);
- method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @Nullable public String getDeviceSoftwareVersion();
- method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @NonNull public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList();
- method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) @NonNull public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList(int);
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getDeviceSoftwareVersion();
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList();
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public java.util.Map<java.lang.Integer,java.util.List<android.telephony.emergency.EmergencyNumber>> getEmergencyNumberList(int);
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String[] getForbiddenPlmns();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getGroupIdLevel1();
method public String getIccAuthentication(int, int, String);
@@ -45292,11 +45311,12 @@
method @Nullable public CharSequence getSimSpecificCarrierIdName();
method public int getSimState();
method public int getSimState(int);
+ method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int getSubIdForPhoneAccountHandle(@NonNull android.telecom.PhoneAccountHandle);
method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSubscriberId();
method public int getSupportedModemCount();
method @Nullable public String getTypeAllocationCode();
method @Nullable public String getTypeAllocationCode(int);
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @NonNull public java.util.List<android.telephony.UiccCardInfo> getUiccCardsInfo();
+ method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public java.util.List<android.telephony.UiccCardInfo> getUiccCardsInfo();
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVisualVoicemailPackageName();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailAlphaTag();
method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public String getVoiceMailNumber();
@@ -47230,7 +47250,7 @@
}
public static class LineHeightSpan.Standard implements android.text.style.LineHeightSpan android.text.ParcelableSpan {
- ctor public LineHeightSpan.Standard(@Px @IntRange(from=1) int);
+ ctor public LineHeightSpan.Standard(@IntRange(from=1) @Px int);
ctor public LineHeightSpan.Standard(@NonNull android.os.Parcel);
method public void chooseHeight(@NonNull CharSequence, int, int, int, int, @NonNull android.graphics.Paint.FontMetricsInt);
method public int describeContents();
@@ -51376,11 +51396,11 @@
field @Deprecated public static final boolean TRACE_RECYCLER = false;
}
- @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface ViewDebug.CapturedViewProperty {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public static @interface ViewDebug.CapturedViewProperty {
method public abstract boolean retrieveReturn() default false;
}
- @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface ViewDebug.ExportedProperty {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) public static @interface ViewDebug.ExportedProperty {
method public abstract String category() default "";
method public abstract boolean deepExport() default false;
method public abstract android.view.ViewDebug.FlagToString[] flagMapping() default {};
@@ -51392,7 +51412,7 @@
method public abstract boolean resolveId() default false;
}
- @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface ViewDebug.FlagToString {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface ViewDebug.FlagToString {
method public abstract int equals();
method public abstract int mask();
method public abstract String name();
@@ -51410,7 +51430,7 @@
enum_constant @Deprecated public static final android.view.ViewDebug.HierarchyTraceType REQUEST_LAYOUT;
}
- @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface ViewDebug.IntToString {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface ViewDebug.IntToString {
method public abstract int from();
method public abstract String to();
}
@@ -53968,18 +53988,18 @@
}
public interface TextClassifier {
- method @WorkerThread @NonNull public default android.view.textclassifier.TextClassification classifyText(@NonNull android.view.textclassifier.TextClassification.Request);
- method @WorkerThread @NonNull public default android.view.textclassifier.TextClassification classifyText(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.os.LocaleList);
+ method @NonNull @WorkerThread public default android.view.textclassifier.TextClassification classifyText(@NonNull android.view.textclassifier.TextClassification.Request);
+ method @NonNull @WorkerThread public default android.view.textclassifier.TextClassification classifyText(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.os.LocaleList);
method public default void destroy();
- method @WorkerThread @NonNull public default android.view.textclassifier.TextLanguage detectLanguage(@NonNull android.view.textclassifier.TextLanguage.Request);
- method @WorkerThread @NonNull public default android.view.textclassifier.TextLinks generateLinks(@NonNull android.view.textclassifier.TextLinks.Request);
+ method @NonNull @WorkerThread public default android.view.textclassifier.TextLanguage detectLanguage(@NonNull android.view.textclassifier.TextLanguage.Request);
+ method @NonNull @WorkerThread public default android.view.textclassifier.TextLinks generateLinks(@NonNull android.view.textclassifier.TextLinks.Request);
method @WorkerThread public default int getMaxGenerateLinksTextLength();
method public default boolean isDestroyed();
method public default void onSelectionEvent(@NonNull android.view.textclassifier.SelectionEvent);
method public default void onTextClassifierEvent(@NonNull android.view.textclassifier.TextClassifierEvent);
- method @WorkerThread @NonNull public default android.view.textclassifier.ConversationActions suggestConversationActions(@NonNull android.view.textclassifier.ConversationActions.Request);
- method @WorkerThread @NonNull public default android.view.textclassifier.TextSelection suggestSelection(@NonNull android.view.textclassifier.TextSelection.Request);
- method @WorkerThread @NonNull public default android.view.textclassifier.TextSelection suggestSelection(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.os.LocaleList);
+ method @NonNull @WorkerThread public default android.view.textclassifier.ConversationActions suggestConversationActions(@NonNull android.view.textclassifier.ConversationActions.Request);
+ method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull android.view.textclassifier.TextSelection.Request);
+ method @NonNull @WorkerThread public default android.view.textclassifier.TextSelection suggestSelection(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @Nullable android.os.LocaleList);
field public static final String EXTRA_FROM_TEXT_CLASSIFIER = "android.view.textclassifier.extra.FROM_TEXT_CLASSIFIER";
field public static final String HINT_TEXT_IS_EDITABLE = "android.text_is_editable";
field public static final String HINT_TEXT_IS_NOT_EDITABLE = "android.text_is_not_editable";
@@ -56443,12 +56463,12 @@
ctor public Magnifier.Builder(@NonNull android.view.View);
method @NonNull public android.widget.Magnifier build();
method @NonNull public android.widget.Magnifier.Builder setClippingEnabled(boolean);
- method @NonNull public android.widget.Magnifier.Builder setCornerRadius(@Px @FloatRange(from=0) float);
+ method @NonNull public android.widget.Magnifier.Builder setCornerRadius(@FloatRange(from=0) @Px float);
method @NonNull public android.widget.Magnifier.Builder setDefaultSourceToMagnifierOffset(@Px int, @Px int);
- method @NonNull public android.widget.Magnifier.Builder setElevation(@Px @FloatRange(from=0) float);
+ method @NonNull public android.widget.Magnifier.Builder setElevation(@FloatRange(from=0) @Px float);
method @NonNull public android.widget.Magnifier.Builder setInitialZoom(@FloatRange(from=0.0f) float);
method @NonNull public android.widget.Magnifier.Builder setOverlay(@Nullable android.graphics.drawable.Drawable);
- method @NonNull public android.widget.Magnifier.Builder setSize(@Px @IntRange(from=0) int, @Px @IntRange(from=0) int);
+ method @NonNull public android.widget.Magnifier.Builder setSize(@IntRange(from=0) @Px int, @IntRange(from=0) @Px int);
method @NonNull public android.widget.Magnifier.Builder setSourceBounds(int, int, int, int);
}
@@ -56942,7 +56962,7 @@
method @NonNull public static android.widget.RemoteViews.RemoteResponse fromPendingIntent(@NonNull android.app.PendingIntent);
}
- @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public static @interface RemoteViews.RemoteView {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public static @interface RemoteViews.RemoteView {
}
public abstract class RemoteViewsService extends android.app.Service {
@@ -57619,7 +57639,7 @@
method public void setExtractedText(android.view.inputmethod.ExtractedText);
method public void setFallbackLineSpacing(boolean);
method public void setFilters(android.text.InputFilter[]);
- method public void setFirstBaselineToTopHeight(@Px @IntRange(from=0) int);
+ method public void setFirstBaselineToTopHeight(@IntRange(from=0) @Px int);
method public void setFontFeatureSettings(@Nullable String);
method public boolean setFontVariationSettings(@Nullable String);
method protected boolean setFrame(int, int, int, int);
@@ -57641,9 +57661,9 @@
method public void setInputType(int);
method public void setJustificationMode(int);
method public void setKeyListener(android.text.method.KeyListener);
- method public void setLastBaselineToBottomHeight(@Px @IntRange(from=0) int);
+ method public void setLastBaselineToBottomHeight(@IntRange(from=0) @Px int);
method public void setLetterSpacing(float);
- method public void setLineHeight(@Px @IntRange(from=0) int);
+ method public void setLineHeight(@IntRange(from=0) @Px int);
method public void setLineSpacing(float, float);
method public void setLines(int);
method public final void setLinkTextColor(@ColorInt int);
@@ -60698,7 +60718,7 @@
ctor public OutOfMemoryError(String);
}
- @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public @interface Override {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Override {
}
public class Package implements java.lang.reflect.AnnotatedElement {
@@ -61202,7 +61222,7 @@
ctor public StringIndexOutOfBoundsException(int);
}
- @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public @interface SuppressWarnings {
+ @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) public @interface SuppressWarnings {
method public abstract String[] value();
}
diff --git a/api/removed.txt b/api/removed.txt
index 74a9346..a395cc7 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -444,13 +444,12 @@
method @Deprecated @NonNull public static android.net.Uri createPending(@NonNull android.content.Context, @NonNull android.provider.MediaStore.PendingParams);
method @Deprecated @NonNull public static java.util.Set<java.lang.String> getAllVolumeNames(@NonNull android.content.Context);
method @Deprecated @NonNull public static android.provider.MediaStore.PendingSession openPending(@NonNull android.content.Context, @NonNull android.net.Uri);
- method @Deprecated @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
- method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);
- method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long);
- method @Deprecated public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri);
}
public static interface MediaStore.Audio.AudioColumns extends android.provider.MediaStore.MediaColumns {
+ field public static final String ALBUM = "album";
+ field public static final String ARTIST = "artist";
+ field public static final String COMPOSER = "composer";
field public static final String DURATION = "duration";
}
@@ -458,6 +457,10 @@
field @Deprecated public static final String DESCRIPTION = "description";
}
+ public static interface MediaStore.Files.FileColumns extends android.provider.MediaStore.MediaColumns {
+ field public static final String TITLE = "title";
+ }
+
public static interface MediaStore.Images.ImageColumns extends android.provider.MediaStore.MediaColumns {
field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
field public static final String BUCKET_ID = "bucket_id";
@@ -468,10 +471,6 @@
public static interface MediaStore.MediaColumns extends android.provider.BaseColumns {
field @Deprecated public static final String GROUP_ID = "group_id";
- field @Deprecated public static final String HASH = "_hash";
- field @Deprecated public static final String IS_TRASHED = "is_trashed";
- field @Deprecated public static final String PRIMARY_DIRECTORY = "primary_directory";
- field @Deprecated public static final String SECONDARY_DIRECTORY = "secondary_directory";
}
@Deprecated public static class MediaStore.PendingParams {
@@ -491,11 +490,14 @@
}
public static interface MediaStore.Video.VideoColumns extends android.provider.MediaStore.MediaColumns {
+ field public static final String ALBUM = "album";
+ field public static final String ARTIST = "artist";
field public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
field public static final String BUCKET_ID = "bucket_id";
field public static final String DATE_TAKEN = "datetaken";
field public static final String DURATION = "duration";
field public static final String GROUP_ID = "group_id";
+ field public static final String RESOLUTION = "resolution";
}
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
diff --git a/api/system-current.txt b/api/system-current.txt
index a35148a..3e2d01f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -391,7 +391,7 @@
field public static final int UID_STATE_CACHED = 700; // 0x2bc
field public static final int UID_STATE_FOREGROUND = 500; // 0x1f4
field public static final int UID_STATE_FOREGROUND_SERVICE = 400; // 0x190
- field public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; // 0x12c
+ field @Deprecated public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; // 0x12c
field public static final int UID_STATE_PERSISTENT = 100; // 0x64
field public static final int UID_STATE_TOP = 200; // 0xc8
}
@@ -602,7 +602,7 @@
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public byte[] getStatsMetadata() throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void removeConfig(long) throws android.app.StatsManager.StatsUnavailableException;
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean removeConfiguration(long);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @NonNull public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
+ method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public long[] setActiveConfigsChangedOperation(@Nullable android.app.PendingIntent) throws android.app.StatsManager.StatsUnavailableException;
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void setBroadcastSubscriber(android.app.PendingIntent, long, long) throws android.app.StatsManager.StatsUnavailableException;
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setBroadcastSubscriber(long, long, android.app.PendingIntent);
method @Deprecated @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public boolean setDataFetchOperation(long, android.app.PendingIntent);
@@ -1391,7 +1391,7 @@
method public abstract void sendBroadcast(android.content.Intent, @Nullable String, @Nullable android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public abstract void sendBroadcastAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle, @Nullable String, @Nullable android.os.Bundle);
method public abstract void sendOrderedBroadcast(@NonNull android.content.Intent, @Nullable String, @Nullable android.os.Bundle, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle);
- method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void startActivityAsUser(@RequiresPermission @NonNull android.content.Intent, @NonNull android.os.UserHandle);
+ method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void startActivityAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.os.UserHandle);
field public static final String APP_PREDICTION_SERVICE = "app_prediction";
field public static final String BACKUP_SERVICE = "backup";
field public static final String BATTERY_STATS_SERVICE = "batterystats";
@@ -1884,8 +1884,8 @@
public final class RollbackManager {
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender);
- method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
- method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks();
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, "android.permission.TEST_MANAGE_ROLLBACKS"}) public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks();
field public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS";
field public static final String EXTRA_STATUS_MESSAGE = "android.content.rollback.extra.STATUS_MESSAGE";
field public static final int STATUS_FAILURE = 1; // 0x1
@@ -2396,24 +2396,24 @@
}
public final class ContextHubManager {
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback, @NonNull java.util.concurrent.Executor);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.app.PendingIntent, long);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubTransaction<java.lang.Void> disableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubTransaction<java.lang.Void> enableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback, @NonNull java.util.concurrent.Executor);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.app.PendingIntent, long);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubTransaction<java.lang.Void> disableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubTransaction<java.lang.Void> enableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int[] findNanoAppOnHub(int, @NonNull android.hardware.location.NanoAppFilter);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int[] getContextHubHandles();
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubInfo getContextHubInfo(int);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public java.util.List<android.hardware.location.ContextHubInfo> getContextHubs();
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<android.hardware.location.ContextHubInfo> getContextHubs();
method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.NanoAppInstanceInfo getNanoAppInstanceInfo(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int loadNanoApp(int, @NonNull android.hardware.location.NanoApp);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubTransaction<java.lang.Void> loadNanoApp(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.NanoAppBinary);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubTransaction<java.util.List<android.hardware.location.NanoAppState>> queryNanoApps(@NonNull android.hardware.location.ContextHubInfo);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubTransaction<java.lang.Void> loadNanoApp(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.NanoAppBinary);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubTransaction<java.util.List<android.hardware.location.NanoAppState>> queryNanoApps(@NonNull android.hardware.location.ContextHubInfo);
method @Deprecated public int registerCallback(@NonNull android.hardware.location.ContextHubManager.Callback);
method @Deprecated public int registerCallback(android.hardware.location.ContextHubManager.Callback, android.os.Handler);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int sendMessage(int, int, @NonNull android.hardware.location.ContextHubMessage);
method @Deprecated @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int unloadNanoApp(int);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) @NonNull public android.hardware.location.ContextHubTransaction<java.lang.Void> unloadNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public android.hardware.location.ContextHubTransaction<java.lang.Void> unloadNanoApp(@NonNull android.hardware.location.ContextHubInfo, long);
method @Deprecated public int unregisterCallback(@NonNull android.hardware.location.ContextHubManager.Callback);
field public static final int EVENT_HUB_RESET = 6; // 0x6
field public static final int EVENT_NANOAPP_ABORTED = 4; // 0x4
@@ -3099,7 +3099,7 @@
}
public final class UsbPort {
- method @RequiresPermission(android.Manifest.permission.MANAGE_USB) @Nullable public android.hardware.usb.UsbPortStatus getStatus();
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USB) public android.hardware.usb.UsbPortStatus getStatus();
method @RequiresPermission(android.Manifest.permission.MANAGE_USB) public void setRoles(int, int);
}
@@ -3480,7 +3480,8 @@
method @NonNull public static android.location.LocationRequest createFromDeprecatedCriteria(@NonNull android.location.Criteria, long, float, boolean);
method @NonNull public static android.location.LocationRequest createFromDeprecatedProvider(@NonNull String, long, float, boolean);
method public int describeContents();
- method public long getExpireAt();
+ method @Deprecated public long getExpireAt();
+ method public long getExpireIn();
method public long getFastestInterval();
method public boolean getHideFromAppOps();
method public long getInterval();
@@ -3491,12 +3492,12 @@
method @Nullable public android.os.WorkSource getWorkSource();
method public boolean isLocationSettingsIgnored();
method public boolean isLowPowerMode();
- method @NonNull public android.location.LocationRequest setExpireAt(long);
+ method @Deprecated @NonNull public android.location.LocationRequest setExpireAt(long);
method @NonNull public android.location.LocationRequest setExpireIn(long);
method @NonNull public android.location.LocationRequest setFastestInterval(long);
method public void setHideFromAppOps(boolean);
method @NonNull public android.location.LocationRequest setInterval(long);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @NonNull public android.location.LocationRequest setLocationSettingsIgnored(boolean);
+ method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest setLocationSettingsIgnored(boolean);
method @NonNull public android.location.LocationRequest setLowPowerMode(boolean);
method @NonNull public android.location.LocationRequest setNumUpdates(int);
method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
@@ -3827,7 +3828,7 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public void deleteModel(java.util.UUID);
method public int getDetectionServiceOperationsTimeout();
method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.media.soundtrigger.SoundTriggerManager.Model getModel(java.util.UUID);
- method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) @Nullable public android.hardware.soundtrigger.SoundTrigger.ModuleProperties getModuleProperties();
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public android.hardware.soundtrigger.SoundTrigger.ModuleProperties getModuleProperties();
method @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER) public void updateModel(android.media.soundtrigger.SoundTriggerManager.Model);
}
@@ -4515,7 +4516,8 @@
method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
- method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
+ method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
+ method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
}
}
@@ -4879,7 +4881,7 @@
public class WifiScanner {
method @Deprecated public void configureWifiChange(int, int, int, int, int, android.net.wifi.WifiScanner.BssidInfo[]);
method @Deprecated public void configureWifiChange(android.net.wifi.WifiScanner.WifiChangeSettings);
- method @Nullable @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
+ method @NonNull @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public java.util.List<java.lang.Integer> getAvailableChannels(int);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean getScanResults();
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void startBackgroundScan(android.net.wifi.WifiScanner.ScanSettings, android.net.wifi.WifiScanner.ScanListener, android.os.WorkSource);
@@ -5238,7 +5240,7 @@
}
public class BatteryStatsManager {
- method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) @NonNull public android.os.connectivity.WifiBatteryStats getWifiBatteryStats();
+ method @NonNull @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public android.os.connectivity.WifiBatteryStats getWifiBatteryStats();
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void noteFullWifiLockAcquiredFromSource(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void noteFullWifiLockReleasedFromSource(@NonNull android.os.WorkSource);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void noteWifiBatchedScanStartedFromSource(@NonNull android.os.WorkSource, @IntRange(from=0) int);
@@ -5458,8 +5460,8 @@
method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void cancelAuthorization(android.os.IncidentManager.AuthListener);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void deleteIncidentReports(android.net.Uri);
method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void denyReport(android.net.Uri);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @Nullable public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @NonNull public java.util.List<android.net.Uri> getIncidentReportList(String);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
+ method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public java.util.List<android.net.Uri> getIncidentReportList(String);
method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public java.util.List<android.os.IncidentManager.PendingReport> getPendingReports();
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void reportIncident(android.os.IncidentReportArgs);
method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener);
@@ -5690,6 +5692,7 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(String, android.os.UserHandle);
method @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public int getUserSwitchability();
method public boolean hasRestrictedProfiles();
+ method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional=true) public boolean hasUserRestrictionForUser(@NonNull String, @NonNull android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isAdminUser();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isGuestUser();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isManagedProfile();
@@ -6009,7 +6012,7 @@
field public static final String NAMESPACE_AUTOFILL = "autofill";
field public static final String NAMESPACE_CONNECTIVITY = "connectivity";
field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture";
- field public static final String NAMESPACE_DEX_BOOT = "dex_boot";
+ field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot";
field public static final String NAMESPACE_DISPLAY_MANAGER = "display_manager";
field public static final String NAMESPACE_GAME_DRIVER = "game_driver";
field public static final String NAMESPACE_INPUT_NATIVE_BOOT = "input_native_boot";
@@ -6277,7 +6280,7 @@
field public static final String MESSAGE_BODY = "body";
field public static final String MESSAGE_BROADCASTED = "message_broadcasted";
field public static final String MESSAGE_FORMAT = "format";
- field @RequiresPermission(android.Manifest.permission.READ_CELL_BROADCASTS) @NonNull public static final android.net.Uri MESSAGE_HISTORY_URI;
+ field @NonNull @RequiresPermission(android.Manifest.permission.READ_CELL_BROADCASTS) public static final android.net.Uri MESSAGE_HISTORY_URI;
field public static final String MESSAGE_PRIORITY = "priority";
field public static final String MESSAGE_READ = "read";
field public static final String PLMN = "plmn";
@@ -6308,7 +6311,7 @@
package android.security.keystore {
public abstract class AttestationUtils {
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @NonNull public static java.security.cert.X509Certificate[] attestDeviceIds(android.content.Context, @NonNull int[], @NonNull byte[]) throws android.security.keystore.DeviceIdAttestationException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static java.security.cert.X509Certificate[] attestDeviceIds(android.content.Context, @NonNull int[], @NonNull byte[]) throws android.security.keystore.DeviceIdAttestationException;
field public static final int ID_TYPE_IMEI = 2; // 0x2
field public static final int ID_TYPE_MEID = 3; // 0x3
field public static final int ID_TYPE_SERIAL = 1; // 0x1
@@ -6389,18 +6392,18 @@
}
public class RecoveryController {
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public android.security.keystore.recovery.RecoverySession createRecoverySession();
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public android.security.keystore.recovery.RecoverySession createRecoverySession();
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.security.Key generateKey(@NonNull String) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public java.security.Key generateKey(@NonNull String, @Nullable byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public java.util.List<java.lang.String> getAliases() throws android.security.keystore.recovery.InternalRecoveryServiceException;
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public static android.security.keystore.recovery.RecoveryController getInstance(@NonNull android.content.Context);
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @Nullable public java.security.Key getKey(@NonNull String) throws android.security.keystore.recovery.InternalRecoveryServiceException, java.security.UnrecoverableKeyException;
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @Nullable public android.security.keystore.recovery.KeyChainSnapshot getKeyChainSnapshot() throws android.security.keystore.recovery.InternalRecoveryServiceException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.security.Key generateKey(@NonNull String, @Nullable byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.util.List<java.lang.String> getAliases() throws android.security.keystore.recovery.InternalRecoveryServiceException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public static android.security.keystore.recovery.RecoveryController getInstance(@NonNull android.content.Context);
+ method @Nullable @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.security.Key getKey(@NonNull String) throws android.security.keystore.recovery.InternalRecoveryServiceException, java.security.UnrecoverableKeyException;
+ method @Nullable @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public android.security.keystore.recovery.KeyChainSnapshot getKeyChainSnapshot() throws android.security.keystore.recovery.InternalRecoveryServiceException;
method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public int[] getRecoverySecretTypes() throws android.security.keystore.recovery.InternalRecoveryServiceException;
method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public int getRecoveryStatus(@NonNull String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public java.util.Map<java.lang.String,java.security.cert.X509Certificate> getRootCertificates();
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.util.Map<java.lang.String,java.security.cert.X509Certificate> getRootCertificates();
method @Deprecated @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.security.Key importKey(@NonNull String, @NonNull byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public java.security.Key importKey(@NonNull String, @NonNull byte[], @Nullable byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.security.Key importKey(@NonNull String, @NonNull byte[], @Nullable byte[]) throws android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.LockScreenRequiredException;
method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public void initRecoveryService(@NonNull String, @NonNull byte[], @NonNull byte[]) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public static boolean isRecoverableKeyStoreEnabled(@NonNull android.content.Context);
method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public void removeKey(@NonNull String) throws android.security.keystore.recovery.InternalRecoveryServiceException;
@@ -6415,8 +6418,8 @@
public class RecoverySession implements java.lang.AutoCloseable {
method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public void close();
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public java.util.Map<java.lang.String,java.security.Key> recoverKeyChainSnapshot(@NonNull byte[], @NonNull java.util.List<android.security.keystore.recovery.WrappedApplicationKey>) throws android.security.keystore.recovery.DecryptionFailedException, android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.SessionExpiredException;
- method @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) @NonNull public byte[] start(@NonNull String, @NonNull java.security.cert.CertPath, @NonNull byte[], @NonNull byte[], @NonNull java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public java.util.Map<java.lang.String,java.security.Key> recoverKeyChainSnapshot(@NonNull byte[], @NonNull java.util.List<android.security.keystore.recovery.WrappedApplicationKey>) throws android.security.keystore.recovery.DecryptionFailedException, android.security.keystore.recovery.InternalRecoveryServiceException, android.security.keystore.recovery.SessionExpiredException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE) public byte[] start(@NonNull String, @NonNull java.security.cert.CertPath, @NonNull byte[], @NonNull byte[], @NonNull java.util.List<android.security.keystore.recovery.KeyChainProtectionParams>) throws java.security.cert.CertificateException, android.security.keystore.recovery.InternalRecoveryServiceException;
}
public class SessionExpiredException extends java.security.GeneralSecurityException {
@@ -6559,7 +6562,29 @@
public abstract class ApnService extends android.app.Service {
ctor public ApnService();
method @NonNull public android.os.IBinder onBind(@Nullable android.content.Intent);
- method @WorkerThread @NonNull public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
+ method @NonNull @WorkerThread public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
+ }
+
+ public abstract class CarrierMessagingServiceWrapper {
+ ctor public CarrierMessagingServiceWrapper();
+ method public boolean bindToCarrierMessagingService(@NonNull android.content.Context, @NonNull String);
+ method public void disposeConnection(@NonNull android.content.Context);
+ method public void downloadMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+ method public void filterSms(@NonNull android.service.carrier.MessagePdu, @NonNull String, int, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+ method public abstract void onServiceReady();
+ method public void sendDataSms(@NonNull byte[], int, @NonNull String, int, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+ method public void sendMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+ method public void sendMultipartTextSms(@NonNull java.util.List<java.lang.String>, int, @NonNull String, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+ method public void sendTextSms(@NonNull String, int, @NonNull String, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+ }
+
+ public abstract static class CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper {
+ ctor public CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper();
+ method public void onDownloadMmsComplete(int);
+ method public void onFilterComplete(int);
+ method public void onSendMmsComplete(int, @Nullable byte[]);
+ method public void onSendMultipartSmsComplete(int, @Nullable int[]);
+ method public void onSendSmsComplete(int, int);
}
}
@@ -6671,13 +6696,13 @@
method public android.service.euicc.EuiccProfileInfo.Builder setUiccAccessRule(@Nullable java.util.List<android.telephony.UiccAccessRule>);
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(flag=true, prefix={"POLICY_RULE_"}, value={android.service.euicc.EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE, android.service.euicc.EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE, android.service.euicc.EuiccProfileInfo.POLICY_RULE_DELETE_AFTER_DISABLING}) public static @interface EuiccProfileInfo.PolicyRule {
+ @IntDef(flag=true, prefix={"POLICY_RULE_"}, value={android.service.euicc.EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE, android.service.euicc.EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE, android.service.euicc.EuiccProfileInfo.POLICY_RULE_DELETE_AFTER_DISABLING}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccProfileInfo.PolicyRule {
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix={"PROFILE_CLASS_"}, value={android.service.euicc.EuiccProfileInfo.PROFILE_CLASS_TESTING, android.service.euicc.EuiccProfileInfo.PROFILE_CLASS_PROVISIONING, android.service.euicc.EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL, 0xffffffff}) public static @interface EuiccProfileInfo.ProfileClass {
+ @IntDef(prefix={"PROFILE_CLASS_"}, value={android.service.euicc.EuiccProfileInfo.PROFILE_CLASS_TESTING, android.service.euicc.EuiccProfileInfo.PROFILE_CLASS_PROVISIONING, android.service.euicc.EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL, 0xffffffff}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccProfileInfo.ProfileClass {
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix={"PROFILE_STATE_"}, value={android.service.euicc.EuiccProfileInfo.PROFILE_STATE_DISABLED, android.service.euicc.EuiccProfileInfo.PROFILE_STATE_ENABLED, 0xffffffff}) public static @interface EuiccProfileInfo.ProfileState {
+ @IntDef(prefix={"PROFILE_STATE_"}, value={android.service.euicc.EuiccProfileInfo.PROFILE_STATE_DISABLED, android.service.euicc.EuiccProfileInfo.PROFILE_STATE_ENABLED, 0xffffffff}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccProfileInfo.ProfileState {
}
public abstract class EuiccService extends android.app.Service {
@@ -6856,7 +6881,7 @@
package android.service.oemlock {
public class OemLockManager {
- method @RequiresPermission(android.Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE) @Nullable public String getLockName();
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE) public String getLockName();
method @RequiresPermission(android.Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE) public boolean isOemUnlockAllowedByCarrier();
method @RequiresPermission(android.Manifest.permission.MANAGE_USER_OEM_UNLOCK_STATE) public boolean isOemUnlockAllowedByUser();
method @RequiresPermission(android.Manifest.permission.MANAGE_CARRIER_OEM_UNLOCK_STATE) public void setOemUnlockAllowedByCarrier(boolean, @Nullable byte[]);
@@ -6869,7 +6894,7 @@
public class PersistentDataBlockManager {
method @RequiresPermission("android.permission.ACCESS_PDB_STATE") public int getDataBlockSize();
- method @RequiresPermission(anyOf={android.Manifest.permission.READ_OEM_UNLOCK_STATE, "android.permission.OEM_UNLOCK_STATE"}) @android.service.persistentdata.PersistentDataBlockManager.FlashLockState public int getFlashLockState();
+ method @android.service.persistentdata.PersistentDataBlockManager.FlashLockState @RequiresPermission(anyOf={android.Manifest.permission.READ_OEM_UNLOCK_STATE, "android.permission.OEM_UNLOCK_STATE"}) public int getFlashLockState();
method public long getMaximumDataBlockSize();
method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_OEM_UNLOCK_STATE, "android.permission.OEM_UNLOCK_STATE"}) public boolean getOemUnlockEnabled();
method public byte[] read();
@@ -7461,6 +7486,7 @@
ctor public CellBroadcastService();
method @CallSuper public android.os.IBinder onBind(android.content.Intent);
method public abstract void onCdmaCellBroadcastSms(int, byte[], int);
+ method public abstract void onCdmaScpMessage(int, @NonNull java.util.List<android.telephony.cdma.CdmaSmsCbProgramData>, @NonNull String, @NonNull java.util.function.Consumer<android.os.Bundle>);
method public abstract void onGsmCellBroadcastSms(int, byte[]);
field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
}
@@ -7892,6 +7918,14 @@
field public static final int WIFI_LOST = 59; // 0x3b
}
+ public final class ImsiEncryptionInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @Nullable public String getKeyIdentifier();
+ method @Nullable public java.security.PublicKey getPublicKey();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ImsiEncryptionInfo> CREATOR;
+ }
+
public final class LteVopsSupportInfo implements android.os.Parcelable {
ctor public LteVopsSupportInfo(int, int);
method public int describeContents();
@@ -8376,6 +8410,7 @@
method @RequiresPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL) public void factoryReset(int);
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int);
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public android.telephony.CarrierRestrictionRules getCarrierRestrictionRules();
@@ -8429,6 +8464,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.MODIFY_PHONE_STATE}) public void requestCellInfoUpdate(@NonNull android.os.WorkSource, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void requestNumberVerification(@NonNull android.telephony.PhoneNumberRange, long, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.NumberVerificationCallback);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void resetCarrierKeysForImsiEncryption();
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean resetRadioConfig();
method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setCarrierDataEnabled(boolean);
@@ -8452,6 +8488,7 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void toggleRadioOnOff();
method public void updateServiceLocation();
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_ANOMALY_REPORTED = "android.telephony.action.ANOMALY_REPORTED";
+ field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final String ACTION_OTA_EMERGENCY_NUMBER_DB_INSTALLED = "android.telephony.action.OTA_EMERGENCY_NUMBER_DB_INSTALLED";
field public static final String ACTION_SIM_APPLICATION_STATE_CHANGED = "android.telephony.action.SIM_APPLICATION_STATE_CHANGED";
field public static final String ACTION_SIM_CARD_STATE_CHANGED = "android.telephony.action.SIM_CARD_STATE_CHANGED";
field public static final String ACTION_SIM_SLOT_STATUS_CHANGED = "android.telephony.action.SIM_SLOT_STATUS_CHANGED";
@@ -8464,6 +8501,8 @@
field public static final String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE";
field public static final String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL";
field public static final String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING";
+ field public static final int KEY_TYPE_EPDG = 1; // 0x1
+ field public static final int KEY_TYPE_WLAN = 2; // 0x2
field public static final long NETWORK_TYPE_BITMASK_1xRTT = 64L; // 0x40L
field public static final long NETWORK_TYPE_BITMASK_CDMA = 8L; // 0x8L
field public static final long NETWORK_TYPE_BITMASK_EDGE = 2L; // 0x2L
@@ -8755,10 +8794,10 @@
field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(prefix={"CANCEL_REASON_"}, value={android.telephony.euicc.EuiccCardManager.CANCEL_REASON_END_USER_REJECTED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_POSTPONED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_TIMEOUT, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_PPR_NOT_ALLOWED}) public static @interface EuiccCardManager.CancelReason {
+ @IntDef(prefix={"CANCEL_REASON_"}, value={android.telephony.euicc.EuiccCardManager.CANCEL_REASON_END_USER_REJECTED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_POSTPONED, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_TIMEOUT, android.telephony.euicc.EuiccCardManager.CANCEL_REASON_PPR_NOT_ALLOWED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.CancelReason {
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(flag=true, prefix={"RESET_OPTION_"}, value={android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS}) public static @interface EuiccCardManager.ResetOption {
+ @IntDef(flag=true, prefix={"RESET_OPTION_"}, value={android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, android.telephony.euicc.EuiccCardManager.RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccCardManager.ResetOption {
}
public static interface EuiccCardManager.ResultCallback<T> {
@@ -8814,7 +8853,7 @@
field public static final int EVENT_INSTALL = 1; // 0x1
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(flag=true, prefix={"EVENT_"}, value={android.telephony.euicc.EuiccNotification.EVENT_INSTALL, android.telephony.euicc.EuiccNotification.EVENT_ENABLE, android.telephony.euicc.EuiccNotification.EVENT_DISABLE, android.telephony.euicc.EuiccNotification.EVENT_DELETE}) public static @interface EuiccNotification.Event {
+ @IntDef(flag=true, prefix={"EVENT_"}, value={android.telephony.euicc.EuiccNotification.EVENT_INSTALL, android.telephony.euicc.EuiccNotification.EVENT_ENABLE, android.telephony.euicc.EuiccNotification.EVENT_DISABLE, android.telephony.euicc.EuiccNotification.EVENT_DELETE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccNotification.Event {
}
public final class EuiccRulesAuthTable implements android.os.Parcelable {
@@ -8832,7 +8871,7 @@
method public android.telephony.euicc.EuiccRulesAuthTable build();
}
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @IntDef(flag=true, prefix={"POLICY_RULE_FLAG_"}, value={android.telephony.euicc.EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED}) public static @interface EuiccRulesAuthTable.PolicyRuleFlag {
+ @IntDef(flag=true, prefix={"POLICY_RULE_FLAG_"}, value={android.telephony.euicc.EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface EuiccRulesAuthTable.PolicyRuleFlag {
}
}
@@ -9041,9 +9080,11 @@
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.ims.ImsExternalCallState> CREATOR;
}
- public class ImsMmTelManager {
+ public class ImsMmTelManager implements android.telephony.ims.RegistrationManager {
method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getFeatureState(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAdvancedCallingSettingEnabled();
@@ -9054,7 +9095,8 @@
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiRoamingSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVtSettingEnabled();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
@@ -9064,7 +9106,8 @@
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiRoamingSettingEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVoWiFiSettingEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setVtSettingEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterMmTelCapabilityCallback(@NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback);
field public static final int WIFI_MODE_CELLULAR_PREFERRED = 1; // 0x1
field public static final int WIFI_MODE_WIFI_ONLY = 0; // 0x0
@@ -9076,12 +9119,8 @@
method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
}
- public static class ImsMmTelManager.RegistrationCallback {
- ctor public ImsMmTelManager.RegistrationCallback();
- method public void onRegistered(int);
- method public void onRegistering(int);
- method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
- method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
+ @Deprecated public static class ImsMmTelManager.RegistrationCallback extends android.telephony.ims.RegistrationManager.RegistrationCallback {
+ ctor @Deprecated public ImsMmTelManager.RegistrationCallback();
}
public final class ImsReasonInfo implements android.os.Parcelable {
@@ -9491,12 +9530,12 @@
public class ProvisioningManager {
method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
- method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getProvisioningIntValue(int);
- method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public int getProvisioningIntValue(int);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public boolean getProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
- method @WorkerThread @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, boolean);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public void setProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
@@ -9513,6 +9552,24 @@
method public void onProvisioningStringChanged(int, @NonNull String);
}
+ public interface RegistrationManager {
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationState(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void getRegistrationTransportType(@NonNull java.util.function.Consumer<java.lang.Integer>, @NonNull java.util.concurrent.Executor);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback, @NonNull java.util.concurrent.Executor) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
+ field public static final int REGISTRATION_STATE_NOT_REGISTERED = 0; // 0x0
+ field public static final int REGISTRATION_STATE_REGISTERED = 2; // 0x2
+ field public static final int REGISTRATION_STATE_REGISTERING = 1; // 0x1
+ }
+
+ public static class RegistrationManager.RegistrationCallback {
+ ctor public RegistrationManager.RegistrationCallback();
+ method public void onRegistered(int);
+ method public void onRegistering(int);
+ method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
+ method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
+ }
+
}
package android.telephony.ims.feature {
diff --git a/api/test-current.txt b/api/test-current.txt
index 1c18ccd..495e57a 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -71,6 +71,9 @@
method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
method public static void resumeAppSwitches() throws android.os.RemoteException;
method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public void scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int);
+ field public static final int PROCESS_CAPABILITY_ALL = 1; // 0x1
+ field public static final int PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1; // 0x1
+ field public static final int PROCESS_CAPABILITY_NONE = 0; // 0x0
}
public static interface ActivityManager.OnUidImportanceListener {
@@ -233,7 +236,7 @@
field public static final int UID_STATE_CACHED = 700; // 0x2bc
field public static final int UID_STATE_FOREGROUND = 500; // 0x1f4
field public static final int UID_STATE_FOREGROUND_SERVICE = 400; // 0x190
- field public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; // 0x12c
+ field @Deprecated public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300; // 0x12c
field public static final int UID_STATE_PERSISTENT = 100; // 0x64
field public static final int UID_STATE_TOP = 200; // 0xc8
}
@@ -852,8 +855,8 @@
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void blockRollbackManager(long);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public void commitRollback(int, @NonNull java.util.List<android.content.pm.VersionedPackage>, @NonNull android.content.IntentSender);
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
- method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
- method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) @NonNull public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks();
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public java.util.List<android.content.rollback.RollbackInfo> getAvailableRollbacks();
+ method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_ROLLBACKS, android.Manifest.permission.TEST_MANAGE_ROLLBACKS}) public java.util.List<android.content.rollback.RollbackInfo> getRecentlyCommittedRollbacks();
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void reloadPersistedData();
field public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS";
field public static final String EXTRA_STATUS_MESSAGE = "android.content.rollback.extra.STATUS_MESSAGE";
@@ -1136,17 +1139,20 @@
public final class LocationRequest implements android.os.Parcelable {
method @NonNull public static android.location.LocationRequest create();
method public int describeContents();
- method public long getExpireAt();
+ method @Deprecated public long getExpireAt();
+ method public long getExpireIn();
method public long getFastestInterval();
method public long getInterval();
method public int getNumUpdates();
method public int getQuality();
method public boolean isLocationSettingsIgnored();
- method @NonNull public android.location.LocationRequest setExpireAt(long);
+ method public boolean isLowPowerMode();
+ method @Deprecated @NonNull public android.location.LocationRequest setExpireAt(long);
method @NonNull public android.location.LocationRequest setExpireIn(long);
method @NonNull public android.location.LocationRequest setFastestInterval(long);
method @NonNull public android.location.LocationRequest setInterval(long);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @NonNull public android.location.LocationRequest setLocationSettingsIgnored(boolean);
+ method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest setLocationSettingsIgnored(boolean);
+ method @NonNull public android.location.LocationRequest setLowPowerMode(boolean);
method @NonNull public android.location.LocationRequest setNumUpdates(int);
method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
method @NonNull public android.location.LocationRequest setQuality(int);
@@ -1722,7 +1728,8 @@
method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
- method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
+ method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
+ method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
}
}
@@ -1920,8 +1927,8 @@
method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void cancelAuthorization(android.os.IncidentManager.AuthListener);
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void deleteIncidentReports(android.net.Uri);
method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public void denyReport(android.net.Uri);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @Nullable public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
- method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) @NonNull public java.util.List<android.net.Uri> getIncidentReportList(String);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public android.os.IncidentManager.IncidentReport getIncidentReport(android.net.Uri);
+ method @NonNull @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public java.util.List<android.net.Uri> getIncidentReportList(String);
method @RequiresPermission(android.Manifest.permission.APPROVE_INCIDENT_REPORTS) public java.util.List<android.os.IncidentManager.PendingReport> getPendingReports();
method @RequiresPermission(allOf={android.Manifest.permission.DUMP, android.Manifest.permission.PACKAGE_USAGE_STATS}) public void reportIncident(android.os.IncidentReportArgs);
method @RequiresPermission("android.permission.REQUEST_INCIDENT_REPORT_APPROVAL") public void requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener);
@@ -2063,6 +2070,8 @@
method @NonNull public static String get(@NonNull String);
method @NonNull public static String get(@NonNull String, @Nullable String);
method public static boolean getBoolean(@NonNull String, boolean);
+ method public static int getInt(@NonNull String, int);
+ method public static long getLong(@NonNull String, long);
}
public final class UserHandle implements android.os.Parcelable {
@@ -2417,6 +2426,7 @@
}
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
+ field public static final String APP_OPS_CONSTANTS = "app_ops_constants";
field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
field public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
field public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
@@ -2476,7 +2486,7 @@
field public static final String MESSAGE_BODY = "body";
field public static final String MESSAGE_BROADCASTED = "message_broadcasted";
field public static final String MESSAGE_FORMAT = "format";
- field @RequiresPermission(android.Manifest.permission.READ_CELL_BROADCASTS) @NonNull public static final android.net.Uri MESSAGE_HISTORY_URI;
+ field @NonNull @RequiresPermission(android.Manifest.permission.READ_CELL_BROADCASTS) public static final android.net.Uri MESSAGE_HISTORY_URI;
field public static final String MESSAGE_PRIORITY = "priority";
field public static final String MESSAGE_READ = "read";
field public static final String PLMN = "plmn";
@@ -2508,7 +2518,7 @@
package android.security.keystore {
public abstract class AttestationUtils {
- method @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") @NonNull public static java.security.cert.X509Certificate[] attestDeviceIds(android.content.Context, @NonNull int[], @NonNull byte[]) throws android.security.keystore.DeviceIdAttestationException;
+ method @NonNull @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public static java.security.cert.X509Certificate[] attestDeviceIds(android.content.Context, @NonNull int[], @NonNull byte[]) throws android.security.keystore.DeviceIdAttestationException;
field public static final int ID_TYPE_IMEI = 2; // 0x2
field public static final int ID_TYPE_MEID = 3; // 0x3
field public static final int ID_TYPE_SERIAL = 1; // 0x1
diff --git a/api/test-lint-baseline.txt b/api/test-lint-baseline.txt
new file mode 100644
index 0000000..a43b45d
--- /dev/null
+++ b/api/test-lint-baseline.txt
@@ -0,0 +1,2203 @@
+// Baseline format: 1.0
+AcronymName: android.app.NotificationChannel#isImportanceLockedByOEM():
+
+AcronymName: android.app.NotificationChannel#setImportanceLockedByOEM(boolean):
+
+
+
+ActionValue: android.location.Location#EXTRA_NO_GPS_LOCATION:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_CLEANUP:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_DOWNLOAD_RESULT_INTERNAL:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#ACTION_FILE_DESCRIPTOR_REQUEST:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FD_COUNT:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FINAL_URI:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_FREE_URI_LIST:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_PAUSED_LIST:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_PAUSED_URI_LIST:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_SERVICE_ID:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_FILES_IN_USE:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_FILE_ROOT:
+
+ActionValue: android.telephony.mbms.vendor.VendorUtils#EXTRA_TEMP_LIST:
+
+
+
+ArrayReturn: android.app.UiAutomation#executeShellCommandRw(String):
+
+ArrayReturn: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #1:
+
+ArrayReturn: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #10:
+
+ArrayReturn: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #11:
+
+ArrayReturn: android.metrics.LogMaker#LogMaker(Object[]) parameter #0:
+
+ArrayReturn: android.metrics.LogMaker#deserialize(Object[]) parameter #0:
+
+ArrayReturn: android.metrics.LogMaker#serialize():
+
+ArrayReturn: android.net.TestNetworkManager#createTunInterface(android.net.LinkAddress[]) parameter #0:
+
+ArrayReturn: android.os.HwBlob#wrapArray(boolean[]):
+
+ArrayReturn: android.os.HwBlob#wrapArray(byte[]):
+
+ArrayReturn: android.os.HwBlob#wrapArray(double[]):
+
+ArrayReturn: android.os.HwBlob#wrapArray(float[]):
+
+ArrayReturn: android.os.HwBlob#wrapArray(int[]):
+
+ArrayReturn: android.os.HwBlob#wrapArray(long[]):
+
+ArrayReturn: android.os.HwBlob#wrapArray(short[]):
+
+ArrayReturn: android.os.NativeHandle#NativeHandle(java.io.FileDescriptor[], int[], boolean) parameter #0:
+
+ArrayReturn: android.os.NativeHandle#getFileDescriptors():
+
+ArrayReturn: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]):
+
+ArrayReturn: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
+
+ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
+
+ArrayReturn: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillOptions(CharSequence[]) parameter #0:
+
+ArrayReturn: android.view.inspector.InspectableProperty#enumMapping():
+
+ArrayReturn: android.view.inspector.InspectableProperty#flagMapping():
+
+
+
+AutoBoxing: android.os.HwBlob#wrapArray(byte[]):
+
+AutoBoxing: android.os.HwBlob#wrapArray(double[]):
+
+AutoBoxing: android.os.HwBlob#wrapArray(float[]):
+
+AutoBoxing: android.os.HwBlob#wrapArray(int[]):
+
+AutoBoxing: android.os.HwBlob#wrapArray(long[]):
+
+AutoBoxing: android.os.HwBlob#wrapArray(short[]):
+
+AutoBoxing: android.os.VintfObject#getTargetFrameworkCompatibilityMatrixVersion():
+
+
+
+BannedThrow: android.app.ActivityTaskManager#removeStacksInWindowingModes(int[]):
+
+BannedThrow: android.app.ActivityTaskManager#removeStacksWithActivityTypes(int[]):
+
+BannedThrow: android.app.ActivityTaskManager#setTaskWindowingMode(int, int, boolean):
+
+BannedThrow: android.app.ActivityTaskManager#setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean):
+
+BannedThrow: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, byte[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, int[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#getParameter(int, short[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#getParameter(int[], short[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, byte[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, int):
+
+BannedThrow: android.media.audiofx.AudioEffect#setParameter(int, short):
+
+BannedThrow: android.media.audiofx.AudioEffect#setParameter(int[], byte[]):
+
+BannedThrow: android.media.audiofx.AudioEffect#setParameter(int[], int[]):
+
+BannedThrow: android.media.audiopolicy.AudioMix.Builder#Builder(android.media.audiopolicy.AudioMixingRule):
+
+BannedThrow: android.media.audiopolicy.AudioMix.Builder#build():
+
+BannedThrow: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
+
+BannedThrow: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
+
+BannedThrow: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
+
+BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
+
+BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
+
+BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
+
+BannedThrow: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
+
+BannedThrow: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix):
+
+BannedThrow: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix):
+
+BannedThrow: android.media.audiopolicy.AudioPolicy#setFocusDuckingBehavior(int):
+
+BannedThrow: android.media.audiopolicy.AudioPolicy.Builder#addMix(android.media.audiopolicy.AudioMix):
+
+BannedThrow: android.media.audiopolicy.AudioPolicy.Builder#setLooper(android.os.Looper):
+
+BannedThrow: android.os.HwBinder#getService(String, String):
+
+BannedThrow: android.os.HwBinder#getService(String, String, boolean):
+
+BannedThrow: android.os.Process#getThreadScheduler(int):
+
+
+
+CallbackInterface: android.app.prediction.AppPredictor.Callback:
+
+CallbackInterface: android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback:
+
+CallbackInterface: android.widget.Magnifier.Callback:
+
+
+
+CallbackMethodName: android.os.RemoteCallback:
+
+
+
+ConcreteCollection: android.content.AutofillOptions#disabledActivities:
+
+ConcreteCollection: android.content.AutofillOptions#whitelistedActivitiesForAugmentedAutofill:
+
+ConcreteCollection: android.content.ContentCaptureOptions#ContentCaptureOptions(int, int, int, int, int, android.util.ArraySet<android.content.ComponentName>) parameter #5:
+
+ConcreteCollection: android.content.ContentCaptureOptions#whitelistedComponents:
+
+ConcreteCollection: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
+
+ConcreteCollection: android.os.HwParcel#readBoolVector():
+
+ConcreteCollection: android.os.HwParcel#readDoubleVector():
+
+ConcreteCollection: android.os.HwParcel#readFloatVector():
+
+ConcreteCollection: android.os.HwParcel#readInt16Vector():
+
+ConcreteCollection: android.os.HwParcel#readInt32Vector():
+
+ConcreteCollection: android.os.HwParcel#readInt64Vector():
+
+ConcreteCollection: android.os.HwParcel#readInt8Vector():
+
+ConcreteCollection: android.os.HwParcel#readNativeHandleVector():
+
+ConcreteCollection: android.os.HwParcel#readStringVector():
+
+ConcreteCollection: android.os.HwParcel#writeBoolVector(java.util.ArrayList<java.lang.Boolean>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeDoubleVector(java.util.ArrayList<java.lang.Double>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeFloatVector(java.util.ArrayList<java.lang.Float>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeInt16Vector(java.util.ArrayList<java.lang.Short>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeInt32Vector(java.util.ArrayList<java.lang.Integer>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeInt64Vector(java.util.ArrayList<java.lang.Long>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeInt8Vector(java.util.ArrayList<java.lang.Byte>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeNativeHandleVector(java.util.ArrayList<android.os.NativeHandle>) parameter #0:
+
+ConcreteCollection: android.os.HwParcel#writeStringVector(java.util.ArrayList<java.lang.String>) parameter #0:
+
+ConcreteCollection: android.service.autofill.CompositeUserData#getFieldClassificationAlgorithms():
+
+ConcreteCollection: android.service.autofill.CompositeUserData#getFieldClassificationArgs():
+
+ConcreteCollection: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>) parameter #2:
+
+ConcreteCollection: android.service.autofill.UserData#getFieldClassificationAlgorithms():
+
+
+
+ContextFirst: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
+
+
+
+ContextNameSuffix: android.telephony.mbms.vendor.MbmsGroupCallServiceBase:
+
+
+
+EndsWithImpl: android.view.contentcapture.ViewNode.ViewStructureImpl:
+
+
+
+Enum: android.view.inspector.InspectableProperty.ValueType:
+
+
+
+EqualsAndHashCode: android.app.prediction.AppPredictionContext#equals(Object):
+
+EqualsAndHashCode: android.app.prediction.AppTarget#equals(Object):
+
+EqualsAndHashCode: android.app.prediction.AppTargetEvent#equals(Object):
+
+EqualsAndHashCode: android.net.apf.ApfCapabilities#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.ApfProgramEvent#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.ApfStats#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.DhcpClientEvent#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.IpManagerEvent#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.IpReachabilityEvent#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.NetworkEvent#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.RaEvent#equals(Object):
+
+EqualsAndHashCode: android.net.metrics.ValidationProbeEvent#equals(Object):
+
+EqualsAndHashCode: android.os.IncidentManager.PendingReport#equals(Object):
+
+EqualsAndHashCode: android.os.StrictMode.ViolationInfo#hashCode():
+
+
+
+ExecutorRegistration: android.content.pm.PackageManager#addOnPermissionsChangeListener(android.content.pm.PackageManager.OnPermissionsChangedListener):
+
+ExecutorRegistration: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler):
+
+ExecutorRegistration: android.media.audiofx.AudioEffect#setParameterListener(android.media.audiofx.AudioEffect.OnParameterChangeListener):
+
+ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
+
+ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
+
+ExecutorRegistration: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyVolumeCallback(android.media.audiopolicy.AudioPolicy.AudioPolicyVolumeCallback):
+
+ExecutorRegistration: android.os.IncidentManager#cancelAuthorization(android.os.IncidentManager.AuthListener):
+
+ExecutorRegistration: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener):
+
+ExecutorRegistration: android.os.RemoteCallback#RemoteCallback(android.os.RemoteCallback.OnResultListener, android.os.Handler):
+
+ExecutorRegistration: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
+
+ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
+
+ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
+
+ExecutorRegistration: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback):
+
+ExecutorRegistration: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
+
+ExecutorRegistration: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#startGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>, android.telephony.mbms.GroupCallCallback):
+
+ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int):
+
+ExecutorRegistration: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback):
+
+
+
+ForbiddenSuperClass: android.app.AppDetailsActivity:
+
+
+
+GenericException: android.app.ActivityView#finalize():
+
+GenericException: android.app.prediction.AppPredictor#finalize():
+
+GenericException: android.service.autofill.CharSequenceTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
+
+GenericException: android.service.autofill.DateTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
+
+GenericException: android.service.autofill.ImageTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
+
+GenericException: android.service.autofill.augmented.FillWindow#finalize():
+
+
+
+GetterSetterNames: android.app.NotificationChannel#isBlockableSystem():
+
+GetterSetterNames: android.app.NotificationChannel#isImportanceLockedByCriticalDeviceFunction():
+
+GetterSetterNames: android.app.NotificationChannel#isImportanceLockedByOEM():
+
+GetterSetterNames: android.location.GnssClock#setBiasNanos(double):
+
+GetterSetterNames: android.location.GnssClock#setBiasUncertaintyNanos(double):
+
+GetterSetterNames: android.location.GnssClock#setDriftNanosPerSecond(double):
+
+GetterSetterNames: android.location.GnssClock#setDriftUncertaintyNanosPerSecond(double):
+
+GetterSetterNames: android.location.GnssClock#setElapsedRealtimeNanos(long):
+
+GetterSetterNames: android.location.GnssClock#setElapsedRealtimeUncertaintyNanos(double):
+
+GetterSetterNames: android.location.GnssClock#setFullBiasNanos(long):
+
+GetterSetterNames: android.location.GnssClock#setLeapSecond(int):
+
+GetterSetterNames: android.location.GnssClock#setTimeUncertaintyNanos(double):
+
+GetterSetterNames: android.location.GnssMeasurement#setCarrierFrequencyHz(float):
+
+GetterSetterNames: android.location.GnssMeasurement#setCodeType(String):
+
+GetterSetterNames: android.location.GnssMeasurement#setSnrInDb(double):
+
+GetterSetterNames: android.location.LocationRequest#isLocationSettingsIgnored():
+
+GetterSetterNames: android.location.LocationRequest#isLowPowerMode():
+
+GetterSetterNames: android.os.IncidentReportArgs#isAll():
+
+GetterSetterNames: android.service.notification.NotificationStats#setDirectReplied():
+
+GetterSetterNames: android.service.notification.NotificationStats#setExpanded():
+
+GetterSetterNames: android.service.notification.NotificationStats#setSeen():
+
+GetterSetterNames: android.service.notification.NotificationStats#setSnoozed():
+
+GetterSetterNames: android.service.notification.NotificationStats#setViewedSettings():
+
+GetterSetterNames: android.view.View#isAutofilled():
+
+GetterSetterNames: android.view.View#isDefaultFocusHighlightEnabled():
+
+
+
+IllegalStateException: android.media.audiopolicy.AudioMix.Builder#build():
+
+
+
+IntentBuilderName: android.app.backup.BackupManager#getConfigurationIntent(String):
+
+IntentBuilderName: android.app.backup.BackupManager#getDataManagementIntent(String):
+
+
+
+IntentName: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
+
+IntentName: android.provider.Telephony.Sms.Intents#SMS_CARRIER_PROVISION_ACTION:
+
+IntentName: android.service.notification.Adjustment#KEY_CONTEXTUAL_ACTIONS:
+
+
+
+InterfaceConstant: android.service.autofill.AutofillFieldClassificationService#SERVICE_INTERFACE:
+
+InterfaceConstant: android.service.autofill.augmented.AugmentedAutofillService#SERVICE_INTERFACE:
+
+InterfaceConstant: android.service.contentcapture.ContentCaptureService#SERVICE_INTERFACE:
+
+InterfaceConstant: android.service.notification.NotificationAssistantService#SERVICE_INTERFACE:
+
+InterfaceConstant: android.telecom.PhoneAccountSuggestionService#SERVICE_INTERFACE:
+
+
+
+KotlinOperator: android.os.WorkSource#get(int):
+
+
+
+ListenerInterface: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener:
+
+ListenerInterface: android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener:
+
+ListenerInterface: android.os.IncidentManager.AuthListener:
+
+
+
+ListenerLast: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #4:
+
+ListenerLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper) parameter #2:
+
+ListenerLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler) parameter #2:
+
+ListenerLast: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int) parameter #1:
+
+ListenerLast: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) parameter #1:
+
+
+
+ManagerConstructor: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context):
+
+
+
+MinMaxConstant: android.os.UserHandle#MIN_SECONDARY_USER_ID:
+
+MinMaxConstant: android.view.autofill.AutofillManager#MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS:
+
+
+
+MissingNullability: android.app.Activity#onMovedToDisplay(int, android.content.res.Configuration) parameter #1:
+
+MissingNullability: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int) parameter #0:
+
+MissingNullability: android.app.ActivityManager#alwaysShowUnsupportedCompileSdkWarning(android.content.ComponentName) parameter #0:
+
+MissingNullability: android.app.ActivityManager#forceStopPackage(String) parameter #0:
+
+MissingNullability: android.app.ActivityManager#getPackageImportance(String) parameter #0:
+
+MissingNullability: android.app.ActivityManager#removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener) parameter #0:
+
+MissingNullability: android.app.ActivityManager#scheduleApplicationInfoChanged(java.util.List<java.lang.String>, int) parameter #0:
+
+MissingNullability: android.app.ActivityManager.TaskDescription#getIconFilename():
+
+MissingNullability: android.app.ActivityTaskManager#clearLaunchParamsForPackages(java.util.List<java.lang.String>) parameter #0:
+
+MissingNullability: android.app.ActivityTaskManager#listAllStacks():
+
+MissingNullability: android.app.ActivityTaskManager#moveTopActivityToPinnedStack(int, android.graphics.Rect) parameter #1:
+
+MissingNullability: android.app.ActivityTaskManager#removeStacksInWindowingModes(int[]) parameter #0:
+
+MissingNullability: android.app.ActivityTaskManager#removeStacksWithActivityTypes(int[]) parameter #0:
+
+MissingNullability: android.app.ActivityTaskManager#resizeDockedStack(android.graphics.Rect, android.graphics.Rect) parameter #0:
+
+MissingNullability: android.app.ActivityTaskManager#resizeDockedStack(android.graphics.Rect, android.graphics.Rect) parameter #1:
+
+MissingNullability: android.app.ActivityTaskManager#resizePinnedStack(int, android.graphics.Rect, boolean) parameter #1:
+
+MissingNullability: android.app.ActivityTaskManager#resizeTask(int, android.graphics.Rect) parameter #1:
+
+MissingNullability: android.app.ActivityTaskManager#setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) parameter #4:
+
+MissingNullability: android.app.ActivityTaskManager#supportsMultiWindow(android.content.Context) parameter #0:
+
+MissingNullability: android.app.ActivityTaskManager#supportsSplitScreenMultiWindow(android.content.Context) parameter #0:
+
+MissingNullability: android.app.ActivityView#ActivityView(android.content.Context) parameter #0:
+
+MissingNullability: android.app.ActivityView#ActivityView(android.content.Context, android.util.AttributeSet) parameter #0:
+
+MissingNullability: android.app.ActivityView#ActivityView(android.content.Context, android.util.AttributeSet) parameter #1:
+
+MissingNullability: android.app.ActivityView#ActivityView(android.content.Context, android.util.AttributeSet, int) parameter #0:
+
+MissingNullability: android.app.ActivityView#ActivityView(android.content.Context, android.util.AttributeSet, int) parameter #1:
+
+MissingNullability: android.app.ActivityView#ActivityView(android.content.Context, android.util.AttributeSet, int, boolean) parameter #0:
+
+MissingNullability: android.app.ActivityView#ActivityView(android.content.Context, android.util.AttributeSet, int, boolean) parameter #1:
+
+MissingNullability: android.app.ActivityView#gatherTransparentRegion(android.graphics.Region) parameter #0:
+
+MissingNullability: android.app.ActivityView#onVisibilityChanged(android.view.View, int) parameter #0:
+
+MissingNullability: android.app.ActivityView#setCallback(android.app.ActivityView.StateCallback) parameter #0:
+
+MissingNullability: android.app.ActivityView#setForwardedInsets(android.graphics.Insets) parameter #0:
+
+MissingNullability: android.app.ActivityView#startActivity(android.content.Intent, android.os.UserHandle) parameter #1:
+
+MissingNullability: android.app.ActivityView.StateCallback#onActivityViewDestroyed(android.app.ActivityView) parameter #0:
+
+MissingNullability: android.app.ActivityView.StateCallback#onActivityViewReady(android.app.ActivityView) parameter #0:
+
+MissingNullability: android.app.ActivityView.StateCallback#onTaskCreated(int, android.content.ComponentName) parameter #1:
+
+MissingNullability: android.app.AppDetailsActivity#onCreate(android.os.Bundle) parameter #0:
+
+MissingNullability: android.app.AppOpsManager#getOpStrs():
+
+MissingNullability: android.app.AppOpsManager#isOperationActive(int, int, String) parameter #2:
+
+MissingNullability: android.app.AppOpsManager#opToPermission(int):
+
+MissingNullability: android.app.AppOpsManager#permissionToOpCode(String) parameter #0:
+
+MissingNullability: android.app.AppOpsManager#setMode(String, int, String, int) parameter #0:
+
+MissingNullability: android.app.AppOpsManager#setMode(String, int, String, int) parameter #2:
+
+MissingNullability: android.app.AppOpsManager#setMode(int, int, String, int) parameter #2:
+
+MissingNullability: android.app.AppOpsManager#setUidMode(String, int, int) parameter #0:
+
+MissingNullability: android.app.AppOpsManager.HistoricalOp#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.AppOpsManager.HistoricalOps#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.AppOpsManager.HistoricalUidOps#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.AppOpsManager.OpEntry#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.NotificationManager#allowAssistantAdjustment(String) parameter #0:
+
+MissingNullability: android.app.NotificationManager#disallowAssistantAdjustment(String) parameter #0:
+
+MissingNullability: android.app.NotificationManager#getEffectsSuppressor():
+
+MissingNullability: android.app.NotificationManager#matchesCallFilter(android.os.Bundle) parameter #0:
+
+MissingNullability: android.app.PictureInPictureParams#getActions():
+
+MissingNullability: android.app.PictureInPictureParams#getSourceRectHint():
+
+MissingNullability: android.app.TimePickerDialog#getTimePicker():
+
+MissingNullability: android.app.UiAutomation#executeShellCommandRw(String):
+
+MissingNullability: android.app.UiAutomation#executeShellCommandRw(String) parameter #0:
+
+MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #0:
+
+MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #1:
+
+MissingNullability: android.app.UiAutomation#grantRuntimePermission(String, String, android.os.UserHandle) parameter #2:
+
+MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #0:
+
+MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #1:
+
+MissingNullability: android.app.UiAutomation#revokeRuntimePermission(String, String, android.os.UserHandle) parameter #2:
+
+MissingNullability: android.app.WallpaperManager#setWallpaperComponent(android.content.ComponentName) parameter #0:
+
+MissingNullability: android.app.WindowConfiguration#compareTo(android.app.WindowConfiguration) parameter #0:
+
+MissingNullability: android.app.WindowConfiguration#getAppBounds():
+
+MissingNullability: android.app.WindowConfiguration#getBounds():
+
+MissingNullability: android.app.WindowConfiguration#setAppBounds(android.graphics.Rect) parameter #0:
+
+MissingNullability: android.app.WindowConfiguration#setBounds(android.graphics.Rect) parameter #0:
+
+MissingNullability: android.app.WindowConfiguration#setTo(android.app.WindowConfiguration) parameter #0:
+
+MissingNullability: android.app.WindowConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts(android.os.UserHandle):
+
+MissingNullability: android.app.admin.SecurityLog.SecurityEvent#SecurityEvent(long, byte[]) parameter #1:
+
+MissingNullability: android.app.backup.BackupManager#getConfigurationIntent(String):
+
+MissingNullability: android.app.backup.BackupManager#getConfigurationIntent(String) parameter #0:
+
+MissingNullability: android.app.backup.BackupManager#getDataManagementIntent(String):
+
+MissingNullability: android.app.backup.BackupManager#getDataManagementIntent(String) parameter #0:
+
+MissingNullability: android.app.backup.BackupManager#getDestinationString(String):
+
+MissingNullability: android.app.backup.BackupManager#getDestinationString(String) parameter #0:
+
+MissingNullability: android.app.prediction.AppPredictionSessionId#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.prediction.AppPredictor#getSessionId():
+
+MissingNullability: android.app.prediction.AppTarget#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.prediction.AppTargetEvent#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.app.prediction.AppTargetId#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.content.AutofillOptions#forWhitelistingItself():
+
+MissingNullability: android.content.AutofillOptions#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.content.ContentCaptureOptions#forWhitelistingItself():
+
+MissingNullability: android.content.ContentCaptureOptions#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.content.ContentResolver#getSyncAdapterPackagesForAuthorityAsUser(String, int):
+
+MissingNullability: android.content.ContentResolver#getSyncAdapterPackagesForAuthorityAsUser(String, int) parameter #0:
+
+MissingNullability: android.content.Context#getDisplay():
+
+MissingNullability: android.content.Context#getUser():
+
+MissingNullability: android.content.ContextWrapper#getDisplay():
+
+MissingNullability: android.content.ContextWrapper#setContentCaptureOptions(android.content.ContentCaptureOptions) parameter #0:
+
+MissingNullability: android.content.pm.ActivityInfo#isTranslucentOrFloating(android.content.res.TypedArray) parameter #0:
+
+MissingNullability: android.content.pm.LauncherApps#LauncherApps(android.content.Context) parameter #0:
+
+MissingNullability: android.content.pm.PackageInstaller.SessionParams#setGrantedRuntimePermissions(String[]) parameter #0:
+
+MissingNullability: android.content.pm.PackageManager#getNamesForUids(int[]) parameter #0:
+
+MissingNullability: android.content.pm.ShortcutManager#ShortcutManager(android.content.Context) parameter #0:
+
+MissingNullability: android.content.res.AssetManager#getOverlayablesToString(String) parameter #0:
+
+MissingNullability: android.content.res.Configuration#windowConfiguration:
+
+MissingNullability: android.content.rollback.PackageRollbackInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.content.rollback.RollbackInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]) parameter #0:
+
+MissingNullability: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]) parameter #1:
+
+MissingNullability: android.database.sqlite.SQLiteDebug#getDatabaseInfo():
+
+MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#DbStats(String, long, long, int, int, int, int) parameter #0:
+
+MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#cache:
+
+MissingNullability: android.database.sqlite.SQLiteDebug.DbStats#dbName:
+
+MissingNullability: android.database.sqlite.SQLiteDebug.PagerStats#dbStats:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #0:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #1:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #2:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#SQLiteDirectCursorDriver(android.database.sqlite.SQLiteDatabase, String, String, android.os.CancellationSignal) parameter #3:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#cursorRequeried(android.database.Cursor) parameter #0:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]):
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]) parameter #0:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]) parameter #1:
+
+MissingNullability: android.database.sqlite.SQLiteDirectCursorDriver#setBindArguments(String[]) parameter #0:
+
+MissingNullability: android.database.sqlite.SQLiteGlobal#getDefaultJournalMode():
+
+MissingNullability: android.database.sqlite.SQLiteGlobal#getDefaultSyncMode():
+
+MissingNullability: android.database.sqlite.SQLiteGlobal#getWALSyncMode():
+
+MissingNullability: android.graphics.ImageDecoder#createSource(android.content.res.Resources, java.io.InputStream, int) parameter #0:
+
+MissingNullability: android.graphics.ImageDecoder#createSource(android.content.res.Resources, java.io.InputStream, int) parameter #1:
+
+MissingNullability: android.graphics.drawable.AdaptiveIconDrawable#getSafeZone():
+
+MissingNullability: android.graphics.drawable.ColorDrawable#getXfermode():
+
+MissingNullability: android.hardware.camera2.CameraDevice#createCustomCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.hardware.camera2.params.OutputConfiguration>, int, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) parameter #0:
+
+MissingNullability: android.hardware.camera2.CameraManager#getCameraIdListNoLazy():
+
+MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getBucketBoundaries():
+
+MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getLocalDate():
+
+MissingNullability: android.hardware.display.AmbientBrightnessDayStats#getStats():
+
+MissingNullability: android.hardware.display.AmbientBrightnessDayStats#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.hardware.display.AmbientDisplayConfiguration#AmbientDisplayConfiguration(android.content.Context) parameter #0:
+
+MissingNullability: android.hardware.display.BrightnessChangeEvent#luxTimestamps:
+
+MissingNullability: android.hardware.display.BrightnessChangeEvent#luxValues:
+
+MissingNullability: android.hardware.display.BrightnessChangeEvent#packageName:
+
+MissingNullability: android.hardware.display.BrightnessChangeEvent#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.hardware.display.BrightnessConfiguration#getCurve():
+
+MissingNullability: android.hardware.display.BrightnessConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.hardware.display.BrightnessConfiguration.Builder#Builder(float[], float[]) parameter #0:
+
+MissingNullability: android.hardware.display.BrightnessConfiguration.Builder#Builder(float[], float[]) parameter #1:
+
+MissingNullability: android.hardware.display.BrightnessCorrection#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.hardware.display.DisplayManager#getAmbientBrightnessStats():
+
+MissingNullability: android.hardware.display.DisplayManager#getBrightnessConfiguration():
+
+MissingNullability: android.hardware.display.DisplayManager#getBrightnessEvents():
+
+MissingNullability: android.hardware.display.DisplayManager#getStableDisplaySize():
+
+MissingNullability: android.hardware.display.DisplayManager#setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration) parameter #0:
+
+MissingNullability: android.location.GnssClock#set(android.location.GnssClock) parameter #0:
+
+MissingNullability: android.location.GnssMeasurement#set(android.location.GnssMeasurement) parameter #0:
+
+MissingNullability: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #0:
+
+MissingNullability: android.location.GnssMeasurementsEvent#GnssMeasurementsEvent(android.location.GnssClock, android.location.GnssMeasurement[]) parameter #1:
+
+MissingNullability: android.location.GnssNavigationMessage#set(android.location.GnssNavigationMessage) parameter #0:
+
+MissingNullability: android.location.GnssNavigationMessage#setData(byte[]) parameter #0:
+
+MissingNullability: android.location.LocationManager#getTestProviderCurrentRequests(String) parameter #0:
+
+MissingNullability: android.location.LocationRequest#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.media.AudioFocusInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #3:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #4:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String) parameter #6:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #10:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #11:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #3:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #4:
+
+MissingNullability: android.media.AudioRecordingConfiguration#AudioRecordingConfiguration(int, int, int, android.media.AudioFormat, android.media.AudioFormat, int, String, int, boolean, int, android.media.audiofx.AudioEffect.Descriptor[], android.media.audiofx.AudioEffect.Descriptor[]) parameter #6:
+
+MissingNullability: android.media.PlaybackParams#setAudioStretchMode(int):
+
+MissingNullability: android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL:
+
+MissingNullability: android.media.audiofx.AudioEffect#byteArrayToInt(byte[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#byteArrayToShort(byte[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#getParameter(byte[], byte[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, byte[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, int[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#getParameter(int, short[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#getParameter(int[], short[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#getParameter(int[], short[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#intToByteArray(int):
+
+MissingNullability: android.media.audiofx.AudioEffect#isEffectTypeAvailable(java.util.UUID) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameter(byte[], byte[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameter(int, byte[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], byte[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], byte[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], int[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameter(int[], int[]) parameter #1:
+
+MissingNullability: android.media.audiofx.AudioEffect#setParameterListener(android.media.audiofx.AudioEffect.OnParameterChangeListener) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect#shortToByteArray(short):
+
+MissingNullability: android.media.audiofx.AudioEffect.Descriptor#Descriptor(android.os.Parcel) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect.Descriptor#writeToParcel(android.os.Parcel) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #0:
+
+MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #2:
+
+MissingNullability: android.media.audiofx.AudioEffect.OnParameterChangeListener#onParameterChange(android.media.audiofx.AudioEffect, int, byte[], byte[]) parameter #3:
+
+MissingNullability: android.media.audiopolicy.AudioMix.Builder#Builder(android.media.audiopolicy.AudioMixingRule) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioMix.Builder#build():
+
+MissingNullability: android.media.audiopolicy.AudioMix.Builder#setDevice(android.media.AudioDeviceInfo):
+
+MissingNullability: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat):
+
+MissingNullability: android.media.audiopolicy.AudioMix.Builder#setFormat(android.media.AudioFormat) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioMix.Builder#setRouteFlags(int):
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object):
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addMixRule(int, Object) parameter #1:
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int):
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#addRule(android.media.AudioAttributes, int) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#build():
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object):
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeMixRule(int, Object) parameter #1:
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int):
+
+MissingNullability: android.media.audiopolicy.AudioMixingRule.Builder#excludeRule(android.media.AudioAttributes, int) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix):
+
+MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioRecordSink(android.media.audiopolicy.AudioMix) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix):
+
+MissingNullability: android.media.audiopolicy.AudioPolicy#createAudioTrackSource(android.media.audiopolicy.AudioMix) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy#setRegistration(String) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy#toLogFriendlyString():
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusAbandon(android.media.AudioFocusInfo) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusGrant(android.media.AudioFocusInfo, int) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusLoss(android.media.AudioFocusInfo, boolean) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener#onAudioFocusRequest(android.media.AudioFocusInfo, int) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener#onMixStateUpdate(android.media.audiopolicy.AudioMix) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#Builder(android.content.Context) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener) parameter #0:
+
+MissingNullability: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener) parameter #0:
+
+MissingNullability: android.metrics.LogMaker#LogMaker(Object[]) parameter #0:
+
+MissingNullability: android.metrics.LogMaker#addTaggedData(int, Object):
+
+MissingNullability: android.metrics.LogMaker#addTaggedData(int, Object) parameter #1:
+
+MissingNullability: android.metrics.LogMaker#clearCategory():
+
+MissingNullability: android.metrics.LogMaker#clearPackageName():
+
+MissingNullability: android.metrics.LogMaker#clearSubtype():
+
+MissingNullability: android.metrics.LogMaker#clearTaggedData(int):
+
+MissingNullability: android.metrics.LogMaker#clearType():
+
+MissingNullability: android.metrics.LogMaker#deserialize(Object[]) parameter #0:
+
+MissingNullability: android.metrics.LogMaker#getCounterName():
+
+MissingNullability: android.metrics.LogMaker#getPackageName():
+
+MissingNullability: android.metrics.LogMaker#getTaggedData(int):
+
+MissingNullability: android.metrics.LogMaker#isSubsetOf(android.metrics.LogMaker) parameter #0:
+
+MissingNullability: android.metrics.LogMaker#isValidValue(Object) parameter #0:
+
+MissingNullability: android.metrics.LogMaker#serialize():
+
+MissingNullability: android.metrics.LogMaker#setCategory(int):
+
+MissingNullability: android.metrics.LogMaker#setPackageName(String):
+
+MissingNullability: android.metrics.LogMaker#setPackageName(String) parameter #0:
+
+MissingNullability: android.metrics.LogMaker#setSubtype(int):
+
+MissingNullability: android.metrics.LogMaker#setType(int):
+
+MissingNullability: android.metrics.MetricsReader#next():
+
+MissingNullability: android.net.NetworkCapabilities#getCapabilities():
+
+MissingNullability: android.net.StaticIpConfiguration#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.net.TestNetworkInterface#CREATOR:
+
+MissingNullability: android.net.TestNetworkInterface#TestNetworkInterface(android.os.ParcelFileDescriptor, String) parameter #0:
+
+MissingNullability: android.net.TestNetworkInterface#TestNetworkInterface(android.os.ParcelFileDescriptor, String) parameter #1:
+
+MissingNullability: android.net.TestNetworkInterface#getFileDescriptor():
+
+MissingNullability: android.net.TestNetworkInterface#getInterfaceName():
+
+MissingNullability: android.net.TestNetworkInterface#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.net.TestNetworkManager#createTapInterface():
+
+MissingNullability: android.net.TestNetworkManager#createTunInterface(android.net.LinkAddress[]):
+
+MissingNullability: android.net.apf.ApfCapabilities#CREATOR:
+
+MissingNullability: android.net.apf.ApfCapabilities#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.net.metrics.DhcpClientEvent.Builder#setMsg(String) parameter #0:
+
+MissingNullability: android.os.Build#is64BitAbi(String) parameter #0:
+
+MissingNullability: android.os.Build.VERSION#ACTIVE_CODENAMES:
+
+MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...):
+
+MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...) parameter #0:
+
+MissingNullability: android.os.Environment#buildPath(java.io.File, java.lang.String...) parameter #1:
+
+MissingNullability: android.os.FileUtils#contains(java.io.File, java.io.File) parameter #0:
+
+MissingNullability: android.os.FileUtils#contains(java.io.File, java.io.File) parameter #1:
+
+MissingNullability: android.os.HwBinder#getService(String, String):
+
+MissingNullability: android.os.HwBinder#getService(String, String) parameter #0:
+
+MissingNullability: android.os.HwBinder#getService(String, String) parameter #1:
+
+MissingNullability: android.os.HwBinder#getService(String, String, boolean):
+
+MissingNullability: android.os.HwBinder#getService(String, String, boolean) parameter #0:
+
+MissingNullability: android.os.HwBinder#getService(String, String, boolean) parameter #1:
+
+MissingNullability: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
+
+MissingNullability: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
+
+MissingNullability: android.os.HwBinder#registerService(String) parameter #0:
+
+MissingNullability: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
+
+MissingNullability: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
+
+MissingNullability: android.os.HwBlob#copyToBoolArray(long, boolean[], int) parameter #1:
+
+MissingNullability: android.os.HwBlob#copyToDoubleArray(long, double[], int) parameter #1:
+
+MissingNullability: android.os.HwBlob#copyToFloatArray(long, float[], int) parameter #1:
+
+MissingNullability: android.os.HwBlob#copyToInt16Array(long, short[], int) parameter #1:
+
+MissingNullability: android.os.HwBlob#copyToInt32Array(long, int[], int) parameter #1:
+
+MissingNullability: android.os.HwBlob#copyToInt64Array(long, long[], int) parameter #1:
+
+MissingNullability: android.os.HwBlob#copyToInt8Array(long, byte[], int) parameter #1:
+
+MissingNullability: android.os.HwBlob#getString(long):
+
+MissingNullability: android.os.HwBlob#putBlob(long, android.os.HwBlob) parameter #1:
+
+MissingNullability: android.os.HwBlob#putBoolArray(long, boolean[]) parameter #1:
+
+MissingNullability: android.os.HwBlob#putDoubleArray(long, double[]) parameter #1:
+
+MissingNullability: android.os.HwBlob#putFloatArray(long, float[]) parameter #1:
+
+MissingNullability: android.os.HwBlob#putInt16Array(long, short[]) parameter #1:
+
+MissingNullability: android.os.HwBlob#putInt32Array(long, int[]) parameter #1:
+
+MissingNullability: android.os.HwBlob#putInt64Array(long, long[]) parameter #1:
+
+MissingNullability: android.os.HwBlob#putInt8Array(long, byte[]) parameter #1:
+
+MissingNullability: android.os.HwBlob#putString(long, String) parameter #1:
+
+MissingNullability: android.os.HwBlob#wrapArray(boolean[]):
+
+MissingNullability: android.os.HwBlob#wrapArray(byte[]):
+
+MissingNullability: android.os.HwBlob#wrapArray(double[]):
+
+MissingNullability: android.os.HwBlob#wrapArray(float[]):
+
+MissingNullability: android.os.HwBlob#wrapArray(int[]):
+
+MissingNullability: android.os.HwBlob#wrapArray(long[]):
+
+MissingNullability: android.os.HwBlob#wrapArray(short[]):
+
+MissingNullability: android.os.HwParcel#enforceInterface(String) parameter #0:
+
+MissingNullability: android.os.HwParcel#readBoolVector():
+
+MissingNullability: android.os.HwParcel#readBuffer(long):
+
+MissingNullability: android.os.HwParcel#readDoubleVector():
+
+MissingNullability: android.os.HwParcel#readEmbeddedBuffer(long, long, long, boolean):
+
+MissingNullability: android.os.HwParcel#readFloatVector():
+
+MissingNullability: android.os.HwParcel#readInt16Vector():
+
+MissingNullability: android.os.HwParcel#readInt32Vector():
+
+MissingNullability: android.os.HwParcel#readInt64Vector():
+
+MissingNullability: android.os.HwParcel#readInt8Vector():
+
+MissingNullability: android.os.HwParcel#readString():
+
+MissingNullability: android.os.HwParcel#readStringVector():
+
+MissingNullability: android.os.HwParcel#readStrongBinder():
+
+MissingNullability: android.os.HwParcel#writeBoolVector(java.util.ArrayList<java.lang.Boolean>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeBuffer(android.os.HwBlob) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeDoubleVector(java.util.ArrayList<java.lang.Double>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeFloatVector(java.util.ArrayList<java.lang.Float>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeInt16Vector(java.util.ArrayList<java.lang.Short>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeInt32Vector(java.util.ArrayList<java.lang.Integer>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeInt64Vector(java.util.ArrayList<java.lang.Long>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeInt8Vector(java.util.ArrayList<java.lang.Byte>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeInterfaceToken(String) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeString(String) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeStringVector(java.util.ArrayList<java.lang.String>) parameter #0:
+
+MissingNullability: android.os.HwParcel#writeStrongBinder(android.os.IHwBinder) parameter #0:
+
+MissingNullability: android.os.IHwBinder#linkToDeath(android.os.IHwBinder.DeathRecipient, long) parameter #0:
+
+MissingNullability: android.os.IHwBinder#queryLocalInterface(String):
+
+MissingNullability: android.os.IHwBinder#queryLocalInterface(String) parameter #0:
+
+MissingNullability: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #1:
+
+MissingNullability: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int) parameter #2:
+
+MissingNullability: android.os.IHwBinder#unlinkToDeath(android.os.IHwBinder.DeathRecipient) parameter #0:
+
+MissingNullability: android.os.IHwInterface#asBinder():
+
+MissingNullability: android.os.IncidentManager#approveReport(android.net.Uri) parameter #0:
+
+MissingNullability: android.os.IncidentManager#cancelAuthorization(android.os.IncidentManager.AuthListener) parameter #0:
+
+MissingNullability: android.os.IncidentManager#deleteIncidentReports(android.net.Uri) parameter #0:
+
+MissingNullability: android.os.IncidentManager#denyReport(android.net.Uri) parameter #0:
+
+MissingNullability: android.os.IncidentManager#getIncidentReport(android.net.Uri) parameter #0:
+
+MissingNullability: android.os.IncidentManager#getIncidentReportList(String) parameter #0:
+
+MissingNullability: android.os.IncidentManager#getPendingReports():
+
+MissingNullability: android.os.IncidentManager#reportIncident(android.os.IncidentReportArgs) parameter #0:
+
+MissingNullability: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener) parameter #1:
+
+MissingNullability: android.os.IncidentManager#requestAuthorization(int, String, int, android.os.IncidentManager.AuthListener) parameter #3:
+
+MissingNullability: android.os.IncidentManager.IncidentReport#IncidentReport(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.IncidentManager.IncidentReport#getInputStream():
+
+MissingNullability: android.os.IncidentManager.IncidentReport#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.IncidentReportArgs#IncidentReportArgs(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.IncidentReportArgs#addHeader(byte[]) parameter #0:
+
+MissingNullability: android.os.IncidentReportArgs#readFromParcel(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.IncidentReportArgs#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor):
+
+MissingNullability: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor) parameter #0:
+
+MissingNullability: android.os.RemoteCallback#RemoteCallback(android.os.RemoteCallback.OnResultListener) parameter #0:
+
+MissingNullability: android.os.RemoteCallback#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.StrictMode#setViolationLogger(android.os.StrictMode.ViolationLogger) parameter #0:
+
+MissingNullability: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel, boolean) parameter #0:
+
+MissingNullability: android.os.StrictMode.ViolationInfo#broadcastIntentAction:
+
+MissingNullability: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String) parameter #0:
+
+MissingNullability: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String) parameter #1:
+
+MissingNullability: android.os.StrictMode.ViolationInfo#getStackTrace():
+
+MissingNullability: android.os.StrictMode.ViolationInfo#getViolationClass():
+
+MissingNullability: android.os.StrictMode.ViolationInfo#getViolationDetails():
+
+MissingNullability: android.os.StrictMode.ViolationInfo#tags:
+
+MissingNullability: android.os.StrictMode.ViolationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.StrictMode.ViolationLogger#log(android.os.StrictMode.ViolationInfo) parameter #0:
+
+MissingNullability: android.os.UserHandle#of(int):
+
+MissingNullability: android.os.VibrationEffect#RINGTONES:
+
+MissingNullability: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #0:
+
+MissingNullability: android.os.VibrationEffect#get(android.net.Uri, android.content.Context) parameter #1:
+
+MissingNullability: android.os.VibrationEffect#get(int):
+
+MissingNullability: android.os.VibrationEffect#get(int, boolean):
+
+MissingNullability: android.os.VibrationEffect.OneShot#OneShot(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.VibrationEffect.OneShot#scale(float, int):
+
+MissingNullability: android.os.VibrationEffect.OneShot#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.VibrationEffect.Prebaked#Prebaked(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.VibrationEffect.Prebaked#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.VibrationEffect.Waveform#Waveform(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.VibrationEffect.Waveform#Waveform(long[], int[], int) parameter #0:
+
+MissingNullability: android.os.VibrationEffect.Waveform#Waveform(long[], int[], int) parameter #1:
+
+MissingNullability: android.os.VibrationEffect.Waveform#getAmplitudes():
+
+MissingNullability: android.os.VibrationEffect.Waveform#getTimings():
+
+MissingNullability: android.os.VibrationEffect.Waveform#scale(float, int):
+
+MissingNullability: android.os.VibrationEffect.Waveform#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.VintfObject#getHalNamesAndVersions():
+
+MissingNullability: android.os.VintfObject#getSepolicyVersion():
+
+MissingNullability: android.os.VintfObject#getTargetFrameworkCompatibilityMatrixVersion():
+
+MissingNullability: android.os.VintfObject#getVndkSnapshots():
+
+MissingNullability: android.os.VintfObject#report():
+
+MissingNullability: android.os.VintfRuntimeInfo#getCpuInfo():
+
+MissingNullability: android.os.VintfRuntimeInfo#getHardwareId():
+
+MissingNullability: android.os.VintfRuntimeInfo#getKernelVersion():
+
+MissingNullability: android.os.VintfRuntimeInfo#getNodeName():
+
+MissingNullability: android.os.VintfRuntimeInfo#getOsName():
+
+MissingNullability: android.os.VintfRuntimeInfo#getOsRelease():
+
+MissingNullability: android.os.VintfRuntimeInfo#getOsVersion():
+
+MissingNullability: android.os.WorkSource#add(int, String) parameter #1:
+
+MissingNullability: android.os.WorkSource#addReturningNewbs(android.os.WorkSource) parameter #0:
+
+MissingNullability: android.os.WorkSource#getName(int):
+
+MissingNullability: android.os.WorkSource#setReturningDiffs(android.os.WorkSource) parameter #0:
+
+MissingNullability: android.os.health.HealthKeys.Constants#Constants(Class) parameter #0:
+
+MissingNullability: android.os.health.HealthKeys.Constants#getDataType():
+
+MissingNullability: android.os.health.HealthKeys.Constants#getKeys(int):
+
+MissingNullability: android.os.health.HealthStats#HealthStats(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.health.HealthStatsWriter) parameter #0:
+
+MissingNullability: android.os.health.HealthStatsParceler#getHealthStats():
+
+MissingNullability: android.os.health.HealthStatsParceler#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.os.health.HealthStatsWriter#HealthStatsWriter(android.os.health.HealthKeys.Constants) parameter #0:
+
+MissingNullability: android.os.health.HealthStatsWriter#addMeasurements(int, String, long) parameter #1:
+
+MissingNullability: android.os.health.HealthStatsWriter#addStats(int, String, android.os.health.HealthStatsWriter) parameter #1:
+
+MissingNullability: android.os.health.HealthStatsWriter#addStats(int, String, android.os.health.HealthStatsWriter) parameter #2:
+
+MissingNullability: android.os.health.HealthStatsWriter#addTimers(int, String, android.os.health.TimerStat) parameter #1:
+
+MissingNullability: android.os.health.HealthStatsWriter#addTimers(int, String, android.os.health.TimerStat) parameter #2:
+
+MissingNullability: android.os.health.HealthStatsWriter#flattenToParcel(android.os.Parcel) parameter #0:
+
+MissingNullability: android.os.storage.StorageVolume#getPath():
+
+MissingNullability: android.permission.RuntimePermissionPresentationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.provider.CalendarContract.Calendars#SYNC_WRITABLE_COLUMNS:
+
+MissingNullability: android.provider.CalendarContract.Events#SYNC_WRITABLE_COLUMNS:
+
+MissingNullability: android.provider.ContactsContract.CommonDataKinds.Phone#ENTERPRISE_CONTENT_URI:
+
+MissingNullability: android.provider.ContactsContract.RawContactsEntity#CORP_CONTENT_URI:
+
+MissingNullability: android.provider.DeviceConfig#getProperty(String, String):
+
+MissingNullability: android.provider.DeviceConfig#getString(String, String, String):
+
+MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #0:
+
+MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #1:
+
+MissingNullability: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle) parameter #2:
+
+MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #0:
+
+MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #1:
+
+MissingNullability: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle) parameter #2:
+
+MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File):
+
+MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File) parameter #0:
+
+MissingNullability: android.provider.MediaStore#scanFile(android.content.Context, java.io.File) parameter #1:
+
+MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File):
+
+MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File) parameter #0:
+
+MissingNullability: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File) parameter #1:
+
+MissingNullability: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File) parameter #0:
+
+MissingNullability: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File) parameter #1:
+
+MissingNullability: android.provider.MediaStore#waitForIdle(android.content.Context) parameter #0:
+
+MissingNullability: android.security.KeyStoreException#KeyStoreException(int, String) parameter #1:
+
+MissingNullability: android.security.keystore.AttestationUtils#attestDeviceIds(android.content.Context, int[], byte[]) parameter #0:
+
+MissingNullability: android.security.keystore.KeyProtection.Builder#setBoundToSpecificSecureUserId(long):
+
+MissingNullability: android.service.autofill.AutofillFieldClassificationService#onBind(android.content.Intent):
+
+MissingNullability: android.service.autofill.AutofillFieldClassificationService#onBind(android.content.Intent) parameter #0:
+
+MissingNullability: android.service.autofill.CompositeUserData#getCategoryIds():
+
+MissingNullability: android.service.autofill.CompositeUserData#getDefaultFieldClassificationArgs():
+
+MissingNullability: android.service.autofill.CompositeUserData#getFieldClassificationAlgorithms():
+
+MissingNullability: android.service.autofill.CompositeUserData#getFieldClassificationArgs():
+
+MissingNullability: android.service.autofill.CompositeUserData#getValues():
+
+MissingNullability: android.service.autofill.CompositeUserData#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.service.autofill.UserData#getFieldClassificationAlgorithms():
+
+MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+
+MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+
+MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+
+MissingNullability: android.service.autofill.augmented.AugmentedAutofillService#onUnbind(android.content.Intent) parameter #0:
+
+MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+
+MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #1:
+
+MissingNullability: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #2:
+
+MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #0:
+
+MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #1:
+
+MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #2:
+
+MissingNullability: android.service.notification.Adjustment#Adjustment(String, String, android.os.Bundle, CharSequence, int) parameter #3:
+
+MissingNullability: android.service.notification.Adjustment#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context) parameter #0:
+
+MissingNullability: android.service.notification.NotificationStats#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #0:
+
+MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #1:
+
+MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(String, CharSequence, CharSequence) parameter #2:
+
+MissingNullability: android.service.notification.SnoozeCriterion#SnoozeCriterion(android.os.Parcel) parameter #0:
+
+MissingNullability: android.service.notification.SnoozeCriterion#getConfirmation():
+
+MissingNullability: android.service.notification.SnoozeCriterion#getExplanation():
+
+MissingNullability: android.service.notification.SnoozeCriterion#getId():
+
+MissingNullability: android.service.notification.SnoozeCriterion#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.telecom.Call.Details#getTelecomCallId():
+
+MissingNullability: android.telecom.CallScreeningService.CallResponse.Builder#setShouldScreenCallFurther(boolean):
+
+MissingNullability: android.telecom.Conference#getPrimaryConnection():
+
+MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent):
+
+MissingNullability: android.telecom.PhoneAccountSuggestionService#onBind(android.content.Intent) parameter #0:
+
+MissingNullability: android.telephony.DataSpecificRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.telephony.LteVopsSupportInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.telephony.NetworkRegistrationInfo#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.telephony.ServiceState#addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo) parameter #0:
+
+MissingNullability: android.telephony.ServiceState#setCellBandwidths(int[]) parameter #0:
+
+MissingNullability: android.telephony.SmsManager#checkSmsShortCodeDestination(String, String) parameter #0:
+
+MissingNullability: android.telephony.SmsManager#checkSmsShortCodeDestination(String, String) parameter #1:
+
+MissingNullability: android.telephony.TelephonyManager#checkCarrierPrivilegesForPackage(String) parameter #0:
+
+MissingNullability: android.telephony.TelephonyManager#getLine1AlphaTag():
+
+MissingNullability: android.telephony.TelephonyManager#getRadioHalVersion():
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #0:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #1:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #2:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #3:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #4:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #5:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String) parameter #6:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #0:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #1:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #2:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #3:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #4:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #5:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #6:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #7:
+
+MissingNullability: android.telephony.TelephonyManager#setCarrierTestOverride(String, String, String, String, String, String, String, String, String) parameter #8:
+
+MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String):
+
+MissingNullability: android.telephony.mbms.DownloadRequest.Builder#setServiceId(String) parameter #0:
+
+MissingNullability: android.telephony.mbms.FileInfo#FileInfo(android.net.Uri, String) parameter #0:
+
+MissingNullability: android.telephony.mbms.FileInfo#FileInfo(android.net.Uri, String) parameter #1:
+
+MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #0:
+
+MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #1:
+
+MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #2:
+
+MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #3:
+
+MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #4:
+
+MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #5:
+
+MissingNullability: android.telephony.mbms.FileServiceInfo#FileServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date, java.util.List<android.telephony.mbms.FileInfo>) parameter #6:
+
+MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #0:
+
+MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #1:
+
+MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #2:
+
+MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #3:
+
+MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #4:
+
+MissingNullability: android.telephony.mbms.StreamingServiceInfo#StreamingServiceInfo(java.util.Map<java.util.Locale,java.lang.String>, String, java.util.List<java.util.Locale>, String, java.util.Date, java.util.Date) parameter #5:
+
+MissingNullability: android.telephony.mbms.UriPathPair#getContentUri():
+
+MissingNullability: android.telephony.mbms.UriPathPair#getFilePathUri():
+
+MissingNullability: android.telephony.mbms.UriPathPair#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#asBinder():
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#cancelDownload(android.telephony.mbms.DownloadRequest) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#download(android.telephony.mbms.DownloadRequest) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #2:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestUpdateFileServices(int, java.util.List<java.lang.String>) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#resetDownloadKnowledge(android.telephony.mbms.DownloadRequest) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsDownloadServiceBase#setTempFileRootDirectory(int, String) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#onBind(android.content.Intent):
+
+MissingNullability: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#onBind(android.content.Intent) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#asBinder():
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#getPlaybackUri(int, String) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int) parameter #2:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#requestUpdateStreamingServices(int, java.util.List<java.lang.String>) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback) parameter #2:
+
+MissingNullability: android.telephony.mbms.vendor.MbmsStreamingServiceBase#stopStreaming(int, String) parameter #1:
+
+MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String):
+
+MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String) parameter #0:
+
+MissingNullability: android.telephony.mbms.vendor.VendorUtils#getAppReceiverFromPackageName(android.content.Context, String) parameter #1:
+
+MissingNullability: android.text.Selection.MemoryTextWatcher#afterTextChanged(android.text.Editable) parameter #0:
+
+MissingNullability: android.text.Selection.MemoryTextWatcher#beforeTextChanged(CharSequence, int, int, int) parameter #0:
+
+MissingNullability: android.text.Selection.MemoryTextWatcher#onTextChanged(CharSequence, int, int, int) parameter #0:
+
+MissingNullability: android.transition.TransitionManager#getTransition(android.transition.Scene):
+
+MissingNullability: android.transition.TransitionManager#getTransition(android.transition.Scene) parameter #0:
+
+MissingNullability: android.util.FeatureFlagUtils#getAllFeatureFlags():
+
+MissingNullability: android.util.FeatureFlagUtils#isEnabled(android.content.Context, String) parameter #0:
+
+MissingNullability: android.util.FeatureFlagUtils#isEnabled(android.content.Context, String) parameter #1:
+
+MissingNullability: android.util.FeatureFlagUtils#setEnabled(android.content.Context, String, boolean) parameter #0:
+
+MissingNullability: android.util.FeatureFlagUtils#setEnabled(android.content.Context, String, boolean) parameter #1:
+
+MissingNullability: android.util.TimeUtils#formatDuration(long):
+
+MissingNullability: android.util.proto.EncodedBuffer#dumpBuffers(String) parameter #0:
+
+MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #0:
+
+MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #1:
+
+MissingNullability: android.util.proto.EncodedBuffer#dumpByteString(String, String, byte[]) parameter #2:
+
+MissingNullability: android.util.proto.EncodedBuffer#getBytes(int):
+
+MissingNullability: android.util.proto.EncodedBuffer#getDebugString():
+
+MissingNullability: android.util.proto.EncodedBuffer#writeRawBuffer(byte[]) parameter #0:
+
+MissingNullability: android.util.proto.EncodedBuffer#writeRawBuffer(byte[], int, int) parameter #0:
+
+MissingNullability: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
+
+MissingNullability: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.OutputStream) parameter #0:
+
+MissingNullability: android.util.proto.ProtoOutputStream#dump(String) parameter #0:
+
+MissingNullability: android.util.proto.ProtoOutputStream#getBytes():
+
+MissingNullability: android.util.proto.ProtoOutputStream#write(long, String) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#write(long, byte[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writeBytes(long, byte[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writeObject(long, byte[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedBool(long, boolean[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedDouble(long, double[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedEnum(long, int[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedFixed32(long, int[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedFixed64(long, long[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedFloat(long, float[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedInt32(long, int[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedInt64(long, long[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedSFixed32(long, int[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedSFixed64(long, long[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedSInt32(long, int[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedSInt64(long, long[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedUInt32(long, int[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writePackedUInt64(long, long[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedBytes(long, byte[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedObject(long, byte[]) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writeRepeatedString(long, String) parameter #1:
+
+MissingNullability: android.util.proto.ProtoOutputStream#writeString(long, String) parameter #1:
+
+MissingNullability: android.util.proto.ProtoParseException#ProtoParseException(String) parameter #0:
+
+MissingNullability: android.util.proto.ProtoStream#FIELD_TYPE_NAMES:
+
+MissingNullability: android.util.proto.ProtoStream#getFieldCountString(long):
+
+MissingNullability: android.util.proto.ProtoStream#getFieldIdString(long):
+
+MissingNullability: android.util.proto.ProtoStream#getFieldTypeString(long):
+
+MissingNullability: android.util.proto.ProtoStream#getWireTypeString(int):
+
+MissingNullability: android.util.proto.ProtoStream#token2String(long):
+
+MissingNullability: android.util.proto.WireTypeMismatchException#WireTypeMismatchException(String) parameter #0:
+
+MissingNullability: android.view.Choreographer#postCallback(int, Runnable, Object) parameter #1:
+
+MissingNullability: android.view.Choreographer#postCallback(int, Runnable, Object) parameter #2:
+
+MissingNullability: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long) parameter #1:
+
+MissingNullability: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long) parameter #2:
+
+MissingNullability: android.view.Choreographer#removeCallbacks(int, Runnable, Object) parameter #1:
+
+MissingNullability: android.view.Choreographer#removeCallbacks(int, Runnable, Object) parameter #2:
+
+MissingNullability: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #0:
+
+MissingNullability: android.view.FocusFinder#sort(android.view.View[], int, int, android.view.ViewGroup, boolean) parameter #3:
+
+MissingNullability: android.view.KeyEvent#actionToString(int):
+
+MissingNullability: android.view.View#getTooltipView():
+
+MissingNullability: android.view.View#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #0:
+
+MissingNullability: android.view.View#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #1:
+
+MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #0:
+
+MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #1:
+
+MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.concurrent.Callable<java.io.OutputStream>) parameter #2:
+
+MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #0:
+
+MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #1:
+
+MissingNullability: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>) parameter #2:
+
+MissingNullability: android.view.WindowManager.LayoutParams#accessibilityTitle:
+
+MissingNullability: android.view.WindowlessViewRoot#WindowlessViewRoot(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #0:
+
+MissingNullability: android.view.WindowlessViewRoot#WindowlessViewRoot(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #1:
+
+MissingNullability: android.view.WindowlessViewRoot#WindowlessViewRoot(android.content.Context, android.view.Display, android.view.SurfaceControl) parameter #2:
+
+MissingNullability: android.view.WindowlessViewRoot#addView(android.view.View, android.view.WindowManager.LayoutParams) parameter #0:
+
+MissingNullability: android.view.WindowlessViewRoot#addView(android.view.View, android.view.WindowManager.LayoutParams) parameter #1:
+
+MissingNullability: android.view.WindowlessViewRoot#relayout(android.view.WindowManager.LayoutParams) parameter #0:
+
+MissingNullability: android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener#onAccessibilityServicesStateChanged(android.view.accessibility.AccessibilityManager) parameter #0:
+
+MissingNullability: android.view.accessibility.AccessibilityNodeInfo#setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger) parameter #0:
+
+MissingNullability: android.view.accessibility.AccessibilityNodeInfo#writeToParcelNoRecycle(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.view.accessibility.AccessibilityWindowInfo#setNumInstancesInUseCounter(java.util.concurrent.atomic.AtomicInteger) parameter #0:
+
+MissingNullability: android.view.contentcapture.ContentCaptureEvent#writeToParcel(android.os.Parcel, int) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#asyncNewChild(int):
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getAutofillId():
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getExtras():
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getHint():
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getNode():
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getTempRect():
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#getText():
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newChild(int):
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newHtmlInfoBuilder(String):
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#newHtmlInfoBuilder(String) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillHints(String[]) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillId(android.view.autofill.AutofillId) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillId(android.view.autofill.AutofillId, int) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillOptions(CharSequence[]) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setAutofillValue(android.view.autofill.AutofillValue) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setClassName(String) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setContentDescription(CharSequence) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHint(CharSequence) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHintIdEntry(String) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setHtmlInfo(android.view.ViewStructure.HtmlInfo) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #1:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #2:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setId(int, String, String, String) parameter #3:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setLocaleList(android.os.LocaleList) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setText(CharSequence) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setText(CharSequence, int, int) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTextLines(int[], int[]) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTextLines(int[], int[]) parameter #1:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setTransformation(android.graphics.Matrix) parameter #0:
+
+MissingNullability: android.view.contentcapture.ViewNode.ViewStructureImpl#setWebDomain(String) parameter #0:
+
+MissingNullability: android.widget.CalendarView#getBoundsForDate(long, android.graphics.Rect) parameter #1:
+
+MissingNullability: android.widget.ImageView#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #0:
+
+MissingNullability: android.widget.ImageView#isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable) parameter #1:
+
+MissingNullability: android.widget.Magnifier#getMagnifierDefaultSize():
+
+MissingNullability: android.widget.Magnifier#setOnOperationCompleteCallback(android.widget.Magnifier.Callback) parameter #0:
+
+MissingNullability: android.widget.NumberPicker#getDisplayedValueForCurrentSelection():
+
+MissingNullability: android.widget.PopupMenu#getMenuListView():
+
+MissingNullability: android.widget.TimePicker#getAmView():
+
+MissingNullability: android.widget.TimePicker#getHourView():
+
+MissingNullability: android.widget.TimePicker#getMinuteView():
+
+MissingNullability: android.widget.TimePicker#getPmView():
+
+
+
+NoByteOrShort: android.media.audiofx.AudioEffect#byteArrayToShort(byte[]):
+
+NoByteOrShort: android.media.audiofx.AudioEffect#setParameter(int, short) parameter #1:
+
+NoByteOrShort: android.media.audiofx.AudioEffect#shortToByteArray(short) parameter #0:
+
+NoByteOrShort: android.os.HwBlob#getInt16(long):
+
+NoByteOrShort: android.os.HwBlob#getInt8(long):
+
+NoByteOrShort: android.os.HwBlob#putInt16(long, short) parameter #1:
+
+NoByteOrShort: android.os.HwBlob#putInt8(long, byte) parameter #1:
+
+NoByteOrShort: android.os.HwParcel#readInt16():
+
+NoByteOrShort: android.os.HwParcel#readInt8():
+
+NoByteOrShort: android.os.HwParcel#writeInt16(short) parameter #0:
+
+NoByteOrShort: android.os.HwParcel#writeInt8(byte) parameter #0:
+
+NoByteOrShort: android.util.proto.EncodedBuffer#readRawByte():
+
+NoByteOrShort: android.util.proto.EncodedBuffer#writeRawByte(byte) parameter #0:
+
+
+
+NoClone: android.net.util.SocketUtils#bindSocketToInterface(java.io.FileDescriptor, String) parameter #0:
+
+NoClone: android.net.util.SocketUtils#closeSocket(java.io.FileDescriptor) parameter #0:
+
+NoClone: android.os.NativeHandle#NativeHandle(java.io.FileDescriptor, boolean) parameter #0:
+
+NoClone: android.os.NativeHandle#getFileDescriptor():
+
+NoClone: android.os.ParcelFileDescriptor#getFile(java.io.FileDescriptor) parameter #0:
+
+NoClone: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+
+NoClone: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]) parameter #0:
+
+NoClone: android.util.proto.ProtoOutputStream#ProtoOutputStream(java.io.FileDescriptor) parameter #0:
+
+
+
+NotCloseable: android.app.ActivityView:
+
+NotCloseable: android.app.prediction.AppPredictor:
+
+NotCloseable: android.os.HwParcel:
+
+
+
+OnNameExpected: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
+
+OnNameExpected: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
+
+OnNameExpected: android.service.notification.ConditionProviderService#isBound():
+
+OnNameExpected: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
+
+OnNameExpected: android.service.quicksettings.TileService#isQuickSettingsSupported():
+
+OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
+
+OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
+
+OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#startGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>, android.telephony.mbms.GroupCallCallback):
+
+OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#stopGroupCall(int, long):
+
+OnNameExpected: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#updateGroupCall(int, long, java.util.List<java.lang.Integer>, java.util.List<java.lang.Integer>):
+
+
+
+PackageLayering: android.util.FeatureFlagUtils:
+
+
+
+ParcelConstructor: android.os.IncidentManager.IncidentReport#IncidentReport(android.os.Parcel):
+
+ParcelConstructor: android.os.IncidentReportArgs#IncidentReportArgs(android.os.Parcel):
+
+ParcelConstructor: android.os.StrictMode.ViolationInfo#ViolationInfo(android.os.Parcel):
+
+ParcelConstructor: android.os.VibrationEffect.OneShot#OneShot(android.os.Parcel):
+
+ParcelConstructor: android.os.VibrationEffect.Prebaked#Prebaked(android.os.Parcel):
+
+ParcelConstructor: android.os.VibrationEffect.Waveform#Waveform(android.os.Parcel):
+
+ParcelConstructor: android.os.health.HealthStatsParceler#HealthStatsParceler(android.os.Parcel):
+
+ParcelConstructor: android.service.notification.SnoozeCriterion#SnoozeCriterion(android.os.Parcel):
+
+
+
+ParcelCreator: android.app.WindowConfiguration:
+
+ParcelCreator: android.net.metrics.ApfProgramEvent:
+
+ParcelCreator: android.net.metrics.ApfStats:
+
+ParcelCreator: android.net.metrics.DhcpClientEvent:
+
+ParcelCreator: android.net.metrics.DhcpErrorEvent:
+
+ParcelCreator: android.net.metrics.IpConnectivityLog.Event:
+
+ParcelCreator: android.net.metrics.IpManagerEvent:
+
+ParcelCreator: android.net.metrics.IpReachabilityEvent:
+
+ParcelCreator: android.net.metrics.NetworkEvent:
+
+ParcelCreator: android.net.metrics.RaEvent:
+
+ParcelCreator: android.net.metrics.ValidationProbeEvent:
+
+ParcelCreator: android.os.VibrationEffect.OneShot:
+
+ParcelCreator: android.os.VibrationEffect.Prebaked:
+
+ParcelCreator: android.os.VibrationEffect.Waveform:
+
+ParcelCreator: android.service.autofill.InternalOnClickAction:
+
+ParcelCreator: android.service.autofill.InternalSanitizer:
+
+ParcelCreator: android.service.autofill.InternalTransformation:
+
+ParcelCreator: android.service.autofill.InternalValidator:
+
+
+
+ParcelNotFinal: android.app.WindowConfiguration:
+
+ParcelNotFinal: android.net.metrics.IpConnectivityLog.Event:
+
+ParcelNotFinal: android.os.IncidentManager.IncidentReport:
+
+ParcelNotFinal: android.os.VibrationEffect.OneShot:
+
+ParcelNotFinal: android.os.VibrationEffect.Prebaked:
+
+ParcelNotFinal: android.os.VibrationEffect.Waveform:
+
+ParcelNotFinal: android.os.health.HealthStatsParceler:
+
+ParcelNotFinal: android.service.autofill.InternalOnClickAction:
+
+ParcelNotFinal: android.service.autofill.InternalSanitizer:
+
+ParcelNotFinal: android.service.autofill.InternalTransformation:
+
+ParcelNotFinal: android.service.autofill.InternalValidator:
+
+
+
+ProtectedMember: android.app.ActivityView#onVisibilityChanged(android.view.View, int):
+
+ProtectedMember: android.app.AppDetailsActivity#onCreate(android.os.Bundle):
+
+ProtectedMember: android.os.VibrationEffect#scale(int, float, int):
+
+ProtectedMember: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
+
+ProtectedMember: android.service.autofill.augmented.AugmentedAutofillService#dump(java.io.PrintWriter, String[]):
+
+ProtectedMember: android.service.contentcapture.ContentCaptureService#dump(java.io.FileDescriptor, java.io.PrintWriter, String[]):
+
+ProtectedMember: android.service.notification.NotificationAssistantService#attachBaseContext(android.content.Context):
+
+ProtectedMember: android.util.proto.ProtoStream#FIELD_TYPE_NAMES:
+
+ProtectedMember: android.view.View#resetResolvedDrawables():
+
+ProtectedMember: android.view.ViewGroup#resetResolvedDrawables():
+
+
+
+RawAidl: android.telephony.mbms.vendor.MbmsDownloadServiceBase:
+
+RawAidl: android.telephony.mbms.vendor.MbmsStreamingServiceBase:
+
+
+
+RethrowRemoteException: android.app.ActivityManager#resumeAppSwitches():
+
+RethrowRemoteException: android.os.HwBinder#getService(String, String):
+
+RethrowRemoteException: android.os.HwBinder#getService(String, String, boolean):
+
+RethrowRemoteException: android.os.HwBinder#onTransact(int, android.os.HwParcel, android.os.HwParcel, int):
+
+RethrowRemoteException: android.os.HwBinder#registerService(String):
+
+RethrowRemoteException: android.os.HwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
+
+RethrowRemoteException: android.os.IHwBinder#transact(int, android.os.HwParcel, android.os.HwParcel, int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#addStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#cancelDownload(android.telephony.mbms.DownloadRequest):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#dispose(int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#download(android.telephony.mbms.DownloadRequest):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#initialize(int, android.telephony.mbms.MbmsDownloadSessionCallback):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#listPendingDownloads(int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeProgressListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadProgressListener):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#removeStatusListener(android.telephony.mbms.DownloadRequest, android.telephony.mbms.DownloadStatusListener):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestDownloadState(android.telephony.mbms.DownloadRequest, android.telephony.mbms.FileInfo):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#requestUpdateFileServices(int, java.util.List<java.lang.String>):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#resetDownloadKnowledge(android.telephony.mbms.DownloadRequest):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsDownloadServiceBase#setTempFileRootDirectory(int, String):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#dispose(int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsGroupCallServiceBase#initialize(android.telephony.mbms.MbmsGroupCallSessionCallback, int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#dispose(int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#getPlaybackUri(int, String):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#initialize(android.telephony.mbms.MbmsStreamingSessionCallback, int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#onTransact(int, android.os.Parcel, android.os.Parcel, int):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#requestUpdateStreamingServices(int, java.util.List<java.lang.String>):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#startStreaming(int, String, android.telephony.mbms.StreamingServiceCallback):
+
+RethrowRemoteException: android.telephony.mbms.vendor.MbmsStreamingServiceBase#stopStreaming(int, String):
+
+
+
+SamShouldBeLast: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
+
+SamShouldBeLast: android.app.role.RoleManager#addOnRoleHoldersChangedListenerAsUser(java.util.concurrent.Executor, android.app.role.OnRoleHoldersChangedListener, android.os.UserHandle):
+
+SamShouldBeLast: android.app.role.RoleManager#removeOnRoleHoldersChangedListenerAsUser(android.app.role.OnRoleHoldersChangedListener, android.os.UserHandle):
+
+SamShouldBeLast: android.database.sqlite.SQLiteDebug#dump(android.util.Printer, String[]):
+
+SamShouldBeLast: android.database.sqlite.SQLiteDirectCursorDriver#query(android.database.sqlite.SQLiteDatabase.CursorFactory, String[]):
+
+SamShouldBeLast: android.location.LocationManager#requestLocationUpdates(android.location.LocationRequest, java.util.concurrent.Executor, android.location.LocationListener):
+
+SamShouldBeLast: android.os.BugreportManager#startBugreport(android.os.ParcelFileDescriptor, android.os.ParcelFileDescriptor, android.os.BugreportParams, java.util.concurrent.Executor, android.os.BugreportManager.BugreportCallback):
+
+SamShouldBeLast: android.os.IHwBinder#linkToDeath(android.os.IHwBinder.DeathRecipient, long):
+
+SamShouldBeLast: android.os.StrictMode.ViolationInfo#dump(android.util.Printer, String):
+
+SamShouldBeLast: android.permission.PermissionControllerManager#getAppPermissions(String, android.permission.PermissionControllerManager.OnGetAppPermissionResultCallback, android.os.Handler):
+
+SamShouldBeLast: android.permission.PermissionControllerManager#revokeRuntimePermissions(java.util.Map<java.lang.String,java.util.List<java.lang.String>>, boolean, int, java.util.concurrent.Executor, android.permission.PermissionControllerManager.OnRevokeRuntimePermissionsCallback):
+
+SamShouldBeLast: android.service.autofill.CharSequenceTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
+
+SamShouldBeLast: android.service.autofill.DateTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
+
+SamShouldBeLast: android.service.autofill.ImageTransformation#apply(android.service.autofill.ValueFinder, android.widget.RemoteViews, int):
+
+SamShouldBeLast: android.service.autofill.InternalTransformation#batchApply(android.service.autofill.ValueFinder, android.widget.RemoteViews, java.util.ArrayList<android.util.Pair<java.lang.Integer,android.service.autofill.InternalTransformation>>):
+
+SamShouldBeLast: android.view.Choreographer#postCallback(int, Runnable, Object):
+
+SamShouldBeLast: android.view.Choreographer#postCallbackDelayed(int, Runnable, Object, long):
+
+SamShouldBeLast: android.view.Choreographer#removeCallbacks(int, Runnable, Object):
+
+SamShouldBeLast: android.view.ViewDebug#startRenderingCommandsCapture(android.view.View, java.util.concurrent.Executor, java.util.function.Function<android.graphics.Picture,java.lang.Boolean>):
+
+SamShouldBeLast: android.view.accessibility.AccessibilityManager#addAccessibilityServicesStateChangeListener(android.view.accessibility.AccessibilityManager.AccessibilityServicesStateChangeListener, android.os.Handler):
+
+
+
+ServiceName: android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE:
+
+ServiceName: android.app.AppOpsManager#OPSTR_BIND_ACCESSIBILITY_SERVICE:
+
+ServiceName: android.provider.Settings.Secure#ACCESSIBILITY_SHORTCUT_TARGET_SERVICE:
+
+ServiceName: android.provider.Settings.Secure#AUTOFILL_SERVICE:
+
+ServiceName: android.provider.Settings.Secure#VOICE_INTERACTION_SERVICE:
+
+
+
+SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyFocusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener):
+
+SetterReturnsThis: android.media.audiopolicy.AudioPolicy.Builder#setAudioPolicyStatusListener(android.media.audiopolicy.AudioPolicy.AudioPolicyStatusListener):
+
+
+
+StaticUtils: android.os.health.HealthKeys:
+
+StaticUtils: android.service.autofill.InternalTransformation:
+
+StaticUtils: android.telephony.mbms.vendor.VendorUtils:
+
+StaticUtils: android.util.FeatureFlagUtils:
+
+StaticUtils: android.util.proto.ProtoStream:
+
+
+
+StreamFiles: android.os.Environment#buildPath(java.io.File, java.lang.String...):
+
+StreamFiles: android.os.FileUtils#contains(java.io.File, java.io.File):
+
+StreamFiles: android.provider.MediaStore#scanFile(android.content.Context, java.io.File):
+
+StreamFiles: android.provider.MediaStore#scanFileFromShell(android.content.Context, java.io.File):
+
+StreamFiles: android.provider.MediaStore#scanVolume(android.content.Context, java.io.File):
+
+
+
+UserHandle: android.app.admin.DevicePolicyManager#getOwnerInstalledCaCerts(android.os.UserHandle):
+
+UserHandle: android.app.role.RoleManager#addOnRoleHoldersChangedListenerAsUser(java.util.concurrent.Executor, android.app.role.OnRoleHoldersChangedListener, android.os.UserHandle):
+
+UserHandle: android.app.role.RoleManager#addRoleHolderAsUser(String, String, int, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>):
+
+UserHandle: android.app.role.RoleManager#clearRoleHoldersAsUser(String, int, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>):
+
+UserHandle: android.app.role.RoleManager#getRoleHoldersAsUser(String, android.os.UserHandle):
+
+UserHandle: android.app.role.RoleManager#removeOnRoleHoldersChangedListenerAsUser(android.app.role.OnRoleHoldersChangedListener, android.os.UserHandle):
+
+UserHandle: android.app.role.RoleManager#removeRoleHolderAsUser(String, String, int, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>):
+
+UserHandle: android.content.pm.PackageManager#getInstallReason(String, android.os.UserHandle):
+
+UserHandle: android.content.pm.PackageManager#getPermissionFlags(String, String, android.os.UserHandle):
+
+UserHandle: android.content.pm.PackageManager#grantRuntimePermission(String, String, android.os.UserHandle):
+
+UserHandle: android.content.pm.PackageManager#revokeRuntimePermission(String, String, android.os.UserHandle):
+
+UserHandle: android.content.pm.PackageManager#updatePermissionFlags(String, String, int, int, android.os.UserHandle):
+
+UserHandle: android.location.LocationManager#setLocationEnabledForUser(boolean, android.os.UserHandle):
+
+UserHandle: android.permission.PermissionControllerManager#applyStagedRuntimePermissionBackup(String, android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Boolean>):
+
+UserHandle: android.permission.PermissionControllerManager#getRuntimePermissionBackup(android.os.UserHandle, java.util.concurrent.Executor, java.util.function.Consumer<byte[]>):
+
+UserHandle: android.permission.PermissionControllerManager#stageAndApplyRuntimePermissionsBackup(byte[], android.os.UserHandle):
+
+
+
+UserHandleName: android.app.ActivityView#startActivity(android.content.Intent, android.os.UserHandle):
+
+UserHandleName: android.content.AutofillOptions:
+
+UserHandleName: android.content.ContentCaptureOptions:
+
+UserHandleName: android.os.IncidentReportArgs:
+
+UserHandleName: android.provider.MediaStore#deleteContributedMedia(android.content.Context, String, android.os.UserHandle):
+
+UserHandleName: android.provider.MediaStore#getContributedMediaSize(android.content.Context, String, android.os.UserHandle):
+
+
+
+VisiblySynchronized: PsiClassObjectAccessExpression:
+
+VisiblySynchronized: PsiThisExpression:
+
+VisiblySynchronized: android.app.ActivityManager#addOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener, int):
+
+VisiblySynchronized: android.app.ActivityManager#removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener):
+
+VisiblySynchronized: android.content.ContentProviderClient#setDetectNotResponding(long):
+
+VisiblySynchronized: android.content.res.AssetManager#getApkPaths():
+
+VisiblySynchronized: android.content.res.AssetManager#getLastResourceResolution():
+
+VisiblySynchronized: android.content.res.AssetManager#getOverlayablesToString(String):
+
+VisiblySynchronized: android.content.res.AssetManager#setResourceResolutionLoggingEnabled(boolean):
+
+VisiblySynchronized: android.os.MessageQueue#removeSyncBarrier(int):
+
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 6fd0327..0ee156b 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -650,6 +650,7 @@
ret.setDouble(value.mValue.double_value);
break;
default:
+ return false;
break;
}
return true;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 7f597fe..1e78fc1 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -163,7 +163,7 @@
}
@Override
- public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
mListener.onUidImportance(uid, RunningAppProcessInfo.procStateToImportanceForClient(
procState, mContext));
}
@@ -432,7 +432,6 @@
public static final int USER_OP_ERROR_RELATED_USERS_CANNOT_STOP = -4;
/**
- * @hide
* Process states, describing the kind of state a particular process is in.
* When updating these, make sure to also check all related references to the
* constant in code, and update these arrays:
@@ -443,7 +442,34 @@
* @see com.android.server.am.ProcessList#sSameAwakePssTimes
* @see com.android.server.am.ProcessList#sTestFirstPssTimes
* @see com.android.server.am.ProcessList#sTestSamePssTimes
+ * @hide
*/
+ @IntDef(flag = false, prefix = { "PROCESS_STATE_" }, value = {
+ PROCESS_STATE_UNKNOWN, // -1
+ PROCESS_STATE_PERSISTENT, // 0
+ PROCESS_STATE_PERSISTENT_UI,
+ PROCESS_STATE_TOP,
+ PROCESS_STATE_BOUND_TOP,
+ PROCESS_STATE_FOREGROUND_SERVICE,
+ PROCESS_STATE_BOUND_FOREGROUND_SERVICE,
+ PROCESS_STATE_IMPORTANT_FOREGROUND,
+ PROCESS_STATE_IMPORTANT_BACKGROUND,
+ PROCESS_STATE_TRANSIENT_BACKGROUND,
+ PROCESS_STATE_BACKUP,
+ PROCESS_STATE_SERVICE,
+ PROCESS_STATE_RECEIVER,
+ PROCESS_STATE_TOP_SLEEPING,
+ PROCESS_STATE_HEAVY_WEIGHT,
+ PROCESS_STATE_HOME,
+ PROCESS_STATE_LAST_ACTIVITY,
+ PROCESS_STATE_CACHED_ACTIVITY,
+ PROCESS_STATE_CACHED_ACTIVITY_CLIENT,
+ PROCESS_STATE_CACHED_RECENT,
+ PROCESS_STATE_CACHED_EMPTY,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ProcessState {}
+
/** @hide Not a real process state. */
public static final int PROCESS_STATE_UNKNOWN = -1;
@@ -459,78 +485,98 @@
@UnsupportedAppUsage
public static final int PROCESS_STATE_TOP = 2;
- /** @hide Process is hosting a foreground service with location type. */
- public static final int PROCESS_STATE_FOREGROUND_SERVICE_LOCATION = 3;
-
/** @hide Process is bound to a TOP app. This is ranked below SERVICE_LOCATION so that
* it doesn't get the capability of location access while-in-use. */
- public static final int PROCESS_STATE_BOUND_TOP = 4;
+ public static final int PROCESS_STATE_BOUND_TOP = 3;
/** @hide Process is hosting a foreground service. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_FOREGROUND_SERVICE = 5;
+ public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4;
/** @hide Process is hosting a foreground service due to a system binding. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 6;
+ public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 5;
/** @hide Process is important to the user, and something they are aware of. */
- public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 7;
+ public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6;
/** @hide Process is important to the user, but not something they are aware of. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 8;
+ public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7;
/** @hide Process is in the background transient so we will try to keep running. */
- public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 9;
+ public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8;
/** @hide Process is in the background running a backup/restore operation. */
- public static final int PROCESS_STATE_BACKUP = 10;
+ public static final int PROCESS_STATE_BACKUP = 9;
/** @hide Process is in the background running a service. Unlike oom_adj, this level
* is used for both the normal running in background state and the executing
* operations state. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_SERVICE = 11;
+ public static final int PROCESS_STATE_SERVICE = 10;
/** @hide Process is in the background running a receiver. Note that from the
* perspective of oom_adj, receivers run at a higher foreground level, but for our
* prioritization here that is not necessary and putting them below services means
* many fewer changes in some process states as they receive broadcasts. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_RECEIVER = 12;
+ public static final int PROCESS_STATE_RECEIVER = 11;
/** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */
- public static final int PROCESS_STATE_TOP_SLEEPING = 13;
+ public static final int PROCESS_STATE_TOP_SLEEPING = 12;
/** @hide Process is in the background, but it can't restore its state so we want
* to try to avoid killing it. */
- public static final int PROCESS_STATE_HEAVY_WEIGHT = 14;
+ public static final int PROCESS_STATE_HEAVY_WEIGHT = 13;
/** @hide Process is in the background but hosts the home activity. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_HOME = 15;
+ public static final int PROCESS_STATE_HOME = 14;
/** @hide Process is in the background but hosts the last shown activity. */
- public static final int PROCESS_STATE_LAST_ACTIVITY = 16;
+ public static final int PROCESS_STATE_LAST_ACTIVITY = 15;
/** @hide Process is being cached for later use and contains activities. */
@UnsupportedAppUsage
- public static final int PROCESS_STATE_CACHED_ACTIVITY = 17;
+ public static final int PROCESS_STATE_CACHED_ACTIVITY = 16;
/** @hide Process is being cached for later use and is a client of another cached
* process that contains activities. */
- public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 18;
+ public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 17;
/** @hide Process is being cached for later use and has an activity that corresponds
* to an existing recent task. */
- public static final int PROCESS_STATE_CACHED_RECENT = 19;
+ public static final int PROCESS_STATE_CACHED_RECENT = 18;
/** @hide Process is being cached for later use and is empty. */
- public static final int PROCESS_STATE_CACHED_EMPTY = 20;
+ public static final int PROCESS_STATE_CACHED_EMPTY = 19;
/** @hide Process does not exist. */
- public static final int PROCESS_STATE_NONEXISTENT = 21;
+ public static final int PROCESS_STATE_NONEXISTENT = 20;
+
+ /**
+ * The set of flags for process capability.
+ * @hide
+ */
+ @IntDef(flag = true, prefix = { "PROCESS_CAPABILITY_" }, value = {
+ PROCESS_CAPABILITY_NONE,
+ PROCESS_CAPABILITY_FOREGROUND_LOCATION,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ProcessCapability {}
+
+ /** @hide Process does not have any capability */
+ @TestApi
+ public static final int PROCESS_CAPABILITY_NONE = 0;
+
+ /** @hide Process can access location while in foreground */
+ @TestApi
+ public static final int PROCESS_CAPABILITY_FOREGROUND_LOCATION = 1 << 0;
+
+ /** @hide all capabilities, the ORing of all flags in {@link ProcessCapability}*/
+ @TestApi
+ public static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION;
// NOTE: If PROCESS_STATEs are added, then new fields must be added
// to frameworks/base/core/proto/android/app/enums.proto and the following method must
@@ -557,7 +603,6 @@
return AppProtoEnums.PROCESS_STATE_TOP;
case PROCESS_STATE_BOUND_TOP:
return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
- case PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
case PROCESS_STATE_FOREGROUND_SERVICE:
return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
case PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
@@ -612,8 +657,7 @@
/** @hide Is this a foreground service type? */
public static boolean isForegroundService(int procState) {
- return procState == PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
- || procState == PROCESS_STATE_FOREGROUND_SERVICE;
+ return procState == PROCESS_STATE_FOREGROUND_SERVICE;
}
/** @hide requestType for assist context: only basic information. */
@@ -2930,7 +2974,7 @@
return IMPORTANCE_PERCEPTIBLE;
} else if (procState >= PROCESS_STATE_IMPORTANT_FOREGROUND) {
return IMPORTANCE_VISIBLE;
- } else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) {
+ } else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE) {
return IMPORTANCE_FOREGROUND_SERVICE;
} else {
return IMPORTANCE_FOREGROUND;
@@ -4087,7 +4131,7 @@
* Action an app can implement to handle reports from {@link #setWatchHeapLimit(long)}.
* If your package has an activity handling this action, it will be launched with the
* heap data provided to it the same way as {@link Intent#ACTION_SEND}. Note that to
- * match the activty must support this action and a MIME type of "*/*".
+ * match, the activity must support this action and a MIME type of "*/*".
*/
public static final String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT";
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 8bca87e6..765c358 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -282,10 +282,14 @@
/**
* Uid state: The UID is running a foreground service of location type.
* The lower the UID state the more important the UID is for the user.
+ * This uid state is a counterpart to PROCESS_STATE_FOREGROUND_SERVICE_LOCATION which has been
+ * deprecated.
* @hide
+ * @deprecated
*/
@TestApi
@SystemApi
+ @Deprecated
public static final int UID_STATE_FOREGROUND_SERVICE_LOCATION = 300;
/**
@@ -298,13 +302,6 @@
public static final int UID_STATE_FOREGROUND_SERVICE = 400;
/**
- * The max, which is min priority, UID state for which any app op
- * would be considered as performed in the foreground.
- * @hide
- */
- public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND_SERVICE;
-
- /**
* Uid state: The UID is a foreground app. The lower the UID
* state the more important the UID is for the user.
* @hide
@@ -314,6 +311,13 @@
public static final int UID_STATE_FOREGROUND = 500;
/**
+ * The max, which is min priority, UID state for which any app op
+ * would be considered as performed in the foreground.
+ * @hide
+ */
+ public static final int UID_STATE_MAX_LAST_NON_RESTRICTED = UID_STATE_FOREGROUND;
+
+ /**
* Uid state: The UID is a background app. The lower the UID
* state the more important the UID is for the user.
* @hide
@@ -344,47 +348,25 @@
public static final int MIN_PRIORITY_UID_STATE = UID_STATE_CACHED;
/**
- * Resolves the first unrestricted state given an app op. Location is
- * special as we want to allow its access only if a dedicated location
- * foreground service is running. For other ops we consider any foreground
- * service as a foreground state.
- *
+ * Resolves the first unrestricted state given an app op.
* @param op The op to resolve.
* @return The last restricted UID state.
*
* @hide
*/
public static int resolveFirstUnrestrictedUidState(int op) {
- switch (op) {
- case OP_FINE_LOCATION:
- case OP_COARSE_LOCATION:
- case OP_MONITOR_LOCATION:
- case OP_MONITOR_HIGH_POWER_LOCATION: {
- return UID_STATE_FOREGROUND_SERVICE_LOCATION;
- }
- }
- return UID_STATE_FOREGROUND_SERVICE;
+ return UID_STATE_FOREGROUND;
}
/**
- * Resolves the last restricted state given an app op. Location is
- * special as we want to allow its access only if a dedicated location
- * foreground service is running. For other ops we consider any foreground
- * service as a foreground state.
- *
+ * Resolves the last restricted state given an app op.
* @param op The op to resolve.
* @return The last restricted UID state.
*
* @hide
*/
public static int resolveLastRestrictedUidState(int op) {
- switch (op) {
- case OP_FINE_LOCATION:
- case OP_COARSE_LOCATION: {
- return UID_STATE_FOREGROUND_SERVICE;
- }
- }
- return UID_STATE_FOREGROUND;
+ return UID_STATE_BACKGROUND;
}
/** @hide Note: Keep these sorted */
@@ -4603,7 +4585,6 @@
*
* @param fromUidState The UID state from which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
* {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
* {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
* @param toUidState The UID state to which to query.
@@ -4664,7 +4645,6 @@
*
* @param fromUidState The UID state from which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
* {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
* {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
* @param toUidState The UID state to which to query.
@@ -4728,7 +4708,6 @@
*
* @param fromUidState The UID state from which to query. Could be one of
* {@link #UID_STATE_PERSISTENT}, {@link #UID_STATE_TOP},
- * {@link #UID_STATE_FOREGROUND_SERVICE_LOCATION},
* {@link #UID_STATE_FOREGROUND_SERVICE}, {@link #UID_STATE_FOREGROUND},
* {@link #UID_STATE_BACKGROUND}, {@link #UID_STATE_CACHED}.
* @param toUidState The UID state from which to query.
diff --git a/core/java/android/app/IUidObserver.aidl b/core/java/android/app/IUidObserver.aidl
index e116d98..7713e25 100644
--- a/core/java/android/app/IUidObserver.aidl
+++ b/core/java/android/app/IUidObserver.aidl
@@ -50,8 +50,9 @@
* @param procState The updated process state for the uid.
* @param procStateSeq The sequence no. associated with process state change of the uid,
* see UidRecord.procStateSeq for details.
+ * @param capability the updated process capability for the uid.
*/
- void onUidStateChanged(int uid, int procState, long procStateSeq);
+ void onUidStateChanged(int uid, int procState, long procStateSeq, int capability);
// =============== End of transactions used on native side as well ============================
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 6a13499..629c2bb 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -23,6 +23,7 @@
import android.app.admin.IDevicePolicyManager;
import android.app.contentsuggestions.ContentSuggestionsManager;
import android.app.contentsuggestions.IContentSuggestionsManager;
+import android.app.job.JobSchedulerFrameworkInitializer;
import android.app.prediction.AppPredictionManager;
import android.app.role.RoleControllerManager;
import android.app.role.RoleManager;
@@ -153,7 +154,6 @@
import android.os.image.DynamicSystemManager;
import android.os.image.IDynamicSystemService;
import android.os.storage.StorageManager;
-import android.telephony.TelephonyRegistryManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.print.IPrintManager;
@@ -167,6 +167,7 @@
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
+import android.telephony.TelephonyRegistryManager;
import android.telephony.euicc.EuiccCardManager;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.RcsMessageManager;
@@ -1298,6 +1299,9 @@
IBatteryStats.Stub.asInterface(b));
}});
//CHECKSTYLE:ON IndentationCheck
+
+ JobSchedulerFrameworkInitializer.initialize();
+ DeviceIdleFrameworkInitializer.initialize();
}
/**
diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index 489a292..e9ea99f 100644
--- a/core/java/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -77,7 +77,9 @@
/**
* Make a socket address that packet socket can send packets to.
+ * @deprecated Use {@link #makePacketSocketAddress(int, int, byte[])} instead.
*/
+ @Deprecated
@NonNull
public static SocketAddress makePacketSocketAddress(int ifIndex, @NonNull byte[] hwAddr) {
return new PacketSocketAddress(
@@ -87,6 +89,18 @@
}
/**
+ * Make a socket address that packet socket can send packets to.
+ */
+ @NonNull
+ public static SocketAddress makePacketSocketAddress(int protocol, int ifIndex,
+ @NonNull byte[] hwAddr) {
+ return new PacketSocketAddress(
+ protocol /* sll_protocol */,
+ ifIndex /* sll_ifindex */,
+ hwAddr /* sll_addr */);
+ }
+
+ /**
* @see IoBridge#closeAndSignalBlockedThreads(FileDescriptor)
*/
public static void closeSocket(@Nullable FileDescriptor fd) throws IOException {
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index af0ec11..fa09cf0 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -17,7 +17,6 @@
package android.os;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
-import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
import android.annotation.IntDef;
import android.annotation.UnsupportedAppUsage;
@@ -923,7 +922,6 @@
*/
public static final int[] CRITICAL_PROC_STATES = {
PROCESS_STATE_TOP,
- PROCESS_STATE_FOREGROUND_SERVICE_LOCATION,
PROCESS_STATE_BOUND_TOP, PROCESS_STATE_FOREGROUND_SERVICE,
PROCESS_STATE_FOREGROUND
};
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index d4abf28..9d14d9d 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -151,6 +151,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static int getInt(@NonNull String key, int def) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get_int(key, def);
@@ -166,6 +167,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static long getLong(@NonNull String key, long def) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get_long(key, def);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index b7a3c8f..3476b18 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -1909,7 +1909,14 @@
* Returns the user-wide restrictions imposed on the user specified by <code>userHandle</code>.
* @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
* @return a Bundle containing all the restrictions.
+ *
+ * <p>Requires {@code android.permission.MANAGE_USERS} or
+ * {@code android.permission.INTERACT_ACROSS_USERS}, otherwise specified {@link UserHandle user}
+ * must be the calling user or a managed profile associated with it.
*/
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
public Bundle getUserRestrictions(UserHandle userHandle) {
try {
return mService.getUserRestrictions(userHandle.getIdentifier());
@@ -2000,7 +2007,7 @@
* @return {@code true} if the current user has the given restriction, {@code false} otherwise.
*/
public boolean hasUserRestriction(String restrictionKey) {
- return hasUserRestriction(restrictionKey, Process.myUserHandle());
+ return hasUserRestrictionForUser(restrictionKey, Process.myUserHandle());
}
/**
@@ -2012,9 +2019,29 @@
*/
@UnsupportedAppUsage
public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
+ return hasUserRestrictionForUser(restrictionKey, userHandle);
+ }
+
+ /**
+ * Returns whether the given user has been disallowed from performing certain actions
+ * or setting certain settings.
+ * @param restrictionKey the string key representing the restriction
+ * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
+ *
+ * <p>Requires {@code android.permission.MANAGE_USERS} or
+ * {@code android.permission.INTERACT_ACROSS_USERS}, otherwise specified {@link UserHandle user}
+ * must be the calling user or a managed profile associated with it.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(anyOf = {
+ android.Manifest.permission.MANAGE_USERS,
+ android.Manifest.permission.INTERACT_ACROSS_USERS}, conditional = true)
+ public boolean hasUserRestrictionForUser(@NonNull String restrictionKey,
+ @NonNull UserHandle userHandle) {
try {
- return mService.hasUserRestriction(restrictionKey,
- userHandle.getIdentifier());
+ return mService.hasUserRestriction(restrictionKey, userHandle.getIdentifier());
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 8b8afd5..0401d7f 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -130,8 +130,10 @@
/**
* Namespace for how dex runs. The feature requires a reboot to reach a clean state.
*
+ * @deprecated No longer used
* @hide
*/
+ @Deprecated
@SystemApi
public static final String NAMESPACE_DEX_BOOT = "dex_boot";
@@ -586,9 +588,8 @@
@RequiresPermission(WRITE_DEVICE_CONFIG)
public static boolean setProperty(@NonNull String namespace, @NonNull String name,
@Nullable String value, boolean makeDefault) {
- String compositeName = createCompositeName(namespace, name);
ContentResolver contentResolver = ActivityThread.currentApplication().getContentResolver();
- return Settings.Config.putString(contentResolver, compositeName, value, makeDefault);
+ return Settings.Config.putString(contentResolver, namespace, name, value, makeDefault);
}
/**
@@ -672,12 +673,6 @@
}
}
- private static String createCompositeName(@NonNull String namespace, @NonNull String name) {
- Preconditions.checkNotNull(namespace);
- Preconditions.checkNotNull(name);
- return namespace + "/" + name;
- }
-
private static Uri createNamespaceUri(@NonNull String namespace) {
Preconditions.checkNotNull(namespace);
return CONTENT_URI.buildUpon().appendPath(namespace).build();
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index 8f772d4..fcbda5f 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -334,10 +334,17 @@
return cachedTypeface;
}
- // Unfortunately the typeface is not available at this time, but requesting from the font
- // provider takes too much time. For now, request the font data to ensure it is in the cache
- // next time and return.
synchronized (sLock) {
+ // It is possible that Font is loaded during the thread sleep time
+ // re-check the cache to avoid re-loading the font
+ cachedTypeface = sTypefaceCache.get(id);
+ if (cachedTypeface != null) {
+ return cachedTypeface;
+ }
+
+ // Unfortunately the typeface is not available at this time, but requesting from
+ // the font provider takes too much time. For now, request the font data to ensure
+ // it is in the cache next time and return.
if (sHandler == null) {
sThread = new HandlerThread("fonts", Process.THREAD_PRIORITY_BACKGROUND);
sThread.start();
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index a1333df..aa67d97 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -47,6 +47,7 @@
import android.media.ExifInterface;
import android.media.MediaFile;
import android.media.MediaFormat;
+import android.media.MediaMetadataRetriever;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
@@ -589,9 +590,7 @@
* @see MediaStore#setIncludeTrashed(Uri)
* @see MediaStore#trash(Context, Uri)
* @see MediaStore#untrash(Context, Uri)
- * @removed
*/
- @Deprecated
public static @NonNull Uri setIncludeTrashed(@NonNull Uri uri) {
return uri.buildUpon().appendQueryParameter(PARAM_INCLUDE_TRASHED, "1").build();
}
@@ -830,9 +829,7 @@
* @see MediaStore#setIncludeTrashed(Uri)
* @see MediaStore#trash(Context, Uri)
* @see MediaStore#untrash(Context, Uri)
- * @removed
*/
- @Deprecated
public static void trash(@NonNull Context context, @NonNull Uri uri) {
trash(context, uri, 48 * DateUtils.HOUR_IN_MILLIS);
}
@@ -850,9 +847,7 @@
* @see MediaStore#setIncludeTrashed(Uri)
* @see MediaStore#trash(Context, Uri)
* @see MediaStore#untrash(Context, Uri)
- * @removed
*/
- @Deprecated
public static void trash(@NonNull Context context, @NonNull Uri uri,
@DurationMillisLong long timeoutMillis) {
if (timeoutMillis < 0) {
@@ -874,9 +869,7 @@
* @see MediaStore#setIncludeTrashed(Uri)
* @see MediaStore#trash(Context, Uri)
* @see MediaStore#untrash(Context, Uri)
- * @removed
*/
- @Deprecated
public static void untrash(@NonNull Context context, @NonNull Uri uri) {
final ContentValues values = new ContentValues();
values.put(MediaColumns.IS_TRASHED, 0);
@@ -907,26 +900,8 @@
public static final String DATA = "_data";
/**
- * Hash of the media item on disk.
- * <p>
- * Contains a 20-byte binary blob which is the SHA-1 hash of the file as
- * persisted on disk. For performance reasons, the hash may not be
- * immediately available, in which case a {@code NULL} value will be
- * returned. If the underlying file is modified, this value will be
- * cleared and recalculated.
- * <p>
- * If you require the hash of a specific item, you can call
- * {@link ContentResolver#canonicalize(Uri)}, which will block until the
- * hash is calculated.
- *
- * @removed
- */
- @Deprecated
- @Column(value = Cursor.FIELD_TYPE_BLOB, readOnly = true)
- public static final String HASH = "_hash";
-
- /**
- * The size of the media item.
+ * Indexed value of {@link File#length()} extracted from this media
+ * item.
*/
@BytesLong
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
@@ -943,12 +918,6 @@
public static final String DISPLAY_NAME = "_display_name";
/**
- * The title of the media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String TITLE = "title";
-
- /**
* The time the media item was first added.
*/
@CurrentTimeSecondsLong
@@ -956,14 +925,22 @@
public static final String DATE_ADDED = "date_added";
/**
- * The time the media item was last modified.
+ * Indexed value of {@link File#lastModified()} extracted from this
+ * media item.
*/
@CurrentTimeSecondsLong
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
public static final String DATE_MODIFIED = "date_modified";
/**
- * The time the media item was taken.
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_DATE} or
+ * {@link ExifInterface#TAG_DATETIME_ORIGINAL} extracted from this media
+ * item.
+ * <p>
+ * Note that images must define both
+ * {@link ExifInterface#TAG_DATETIME_ORIGINAL} and
+ * {@code ExifInterface#TAG_OFFSET_TIME_ORIGINAL} to reliably determine
+ * this value in relation to the epoch.
*/
@CurrentTimeMillisLong
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
@@ -989,17 +966,6 @@
public static final String MIME_TYPE = "mime_type";
/**
- * The MTP object handle of a newly transfered file.
- * Used to pass the new file's object handle through the media scanner
- * from MTP to the media provider
- * For internal use only by MTP, media scanner and media provider.
- * @hide
- */
- @Deprecated
- // @Column(Cursor.FIELD_TYPE_INTEGER)
- public static final String MEDIA_SCANNER_NEW_OBJECT_ID = "media_scanner_new_object_id";
-
- /**
* Non-zero if the media file is drm-protected
* @hide
*/
@@ -1012,6 +978,10 @@
* Flag indicating if a media item is pending, and still being inserted
* by its owner. While this flag is set, only the owner of the item can
* open the underlying file; requests from other apps will be rejected.
+ * <p>
+ * Pending items are retained either until they are published by setting
+ * the field to {@code 0}, or until they expire as defined by
+ * {@link #DATE_EXPIRES}.
*
* @see MediaStore#setIncludePending(Uri)
*/
@@ -1020,38 +990,54 @@
/**
* Flag indicating if a media item is trashed.
+ * <p>
+ * Trashed items are retained until they expire as defined by
+ * {@link #DATE_EXPIRES}.
*
* @see MediaColumns#IS_TRASHED
* @see MediaStore#setIncludeTrashed(Uri)
* @see MediaStore#trash(Context, Uri)
* @see MediaStore#untrash(Context, Uri)
- * @removed
*/
- @Deprecated
@Column(Cursor.FIELD_TYPE_INTEGER)
public static final String IS_TRASHED = "is_trashed";
/**
* The time the media item should be considered expired. Typically only
- * meaningful in the context of {@link #IS_PENDING}.
+ * meaningful in the context of {@link #IS_PENDING} or
+ * {@link #IS_TRASHED}.
*/
@CurrentTimeSecondsLong
@Column(Cursor.FIELD_TYPE_INTEGER)
public static final String DATE_EXPIRES = "date_expires";
/**
- * The width of the media item, in pixels.
+ * Indexed value of
+ * {@link MediaMetadataRetriever#METADATA_KEY_VIDEO_WIDTH},
+ * {@link MediaMetadataRetriever#METADATA_KEY_IMAGE_WIDTH} or
+ * {@link ExifInterface#TAG_IMAGE_WIDTH} extracted from this media item.
*/
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
public static final String WIDTH = "width";
/**
- * The height of the media item, in pixels.
+ * Indexed value of
+ * {@link MediaMetadataRetriever#METADATA_KEY_VIDEO_HEIGHT},
+ * {@link MediaMetadataRetriever#METADATA_KEY_IMAGE_HEIGHT} or
+ * {@link ExifInterface#TAG_IMAGE_LENGTH} extracted from this media
+ * item.
*/
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
public static final String HEIGHT = "height";
/**
+ * Calculated value that combines {@link #WIDTH} and {@link #HEIGHT}
+ * into a user-presentable string.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String RESOLUTION = "resolution";
+
+ /**
* Package name that contributed this media. The value may be
* {@code NULL} if ownership cannot be reliably determined.
*/
@@ -1097,28 +1083,6 @@
public static final String RELATIVE_PATH = "relative_path";
/**
- * The primary directory name this media exists under. The value may be
- * {@code NULL} if the media doesn't have a primary directory name.
- *
- * @removed
- * @deprecated Replaced by {@link #RELATIVE_PATH}.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- @Deprecated
- 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.
- *
- * @removed
- * @deprecated Replaced by {@link #RELATIVE_PATH}.
- */
- @Column(Cursor.FIELD_TYPE_STRING)
- @Deprecated
- public static final String SECONDARY_DIRECTORY = "secondary_directory";
-
- /**
* The primary bucket ID of this media item. This can be useful to
* present the user a first-level clustering of related media items.
* This is a read-only column that is automatically computed.
@@ -1191,18 +1155,171 @@
public static final String ORIGINAL_DOCUMENT_ID = "original_document_id";
/**
- * The duration of the media item.
+ * Indexed value of
+ * {@link MediaMetadataRetriever#METADATA_KEY_VIDEO_ROTATION},
+ * {@link MediaMetadataRetriever#METADATA_KEY_IMAGE_ROTATION}, or
+ * {@link ExifInterface#TAG_ORIENTATION} extracted from this media item.
+ * <p>
+ * For consistency the indexed value is expressed in degrees, such as 0,
+ * 90, 180, or 270.
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String ORIENTATION = "orientation";
+
+ /**
+ * Flag indicating if the media item has been marked as being a
+ * "favorite" by the user.
+ */
+ @Column(Cursor.FIELD_TYPE_INTEGER)
+ public static final String IS_FAVORITE = "is_favorite";
+
+ // =======================================
+ // ==== MediaMetadataRetriever values ====
+ // =======================================
+
+ /**
+ * Indexed value of
+ * {@link MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER} extracted
+ * from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String CD_TRACK_NUMBER = "cd_track_number";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_ALBUM}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String ALBUM = "album";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_ARTIST}
+ * or {@link ExifInterface#TAG_ARTIST} extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String ARTIST = "artist";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_AUTHOR}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String AUTHOR = "author";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_COMPOSER}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String COMPOSER = "composer";
+
+ // METADATA_KEY_DATE is DATE_TAKEN
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_GENRE}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String GENRE = "genre";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_TITLE}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String TITLE = "title";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_YEAR}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String YEAR = "year";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_DURATION}
+ * extracted from this media item.
*/
@DurationMillisLong
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
public static final String DURATION = "duration";
/**
- * The orientation for the media item, expressed in degrees. For
- * example, 0, 90, 180, or 270 degrees.
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_NUM_TRACKS}
+ * extracted from this media item.
*/
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
- public static final String ORIENTATION = "orientation";
+ public static final String NUM_TRACKS = "num_tracks";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_WRITER}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String WRITER = "writer";
+
+ // METADATA_KEY_MIMETYPE is MIME_TYPE
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String ALBUM_ARTIST = "album_artist";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String DISC_NUMBER = "disc_number";
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_COMPILATION}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String COMPILATION = "compilation";
+
+ // HAS_AUDIO is ignored
+ // HAS_VIDEO is ignored
+ // VIDEO_WIDTH is WIDTH
+ // VIDEO_HEIGHT is HEIGHT
+
+ /**
+ * Indexed value of {@link MediaMetadataRetriever#METADATA_KEY_BITRATE}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String BITRATE = "bitrate";
+
+ // TIMED_TEXT_LANGUAGES is ignored
+ // IS_DRM is ignored
+ // LOCATION is LATITUDE and LONGITUDE
+ // VIDEO_ROTATION is ORIENTATION
+
+ /**
+ * Indexed value of
+ * {@link MediaMetadataRetriever#METADATA_KEY_CAPTURE_FRAMERATE}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_FLOAT, readOnly = true)
+ public static final String CAPTURE_FRAMERATE = "capture_framerate";
+
+ // HAS_IMAGE is ignored
+ // IMAGE_COUNT is ignored
+ // IMAGE_PRIMARY is ignored
+ // IMAGE_WIDTH is WIDTH
+ // IMAGE_HEIGHT is HEIGHT
+ // IMAGE_ROTATION is ORIENTATION
+ // VIDEO_FRAME_COUNT is ignored
+ // EXIF_OFFSET is ignored
+ // EXIF_LENGTH is ignored
+ // COLOR_STANDARD is ignored
+ // COLOR_TRANSFER is ignored
+ // COLOR_RANGE is ignored
+ // SAMPLERATE is ignored
+ // BITS_PER_SAMPLE is ignored
}
/**
@@ -1331,10 +1448,7 @@
@Column(Cursor.FIELD_TYPE_STRING)
public static final String MIME_TYPE = "mime_type";
- /**
- * The title of the media item.
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String TITLE = "title";
/**
@@ -1589,12 +1703,6 @@
*/
public interface ImageColumns extends MediaColumns {
/**
- * The description of the image
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
- public static final String DESCRIPTION = "description";
-
- /**
* The picasa id of the image
*
* @deprecated this value was only relevant for images hosted on
@@ -1656,6 +1764,34 @@
public static final String BUCKET_DISPLAY_NAME = "bucket_display_name";
/** @removed promoted to parent interface */
public static final String GROUP_ID = "group_id";
+
+ /**
+ * Indexed value of {@link ExifInterface#TAG_IMAGE_DESCRIPTION}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String DESCRIPTION = "description";
+
+ /**
+ * Indexed value of {@link ExifInterface#TAG_EXPOSURE_TIME}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String EXPOSURE_TIME = "exposure_time";
+
+ /**
+ * Indexed value of {@link ExifInterface#TAG_F_NUMBER}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ public static final String F_NUMBER = "f_number";
+
+ /**
+ * Indexed value of {@link ExifInterface#TAG_ISO_SPEED_RATINGS}
+ * extracted from this media item.
+ */
+ @Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
+ public static final String ISO = "iso";
}
public static final class Media implements ImageColumns {
@@ -1904,6 +2040,10 @@
* generated. Callers are responsible for their own in-memory
* caching of returned values.
*
+ * As of {@link android.os.Build.VERSION_CODES#Q}, this output
+ * of the thumbnail has correct rotation, don't need to rotate
+ * it again.
+ *
* @param imageId the image item to obtain a thumbnail for.
* @param kind optimal thumbnail size desired.
* @return decoded thumbnail, or {@code null} if problem was
@@ -1946,6 +2086,10 @@
* generated. Callers are responsible for their own in-memory
* caching of returned values.
*
+ * As of {@link android.os.Build.VERSION_CODES#Q}, this output
+ * of the thumbnail has correct rotation, don't need to rotate
+ * it again.
+ *
* @param imageId the image item to obtain a thumbnail for.
* @param kind optimal thumbnail size desired.
* @return decoded thumbnail, or {@code null} if problem was
@@ -2000,6 +2144,9 @@
* {@link ContentResolver#openFileDescriptor(Uri, String)} to gain
* access.
*
+ * As of {@link android.os.Build.VERSION_CODES#Q}, this thumbnail
+ * has correct rotation, don't need to rotate it again.
+ *
* @deprecated Apps may not have filesystem permissions to directly
* access this path. Instead of trying to open this path
* directly, apps should use
@@ -2093,10 +2240,7 @@
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
public static final String ARTIST_ID = "artist_id";
- /**
- * The artist who created the audio file, if any
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String ARTIST = "artist";
/**
@@ -2107,14 +2251,6 @@
public static final String ALBUM_ARTIST = "album_artist";
/**
- * Whether the song is part of a compilation
- * @hide
- */
- @Deprecated
- // @Column(Cursor.FIELD_TYPE_STRING)
- public static final String COMPILATION = "compilation";
-
- /**
* A non human readable key calculated from the ARTIST, used for
* searching, sorting and grouping
*
@@ -2131,10 +2267,7 @@
@Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
public static final String ARTIST_KEY = "artist_key";
- /**
- * The composer of the audio file, if any
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String COMPOSER = "composer";
/**
@@ -2143,10 +2276,7 @@
@Column(value = Cursor.FIELD_TYPE_INTEGER, readOnly = true)
public static final String ALBUM_ID = "album_id";
- /**
- * The album the audio file is from, if any
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String ALBUM = "album";
/**
@@ -2973,23 +3103,11 @@
public interface VideoColumns extends MediaColumns {
/** @removed promoted to parent interface */
public static final String DURATION = "duration";
-
- /**
- * The artist who created the video file, if any
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String ARTIST = "artist";
-
- /**
- * The album the video file is from, if any
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String ALBUM = "album";
-
- /**
- * The resolution of the video file, formatted as "XxY"
- */
- @Column(value = Cursor.FIELD_TYPE_STRING, readOnly = true)
+ /** @removed promoted to parent interface */
public static final String RESOLUTION = "resolution";
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5331cb40..381d492 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -78,6 +78,7 @@
import android.view.Display;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
import com.android.internal.widget.ILockSettings;
import java.io.IOException;
@@ -2507,7 +2508,7 @@
boolean prefixCached = false;
int size = mValues.size();
for (int i = 0; i < size; ++i) {
- if (mValues.keyAt(i).startsWith(prefix + "/")) {
+ if (mValues.keyAt(i).startsWith(prefix)) {
prefixCached = true;
break;
}
@@ -2522,7 +2523,7 @@
} else {
for (int i = 0; i < size; ++i) {
String key = mValues.keyAt(i);
- if (key.startsWith(prefix + "/")) {
+ if (key.startsWith(prefix)) {
keyValues.put(key, mValues.get(key));
}
}
@@ -10653,6 +10654,7 @@
* @hide
* @see com.android.server.AppOpsService.Constants
*/
+ @TestApi
public static final String APP_OPS_CONSTANTS = "app_ops_constants";
/**
@@ -13685,10 +13687,10 @@
}
/**
- * Look up a list of names in the database, based on a common prefix.
+ * Look up a list of names in the database, within the specified namespace.
*
* @param resolver to access the database with
- * @param prefix to apply to all of the names which will be fetched
+ * @param namespace to which the names belong
* @param names to look up in the table
* @return a non null, but possibly empty, map from name to value for any of the names that
* were found during lookup.
@@ -13697,16 +13699,17 @@
*/
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
static Map<String, String> getStrings(@NonNull ContentResolver resolver,
- @NonNull String prefix, @NonNull List<String> names) {
- List<String> concatenatedNames = new ArrayList<>(names.size());
+ @NonNull String namespace, @NonNull List<String> names) {
+ List<String> compositeNames = new ArrayList<>(names.size());
for (String name : names) {
- concatenatedNames.add(prefix + "/" + name);
+ compositeNames.add(createCompositeName(namespace, name));
}
+ String prefix = createPrefix(namespace);
ArrayMap<String, String> rawKeyValues = sNameValueCache.getStringsForPrefix(
- resolver, prefix, concatenatedNames);
+ resolver, prefix, compositeNames);
int size = rawKeyValues.size();
- int substringLength = prefix.length() + 1;
+ int substringLength = prefix.length();
ArrayMap<String, String> keyValues = new ArrayMap<>(size);
for (int i = 0; i < size; ++i) {
keyValues.put(rawKeyValues.keyAt(i).substring(substringLength),
@@ -13716,7 +13719,7 @@
}
/**
- * Store a name/value pair into the database.
+ * Store a name/value pair into the database within the specified namespace.
* <p>
* Also the method takes an argument whether to make the value the default for this setting.
* If the system already specified a default value, then the one passed in here will
@@ -13724,6 +13727,7 @@
* </p>
*
* @param resolver to access the database with.
+ * @param namespace to store the name/value pair in.
* @param name to store.
* @param value to associate with the name.
* @param makeDefault whether to make the value the default one.
@@ -13734,10 +13738,10 @@
* @hide
*/
@RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG)
- static boolean putString(@NonNull ContentResolver resolver, @NonNull String name,
- @Nullable String value, boolean makeDefault) {
- return sNameValueCache.putStringForUser(resolver, name, value, null, makeDefault,
- resolver.getUserId());
+ static boolean putString(@NonNull ContentResolver resolver, @NonNull String namespace,
+ @NonNull String name, @Nullable String value, boolean makeDefault) {
+ return sNameValueCache.putStringForUser(resolver, createCompositeName(namespace, name),
+ value, null, makeDefault, resolver.getUserId());
}
/**
@@ -13748,21 +13752,21 @@
*
* @param resolver Handle to the content resolver.
* @param resetMode The reset mode to use.
- * @param prefix Optionally, to limit which which pairs are reset.
+ * @param namespace Optionally, to limit which which namespace is reset.
*
- * @see #putString(ContentResolver, String, String, boolean)
+ * @see #putString(ContentResolver, String, String, String, boolean)
*
* @hide
*/
@RequiresPermission(Manifest.permission.WRITE_DEVICE_CONFIG)
static void resetToDefaults(@NonNull ContentResolver resolver, @ResetMode int resetMode,
- @Nullable String prefix) {
+ @Nullable String namespace) {
try {
Bundle arg = new Bundle();
arg.putInt(CALL_METHOD_USER_KEY, resolver.getUserId());
arg.putInt(CALL_METHOD_RESET_MODE_KEY, resetMode);
- if (prefix != null) {
- arg.putString(Settings.CALL_METHOD_PREFIX_KEY, prefix);
+ if (namespace != null) {
+ arg.putString(Settings.CALL_METHOD_PREFIX_KEY, createPrefix(namespace));
}
IContentProvider cp = sProviderHolder.getProvider(resolver);
cp.call(resolver.getPackageName(), resolver.getFeatureId(),
@@ -13771,6 +13775,17 @@
Log.w(TAG, "Can't reset to defaults for " + DeviceConfig.CONTENT_URI, e);
}
}
+
+ private static String createCompositeName(@NonNull String namespace, @NonNull String name) {
+ Preconditions.checkNotNull(namespace);
+ Preconditions.checkNotNull(name);
+ return createPrefix(namespace) + name;
+ }
+
+ private static String createPrefix(@NonNull String namespace) {
+ Preconditions.checkNotNull(namespace);
+ return namespace + "/";
+ }
}
/**
diff --git a/core/java/android/provider/SettingsStringUtil.java b/core/java/android/provider/SettingsStringUtil.java
index a3dc947..9e495dd 100644
--- a/core/java/android/provider/SettingsStringUtil.java
+++ b/core/java/android/provider/SettingsStringUtil.java
@@ -126,7 +126,7 @@
@Override
protected String itemToString(ComponentName item) {
- return item.flattenToString();
+ return item != null ? item.flattenToString() : "null";
}
public static String add(String delimitedElements, ComponentName element) {
diff --git a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
new file mode 100644
index 0000000..de90b94
--- /dev/null
+++ b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
@@ -0,0 +1,389 @@
+/*
+ * 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.service.carrier;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+
+/**
+ * Provides basic structure for platform to connect to the carrier messaging service.
+ * <p>
+ * <code>
+ * CarrierMessagingServiceWrapper carrierMessagingServiceWrapper =
+ * new CarrierMessagingServiceWrapperImpl();
+ * if (carrierMessagingServiceWrapper.bindToCarrierMessagingService(context, carrierPackageName)) {
+ * // wait for onServiceReady callback
+ * } else {
+ * // Unable to bind: handle error.
+ * }
+ * </code>
+ * <p> Upon completion {@link #disposeConnection} should be called to unbind the
+ * CarrierMessagingService.
+ * @hide
+ */
+@SystemApi
+public abstract class CarrierMessagingServiceWrapper {
+ // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
+ // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
+ private volatile CarrierMessagingServiceConnection mCarrierMessagingServiceConnection;
+
+ private volatile ICarrierMessagingService mICarrierMessagingService;
+
+ /**
+ * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
+ * should be called exactly once.
+ *
+ * @param context the context
+ * @param carrierPackageName the carrier package name
+ * @return true upon successfully binding to a carrier messaging service, false otherwise
+ * @hide
+ */
+ @SystemApi
+ public boolean bindToCarrierMessagingService(@NonNull Context context,
+ @NonNull String carrierPackageName) {
+ Preconditions.checkState(mCarrierMessagingServiceConnection == null);
+
+ Intent intent = new Intent(CarrierMessagingService.SERVICE_INTERFACE);
+ intent.setPackage(carrierPackageName);
+ mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
+ return context.bindService(intent, mCarrierMessagingServiceConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ /**
+ * Unbinds the carrier messaging service. This method should be called exactly once.
+ *
+ * @param context the context
+ * @hide
+ */
+ @SystemApi
+ public void disposeConnection(@NonNull Context context) {
+ Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
+ context.unbindService(mCarrierMessagingServiceConnection);
+ mCarrierMessagingServiceConnection = null;
+ }
+
+ /**
+ * Implemented by subclasses to use the carrier messaging service once it is ready.
+ * @hide
+ */
+ @SystemApi
+ public abstract void onServiceReady();
+
+ /**
+ * Called when connection with service is established.
+ *
+ * @param carrierMessagingService the carrier messaing service interface
+ */
+ private void onServiceReady(ICarrierMessagingService carrierMessagingService) {
+ mICarrierMessagingService = carrierMessagingService;
+ onServiceReady();
+ }
+
+ /**
+ * Request filtering an incoming SMS message.
+ * The service will call callback.onFilterComplete with the filtering result.
+ *
+ * @param pdu the PDUs of the message
+ * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
+ * @param destPort the destination port of a data SMS. It will be -1 for text SMS
+ * @param subId SMS subscription ID of the SIM
+ * @param callback the callback to notify upon completion
+ * @hide
+ */
+ @SystemApi
+ public void filterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort,
+ int subId, @NonNull final CarrierMessagingCallbackWrapper callback) {
+ if (mICarrierMessagingService != null) {
+ try {
+ mICarrierMessagingService.filterSms(pdu, format, destPort, subId,
+ new CarrierMessagingCallbackWrapperInternal(callback));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Request sending a new text SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+ * status.
+ *
+ * @param text the text to send
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param sendSmsFlag flag for sending SMS
+ * @param callback the callback to notify upon completion
+ * @hide
+ */
+ @SystemApi
+ public void sendTextSms(@NonNull String text, int subId, @NonNull String destAddress,
+ int sendSmsFlag, @NonNull final CarrierMessagingCallbackWrapper callback) {
+ if (mICarrierMessagingService != null) {
+ try {
+ mICarrierMessagingService.sendTextSms(text, subId, destAddress, sendSmsFlag,
+ new CarrierMessagingCallbackWrapperInternal(callback));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Request sending a new data SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+ * status.
+ *
+ * @param data the data to send
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param destPort port number of the recipient of the message
+ * @param sendSmsFlag flag for sending SMS
+ * @param callback the callback to notify upon completion
+ * @hide
+ */
+ @SystemApi
+ public void sendDataSms(@NonNull byte[] data, int subId, @NonNull String destAddress,
+ int destPort, int sendSmsFlag,
+ @NonNull final CarrierMessagingCallbackWrapper callback) {
+ if (mICarrierMessagingService != null) {
+ try {
+ mICarrierMessagingService.sendDataSms(data, subId, destAddress, destPort,
+ sendSmsFlag, new CarrierMessagingCallbackWrapperInternal(callback));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Request sending a new multi-part text SMS from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendMultipartSmsComplete}
+ * with the send status.
+ *
+ * @param parts the parts of the multi-part text SMS to send
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param sendSmsFlag flag for sending SMS
+ * @param callback the callback to notify upon completion
+ * @hide
+ */
+ @SystemApi
+ public void sendMultipartTextSms(@NonNull List<String> parts, int subId,
+ @NonNull String destAddress, int sendSmsFlag,
+ @NonNull final CarrierMessagingCallbackWrapper callback) {
+ if (mICarrierMessagingService != null) {
+ try {
+ mICarrierMessagingService.sendMultipartTextSms(parts, subId, destAddress,
+ sendSmsFlag, new CarrierMessagingCallbackWrapperInternal(callback));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Request sending a new MMS PDU from the device.
+ * The service will call {@link ICarrierMessagingCallback#onSendMmsComplete} with the send
+ * status.
+ *
+ * @param pduUri the content provider URI of the PDU to send
+ * @param subId SMS subscription ID of the SIM
+ * @param location the optional URI to send this MMS PDU. If this is {code null},
+ * the PDU should be sent to the default MMSC URL.
+ * @param callback the callback to notify upon completion
+ * @hide
+ */
+ @SystemApi
+ public void sendMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+ @NonNull final CarrierMessagingCallbackWrapper callback) {
+ if (mICarrierMessagingService != null) {
+ try {
+ mICarrierMessagingService.sendMms(pduUri, subId, location,
+ new CarrierMessagingCallbackWrapperInternal(callback));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * Request downloading a new MMS.
+ * The service will call {@link ICarrierMessagingCallback#onDownloadMmsComplete} with the
+ * download status.
+ *
+ * @param pduUri the content provider URI of the PDU to be downloaded.
+ * @param subId SMS subscription ID of the SIM
+ * @param location the URI of the message to be downloaded.
+ * @param callback the callback to notify upon completion
+ * @hide
+ */
+ @SystemApi
+ public void downloadMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+ @NonNull final CarrierMessagingCallbackWrapper callback) {
+ if (mICarrierMessagingService != null) {
+ try {
+ mICarrierMessagingService.downloadMms(pduUri, subId, location,
+ new CarrierMessagingCallbackWrapperInternal(callback));
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ /**
+ * A basic {@link ServiceConnection}.
+ */
+ private final class CarrierMessagingServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ onServiceReady(ICarrierMessagingService.Stub.asInterface(service));
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+ }
+
+ /**
+ * Callback wrapper used for response to requests exposed by
+ * {@link CarrierMessagingServiceWrapper}.
+ * @hide
+ */
+ @SystemApi
+ public abstract static class CarrierMessagingCallbackWrapper {
+
+ /**
+ * Response callback for {@link CarrierMessagingServiceWrapper#filterSms}.
+ * @param result a bitmask integer to indicate how the incoming text SMS should be handled
+ * by the platform. Bits set can be
+ * {@link CarrierMessagingService#RECEIVE_OPTIONS_DROP} and
+ * {@link CarrierMessagingService#
+ * RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE}.
+ * {@see CarrierMessagingService#onReceiveTextSms}.
+ * @hide
+ */
+ @SystemApi
+ public void onFilterComplete(int result) {
+
+ }
+
+ /**
+ * Response callback for {@link CarrierMessagingServiceWrapper#sendTextSms} and
+ * {@link CarrierMessagingServiceWrapper#sendDataSms}.
+ * @param result send status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
+ * {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
+ * and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
+ * @param messageRef message reference of the just-sent message. This field is applicable
+ * only if result is {@link CarrierMessagingService#SEND_STATUS_OK}.
+ * @hide
+ */
+ @SystemApi
+ public void onSendSmsComplete(int result, int messageRef) {
+
+ }
+
+ /**
+ * Response callback for {@link CarrierMessagingServiceWrapper#sendMultipartTextSms}.
+ * @param result send status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
+ * {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
+ * and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
+ * @param messageRefs an array of message references, one for each part of the
+ * multipart SMS. This field is applicable only if result is
+ * {@link CarrierMessagingService#SEND_STATUS_OK}.
+ * @hide
+ */
+ @SystemApi
+ public void onSendMultipartSmsComplete(int result, @Nullable int[] messageRefs) {
+
+ }
+
+ /**
+ * Response callback for {@link CarrierMessagingServiceWrapper#sendMms}.
+ * @param result send status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
+ * {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
+ * and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
+ * @param sendConfPdu a possibly {code null} SendConf PDU, which confirms that the message
+ * was sent. sendConfPdu is ignored if the {@code result} is not
+ * {@link CarrierMessagingService#SEND_STATUS_OK}.
+ * @hide
+ */
+ @SystemApi
+ public void onSendMmsComplete(int result, @Nullable byte[] sendConfPdu) {
+
+ }
+
+ /**
+ * Response callback for {@link CarrierMessagingServiceWrapper#downloadMms}.
+ * @param result download status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
+ * {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
+ * and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
+ * @hide
+ */
+ @SystemApi
+ public void onDownloadMmsComplete(int result) {
+
+ }
+ }
+
+ private final class CarrierMessagingCallbackWrapperInternal
+ extends ICarrierMessagingCallback.Stub {
+ CarrierMessagingCallbackWrapper mCarrierMessagingCallbackWrapper;
+
+ CarrierMessagingCallbackWrapperInternal(CarrierMessagingCallbackWrapper callback) {
+ mCarrierMessagingCallbackWrapper = callback;
+ }
+
+ @Override
+ public void onFilterComplete(int result) throws RemoteException {
+ mCarrierMessagingCallbackWrapper.onFilterComplete(result);
+ }
+
+ @Override
+ public void onSendSmsComplete(int result, int messageRef) throws RemoteException {
+ mCarrierMessagingCallbackWrapper.onSendSmsComplete(result, messageRef);
+ }
+
+ @Override
+ public void onSendMultipartSmsComplete(int result, int[] messageRefs)
+ throws RemoteException {
+ mCarrierMessagingCallbackWrapper.onSendMultipartSmsComplete(result, messageRefs);
+ }
+
+ @Override
+ public void onSendMmsComplete(int result, byte[] sendConfPdu) throws RemoteException {
+ mCarrierMessagingCallbackWrapper.onSendMmsComplete(result, sendConfPdu);
+ }
+
+ @Override
+ public void onDownloadMmsComplete(int result) throws RemoteException {
+ mCarrierMessagingCallbackWrapper.onDownloadMmsComplete(result);
+ }
+ }
+}
diff --git a/core/java/android/util/StatsEvent.java b/core/java/android/util/StatsEvent.java
index 91a5ec0..8d9607f 100644
--- a/core/java/android/util/StatsEvent.java
+++ b/core/java/android/util/StatsEvent.java
@@ -20,312 +20,540 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.os.SystemClock;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
/**
* StatsEvent builds and stores the buffer sent over the statsd socket.
* This class defines and encapsulates the socket protocol.
+ *
+ * <p>Usage:</p>
+ * <pre>
+ * StatsEvent statsEvent = StatsEvent.newBuilder()
+ * .setAtomId(atomId)
+ * .writeBoolean(false)
+ * .writeString("annotated String field")
+ * .addBooleanAnnotation(annotationId, true)
+ * .build();
+ *
+ * StatsLog.write(statsEvent);
+ * </pre>
* @hide
**/
-public final class StatsEvent implements AutoCloseable {
- private static final int POS_NUM_ELEMENTS = 1;
- private static final int POS_TIMESTAMP = POS_NUM_ELEMENTS + 1;
-
+public final class StatsEvent {
private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;
- // Max payload size is 4 KB less 4 bytes which are reserved for statsEventTag.
+ // Max payload size is 4 bytes less as 4 bytes are reserved for statsEventTag.
// See android_util_StatsLog.cpp.
- private static final int MAX_EVENT_PAYLOAD = LOGGER_ENTRY_MAX_PAYLOAD - 4;
+ private static final int MAX_PAYLOAD_SIZE = LOGGER_ENTRY_MAX_PAYLOAD - 4;
- private static final byte INT_TYPE = 0;
- private static final byte LONG_TYPE = 1;
- private static final byte STRING_TYPE = 2;
- private static final byte LIST_TYPE = 3;
- private static final byte FLOAT_TYPE = 4;
+ private final Buffer mBuffer;
+ private final int mNumBytes;
- private static final int INT_TYPE_SIZE = 5;
- private static final int FLOAT_TYPE_SIZE = 5;
- private static final int LONG_TYPE_SIZE = 9;
-
- private static final int STRING_TYPE_OVERHEAD = 5;
- private static final int LIST_TYPE_OVERHEAD = 2;
-
- public static final int SUCCESS = 0;
- public static final int ERROR_BUFFER_LIMIT_EXCEEDED = -1;
- public static final int ERROR_NO_TIMESTAMP = -2;
- public static final int ERROR_TIMESTAMP_ALREADY_WRITTEN = -3;
- public static final int ERROR_NO_ATOM_ID = -4;
- public static final int ERROR_ATOM_ID_ALREADY_WRITTEN = -5;
- public static final int ERROR_UID_TAG_COUNT_MISMATCH = -6;
-
- private static Object sLock = new Object();
-
- @GuardedBy("sLock")
- private static StatsEvent sPool;
-
- private final byte[] mBuffer = new byte[MAX_EVENT_PAYLOAD];
- private int mPos;
- private int mNumElements;
- private int mAtomId;
-
- private StatsEvent() {
- // Write LIST_TYPE to buffer
- mBuffer[0] = LIST_TYPE;
- reset();
- }
-
- private void reset() {
- // Reset state.
- mPos = POS_TIMESTAMP;
- mNumElements = 0;
- mAtomId = 0;
+ private StatsEvent(@NonNull final Buffer buffer, final int numBytes) {
+ mBuffer = buffer;
+ mNumBytes = numBytes;
}
/**
- * Returns a StatsEvent object from the pool.
+ * Returns a new StatsEvent.Builder for building StatsEvent object.
**/
@NonNull
- public static StatsEvent obtain() {
- final StatsEvent statsEvent;
- synchronized (sLock) {
- statsEvent = null == sPool ? new StatsEvent() : sPool;
- sPool = null;
- }
- statsEvent.reset();
- return statsEvent;
+ public StatsEvent.Builder newBuilder() {
+ return new StatsEvent.Builder(Buffer.obtain());
}
- @Override
- public void close() {
- synchronized (sLock) {
- if (null == sPool) {
- sPool = this;
- }
- }
+ @NonNull
+ byte[] getBytes() {
+ return mBuffer.getBytes();
+ }
+
+ int getNumBytes() {
+ return mNumBytes;
+ }
+
+ void release() {
+ mBuffer.release();
}
/**
- * Writes the event timestamp to the buffer.
+ * Builder for constructing a StatsEvent object.
+ *
+ * <p>This class defines and encapsulates the socket encoding for the buffer.
+ * The write methods must be called in the same order as the order of fields in the
+ * atom definition.</p>
+ *
+ * <p>setAtomId() can be called anytime before build().</p>
+ *
+ * <p>Example:</p>
+ * <pre>
+ * // Atom definition.
+ * message MyAtom {
+ * optional int32 field1 = 1;
+ * optional int64 field2 = 2;
+ * optional string field3 = 3 [(annotation1) = true];
+ * }
+ *
+ * // StatsEvent construction.
+ * StatsEvent.newBuilder()
+ * StatsEvent statsEvent = StatsEvent.newBuilder()
+ * .setAtomId(atomId)
+ * .writeInt(3) // field1
+ * .writeLong(8L) // field2
+ * .writeString("foo") // field 3
+ * .addBooleanAnnotation(annotation1Id, true)
+ * .build();
+ * </pre>
+ * @hide
**/
- public int writeTimestampNs(final long timestampNs) {
- if (hasTimestamp()) {
- return ERROR_TIMESTAMP_ALREADY_WRITTEN;
- }
- return writeLong(timestampNs);
- }
+ public static final class Builder {
+ // Type Ids.
+ private static final byte TYPE_INT = 0x00;
+ private static final byte TYPE_LONG = 0x01;
+ private static final byte TYPE_STRING = 0x02;
+ private static final byte TYPE_LIST = 0x03;
+ private static final byte TYPE_FLOAT = 0x04;
+ private static final byte TYPE_BOOLEAN = 0x05;
+ private static final byte TYPE_OBJECT = 0x06;
+ private static final byte TYPE_BYTE_ARRAY = 0x07;
+ private static final byte TYPE_ATTRIBUTION_CHAIN = 0x08;
+ private static final byte TYPE_ERRORS = 0x0F;
- private boolean hasTimestamp() {
- return mPos > POS_TIMESTAMP;
- }
+ // Error flags.
+ private static final int ERROR_NO_TIMESTAMP = 0x1;
+ private static final int ERROR_NO_ATOM_ID = 0x2;
+ private static final int ERROR_OVERFLOW = 0x4;
+ private static final int ERROR_ATTRIBUTION_CHAIN_TOO_LONG = 0x8;
+ private static final int ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD = 0x10;
+ private static final int ERROR_INVALID_ANNOTATION_ID = 0x20;
+ private static final int ERROR_ANNOTATION_ID_TOO_LARGE = 0x40;
+ private static final int ERROR_TOO_MANY_ANNOTATIONS = 0x80;
+ private static final int ERROR_TOO_MANY_FIELDS = 0x100;
+ private static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x200;
- private boolean hasAtomId() {
- return mAtomId != 0;
- }
+ // Size limits.
+ private static final int MAX_ANNOTATION_COUNT = 15;
+ private static final int MAX_ATTRIBUTION_NODES = 127;
+ private static final int MAX_NUM_ELEMENTS = 127;
- /**
- * Writes the atom id to the buffer.
- **/
- public int writeAtomId(final int atomId) {
- if (!hasTimestamp()) {
- return ERROR_NO_TIMESTAMP;
- } else if (hasAtomId()) {
- return ERROR_ATOM_ID_ALREADY_WRITTEN;
+ // Fixed positions.
+ private static final int POS_NUM_ELEMENTS = 1;
+ private static final int POS_TIMESTAMP_NS = POS_NUM_ELEMENTS + Byte.BYTES;
+ private static final int POS_ATOM_ID = POS_TIMESTAMP_NS + Byte.BYTES + Long.BYTES;
+
+ private final Buffer mBuffer;
+ private long mTimestampNs;
+ private int mAtomId;
+ private byte mCurrentAnnotationCount;
+ private int mPos;
+ private int mPosLastField;
+ private byte mLastType;
+ private int mNumElements;
+ private int mErrorMask;
+
+ private Builder(final Buffer buffer) {
+ mBuffer = buffer;
+ mCurrentAnnotationCount = 0;
+ mAtomId = 0;
+ mTimestampNs = SystemClock.elapsedRealtimeNanos();
+ mNumElements = 0;
+
+ // Set mPos to 0 for writing TYPE_OBJECT at 0th position.
+ mPos = 0;
+ writeTypeId(TYPE_OBJECT);
+
+ // Set mPos to after atom id's location in the buffer.
+ // First 2 elements in the buffer are event timestamp followed by the atom id.
+ mPos = POS_ATOM_ID + Byte.BYTES + Integer.BYTES;
+ mPosLastField = 0;
+ mLastType = 0;
}
- final int writeResult = writeInt(atomId);
- if (SUCCESS == writeResult) {
+ /**
+ * Sets the atom id for this StatsEvent.
+ **/
+ @NonNull
+ public Builder setAtomId(final int atomId) {
mAtomId = atomId;
- }
- return writeResult;
- }
-
- /**
- * Appends the given int to the StatsEvent buffer.
- **/
- public int writeInt(final int value) {
- if (!hasTimestamp()) {
- return ERROR_NO_TIMESTAMP;
- } else if (!hasAtomId()) {
- return ERROR_NO_ATOM_ID;
- } else if (mPos + INT_TYPE_SIZE > MAX_EVENT_PAYLOAD) {
- return ERROR_BUFFER_LIMIT_EXCEEDED;
+ return this;
}
- mBuffer[mPos] = INT_TYPE;
- copyInt(mBuffer, mPos + 1, value);
- mPos += INT_TYPE_SIZE;
- mNumElements++;
- return SUCCESS;
- }
-
- /**
- * Appends the given long to the StatsEvent buffer.
- **/
- public int writeLong(final long value) {
- if (!hasTimestamp()) {
- return ERROR_NO_TIMESTAMP;
- } else if (!hasAtomId()) {
- return ERROR_NO_ATOM_ID;
- } else if (mPos + LONG_TYPE_SIZE > MAX_EVENT_PAYLOAD) {
- return ERROR_BUFFER_LIMIT_EXCEEDED;
+ /**
+ * Sets the timestamp in nanos for this StatsEvent.
+ **/
+ @VisibleForTesting
+ @NonNull
+ public Builder setTimestampNs(final long timestampNs) {
+ mTimestampNs = timestampNs;
+ return this;
}
- mBuffer[mPos] = LONG_TYPE;
- copyLong(mBuffer, mPos + 1, value);
- mPos += LONG_TYPE_SIZE;
- mNumElements++;
- return SUCCESS;
- }
-
- /**
- * Appends the given float to the StatsEvent buffer.
- **/
- public int writeFloat(final float value) {
- if (!hasTimestamp()) {
- return ERROR_NO_TIMESTAMP;
- } else if (!hasAtomId()) {
- return ERROR_NO_ATOM_ID;
- } else if (mPos + FLOAT_TYPE_SIZE > MAX_EVENT_PAYLOAD) {
- return ERROR_BUFFER_LIMIT_EXCEEDED;
+ /**
+ * Write a boolean field to this StatsEvent.
+ **/
+ @NonNull
+ public Builder writeBoolean(final boolean value) {
+ // Write boolean typeId byte followed by boolean byte representation.
+ writeTypeId(TYPE_BOOLEAN);
+ mPos += mBuffer.putBoolean(mPos, value);
+ mNumElements++;
+ return this;
}
- mBuffer[mPos] = FLOAT_TYPE;
- copyInt(mBuffer, mPos + 1, Float.floatToIntBits(value));
- mPos += FLOAT_TYPE_SIZE;
- mNumElements++;
- return SUCCESS;
- }
-
- /**
- * Appends the given boolean to the StatsEvent buffer.
- **/
- public int writeBoolean(final boolean value) {
- return writeInt(value ? 1 : 0);
- }
-
- /**
- * Appends the given byte array to the StatsEvent buffer.
- **/
- public int writeByteArray(@NonNull final byte[] value) {
- if (!hasTimestamp()) {
- return ERROR_NO_TIMESTAMP;
- } else if (!hasAtomId()) {
- return ERROR_NO_ATOM_ID;
- } else if (mPos + STRING_TYPE_OVERHEAD + value.length > MAX_EVENT_PAYLOAD) {
- return ERROR_BUFFER_LIMIT_EXCEEDED;
+ /**
+ * Write an integer field to this StatsEvent.
+ **/
+ @NonNull
+ public Builder writeInt(final int value) {
+ // Write integer typeId byte followed by 4-byte representation of value.
+ writeTypeId(TYPE_INT);
+ mPos += mBuffer.putInt(mPos, value);
+ mNumElements++;
+ return this;
}
- mBuffer[mPos] = STRING_TYPE;
- copyInt(mBuffer, mPos + 1, value.length);
- System.arraycopy(value, 0, mBuffer, mPos + STRING_TYPE_OVERHEAD, value.length);
- mPos += STRING_TYPE_OVERHEAD + value.length;
- mNumElements++;
- return SUCCESS;
- }
-
- /**
- * Appends the given String to the StatsEvent buffer.
- **/
- public int writeString(@NonNull final String value) {
- final byte[] valueBytes = stringToBytes(value);
- return writeByteArray(valueBytes);
- }
-
- /**
- * Appends the AttributionNode specified as array of uids and array of tags.
- **/
- public int writeAttributionNode(@NonNull final int[] uids, @NonNull final String[] tags) {
- if (!hasTimestamp()) {
- return ERROR_NO_TIMESTAMP;
- } else if (!hasAtomId()) {
- return ERROR_NO_ATOM_ID;
- } else if (mPos + LIST_TYPE_OVERHEAD > MAX_EVENT_PAYLOAD) {
- return ERROR_BUFFER_LIMIT_EXCEEDED;
+ /**
+ * Write a long field to this StatsEvent.
+ **/
+ @NonNull
+ public Builder writeLong(final long value) {
+ // Write long typeId byte followed by 8-byte representation of value.
+ writeTypeId(TYPE_LONG);
+ mPos += mBuffer.putLong(mPos, value);
+ mNumElements++;
+ return this;
}
- final int numTags = tags.length;
- final int numUids = uids.length;
- if (numTags != numUids) {
- return ERROR_UID_TAG_COUNT_MISMATCH;
+ /**
+ * Write a float field to this StatsEvent.
+ **/
+ @NonNull
+ public Builder writeFloat(final float value) {
+ // Write float typeId byte followed by 4-byte representation of value.
+ writeTypeId(TYPE_FLOAT);
+ mPos += mBuffer.putFloat(mPos, value);
+ mNumElements++;
+ return this;
}
- int pos = mPos;
- mBuffer[pos] = LIST_TYPE;
- mBuffer[pos + 1] = (byte) numTags;
- pos += LIST_TYPE_OVERHEAD;
- for (int i = 0; i < numTags; i++) {
- final byte[] tagBytes = stringToBytes(tags[i]);
+ /**
+ * Write a String field to this StatsEvent.
+ **/
+ @NonNull
+ public Builder writeString(@NonNull final String value) {
+ // Write String typeId byte, followed by 4-byte representation of number of bytes
+ // in the UTF-8 encoding, followed by the actual UTF-8 byte encoding of value.
+ final byte[] valueBytes = stringToBytes(value);
+ writeByteArray(valueBytes, TYPE_STRING);
+ return this;
+ }
- if (pos + LIST_TYPE_OVERHEAD + INT_TYPE_SIZE
- + STRING_TYPE_OVERHEAD + tagBytes.length > MAX_EVENT_PAYLOAD) {
- return ERROR_BUFFER_LIMIT_EXCEEDED;
+ /**
+ * Write a byte array field to this StatsEvent.
+ **/
+ @NonNull
+ public Builder writeByteArray(@NonNull final byte[] value) {
+ // Write byte array typeId byte, followed by 4-byte representation of number of bytes
+ // in value, followed by the actual byte array.
+ writeByteArray(value, TYPE_BYTE_ARRAY);
+ return this;
+ }
+
+ private void writeByteArray(@NonNull final byte[] value, final byte typeId) {
+ writeTypeId(typeId);
+ final int numBytes = value.length;
+ mPos += mBuffer.putInt(mPos, numBytes);
+ mPos += mBuffer.putByteArray(mPos, value);
+ mNumElements++;
+ }
+
+ /**
+ * Write an attribution chain field to this StatsEvent.
+ *
+ * The sizes of uids and tags must be equal. The AttributionNode at position i is
+ * made up of uids[i] and tags[i].
+ *
+ * @param uids array of uids in the attribution nodes.
+ * @param tags array of tags in the attribution nodes.
+ **/
+ @NonNull
+ public Builder writeAttributionNode(
+ @NonNull final int[] uids, @NonNull final String[] tags) {
+ final byte numUids = (byte) uids.length;
+ final byte numTags = (byte) tags.length;
+
+ if (numUids != numTags) {
+ mErrorMask |= ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL;
+ } else if (numUids > MAX_ATTRIBUTION_NODES) {
+ mErrorMask |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
+ } else {
+ // Write attribution chain typeId byte, followed by 1-byte representation of
+ // number of attribution nodes, followed by encoding of each attribution node.
+ writeTypeId(TYPE_ATTRIBUTION_CHAIN);
+ mPos += mBuffer.putByte(mPos, numUids);
+ for (int i = 0; i < numUids; i++) {
+ // Each uid is encoded as 4-byte representation of its int value.
+ mPos += mBuffer.putInt(mPos, uids[i]);
+
+ // Each tag is encoded as 4-byte representation of number of bytes in its
+ // UTF-8 encoding, followed by the actual UTF-8 bytes.
+ final byte[] tagBytes = stringToBytes(tags[i]);
+ mPos += mBuffer.putInt(mPos, tagBytes.length);
+ mPos += mBuffer.putByteArray(mPos, tagBytes);
+ }
+ mNumElements++;
+ }
+ return this;
+ }
+
+ /**
+ * Write a boolean annotation for the last field written.
+ **/
+ @NonNull
+ public Builder addBooleanAnnotation(
+ final byte annotationId, final boolean value) {
+ // Ensure there's a field written to annotate.
+ if (0 == mPosLastField) {
+ mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
+ } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
+ mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
+ } else {
+ mPos += mBuffer.putByte(mPos, annotationId);
+ mPos += mBuffer.putByte(mPos, TYPE_BOOLEAN);
+ mPos += mBuffer.putBoolean(mPos, value);
+ mCurrentAnnotationCount++;
+ writeAnnotationCount();
+ }
+ return this;
+ }
+
+ /**
+ * Write an integer annotation for the last field written.
+ **/
+ @NonNull
+ public Builder addIntAnnotation(final byte annotationId, final int value) {
+ if (0 == mPosLastField) {
+ mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
+ } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
+ mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
+ } else {
+ mPos += mBuffer.putByte(mPos, annotationId);
+ mPos += mBuffer.putByte(mPos, TYPE_INT);
+ mPos += mBuffer.putInt(mPos, value);
+ mCurrentAnnotationCount++;
+ writeAnnotationCount();
+ }
+ return this;
+ }
+
+ /**
+ * Builds a StatsEvent object with values entered in this Builder.
+ **/
+ @NonNull
+ public StatsEvent build() {
+ if (0L == mTimestampNs) {
+ mErrorMask |= ERROR_NO_TIMESTAMP;
+ }
+ if (0 == mAtomId) {
+ mErrorMask |= ERROR_NO_ATOM_ID;
+ }
+ if (mBuffer.hasOverflowed()) {
+ mErrorMask |= ERROR_OVERFLOW;
+ }
+ if (mNumElements > MAX_NUM_ELEMENTS) {
+ mErrorMask |= ERROR_TOO_MANY_FIELDS;
}
- mBuffer[pos] = LIST_TYPE;
- mBuffer[pos + 1] = 2;
- pos += LIST_TYPE_OVERHEAD;
- mBuffer[pos] = INT_TYPE;
- copyInt(mBuffer, pos + 1, uids[i]);
- pos += INT_TYPE_SIZE;
- mBuffer[pos] = STRING_TYPE;
- copyInt(mBuffer, pos + 1, tagBytes.length);
- System.arraycopy(tagBytes, 0, mBuffer, pos + STRING_TYPE_OVERHEAD, tagBytes.length);
- pos += STRING_TYPE_OVERHEAD + tagBytes.length;
+ int size = mPos;
+ mPos = POS_TIMESTAMP_NS;
+ writeLong(mTimestampNs);
+ writeInt(mAtomId);
+ if (0 == mErrorMask) {
+ mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements);
+ } else {
+ mBuffer.putByte(0, TYPE_ERRORS);
+ mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3);
+ mPos += mBuffer.putInt(mPos, mErrorMask);
+ size = mPos;
+ }
+
+ return new StatsEvent(mBuffer, size);
}
- mPos = pos;
- mNumElements++;
- return SUCCESS;
+
+ private void writeTypeId(final byte typeId) {
+ mPosLastField = mPos;
+ mLastType = typeId;
+ mCurrentAnnotationCount = 0;
+ final byte encodedId = (byte) (typeId & 0x0F);
+ mPos += mBuffer.putByte(mPos, encodedId);
+ }
+
+ private void writeAnnotationCount() {
+ // Use first 4 bits for annotation count and last 4 bits for typeId.
+ final byte encodedId = (byte) ((mCurrentAnnotationCount << 4) | (mLastType & 0x0F));
+ mBuffer.putByte(mPosLastField, encodedId);
+ }
+
+ @NonNull
+ private static byte[] stringToBytes(@Nullable final String value) {
+ return (null == value ? "" : value).getBytes(UTF_8);
+ }
}
- /**
- * Returns the byte array containing data in the statsd socket format.
- * @hide
- **/
- @NonNull
- public byte[] getBuffer() {
- // Encode number of elements in the buffer.
- mBuffer[POS_NUM_ELEMENTS] = (byte) mNumElements;
- return mBuffer;
- }
+ private static final class Buffer {
+ private static Object sLock = new Object();
- /**
- * Returns number of bytes used by the buffer.
- * @hide
- **/
- public int size() {
- return mPos;
- }
+ @GuardedBy("sLock")
+ private static Buffer sPool;
- /**
- * Getter for atom id.
- * @hide
- **/
- public int getAtomId() {
- return mAtomId;
- }
+ private final byte[] mBytes = new byte[MAX_PAYLOAD_SIZE];
+ private boolean mOverflow = false;
- @NonNull
- private static byte[] stringToBytes(@Nullable final String value) {
- return (null == value ? "" : value).getBytes(UTF_8);
- }
+ @NonNull
+ private static Buffer obtain() {
+ final Buffer buffer;
+ synchronized (sLock) {
+ buffer = null == sPool ? new Buffer() : sPool;
+ sPool = null;
+ }
+ buffer.reset();
+ return buffer;
+ }
- // Helper methods for copying primitives
- private static void copyInt(@NonNull byte[] buff, int pos, int value) {
- buff[pos] = (byte) (value);
- buff[pos + 1] = (byte) (value >> 8);
- buff[pos + 2] = (byte) (value >> 16);
- buff[pos + 3] = (byte) (value >> 24);
- }
+ private Buffer() {
+ }
- private static void copyLong(@NonNull byte[] buff, int pos, long value) {
- buff[pos] = (byte) (value);
- buff[pos + 1] = (byte) (value >> 8);
- buff[pos + 2] = (byte) (value >> 16);
- buff[pos + 3] = (byte) (value >> 24);
- buff[pos + 4] = (byte) (value >> 32);
- buff[pos + 5] = (byte) (value >> 40);
- buff[pos + 6] = (byte) (value >> 48);
- buff[pos + 7] = (byte) (value >> 56);
+ @NonNull
+ private byte[] getBytes() {
+ return mBytes;
+ }
+
+ private void release() {
+ synchronized (sLock) {
+ if (null == sPool) {
+ sPool = this;
+ }
+ }
+ }
+
+ private void reset() {
+ mOverflow = false;
+ }
+
+ private boolean hasOverflowed() {
+ return mOverflow;
+ }
+
+ /**
+ * Checks for available space in the byte array.
+ *
+ * @param index starting position in the buffer to start the check.
+ * @param numBytes number of bytes to check from index.
+ * @return true if space is available, false otherwise.
+ **/
+ private boolean hasEnoughSpace(final int index, final int numBytes) {
+ final boolean result = index + numBytes < MAX_PAYLOAD_SIZE;
+ if (!result) {
+ mOverflow = true;
+ }
+ return result;
+ }
+
+ /**
+ * Writes a byte into the buffer.
+ *
+ * @param index position in the buffer where the byte is written.
+ * @param value the byte to write.
+ * @return number of bytes written to buffer from this write operation.
+ **/
+ private int putByte(final int index, final byte value) {
+ if (hasEnoughSpace(index, Byte.BYTES)) {
+ mBytes[index] = (byte) (value);
+ return Byte.BYTES;
+ }
+ return 0;
+ }
+
+ /**
+ * Writes a boolean into the buffer.
+ *
+ * @param index position in the buffer where the boolean is written.
+ * @param value the boolean to write.
+ * @return number of bytes written to buffer from this write operation.
+ **/
+ private int putBoolean(final int index, final boolean value) {
+ return putByte(index, (byte) (value ? 1 : 0));
+ }
+
+ /**
+ * Writes an integer into the buffer.
+ *
+ * @param index position in the buffer where the integer is written.
+ * @param value the integer to write.
+ * @return number of bytes written to buffer from this write operation.
+ **/
+ private int putInt(final int index, final int value) {
+ if (hasEnoughSpace(index, Integer.BYTES)) {
+ // Use little endian byte order.
+ mBytes[index] = (byte) (value);
+ mBytes[index + 1] = (byte) (value >> 8);
+ mBytes[index + 2] = (byte) (value >> 16);
+ mBytes[index + 3] = (byte) (value >> 24);
+ return Integer.BYTES;
+ }
+ return 0;
+ }
+
+ /**
+ * Writes a long into the buffer.
+ *
+ * @param index position in the buffer where the long is written.
+ * @param value the long to write.
+ * @return number of bytes written to buffer from this write operation.
+ **/
+ private int putLong(final int index, final long value) {
+ if (hasEnoughSpace(index, Long.BYTES)) {
+ // Use little endian byte order.
+ mBytes[index] = (byte) (value);
+ mBytes[index + 1] = (byte) (value >> 8);
+ mBytes[index + 2] = (byte) (value >> 16);
+ mBytes[index + 3] = (byte) (value >> 24);
+ mBytes[index + 4] = (byte) (value >> 32);
+ mBytes[index + 5] = (byte) (value >> 40);
+ mBytes[index + 6] = (byte) (value >> 48);
+ mBytes[index + 7] = (byte) (value >> 56);
+ return Long.BYTES;
+ }
+ return 0;
+ }
+
+ /**
+ * Writes a float into the buffer.
+ *
+ * @param index position in the buffer where the float is written.
+ * @param value the float to write.
+ * @return number of bytes written to buffer from this write operation.
+ **/
+ private int putFloat(final int index, final float value) {
+ return putInt(index, Float.floatToIntBits(value));
+ }
+
+ /**
+ * Copies a byte array into the buffer.
+ *
+ * @param index position in the buffer where the byte array is copied.
+ * @param value the byte array to copy.
+ * @return number of bytes written to buffer from this write operation.
+ **/
+ private int putByteArray(final int index, @NonNull final byte[] value) {
+ final int numBytes = value.length;
+ if (hasEnoughSpace(index, numBytes)) {
+ System.arraycopy(value, 0, mBytes, index, numBytes);
+ return numBytes;
+ }
+ return 0;
+ }
}
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index ad59ae5..36daa5c 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -945,6 +945,94 @@
return null;
}
+ private static class StreamingPictureCallbackHandler implements AutoCloseable,
+ HardwareRenderer.PictureCapturedCallback, Runnable {
+ private final HardwareRenderer mRenderer;
+ private final Callable<OutputStream> mCallback;
+ private final Executor mExecutor;
+ private final ReentrantLock mLock = new ReentrantLock(false);
+ private final ArrayDeque<byte[]> mQueue = new ArrayDeque<>(3);
+ private final ByteArrayOutputStream mByteStream = new ByteArrayOutputStream();
+ private boolean mStopListening;
+ private Thread mRenderThread;
+
+ private StreamingPictureCallbackHandler(HardwareRenderer renderer,
+ Callable<OutputStream> callback, Executor executor) {
+ mRenderer = renderer;
+ mCallback = callback;
+ mExecutor = executor;
+ mRenderer.setPictureCaptureCallback(this);
+ }
+
+ @Override
+ public void close() {
+ mLock.lock();
+ mStopListening = true;
+ mLock.unlock();
+ mRenderer.setPictureCaptureCallback(null);
+ }
+
+ @Override
+ public void onPictureCaptured(Picture picture) {
+ mLock.lock();
+ if (mStopListening) {
+ mLock.unlock();
+ mRenderer.setPictureCaptureCallback(null);
+ return;
+ }
+ if (mRenderThread == null) {
+ mRenderThread = Thread.currentThread();
+ }
+ boolean needsInvoke = true;
+ if (mQueue.size() == 3) {
+ mQueue.removeLast();
+ needsInvoke = false;
+ }
+ picture.writeToStream(mByteStream);
+ mQueue.add(mByteStream.toByteArray());
+ mByteStream.reset();
+ mLock.unlock();
+
+ if (needsInvoke) {
+ mExecutor.execute(this);
+ }
+ }
+
+ @Override
+ public void run() {
+ mLock.lock();
+ final byte[] picture = mQueue.poll();
+ final boolean isStopped = mStopListening;
+ mLock.unlock();
+ if (Thread.currentThread() == mRenderThread) {
+ close();
+ throw new IllegalStateException(
+ "ViewDebug#startRenderingCommandsCapture must be given an executor that "
+ + "invokes asynchronously");
+ }
+ if (isStopped) {
+ return;
+ }
+ OutputStream stream = null;
+ try {
+ stream = mCallback.call();
+ } catch (Exception ex) {
+ Log.w("ViewDebug", "Aborting rendering commands capture "
+ + "because callback threw exception", ex);
+ }
+ if (stream != null) {
+ try {
+ stream.write(picture);
+ } catch (IOException ex) {
+ Log.w("ViewDebug", "Aborting rendering commands capture "
+ + "due to IOException writing to output stream", ex);
+ }
+ } else {
+ close();
+ }
+ }
+ }
+
/**
* Begins capturing the entire rendering commands for the view tree referenced by the given
* view. The view passed may be any View in the tree as long as it is attached. That is,
@@ -990,18 +1078,7 @@
}
final HardwareRenderer renderer = attachInfo.mThreadedRenderer;
if (renderer != null) {
- return new PictureCallbackHandler(renderer, (picture -> {
- try {
- OutputStream stream = callback.call();
- if (stream != null) {
- picture.writeToStream(stream);
- return true;
- }
- } catch (Exception ex) {
- // fall through
- }
- return false;
- }), executor);
+ return new StreamingPictureCallbackHandler(renderer, callback, executor);
}
return null;
}
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 23d1237..3824c22 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -22,7 +22,10 @@
/**
* Manages the cookies used by an application's {@link WebView} instances.
- * Cookies are manipulated according to RFC2109.
+ * <p>
+ * CookieManager represents cookies as strings in the same format as the
+ * HTTP {@code Cookie} and {@code Set-Cookie} header fields (defined in
+ * <a href="https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03">RFC6265bis</a>).
*/
public abstract class CookieManager {
/**
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 57ce28e..27402a4 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1189,6 +1189,9 @@
}
public boolean performLongClick(boolean handled) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("performLongClick", "handled=%s", handled);
+ }
// Long press in empty space moves cursor and starts the insertion action mode.
if (!handled && !isPositionOnText(mLastDownPositionX, mLastDownPositionY)
&& mInsertionControllerEnabled) {
@@ -1252,6 +1255,10 @@
}
void onFocusChanged(boolean focused, int direction) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("onFocusChanged", "focused=%s", focused);
+ }
+
mShowCursor = SystemClock.uptimeMillis();
ensureEndedBatchEdit();
@@ -1450,12 +1457,22 @@
} else {
mTapState = TAP_STATE_TRIPLE_CLICK;
}
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("updateTapState", "ACTION_DOWN: %s tap detected",
+ (mTapState == TAP_STATE_DOUBLE_TAP ? "double" : "triple"));
+ }
} else {
mTapState = TAP_STATE_FIRST_TAP;
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("updateTapState", "ACTION_DOWN: first tap detected");
+ }
}
}
if (action == MotionEvent.ACTION_UP) {
mLastTouchUpTime = SystemClock.uptimeMillis();
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("updateTapState", "ACTION_UP");
+ }
}
}
@@ -2354,6 +2371,9 @@
}
void onTouchUpEvent(MotionEvent event) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("onTouchUpEvent", null);
+ }
if (getSelectionActionModeHelper().resetSelection(
getTextView().getOffsetForPosition(event.getX(), event.getY()))) {
return;
@@ -2481,6 +2501,9 @@
loadCursorDrawable();
final int left = clampHorizontalPosition(mDrawableForCursor, horizontal);
final int width = mDrawableForCursor.getIntrinsicWidth();
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("updateCursorPosition", "left=%s, top=%s", left, (top - mTempRect.top));
+ }
mDrawableForCursor.setBounds(left, top - mTempRect.top, left + width,
bottom + mTempRect.bottom);
}
@@ -4621,6 +4644,11 @@
}
public void show() {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor(getClass().getSimpleName() + ": HandleView: show()", "offset=%s",
+ getCurrentCursorOffset());
+ }
+
if (isShowing()) return;
getPositionListener().addSubscriber(this, true /* local position may change */);
@@ -4637,6 +4665,11 @@
}
public void hide() {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor(getClass().getSimpleName() + ": HandleView: hide()", "offset=%s",
+ getCurrentCursorOffset());
+ }
+
dismiss();
getPositionListener().removeSubscriber(this);
@@ -5033,6 +5066,11 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor(this.getClass().getSimpleName() + ": HandleView: onTouchEvent",
+ MotionEvent.actionToString(ev.getActionMasked()));
+ }
+
updateFloatingToolbarVisibility(ev);
switch (ev.getActionMasked()) {
@@ -5951,6 +5989,10 @@
distanceSquared < doubleTapSlop * doubleTapSlop;
if (stayedInArea && (isMouse || isPositionOnText(eventX, eventY))) {
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("SelectionModifierCursorController: onTouchEvent",
+ "ACTION_DOWN: select and start drag");
+ }
if (mTapState == TAP_STATE_DOUBLE_TAP) {
selectCurrentWordAndStartDrag();
} else if (mTapState == TAP_STATE_TRIPLE_CLICK) {
@@ -6028,6 +6070,9 @@
break;
case MotionEvent.ACTION_UP:
+ if (TextView.DEBUG_CURSOR) {
+ logCursor("SelectionModifierCursorController: onTouchEvent", "ACTION_UP");
+ }
if (!isDragAcceleratorActive()) {
break;
}
@@ -7119,4 +7164,12 @@
return resolveInfo.loadLabel(mPackageManager);
}
}
+
+ private static void logCursor(String location, @Nullable String msgFormat, Object ... msgArgs) {
+ if (msgFormat == null) {
+ Log.d(TAG, location);
+ } else {
+ Log.d(TAG, location + ": " + String.format(msgFormat, msgArgs));
+ }
+ }
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index 2e95743..d58d858 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -163,7 +163,6 @@
public class ProgressBar extends View {
private static final int MAX_LEVEL = 10000;
- private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;
/** Interpolator used for smooth progress animations. */
private static final DecelerateInterpolator PROGRESS_ANIM_INTERPOLATOR =
@@ -244,8 +243,6 @@
private final ArrayList<RefreshData> mRefreshData = new ArrayList<RefreshData>();
- private AccessibilityEventSender mAccessibilityEventSender;
-
/**
* Create a new progress bar with range 0...100 and initial progress of 0.
* @param context the application environment
@@ -1556,7 +1553,7 @@
void onProgressRefresh(float scale, boolean fromUser, int progress) {
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
- scheduleAccessibilityEventSender();
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
}
}
@@ -2250,9 +2247,6 @@
removeCallbacks(mRefreshProgressRunnable);
mRefreshIsPosted = false;
}
- if (mAccessibilityEventSender != null) {
- removeCallbacks(mAccessibilityEventSender);
- }
// This should come after stopAnimation(), otherwise an invalidate message remains in the
// queue, which can prevent the entire view hierarchy from being GC'ed during a rotation
super.onDetachedFromWindow();
@@ -2285,22 +2279,6 @@
}
}
- /**
- * Schedule a command for sending an accessibility event.
- * </br>
- * Note: A command is used to ensure that accessibility events
- * are sent at most one in a given time frame to save
- * system resources while the progress changes quickly.
- */
- private void scheduleAccessibilityEventSender() {
- if (mAccessibilityEventSender == null) {
- mAccessibilityEventSender = new AccessibilityEventSender();
- } else {
- removeCallbacks(mAccessibilityEventSender);
- }
- postDelayed(mAccessibilityEventSender, TIMEOUT_SEND_ACCESSIBILITY_EVENT);
- }
-
/** @hide */
@Override
protected void encodeProperties(@NonNull ViewHierarchyEncoder stream) {
@@ -2324,15 +2302,6 @@
return isIndeterminate() && getWindowVisibility() == VISIBLE && isShown();
}
- /**
- * Command for sending an accessibility event.
- */
- private class AccessibilityEventSender implements Runnable {
- public void run() {
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
- }
- }
-
private static class ProgressTintInfo {
ColorStateList mIndeterminateTintList;
BlendMode mIndeterminateBlendMode;
diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java
index 562cc4f..217693e 100644
--- a/core/java/android/widget/SimpleMonthView.java
+++ b/core/java/android/widget/SimpleMonthView.java
@@ -28,6 +28,7 @@
import android.graphics.Rect;
import android.graphics.Typeface;
import android.icu.text.DisplayContext;
+import android.icu.text.RelativeDateTimeFormatter;
import android.icu.text.SimpleDateFormat;
import android.icu.util.Calendar;
import android.os.Bundle;
@@ -1095,6 +1096,14 @@
node.setText(getDayText(virtualViewId));
node.setContentDescription(getDayDescription(virtualViewId));
+ if (virtualViewId == mToday) {
+ RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance();
+ node.setStateDescription(fmt.format(RelativeDateTimeFormatter.Direction.THIS,
+ RelativeDateTimeFormatter.AbsoluteUnit.DAY));
+ }
+ if (virtualViewId == mActivatedDay) {
+ node.setSelected(true);
+ }
node.setBoundsInParent(mTempRect);
final boolean isDayEnabled = isDayEnabled(virtualViewId);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 31f5055..90e8ef2 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -345,6 +345,8 @@
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
static final String LOG_TAG = "TextView";
static final boolean DEBUG_EXTRACT = false;
+ static final boolean DEBUG_CURSOR = false;
+
private static final float[] TEMP_POSITION = new float[2];
// Enum for the "typeface" XML parameter.
@@ -10857,6 +10859,10 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
+ if (DEBUG_CURSOR) {
+ logCursor("onTouchEvent", MotionEvent.actionToString(event.getActionMasked()));
+ }
+
final int action = event.getActionMasked();
if (mEditor != null) {
mEditor.onTouchEvent(event);
@@ -10868,6 +10874,9 @@
}
final boolean superResult = super.onTouchEvent(event);
+ if (DEBUG_CURSOR) {
+ logCursor("onTouchEvent", "superResult=%s", superResult);
+ }
/*
* Don't handle the release after a long press, because it will move the selection away from
@@ -10876,7 +10885,9 @@
*/
if (mEditor != null && mEditor.mDiscardNextActionUp && action == MotionEvent.ACTION_UP) {
mEditor.mDiscardNextActionUp = false;
-
+ if (DEBUG_CURSOR) {
+ logCursor("onTouchEvent", "release after long press detected");
+ }
if (mEditor.mIsInsertionActionModeStartPending) {
mEditor.startInsertionActionMode();
mEditor.mIsInsertionActionModeStartPending = false;
@@ -12254,6 +12265,10 @@
@Override
public boolean performLongClick() {
+ if (DEBUG_CURSOR) {
+ logCursor("performLongClick", null);
+ }
+
boolean handled = false;
boolean performedHapticFeedback = false;
@@ -13481,4 +13496,12 @@
TextView.this.spanChange(buf, what, s, -1, e, -1);
}
}
+
+ private static void logCursor(String location, @Nullable String msgFormat, Object ... msgArgs) {
+ if (msgFormat == null) {
+ Log.d(LOG_TAG, location);
+ } else {
+ Log.d(LOG_TAG, location + ": " + String.format(msgFormat, msgArgs));
+ }
+ }
}
diff --git a/core/java/com/android/internal/app/DumpHeapActivity.java b/core/java/com/android/internal/app/DumpHeapActivity.java
deleted file mode 100644
index e04e870..0000000
--- a/core/java/com/android/internal/app/DumpHeapActivity.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.app;
-
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.AlertDialog;
-import android.content.ActivityNotFoundException;
-import android.content.ClipData;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.DebugUtils;
-import android.util.Slog;
-
-/**
- * This activity is displayed when the system has collected a heap dump from
- * a large process and the user has selected to share it.
- */
-public class DumpHeapActivity extends Activity {
- /** The process we are reporting */
- public static final String KEY_PROCESS = "process";
- /** The size limit the process reached */
- public static final String KEY_SIZE = "size";
- /** Whether the user initiated the dump or not. */
- public static final String KEY_IS_USER_INITIATED = "is_user_initiated";
- /** Whether the process is a system process (eg: Android System) or not. */
- public static final String KEY_IS_SYSTEM_PROCESS = "is_system_process";
- /** Optional name of package to directly launch */
- public static final String KEY_DIRECT_LAUNCH = "direct_launch";
-
- // Broadcast action to determine when to delete the current dump heap data.
- public static final String ACTION_DELETE_DUMPHEAP = "com.android.server.am.DELETE_DUMPHEAP";
-
- // Extra for above: delay delete of data, since the user is in the process of sharing it.
- public static final String EXTRA_DELAY_DELETE = "delay_delete";
-
- static final public Uri JAVA_URI = Uri.parse("content://com.android.server.heapdump/java");
-
- String mProcess;
- long mSize;
- AlertDialog mDialog;
- boolean mHandled = false;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- mProcess = getIntent().getStringExtra(KEY_PROCESS);
- mSize = getIntent().getLongExtra(KEY_SIZE, 0);
- final boolean isUserInitiated = getIntent().getBooleanExtra(KEY_IS_USER_INITIATED, false);
- final boolean isSystemProcess = getIntent().getBooleanExtra(KEY_IS_SYSTEM_PROCESS, false);
-
- String directLaunch = getIntent().getStringExtra(KEY_DIRECT_LAUNCH);
- if (directLaunch != null) {
- Intent intent = new Intent(ActivityManager.ACTION_REPORT_HEAP_LIMIT);
- intent.setPackage(directLaunch);
- ClipData clip = ClipData.newUri(getContentResolver(), "Heap Dump", JAVA_URI);
- intent.setClipData(clip);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.setType(clip.getDescription().getMimeType(0));
- intent.putExtra(Intent.EXTRA_STREAM, JAVA_URI);
- try {
- startActivity(intent);
- scheduleDelete();
- mHandled = true;
- finish();
- return;
- } catch (ActivityNotFoundException e) {
- Slog.i("DumpHeapActivity", "Unable to direct launch to " + directLaunch
- + ": " + e.getMessage());
- }
- }
-
- final int messageId;
- if (isUserInitiated) {
- messageId = com.android.internal.R.string.dump_heap_ready_text;
- } else if (isSystemProcess) {
- messageId = com.android.internal.R.string.dump_heap_system_text;
- } else {
- messageId = com.android.internal.R.string.dump_heap_text;
- }
- AlertDialog.Builder b = new AlertDialog.Builder(this,
- android.R.style.Theme_Material_Light_Dialog_Alert);
- b.setTitle(com.android.internal.R.string.dump_heap_title);
- b.setMessage(getString(
- messageId, mProcess, DebugUtils.sizeValueToString(mSize, null)));
- b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mHandled = true;
- sendBroadcast(new Intent(ACTION_DELETE_DUMPHEAP));
- finish();
- }
- });
- b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- mHandled = true;
- scheduleDelete();
- Intent intent = new Intent(Intent.ACTION_SEND);
- ClipData clip = ClipData.newUri(getContentResolver(), "Heap Dump", JAVA_URI);
- intent.setClipData(clip);
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.setType(clip.getDescription().getMimeType(0));
- intent.putExtra(Intent.EXTRA_STREAM, JAVA_URI);
- startActivity(Intent.createChooser(intent,
- getText(com.android.internal.R.string.dump_heap_title)));
- finish();
- }
- });
- mDialog = b.show();
- }
-
- void scheduleDelete() {
- Intent broadcast = new Intent(ACTION_DELETE_DUMPHEAP);
- broadcast.putExtra(EXTRA_DELAY_DELETE, true);
- sendBroadcast(broadcast);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- if (!isChangingConfigurations()) {
- if (!mHandled) {
- sendBroadcast(new Intent(ACTION_DELETE_DUMPHEAP));
- }
- }
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mDialog.dismiss();
- }
-}
diff --git a/core/java/com/android/internal/app/procstats/ProcessState.java b/core/java/com/android/internal/app/procstats/ProcessState.java
index 2f9136a..392b8d3 100644
--- a/core/java/com/android/internal/app/procstats/ProcessState.java
+++ b/core/java/com/android/internal/app/procstats/ProcessState.java
@@ -77,7 +77,6 @@
STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
STATE_TOP, // ActivityManager.PROCESS_STATE_TOP
- STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_TOP
STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
STATE_IMPORTANT_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
index fd2ada0..36bc229 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
@@ -49,6 +49,18 @@
return mChangeConfig.forceDisabledSet();
}
+ /**
+ * Returns if a change is enabled or disabled in this config.
+ */
+ public boolean isChangeEnabled(long changeId) {
+ if (mChangeConfig.isForceEnabled(changeId)) {
+ return true;
+ } else if (mChangeConfig.isForceDisabled(changeId)) {
+ return false;
+ }
+ throw new IllegalStateException("Change " + changeId + " is not defined.");
+ }
+
private CompatibilityChangeConfig(Parcel in) {
long[] enabledArray = in.createLongArray();
long[] disabledArray = in.createLongArray();
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.aidl b/core/java/com/android/internal/compat/CompatibilityChangeInfo.aidl
new file mode 100644
index 0000000..3bc7277
--- /dev/null
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.internal.compat;
+
+parcelable CompatibilityChangeInfo;
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
new file mode 100644
index 0000000..e48e2df
--- /dev/null
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
@@ -0,0 +1,92 @@
+/*
+ * 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.internal.compat;
+
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This class is a parcelable version of {@link com.android.server.compat.Change}.
+ *
+ * @hide
+ */
+public class CompatibilityChangeInfo implements Parcelable {
+ private final long mChangeId;
+ private final @Nullable String mName;
+ private final int mEnableAfterTargetSdk;
+ private final boolean mDisabled;
+
+ public long getId() {
+ return mChangeId;
+ }
+
+ @Nullable
+ public String getName() {
+ return mName;
+ }
+
+ public int getEnableAfterTargetSdk() {
+ return mEnableAfterTargetSdk;
+ }
+
+ public boolean getDisabled() {
+ return mDisabled;
+ }
+
+ public CompatibilityChangeInfo(
+ Long changeId, String name, int enableAfterTargetSdk, boolean disabled) {
+ this.mChangeId = changeId;
+ this.mName = name;
+ this.mEnableAfterTargetSdk = enableAfterTargetSdk;
+ this.mDisabled = disabled;
+ }
+
+ private CompatibilityChangeInfo(Parcel in) {
+ mChangeId = in.readLong();
+ mName = in.readString();
+ mEnableAfterTargetSdk = in.readInt();
+ mDisabled = in.readBoolean();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(mChangeId);
+ dest.writeString(mName);
+ dest.writeInt(mEnableAfterTargetSdk);
+ dest.writeBoolean(mDisabled);
+ }
+
+ public static final Parcelable.Creator<CompatibilityChangeInfo> CREATOR =
+ new Parcelable.Creator<CompatibilityChangeInfo>() {
+
+ @Override
+ public CompatibilityChangeInfo createFromParcel(Parcel in) {
+ return new CompatibilityChangeInfo(in);
+ }
+
+ @Override
+ public CompatibilityChangeInfo[] newArray(int size) {
+ return new CompatibilityChangeInfo[size];
+ }
+ };
+}
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 8391ad2..5857642 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -17,8 +17,10 @@
package com.android.internal.compat;
import android.content.pm.ApplicationInfo;
+import java.util.Map;
parcelable CompatibilityChangeConfig;
+parcelable CompatibilityChangeInfo;
/**
* Platform private API for talking with the PlatformCompat service.
@@ -146,4 +148,21 @@
*
*/
void clearOverrides(in String packageName);
+
+ /**
+ * Get configs for an application.
+ *
+ * @param appInfo The application whose config will be returned.
+ *
+ * @return A {@link CompatibilityChangeConfig}, representing whether a change is enabled for
+ * the given app or not.
+ */
+ CompatibilityChangeConfig getAppConfig(in ApplicationInfo appInfo);
+
+ /**
+ * List all compatibility changes.
+ *
+ * @return An array of {@link CompatChangeInfo} known to the service.
+ */
+ CompatibilityChangeInfo[] listAllChanges();
}
diff --git a/core/jni/android_graphics_Picture.cpp b/core/jni/android_graphics_Picture.cpp
index 03fcdef..1d085e5 100644
--- a/core/jni/android_graphics_Picture.cpp
+++ b/core/jni/android_graphics_Picture.cpp
@@ -20,9 +20,12 @@
#include "SkCanvas.h"
#include "SkStream.h"
#include "core_jni_helpers.h"
+#include "nativehelper/jni_macros.h"
#include <jni.h>
+#include <array>
+
namespace android {
static jlong android_graphics_Picture_newPicture(JNIEnv* env, jobject, jlong srcHandle) {
@@ -91,20 +94,20 @@
pict->endRecording();
}
-static const JNINativeMethod gMethods[] = {
- {"nativeGetWidth", "(J)I", (void*) android_graphics_Picture_getWidth},
- {"nativeGetHeight", "(J)I", (void*) android_graphics_Picture_getHeight},
- {"nativeConstructor", "(J)J", (void*) android_graphics_Picture_newPicture},
- {"nativeCreateFromStream", "(Ljava/io/InputStream;[B)J", (void*)android_graphics_Picture_deserialize},
- {"nativeBeginRecording", "(JII)J", (void*) android_graphics_Picture_beginRecording},
- {"nativeEndRecording", "(J)V", (void*) android_graphics_Picture_endRecording},
- {"nativeDraw", "(JJ)V", (void*) android_graphics_Picture_draw},
- {"nativeWriteToStream", "(JLjava/io/OutputStream;[B)Z", (void*)android_graphics_Picture_serialize},
- {"nativeDestructor","(J)V", (void*) android_graphics_Picture_killPicture}
+static const std::array gMethods = {
+ MAKE_JNI_NATIVE_METHOD("nativeGetWidth", "(J)I", android_graphics_Picture_getWidth),
+ MAKE_JNI_NATIVE_METHOD("nativeGetHeight", "(J)I", android_graphics_Picture_getHeight),
+ MAKE_JNI_NATIVE_METHOD("nativeConstructor", "(J)J", android_graphics_Picture_newPicture),
+ MAKE_JNI_NATIVE_METHOD("nativeCreateFromStream", "(Ljava/io/InputStream;[B)J", android_graphics_Picture_deserialize),
+ MAKE_JNI_NATIVE_METHOD("nativeBeginRecording", "(JII)J", android_graphics_Picture_beginRecording),
+ MAKE_JNI_NATIVE_METHOD("nativeEndRecording", "(J)V", android_graphics_Picture_endRecording),
+ MAKE_JNI_NATIVE_METHOD("nativeDraw", "(JJ)V", android_graphics_Picture_draw),
+ MAKE_JNI_NATIVE_METHOD("nativeWriteToStream", "(JLjava/io/OutputStream;[B)Z", android_graphics_Picture_serialize),
+ MAKE_JNI_NATIVE_METHOD("nativeDestructor","(J)V", android_graphics_Picture_killPicture)
};
int register_android_graphics_Picture(JNIEnv* env) {
- return RegisterMethodsOrDie(env, "android/graphics/Picture", gMethods, NELEM(gMethods));
+ return RegisterMethodsOrDie(env, "android/graphics/Picture", gMethods.data(), gMethods.size());
}
}; // namespace android
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 6ab0fc9..74ced89 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -3,8 +3,10 @@
# Metrics
joeo@google.com
singhtejinder@google.com
+yanmin@google.com
yaochen@google.com
yro@google.com
+zhouwenjie@google.com
# Settings UI
per-file settings_enums.proto=tmfang@google.com
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 7d0629e..047c095 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -42,6 +42,7 @@
import "frameworks/base/core/proto/android/service/battery.proto";
import "frameworks/base/core/proto/android/service/batterystats.proto";
import "frameworks/base/core/proto/android/service/diskstats.proto";
+import "frameworks/base/core/proto/android/service/dropbox.proto";
import "frameworks/base/core/proto/android/service/graphicsstats.proto";
import "frameworks/base/core/proto/android/service/netstats.proto";
import "frameworks/base/core/proto/android/service/notification.proto";
@@ -329,6 +330,22 @@
(section).userdebug_and_eng_only = true
];
+ // Dropbox entries split by tags.
+ optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_crashes = 3027 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "dropbox --proto data_app_crash"
+ ];
+
+ optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_anr = 3028 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "dropbox --proto data_app_anr"
+ ];
+
+ optional android.service.dropbox.DropBoxManagerServiceDumpProto dropbox_data_app_native_crash = 3029 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "dropbox --proto data_app_native_crash"
+ ];
+
// Reserved for OEMs.
extensions 50000 to 100000;
}
diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto
index d01a45c..2f87deb 100644
--- a/core/proto/android/server/activitymanagerservice.proto
+++ b/core/proto/android/server/activitymanagerservice.proto
@@ -771,10 +771,11 @@
option (.android.msg_privacy).dest = DEST_AUTOMATIC;
optional string proc_name = 1;
- optional string file = 2 [ (.android.privacy).dest = DEST_EXPLICIT ];
+ reserved 2; // file, DEST_EXPLICIT
optional int32 pid = 3;
optional int32 uid = 4;
optional bool is_user_initiated = 5;
+ optional string uri = 6 [ (.android.privacy).dest = DEST_EXPLICIT ];
}
optional Dump dump = 2;
}
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index a346a63..69e67d1 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -231,7 +231,7 @@
optional WindowTokenProto window_token = 2;
optional bool last_surface_showing = 3;
optional bool is_waiting_for_transition_start = 4;
- optional bool is_really_animating = 5;
+ optional bool is_animating = 5;
optional AppWindowThumbnailProto thumbnail = 6;
optional bool fills_parent = 7;
optional bool app_stopped = 8;
diff --git a/core/proto/android/service/dropbox.proto b/core/proto/android/service/dropbox.proto
new file mode 100644
index 0000000..29fe62b
--- /dev/null
+++ b/core/proto/android/service/dropbox.proto
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+package android.service.dropbox;
+
+import "frameworks/base/core/proto/android/privacy.proto";
+
+option java_multiple_files = true;
+
+// Dump from com.android.server.DropboxManagerService.java.
+message DropBoxManagerServiceDumpProto {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ message Entry {
+ // Time when entry was originally created.
+ optional int64 time_ms = 1 [ (.android.privacy).dest = DEST_AUTOMATIC ] ;
+ optional bytes data = 2;
+ }
+ repeated Entry entries = 1;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 11a5062..a15e1ae 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -497,6 +497,7 @@
<protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" />
<protected-broadcast android:name="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" />
<protected-broadcast android:name="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" />
+ <protected-broadcast android:name="android.telephony.action.OTA_EMERGENCY_NUMBER_DB_INSTALLED" />
<protected-broadcast android:name="android.telephony.action.SECRET_CODE" />
<protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" />
<protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_PLANS_CHANGED" />
@@ -4647,6 +4648,13 @@
android:protectionLevel="normal" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
+ <!-- @hide Allow the caller to collect debugging data from processes that otherwise
+ would require USAGE_STATS. Before sharing this data with other apps, holders
+ of this permission are REQUIRED to themselves check that the caller has
+ PACKAGE_USAGE_STATS and OP_GET_USAGE_STATS. -->
+ <permission android:name="android.permission.PEEK_DROPBOX_DATA"
+ android:protectionLevel="signature|privileged" />
+
<application android:process="system"
android:persistent="true"
android:hasCode="false"
@@ -4728,19 +4736,6 @@
android:excludeFromRecents="true"
android:process=":ui">
</activity>
- <activity android:name="com.android.internal.app.DumpHeapActivity"
- android:theme="@style/Theme.Translucent.NoTitleBar"
- android:label="@string/dump_heap_title"
- android:finishOnCloseSystemDialogs="true"
- android:noHistory="true"
- android:excludeFromRecents="true"
- android:process=":ui">
- </activity>
- <provider android:name="com.android.server.am.DumpHeapProvider"
- android:authorities="com.android.server.heapdump"
- android:grantUriPermissions="true"
- android:multiprocess="false"
- android:singleUser="true" />
<activity android:name="android.accounts.ChooseAccountActivity"
android:excludeFromRecents="true"
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index 1f2dfe0..0c83390 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -388,6 +388,13 @@
assertThat(properties.getKeyset()).containsExactly(KEY, KEY2);
assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE3);
assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2);
+
+ DeviceConfig.setProperty(NAMESPACE, KEY3, VALUE, false);
+ properties = DeviceConfig.getProperties(NAMESPACE);
+ assertThat(properties.getKeyset()).containsExactly(KEY, KEY2, KEY3);
+ assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE3);
+ assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2);
+ assertThat(properties.getString(KEY3, DEFAULT_VALUE)).isEqualTo(VALUE);
}
@Test
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index dceb243..80098c5 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -174,6 +174,7 @@
<assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="incidentd" />
<assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="incidentd" />
<assign-permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL" uid="incidentd" />
+ <assign-permission name="android.permission.PEEK_DROPBOX_DATA" uid="incidentd" />
<assign-permission name="android.permission.ACCESS_LOWPAN_STATE" uid="lowpan" />
<assign-permission name="android.permission.MANAGE_LOWPAN_INTERFACES" uid="lowpan" />
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 342259d..ecdf537 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -169,12 +169,6 @@
"group": "WM_DEBUG_RESIZE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
- "-1822611824": {
- "message": "\tRemove token=%s",
- "level": "DEBUG",
- "group": "WM_DEBUG_REMOTE_ANIMATIONS",
- "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
- },
"-1797409732": {
"message": "Skipping %s because %s",
"level": "VERBOSE",
@@ -421,6 +415,12 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-1248645819": {
+ "message": "\tAdd container=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"-1219773477": {
"message": "setInputConsumerEnabled(%s): mCanceled=%b",
"level": "DEBUG",
@@ -493,12 +493,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/RootWindowContainer.java"
},
- "-1099052739": {
- "message": "\tAdd token=%s",
- "level": "DEBUG",
- "group": "WM_DEBUG_REMOTE_ANIMATIONS",
- "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
- },
"-1089874824": {
"message": "SURFACE SHOW (performLayout): %s",
"level": "INFO",
@@ -721,6 +715,12 @@
"group": "WM_DEBUG_SCREEN_ON",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
+ "-633961578": {
+ "message": "applyAnimation: transition animation is disabled or skipped. container=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ },
"-622997754": {
"message": "postWindowRemoveCleanupLocked: %s",
"level": "VERBOSE",
@@ -883,12 +883,6 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "-253016819": {
- "message": "applyAnimation: transition animation is disabled or skipped. atoken=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"-251259736": {
"message": "No longer freezing: %s",
"level": "VERBOSE",
@@ -961,6 +955,12 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/Session.java"
},
+ "-33096143": {
+ "message": "applyAnimation: transition animation is disabled or skipped. container=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/WindowContainer.java"
+ },
"-29233992": {
"message": "SURFACE CLEAR CROP: %s",
"level": "INFO",
@@ -1375,6 +1375,12 @@
"group": "WM_SHOW_TRANSACTIONS",
"at": "com\/android\/server\/wm\/WindowSurfaceController.java"
},
+ "638429464": {
+ "message": "\tRemove container=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"644675193": {
"message": "Real start recents",
"level": "DEBUG",
@@ -1465,12 +1471,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "815803557": {
- "message": "applyAnimation: atoken=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"829434921": {
"message": "Draw state now committed in %s",
"level": "VERBOSE",
@@ -1543,6 +1543,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "972354148": {
+ "message": "\tcontainer=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"1001904964": {
"message": "***** BOOT TIMEOUT: forcing display enabled",
"level": "WARN",
@@ -1675,12 +1681,6 @@
"group": "WM_DEBUG_FOCUS",
"at": "com\/android\/server\/wm\/DisplayContent.java"
},
- "1358786604": {
- "message": "No thumbnail header bitmap for: %d",
- "level": "DEBUG",
- "group": "WM_DEBUG_APP_TRANSITIONS",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"1364498663": {
"message": "notifyAppResumed: wasStopped=%b %s",
"level": "VERBOSE",
@@ -1795,11 +1795,11 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimationController.java"
},
- "1531527061": {
- "message": "createAnimationAdapter(): token=%s",
+ "1528528509": {
+ "message": "No thumbnail header bitmap for: %s",
"level": "DEBUG",
- "group": "WM_DEBUG_REMOTE_ANIMATIONS",
- "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/ActivityRecord.java"
},
"1563755163": {
"message": "Permission Denial: %s from pid=%d, uid=%d requires %s",
@@ -1819,6 +1819,12 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
+ "1584270979": {
+ "message": "applyAnimation: container=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS_ANIM",
+ "at": "com\/android\/server\/wm\/WindowContainer.java"
+ },
"1589610525": {
"message": "applyAnimation NEXT_TRANSIT_TYPE_OPEN_CROSS_PROFILE_APPS: anim=%s transit=%s isEntrance=true Callers=%s",
"level": "VERBOSE",
@@ -1909,11 +1915,11 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "1804869745": {
+ "1831008694": {
"message": "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s surfaceInsets=%s",
"level": "DEBUG",
"group": "WM_DEBUG_APP_TRANSITIONS",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
+ "at": "com\/android\/server\/wm\/WindowContainer.java"
},
"1836214582": {
"message": "startingData was nulled out before handling mAddStartingWindow: %s",
@@ -1939,12 +1945,6 @@
"group": "WM_DEBUG_SCREEN_ON",
"at": "com\/android\/server\/wm\/DisplayPolicy.java"
},
- "1865246212": {
- "message": "\tapp=%s",
- "level": "DEBUG",
- "group": "WM_DEBUG_REMOTE_ANIMATIONS",
- "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
- },
"1866772666": {
"message": "SAFE MODE not enabled",
"level": "INFO",
@@ -2017,6 +2017,12 @@
"group": "WM_DEBUG_STARTING_WINDOW",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
+ "2022422429": {
+ "message": "createAnimationAdapter(): container=%s",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_REMOTE_ANIMATIONS",
+ "at": "com\/android\/server\/wm\/RemoteAnimationController.java"
+ },
"2028163120": {
"message": "applyAnimation: anim=%s nextAppTransition=ANIM_SCALE_UP transit=%s isEntrance=%s Callers=%s",
"level": "VERBOSE",
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index c6586ec..45b2de5 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -784,7 +784,9 @@
mFillPaint.setDither(st.mDither);
mFillPaint.setColorFilter(colorFilter);
if (colorFilter != null && st.mSolidColors == null) {
- mFillPaint.setColor(mAlpha << 24);
+ // If we don't have a solid color and we don't have a gradient,
+ // the app is stroking the shape, set the color to transparent
+ mFillPaint.setColor(st.mGradientColors != null ? mAlpha << 24 : 0);
}
if (haveStroke) {
mStrokePaint.setAlpha(currStrokeAlpha);
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index 40bff88..3681c69 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -302,6 +302,7 @@
switch (skBitmap.info().colorType()) {
case kRGBA_8888_SkColorType:
formatInfo.isSupported = true;
+ [[fallthrough]];
// ARGB_4444 is upconverted to RGBA_8888
case kARGB_4444_SkColorType:
formatInfo.pixelFormat = PIXEL_FORMAT_RGBA_8888;
diff --git a/location/java/android/location/ILocationListener.aidl b/location/java/android/location/ILocationListener.aidl
index ec11345..8479caf 100644
--- a/location/java/android/location/ILocationListener.aidl
+++ b/location/java/android/location/ILocationListener.aidl
@@ -31,8 +31,6 @@
void onProviderEnabled(String provider);
@UnsupportedAppUsage
void onProviderDisabled(String provider);
-
- // --- deprecated ---
- @UnsupportedAppUsage
- void onStatusChanged(String provider, int status, in Bundle extras);
+ // called when the listener is removed from the server side; no further callbacks are expected
+ void onRemoved();
}
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index c3aae7d..b7dd543 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -230,7 +230,7 @@
public static final String METADATA_SETTINGS_FOOTER_STRING =
"com.android.settings.location.FOOTER_STRING";
- private static final long GET_CURRENT_LOCATION_TIMEOUT_MS = 30 * 1000;
+ private static final long GET_CURRENT_LOCATION_MAX_TIMEOUT_MS = 30 * 1000;
private final Context mContext;
@@ -630,7 +630,10 @@
@Nullable CancellationSignal cancellationSignal,
@NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) {
LocationRequest currentLocationRequest = new LocationRequest(locationRequest)
- .setNumUpdates(1).setExpireIn(GET_CURRENT_LOCATION_TIMEOUT_MS);
+ .setNumUpdates(1);
+ if (currentLocationRequest.getExpireIn() > GET_CURRENT_LOCATION_MAX_TIMEOUT_MS) {
+ currentLocationRequest.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
+ }
GetCurrentLocationTransport listenerTransport = new GetCurrentLocationTransport(executor,
consumer);
@@ -684,6 +687,7 @@
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
provider, 0, 0, true);
+ request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
requestLocationUpdates(request, listener, looper);
}
@@ -704,6 +708,7 @@
* @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)}
* instead as it does not carry a risk of extreme battery drain.
*/
+ @Deprecated
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestSingleUpdate(
@NonNull Criteria criteria,
@@ -714,6 +719,7 @@
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
criteria, 0, 0, true);
+ request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
requestLocationUpdates(request, listener, looper);
}
@@ -732,6 +738,7 @@
* @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)}
* instead as it does not carry a risk of extreme battery drain.
*/
+ @Deprecated
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestSingleUpdate(@NonNull String provider,
@NonNull PendingIntent pendingIntent) {
@@ -740,6 +747,7 @@
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
provider, 0, 0, true);
+ request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
requestLocationUpdates(request, pendingIntent);
}
@@ -759,6 +767,7 @@
* @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)}
* instead as it does not carry a risk of extreme battery drain.
*/
+ @Deprecated
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void requestSingleUpdate(@NonNull Criteria criteria,
@NonNull PendingIntent pendingIntent) {
@@ -767,6 +776,7 @@
LocationRequest request = LocationRequest.createFromDeprecatedCriteria(
criteria, 0, 0, true);
+ request.setExpireIn(GET_CURRENT_LOCATION_MAX_TIMEOUT_MS);
requestLocationUpdates(request, pendingIntent);
}
@@ -2422,7 +2432,7 @@
mAlarmManager = alarmManager;
mAlarmManager.set(
ELAPSED_REALTIME,
- SystemClock.elapsedRealtime() + GET_CURRENT_LOCATION_TIMEOUT_MS,
+ SystemClock.elapsedRealtime() + GET_CURRENT_LOCATION_MAX_TIMEOUT_MS,
"GetCurrentLocation",
this,
null);
@@ -2474,9 +2484,6 @@
}
@Override
- public void onStatusChanged(String provider, int status, Bundle extras) {}
-
- @Override
public void onProviderEnabled(String provider) {}
@Override
@@ -2486,6 +2493,11 @@
deliverResult(null);
}
+ @Override
+ public void onRemoved() {
+ deliverResult(null);
+ }
+
private synchronized void deliverResult(@Nullable Location location) {
if (mExecutor == null) {
return;
@@ -2561,37 +2573,6 @@
}
@Override
- public void onStatusChanged(String provider, int status, Bundle extras) {
- Executor currentExecutor = mExecutor;
- if (currentExecutor == null) {
- return;
- }
-
- try {
- currentExecutor.execute(() -> {
- try {
- if (currentExecutor != mExecutor) {
- return;
- }
-
- // we may be under the binder identity if a direct executor is used
- long identity = Binder.clearCallingIdentity();
- try {
- mListener.onStatusChanged(provider, status, extras);
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- } finally {
- locationCallbackFinished();
- }
- });
- } catch (RejectedExecutionException e) {
- locationCallbackFinished();
- throw e;
- }
- }
-
- @Override
public void onProviderEnabled(String provider) {
Executor currentExecutor = mExecutor;
if (currentExecutor == null) {
@@ -2653,6 +2634,14 @@
}
}
+ @Override
+ public void onRemoved() {
+ unregister();
+ synchronized (mListeners) {
+ mListeners.remove(mListener, this);
+ }
+ }
+
private void locationCallbackFinished() {
try {
mService.locationCallbackFinished(this);
@@ -2750,9 +2739,14 @@
protected boolean registerService() throws RemoteException {
Preconditions.checkState(mListenerTransport == null);
- mListenerTransport = new GnssStatusListener();
- return mService.registerGnssStatusCallback(mListenerTransport,
- mContext.getPackageName(), mContext.getFeatureId());
+ GnssStatusListener transport = new GnssStatusListener();
+ if (mService.registerGnssStatusCallback(transport, mContext.getPackageName(),
+ mContext.getFeatureId())) {
+ mListenerTransport = transport;
+ return true;
+ } else {
+ return false;
+ }
}
@Override
@@ -2810,10 +2804,14 @@
protected boolean registerService() throws RemoteException {
Preconditions.checkState(mListenerTransport == null);
- mListenerTransport = new GnssMeasurementsListener();
- return mService.addGnssMeasurementsListener(mListenerTransport,
- mContext.getPackageName(), mContext.getFeatureId(),
- "gnss measurement callback");
+ GnssMeasurementsListener transport = new GnssMeasurementsListener();
+ if (mService.addGnssMeasurementsListener(transport, mContext.getPackageName(),
+ mContext.getFeatureId(), "gnss measurement callback")) {
+ mListenerTransport = transport;
+ return true;
+ } else {
+ return false;
+ }
}
@Override
@@ -2847,10 +2845,14 @@
protected boolean registerService() throws RemoteException {
Preconditions.checkState(mListenerTransport == null);
- mListenerTransport = new GnssNavigationMessageListener();
- return mService.addGnssNavigationMessageListener(mListenerTransport,
- mContext.getPackageName(), mContext.getFeatureId(),
- "gnss navigation callback");
+ GnssNavigationMessageListener transport = new GnssNavigationMessageListener();
+ if (mService.addGnssNavigationMessageListener(transport, mContext.getPackageName(),
+ mContext.getFeatureId(), "gnss navigation callback")) {
+ mListenerTransport = transport;
+ return true;
+ } else {
+ return false;
+ }
}
@Override
@@ -2884,9 +2886,14 @@
protected boolean registerService() throws RemoteException {
Preconditions.checkState(mListenerTransport == null);
- mListenerTransport = new BatchedLocationCallback();
- return mService.addGnssBatchingCallback(mListenerTransport, mContext.getPackageName(),
- mContext.getFeatureId(), "batched location callback");
+ BatchedLocationCallback transport = new BatchedLocationCallback();
+ if (mService.addGnssBatchingCallback(transport, mContext.getPackageName(),
+ mContext.getFeatureId(), "batched location callback")) {
+ mListenerTransport = transport;
+ return true;
+ } else {
+ return false;
+ }
}
@Override
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 0f38f7f..3abd2c2 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -161,6 +161,7 @@
private boolean mExplicitFastestInterval = false;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private long mExpireAt = Long.MAX_VALUE; // no expiry
+ private long mExpireIn = Long.MAX_VALUE; // no expiry
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private int mNumUpdates = Integer.MAX_VALUE; // no expiry
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -268,6 +269,7 @@
mFastestInterval = src.mFastestInterval;
mExplicitFastestInterval = src.mExplicitFastestInterval;
mExpireAt = src.mExpireAt;
+ mExpireIn = src.mExpireIn;
mNumUpdates = src.mNumUpdates;
mSmallestDisplacement = src.mSmallestDisplacement;
mProvider = src.mProvider;
@@ -342,7 +344,7 @@
* @throws IllegalArgumentException if the interval is less than zero
*/
public @NonNull LocationRequest setInterval(long millis) {
- checkInterval(millis);
+ Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
mInterval = millis;
if (!mExplicitFastestInterval) {
mFastestInterval = (long) (mInterval / FASTEST_INTERVAL_FACTOR);
@@ -370,9 +372,7 @@
*
* @param enabled Enable or disable low power mode
* @return the same object, so that setters can be chained
- * @hide
*/
- @SystemApi
public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
mLowPowerMode = enabled;
return this;
@@ -380,10 +380,7 @@
/**
* Returns true if low power mode is enabled.
- *
- * @hide
*/
- @SystemApi
public boolean isLowPowerMode() {
return mLowPowerMode;
}
@@ -431,93 +428,80 @@
* <p>An interval of 0 is allowed, but not recommended, since
* location updates may be extremely fast on future implementations.
*
- * <p>If {@link #setFastestInterval} is set slower than {@link #setInterval},
+ * <p>If the fastest interval set is slower than {@link #setInterval},
* then your effective fastest interval is {@link #setInterval}.
*
- * @param millis fastest interval for updates in milliseconds, exact
+ * @param millis fastest interval for updates in milliseconds
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the interval is less than zero
*/
public @NonNull LocationRequest setFastestInterval(long millis) {
- checkInterval(millis);
+ Preconditions.checkArgument(millis >= 0, "invalid interval: + millis");
mExplicitFastestInterval = true;
mFastestInterval = millis;
return this;
}
/**
- * Get the fastest interval of this request, in milliseconds.
+ * Get the fastest interval of this request in milliseconds. The system will never provide
+ * location updates faster than the minimum of the fastest interval and {@link #getInterval}.
*
- * <p>The system will never provide location updates faster
- * than the minimum of {@link #getFastestInterval} and
- * {@link #getInterval}.
- *
- * @return fastest interval in milliseconds, exact
+ * @return fastest interval in milliseconds
*/
public long getFastestInterval() {
return mFastestInterval;
}
/**
- * Set the duration of this request, in milliseconds.
+ * Set the expiration time of this request in milliseconds of realtime since boot. Values in the
+ * past are allowed, but indicate that the request has already expired. The location manager
+ * will automatically stop updates after the request expires.
*
- * <p>The duration begins immediately (and not when the request
- * is passed to the location manager), so call this method again
- * if the request is re-used at a later time.
+ * @param millis expiration time of request in milliseconds since boot
+ * @return the same object, so that setters can be chained
+ * @see SystemClock#elapsedRealtime()
+ * @deprecated Prefer {@link #setExpireIn(long)}.
+ */
+ @Deprecated
+ public @NonNull LocationRequest setExpireAt(long millis) {
+ mExpireAt = Math.max(millis, 0);
+ return this;
+ }
+
+ /**
+ * Get the request expiration time in milliseconds of realtime since boot.
*
- * <p>The location manager will automatically stop updates after
- * the request expires.
- *
- * <p>The duration includes suspend time. Values less than 0
- * are allowed, but indicate that the request has already expired.
+ * @return request expiration time in milliseconds since boot
+ * @see SystemClock#elapsedRealtime()
+ * @deprecated Prefer {@link #getExpireIn()}.
+ */
+ @Deprecated
+ public long getExpireAt() {
+ return mExpireAt;
+ }
+
+ /**
+ * Set the duration of this request in milliseconds of realtime. Values less than 0 are allowed,
+ * but indicate that the request has already expired. The location manager will automatically
+ * stop updates after the request expires.
*
* @param millis duration of request in milliseconds
* @return the same object, so that setters can be chained
+ * @see SystemClock#elapsedRealtime()
*/
public @NonNull LocationRequest setExpireIn(long millis) {
- long elapsedRealtime = SystemClock.elapsedRealtime();
-
- // Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
- if (millis > Long.MAX_VALUE - elapsedRealtime) {
- mExpireAt = Long.MAX_VALUE;
- } else {
- mExpireAt = millis + elapsedRealtime;
- }
-
- if (mExpireAt < 0) mExpireAt = 0;
+ mExpireIn = millis;
return this;
}
/**
- * Set the request expiration time, in millisecond since boot.
+ * Get the request expiration duration in milliseconds of realtime.
*
- * <p>This expiration time uses the same time base as {@link SystemClock#elapsedRealtime}.
- *
- * <p>The location manager will automatically stop updates after
- * the request expires.
- *
- * <p>The duration includes suspend time. Values before {@link SystemClock#elapsedRealtime}
- * are allowed, but indicate that the request has already expired.
- *
- * @param millis expiration time of request, in milliseconds since boot including suspend
- * @return the same object, so that setters can be chained
+ * @return request expiration duration in milliseconds
+ * @see SystemClock#elapsedRealtime()
*/
- public @NonNull LocationRequest setExpireAt(long millis) {
- mExpireAt = millis;
- if (mExpireAt < 0) mExpireAt = 0;
- return this;
- }
-
- /**
- * Get the request expiration time, in milliseconds since boot.
- *
- * <p>This value can be compared to {@link SystemClock#elapsedRealtime} to determine
- * the time until expiration.
- *
- * @return expiration time of request, in milliseconds since boot including suspend
- */
- public long getExpireAt() {
- return mExpireAt;
+ public long getExpireIn() {
+ return mExpireIn;
}
/**
@@ -638,13 +622,6 @@
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- private static void checkInterval(long millis) {
- if (millis < 0) {
- throw new IllegalArgumentException("invalid interval: " + millis);
- }
- }
-
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
private static void checkQuality(int quality) {
switch (quality) {
case ACCURACY_FINE:
@@ -682,6 +659,7 @@
request.setFastestInterval(in.readLong());
request.setInterval(in.readLong());
request.setExpireAt(in.readLong());
+ request.setExpireIn(in.readLong());
request.setNumUpdates(in.readInt());
request.setSmallestDisplacement(in.readFloat());
request.setHideFromAppOps(in.readInt() != 0);
@@ -711,6 +689,7 @@
parcel.writeLong(mFastestInterval);
parcel.writeLong(mInterval);
parcel.writeLong(mExpireAt);
+ parcel.writeLong(mExpireIn);
parcel.writeInt(mNumUpdates);
parcel.writeFloat(mSmallestDisplacement);
parcel.writeInt(mHideFromAppOps ? 1 : 0);
@@ -753,9 +732,11 @@
s.append(" fastest=");
TimeUtils.formatDuration(mFastestInterval, s);
if (mExpireAt != Long.MAX_VALUE) {
- long expireIn = mExpireAt - SystemClock.elapsedRealtime();
+ s.append(" expireAt=").append(TimeUtils.formatUptime(mExpireAt));
+ }
+ if (mExpireIn != Long.MAX_VALUE) {
s.append(" expireIn=");
- TimeUtils.formatDuration(expireIn, s);
+ TimeUtils.formatDuration(mExpireIn, s);
}
if (mNumUpdates != Integer.MAX_VALUE) {
s.append(" num=").append(mNumUpdates);
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index fe0f669..cd45e8e 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -17,10 +17,8 @@
java_sdk_library {
name: "com.android.location.provider",
srcs: ["java/**/*.java"],
- api_srcs: [":framework-all-sources"],
libs: [
"androidx.annotation_annotation",
- "framework-all",
],
api_packages: ["com.android.location.provider"],
}
diff --git a/media/java/android/media/ImageWriter.java b/media/java/android/media/ImageWriter.java
index f813d1b..7bc2b31 100644
--- a/media/java/android/media/ImageWriter.java
+++ b/media/java/android/media/ImageWriter.java
@@ -192,13 +192,15 @@
mMaxImages = maxImages;
- if (format == ImageFormat.UNKNOWN) {
- format = SurfaceUtils.getSurfaceFormat(surface);
- }
// Note that the underlying BufferQueue is working in synchronous mode
// to avoid dropping any buffers.
mNativeContext = nativeInit(new WeakReference<>(this), surface, maxImages, format);
+ // nativeInit internally overrides UNKNOWN format. So does surface format query after
+ // nativeInit and before getEstimatedNativeAllocBytes().
+ if (format == ImageFormat.UNKNOWN) {
+ format = SurfaceUtils.getSurfaceFormat(surface);
+ }
// Estimate the native buffer allocation size and register it so it gets accounted for
// during GC. Note that this doesn't include the buffers required by the buffer queue
// itself and the buffers requested by the producer.
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index cc5ddeb..5d2bdd7 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -34,6 +34,7 @@
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -62,7 +63,8 @@
* method before the rest of the methods in this class. This method may be
* time-consuming.
*
- * @param path The path of the input media file.
+ * @param path The path, or the URI (doesn't support streaming source currently)
+ * of the input media file.
* @throws IllegalArgumentException If the path is invalid.
*/
public void setDataSource(String path) throws IllegalArgumentException {
@@ -70,6 +72,15 @@
throw new IllegalArgumentException("null path");
}
+ final Uri uri = Uri.parse(path);
+ final String scheme = uri.getScheme();
+ if ("file".equals(scheme)) {
+ path = uri.getPath();
+ } else if (scheme != null) {
+ setDataSource(path, new HashMap<String, String>());
+ return;
+ }
+
try (FileInputStream is = new FileInputStream(path)) {
FileDescriptor fd = is.getFD();
setDataSource(fd, 0, 0x7ffffffffffffffL);
diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java
index 5b62f16..d942bb6 100644
--- a/media/java/android/media/Utils.java
+++ b/media/java/android/media/Utils.java
@@ -16,8 +16,8 @@
package android.media;
-import android.content.Context;
import android.content.ContentResolver;
+import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Environment;
@@ -206,12 +206,13 @@
}
static Size parseSize(Object o, Size fallback) {
+ if (o == null) {
+ return fallback;
+ }
try {
return Size.parseSize((String) o);
} catch (ClassCastException e) {
} catch (NumberFormatException e) {
- } catch (NullPointerException e) {
- return fallback;
}
Log.w(TAG, "could not parse size '" + o + "'");
return fallback;
@@ -226,14 +227,15 @@
return Integer.parseInt(s);
} catch (ClassCastException e) {
} catch (NumberFormatException e) {
- } catch (NullPointerException e) {
- return fallback;
}
Log.w(TAG, "could not parse integer '" + o + "'");
return fallback;
}
static Range<Integer> parseIntRange(Object o, Range<Integer> fallback) {
+ if (o == null) {
+ return fallback;
+ }
try {
String s = (String)o;
int ix = s.indexOf('-');
@@ -246,8 +248,6 @@
return Range.create(value, value);
} catch (ClassCastException e) {
} catch (NumberFormatException e) {
- } catch (NullPointerException e) {
- return fallback;
} catch (IllegalArgumentException e) {
}
Log.w(TAG, "could not parse integer range '" + o + "'");
@@ -255,6 +255,9 @@
}
static Range<Long> parseLongRange(Object o, Range<Long> fallback) {
+ if (o == null) {
+ return fallback;
+ }
try {
String s = (String)o;
int ix = s.indexOf('-');
@@ -267,8 +270,6 @@
return Range.create(value, value);
} catch (ClassCastException e) {
} catch (NumberFormatException e) {
- } catch (NullPointerException e) {
- return fallback;
} catch (IllegalArgumentException e) {
}
Log.w(TAG, "could not parse long range '" + o + "'");
@@ -276,6 +277,9 @@
}
static Range<Rational> parseRationalRange(Object o, Range<Rational> fallback) {
+ if (o == null) {
+ return fallback;
+ }
try {
String s = (String)o;
int ix = s.indexOf('-');
@@ -288,8 +292,6 @@
return Range.create(value, value);
} catch (ClassCastException e) {
} catch (NumberFormatException e) {
- } catch (NullPointerException e) {
- return fallback;
} catch (IllegalArgumentException e) {
}
Log.w(TAG, "could not parse rational range '" + o + "'");
@@ -297,6 +299,9 @@
}
static Pair<Size, Size> parseSizeRange(Object o) {
+ if (o == null) {
+ return null;
+ }
try {
String s = (String)o;
int ix = s.indexOf('-');
@@ -309,8 +314,6 @@
return Pair.create(value, value);
} catch (ClassCastException e) {
} catch (NumberFormatException e) {
- } catch (NullPointerException e) {
- return null;
} catch (IllegalArgumentException e) {
}
Log.w(TAG, "could not parse size range '" + o + "'");
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 3742f97..2f53cbb 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -99,13 +99,14 @@
"android_media_Utils.cpp",
],
+ header_libs: [
+ "libgui_headers",
+ ],
+
shared_libs: [
"liblog",
- "libgui",
- "libnativewindow",
"libui",
"libutils",
- "android.hidl.token@1.0-utils",
],
include_dirs: [
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
index 6b03e4d..3b25787 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -17,7 +17,5 @@
java_sdk_library {
name: "com.android.mediadrm.signer",
srcs: ["java/**/*.java"],
- api_srcs: [":framework-all-sources"],
- libs: ["framework-all"],
api_packages: ["com.android.mediadrm.signer"],
}
diff --git a/packages/CarSystemUI/res/values/integers_car.xml b/packages/CarSystemUI/res/values/integers_car.xml
index fb67b30..d6c16cb 100644
--- a/packages/CarSystemUI/res/values/integers_car.xml
+++ b/packages/CarSystemUI/res/values/integers_car.xml
@@ -34,4 +34,7 @@
<!-- The delay before the unlock dialog pops up -->
<integer name="unlock_dialog_delay_ms">0</integer>
+ <!-- Timeout values in milliseconds for displaying volume dialog-->
+ <integer name="car_volume_dialog_display_normal_timeout">3000</integer>
+ <integer name="car_volume_dialog_display_hovering_timeout">16000</integer>
</resources>
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
index 4f7b5d5..59b1068 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -16,19 +16,87 @@
package com.android.systemui;
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.util.DisplayMetrics;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.appops.AppOpsController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.navigationbar.car.CarNavigationBar;
+import com.android.systemui.navigationbar.car.CarNavigationBarController;
import com.android.systemui.pip.PipUI;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
+import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.car.CarStatusBar;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NewNotifPipeline;
+import com.android.systemui.statusbar.notification.NotificationAlertingManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotifLog;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.DozeScrimController;
+import com.android.systemui.statusbar.phone.DozeServiceHost;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.util.leak.GarbageMonitor;
import com.android.systemui.volume.VolumeUI;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
import dagger.Binds;
+import dagger.Lazy;
import dagger.Module;
+import dagger.Provides;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;
@@ -100,4 +168,141 @@
@IntoMap
@ClassKey(VolumeUI.class)
public abstract SystemUI bindVolumeUI(VolumeUI sysui);
+
+ /**
+ * Provides our instance of StatusBar which is considered optional.
+ */
+ @Provides
+ @Singleton
+ static CarStatusBar provideStatusBar(
+ Context context,
+ FeatureFlags featureFlags,
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ DozeLog dozeLog,
+ InjectionInflationController injectionInflationController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowNotificationLongPress,
+ Lazy<NewNotifPipeline> newNotifPipeline,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationEntryManager notificationEntryManager,
+ NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ ForegroundServiceController foregroundServiceController,
+ AppOpsController appOpsController,
+ KeyguardViewMediator keyguardViewMediator,
+ ZenModeController zenModeController,
+ NotificationAlertingManager notificationAlertingManager,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ UiOffloadThread uiOffloadThread,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ NotificationGroupAlertTransferHelper groupAlertTransferHelper,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ AssistManager assistManager,
+ NotificationListener notificationListener,
+ ConfigurationController configurationController,
+ StatusBarWindowController statusBarWindowController,
+ StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
+ NotifLog notifLog,
+ DozeParameters dozeParameters,
+ ScrimController scrimController,
+ Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
+ Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
+ DozeServiceHost dozeServiceHost,
+ PowerManager powerManager,
+ DozeScrimController dozeScrimController,
+ CarNavigationBarController carNavigationBarController) {
+ return new CarStatusBar(
+ context,
+ featureFlags,
+ lightBarController,
+ autoHideController,
+ keyguardUpdateMonitor,
+ statusBarIconController,
+ dozeLog,
+ injectionInflationController,
+ pulseExpansionHandler,
+ notificationWakeUpCoordinator,
+ keyguardBypassController,
+ keyguardStateController,
+ headsUpManagerPhone,
+ dynamicPrivacyController,
+ bypassHeadsUpNotifier,
+ allowNotificationLongPress,
+ newNotifPipeline,
+ falsingManager,
+ broadcastDispatcher,
+ remoteInputQuickSettingsDisabler,
+ notificationGutsManager,
+ notificationLogger,
+ notificationEntryManager,
+ notificationInterruptionStateProvider,
+ notificationViewHierarchyManager,
+ foregroundServiceController,
+ appOpsController,
+ keyguardViewMediator,
+ zenModeController,
+ notificationAlertingManager,
+ displayMetrics,
+ metricsLogger,
+ uiOffloadThread,
+ notificationMediaManager,
+ lockScreenUserManager,
+ remoteInputManager,
+ userSwitcherController,
+ networkController,
+ batteryController,
+ colorExtractor,
+ screenLifecycle,
+ wakefulnessLifecycle,
+ statusBarStateController,
+ vibratorHelper,
+ bubbleController,
+ groupManager,
+ groupAlertTransferHelper,
+ visualStabilityManager,
+ deviceProvisionedController,
+ navigationBarController,
+ assistManager,
+ notificationListener,
+ configurationController,
+ statusBarWindowController,
+ statusBarWindowViewControllerBuilder,
+ notifLog,
+ dozeParameters,
+ scrimController,
+ lockscreenWallpaperLazy,
+ biometricUnlockControllerLazy,
+ dozeServiceHost,
+ powerManager,
+ dozeScrimController,
+ carNavigationBarController);
+ }
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index d548fa1..85472ff 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -134,16 +134,13 @@
import java.io.PrintWriter;
import java.util.Map;
-import javax.inject.Inject;
import javax.inject.Named;
-import javax.inject.Singleton;
import dagger.Lazy;
/**
* A status bar tailored for the automotive use case.
*/
-@Singleton
public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler {
private static final String TAG = "CarStatusBar";
// used to calculate how fast to open or close the window
@@ -236,7 +233,6 @@
}
};
- @Inject
public CarStatusBar(
Context context,
FeatureFlags featureFlags,
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index 05657ff..fb1870a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -19,6 +19,7 @@
import static android.content.DialogInterface.BUTTON_NEGATIVE;
import static android.content.DialogInterface.BUTTON_POSITIVE;
import static android.os.UserManager.DISALLOW_ADD_USER;
+import static android.os.UserManager.SWITCHABILITY_STATUS_OK;
import android.app.ActivityManager;
import android.app.AlertDialog;
@@ -123,10 +124,12 @@
}
private List<UserRecord> createUserRecords(List<UserInfo> userInfoList) {
+ int fgUserId = ActivityManager.getCurrentUser();
+ UserHandle fgUserHandle = UserHandle.of(fgUserId);
List<UserRecord> userRecords = new ArrayList<>();
// If the foreground user CANNOT switch to other users, only display the foreground user.
- if (!mCarUserManagerHelper.canForegroundUserSwitchUsers()) {
+ if (mUserManager.getUserSwitchability(fgUserHandle) != SWITCHABILITY_STATUS_OK) {
userRecords.add(createForegroundUserRecord());
return userRecords;
}
@@ -137,7 +140,7 @@
continue;
}
- boolean isForeground = ActivityManager.getCurrentUser() == userInfo.id;
+ boolean isForeground = fgUserId == userInfo.id;
UserRecord record = new UserRecord(userInfo, false /* isStartGuestSession */,
false /* isAddUser */, isForeground);
userRecords.add(record);
@@ -147,7 +150,6 @@
userRecords.add(createStartGuestUserRecord());
// Add add user record if the foreground user can add users
- UserHandle fgUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
if (!mUserManager.hasUserRestriction(DISALLOW_ADD_USER, fgUserHandle)) {
userRecords.add(createAddUserRecord());
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index d979bad..09223e8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -62,7 +62,6 @@
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Iterator;
import java.util.List;
/**
@@ -76,8 +75,6 @@
private static final String XML_TAG_VOLUME_ITEMS = "carVolumeItems";
private static final String XML_TAG_VOLUME_ITEM = "item";
- private static final int HOVERING_TIMEOUT = 16000;
- private static final int NORMAL_TIMEOUT = 3000;
private static final int LISTVIEW_ANIMATION_DURATION_IN_MILLIS = 250;
private static final int DISMISS_DELAY_IN_MILLIS = 50;
private static final int ARROW_FADE_IN_START_DELAY_IN_MILLIS = 100;
@@ -91,12 +88,23 @@
// Volume items in the RecyclerView.
private final List<CarVolumeItem> mCarVolumeLineItems = new ArrayList<>();
private final KeyguardManager mKeyguard;
+ private final int mNormalTimeout;
+ private final int mHoveringTimeout;
+
private Window mWindow;
private CustomDialog mDialog;
private RecyclerView mListView;
private CarVolumeItemAdapter mVolumeItemsAdapter;
private Car mCar;
private CarAudioManager mCarAudioManager;
+ private boolean mHovering;
+ private int mCurrentlyDisplayingGroupId;
+ private int mPreviouslyDisplayingGroupId;
+ private boolean mShowing;
+ private boolean mDismissing;
+ private boolean mExpanded;
+ private View mExpandIcon;
+
private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback =
new CarAudioManager.CarVolumeCallback() {
@Override
@@ -126,6 +134,7 @@
volumeItem.progress = value;
}
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
+ mPreviouslyDisplayingGroupId = mCurrentlyDisplayingGroupId;
mCurrentlyDisplayingGroupId = groupId;
mHandler.obtainMessage(H.SHOW,
Events.SHOW_REASON_VOLUME_CHANGED).sendToTarget();
@@ -137,12 +146,6 @@
// ignored
}
};
- private boolean mHovering;
- private int mCurrentlyDisplayingGroupId;
- private boolean mShowing;
- private boolean mDismissing;
- private boolean mExpanded;
- private View mExpandIcon;
private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
if (!ready) {
@@ -158,7 +161,7 @@
mAvailableVolumeItems.add(volumeItem);
// The first one is the default item.
if (groupId == 0) {
- setuptListItem(0);
+ clearAllAndSetupDefaultCarVolumeLineItem(0);
}
}
@@ -169,18 +172,13 @@
mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
};
- private void setuptListItem(int groupId) {
- mCarVolumeLineItems.clear();
- VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
- volumeItem.defaultItem = true;
- addCarVolumeListItem(volumeItem, /* volumeGroupId = */ groupId,
- R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener()
- );
- }
-
public CarVolumeDialogImpl(Context context) {
mContext = context;
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+ mNormalTimeout = mContext.getResources().getInteger(
+ R.integer.car_volume_dialog_display_normal_timeout);
+ mHoveringTimeout = mContext.getResources().getInteger(
+ R.integer.car_volume_dialog_display_hovering_timeout);
}
private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
@@ -204,7 +202,7 @@
@Override
public void destroy() {
- mHandler.removeCallbacksAndMessages(null);
+ mHandler.removeCallbacksAndMessages(/* token= */ null);
cleanupAudioManager();
// unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
@@ -280,19 +278,36 @@
mHandler.removeMessages(H.SHOW);
mHandler.removeMessages(H.DISMISS);
+
rescheduleTimeoutH();
+
// Refresh the data set before showing.
mVolumeItemsAdapter.notifyDataSetChanged();
+
if (mShowing) {
+ if (mPreviouslyDisplayingGroupId == mCurrentlyDisplayingGroupId || mExpanded) {
+ return;
+ }
+
+ clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
return;
}
+
mShowing = true;
- setuptListItem(mCurrentlyDisplayingGroupId);
+ clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
mDialog.show();
Events.writeEvent(mContext, Events.EVENT_SHOW_DIALOG, reason, mKeyguard.isKeyguardLocked());
}
- private void rescheduleTimeoutH() {
+ private void clearAllAndSetupDefaultCarVolumeLineItem(int groupId) {
+ mCarVolumeLineItems.clear();
+ VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
+ volumeItem.defaultItem = true;
+ addCarVolumeListItem(volumeItem, /* volumeGroupId = */ groupId,
+ R.drawable.car_ic_keyboard_arrow_down, new ExpandIconListener());
+ }
+
+ protected void rescheduleTimeoutH() {
mHandler.removeMessages(H.DISMISS);
final int timeout = computeTimeoutH();
mHandler.sendMessageDelayed(mHandler
@@ -304,7 +319,7 @@
}
private int computeTimeoutH() {
- return mHovering ? HOVERING_TIMEOUT : NORMAL_TIMEOUT;
+ return mHovering ? mHoveringTimeout : mNormalTimeout;
}
private void dismissH(int reason) {
@@ -366,12 +381,13 @@
if (XML_TAG_VOLUME_ITEM.equals(parser.getName())) {
TypedArray item = mContext.getResources().obtainAttributes(
attrs, R.styleable.carVolumeItems_item);
- int usage = item.getInt(R.styleable.carVolumeItems_item_usage, -1);
+ int usage = item.getInt(R.styleable.carVolumeItems_item_usage,
+ /* defValue= */ -1);
if (usage >= 0) {
VolumeItem volumeItem = new VolumeItem();
volumeItem.rank = rank;
- volumeItem.icon = item.getResourceId(R.styleable.carVolumeItems_item_icon,
- 0);
+ volumeItem.icon = item.getResourceId(
+ R.styleable.carVolumeItems_item_icon, /* defValue= */ 0);
mVolumeItems.put(usage, volumeItem);
rank++;
}
@@ -396,22 +412,22 @@
return result;
}
- private CarVolumeItem addCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
- int supplementalIconId,
+ private CarVolumeItem createCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
+ Drawable supplementalIcon, int seekbarProgressValue,
@Nullable View.OnClickListener supplementalIconOnClickListener) {
CarVolumeItem carVolumeItem = new CarVolumeItem();
carVolumeItem.setMax(getMaxSeekbarValue(mCarAudioManager, volumeGroupId));
- int color = mContext.getResources().getColor(R.color.car_volume_dialog_tint);
- int progress = getSeekbarValue(mCarAudioManager, volumeGroupId);
- carVolumeItem.setProgress(progress);
+ carVolumeItem.setProgress(seekbarProgressValue);
carVolumeItem.setOnSeekBarChangeListener(
new CarVolumeDialogImpl.VolumeSeekBarChangeListener(volumeGroupId,
mCarAudioManager));
- Drawable primaryIcon = mContext.getResources().getDrawable(volumeItem.icon);
+ carVolumeItem.setGroupId(volumeGroupId);
+
+ int color = mContext.getColor(R.color.car_volume_dialog_tint);
+ Drawable primaryIcon = mContext.getDrawable(volumeItem.icon);
primaryIcon.mutate().setTint(color);
carVolumeItem.setPrimaryIcon(primaryIcon);
- if (supplementalIconId != 0) {
- Drawable supplementalIcon = mContext.getResources().getDrawable(supplementalIconId);
+ if (supplementalIcon != null) {
supplementalIcon.mutate().setTint(color);
carVolumeItem.setSupplementalIcon(supplementalIcon,
/* showSupplementalIconDivider= */ true);
@@ -420,21 +436,23 @@
carVolumeItem.setSupplementalIcon(/* drawable= */ null,
/* showSupplementalIconDivider= */ false);
}
- carVolumeItem.setGroupId(volumeGroupId);
- mCarVolumeLineItems.add(carVolumeItem);
+
volumeItem.carVolumeItem = carVolumeItem;
- volumeItem.progress = progress;
+ volumeItem.progress = seekbarProgressValue;
+
return carVolumeItem;
}
- private VolumeItem findVolumeItem(CarVolumeItem targetItem) {
- for (int i = 0; i < mVolumeItems.size(); ++i) {
- VolumeItem volumeItem = mVolumeItems.valueAt(i);
- if (volumeItem.carVolumeItem == targetItem) {
- return volumeItem;
- }
- }
- return null;
+ private CarVolumeItem addCarVolumeListItem(VolumeItem volumeItem, int volumeGroupId,
+ int supplementalIconId,
+ @Nullable View.OnClickListener supplementalIconOnClickListener) {
+ int seekbarProgressValue = getSeekbarValue(mCarAudioManager, volumeGroupId);
+ Drawable supplementalIcon = supplementalIconId == 0 ? null : mContext.getDrawable(
+ supplementalIconId);
+ CarVolumeItem carVolumeItem = createCarVolumeListItem(volumeItem, volumeGroupId,
+ supplementalIcon, seekbarProgressValue, supplementalIconOnClickListener);
+ mCarVolumeLineItems.add(carVolumeItem);
+ return carVolumeItem;
}
private void cleanupAudioManager() {
@@ -530,21 +548,15 @@
for (int groupId = 0; groupId < mAvailableVolumeItems.size(); ++groupId) {
if (groupId != mCurrentlyDisplayingGroupId) {
VolumeItem volumeItem = mAvailableVolumeItems.get(groupId);
- addCarVolumeListItem(volumeItem, groupId, 0, null);
+ addCarVolumeListItem(volumeItem, groupId, /* supplementalIconId= */ 0,
+ /* supplementalIconOnClickListener= */ null);
}
}
inAnimator = AnimatorInflater.loadAnimator(
mContext, R.anim.car_arrow_fade_in_rotate_up);
} else {
- // Only keeping the default stream if it is not expended.
- Iterator itr = mCarVolumeLineItems.iterator();
- while (itr.hasNext()) {
- CarVolumeItem carVolumeItem = (CarVolumeItem) itr.next();
- if (carVolumeItem.getGroupId() != mCurrentlyDisplayingGroupId) {
- itr.remove();
- }
- }
+ clearAllAndSetupDefaultCarVolumeLineItem(mCurrentlyDisplayingGroupId);
inAnimator = AnimatorInflater.loadAnimator(
mContext, R.anim.car_arrow_fade_in_rotate_down);
}
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
index 0a37cc6..99f6a92 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/handheld/UninstallAlertDialogFragment.java
@@ -16,7 +16,6 @@
package com.android.packageinstaller.handheld;
-import static android.os.storage.StorageManager.convert;
import static android.text.format.Formatter.formatFileSize;
import android.annotation.NonNull;
@@ -34,8 +33,6 @@
import android.os.Bundle;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.storage.StorageManager;
-import android.os.storage.StorageVolume;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -64,29 +61,18 @@
* @return The number of bytes.
*/
private long getAppDataSizeForUser(@NonNull String pkg, @NonNull UserHandle user) {
- StorageManager storageManager = getContext().getSystemService(StorageManager.class);
StorageStatsManager storageStatsManager =
getContext().getSystemService(StorageStatsManager.class);
-
- List<StorageVolume> volumes = storageManager.getStorageVolumes();
- long appDataSize = 0;
-
- int numVolumes = volumes.size();
- for (int i = 0; i < numVolumes; i++) {
- StorageStats stats;
- try {
- stats = storageStatsManager.queryStatsForPackage(convert(volumes.get(i).getUuid()),
- pkg, user);
- } catch (PackageManager.NameNotFoundException | IOException e) {
- Log.e(LOG_TAG, "Cannot determine amount of app data for " + pkg + " on "
- + volumes.get(i) + " (user " + user + ")", e);
- continue;
- }
-
- appDataSize += stats.getDataBytes();
+ try {
+ StorageStats stats = storageStatsManager.queryStatsForPackage(
+ getContext().getPackageManager().getApplicationInfo(pkg, 0).storageUuid,
+ pkg, user);
+ return stats.getDataBytes();
+ } catch (PackageManager.NameNotFoundException | IOException e) {
+ Log.e(LOG_TAG, "Cannot determine amount of app data for " + pkg, e);
}
- return appDataSize;
+ return 0;
}
/**
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 66e8923..a1ef831 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1186,4 +1186,7 @@
<!-- Name of the this device. [CHAR LIMIT=30] -->
<string name="media_transfer_this_device_name">This device</string>
+
+ <!-- Warning message to tell user is have problem during profile connect, it need to turn off device and back on. [CHAR_LIMIT=NONE] -->
+ <string name="profile_connect_timeout_subtext">Problem connecting. Turn device off & back on</string>
</resources>
diff --git a/packages/SettingsLib/search/src/com/android/settingslib/search/Indexable.java b/packages/SettingsLib/search/src/com/android/settingslib/search/Indexable.java
index e68b0d1..8b17ddf 100644
--- a/packages/SettingsLib/search/src/com/android/settingslib/search/Indexable.java
+++ b/packages/SettingsLib/search/src/com/android/settingslib/search/Indexable.java
@@ -56,6 +56,16 @@
List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled);
/**
+ * Return a list of dynamic raw data for indexing. See {@link SearchIndexableRaw}
+ *
+ * @param context the context.
+ * @param enabled hint telling if the data needs to be considered into the search results
+ * or not.
+ * @return a list of {@link SearchIndexableRaw} references. Can be null.
+ */
+ List<SearchIndexableRaw> getDynamicRawDataToIndex(Context context, boolean enabled);
+
+ /**
* Return a list of data keys that cannot be indexed. See {@link SearchIndexableRaw}
*
* @param context the context.
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 98db7c8..2507a34 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -24,6 +24,9 @@
import android.bluetooth.BluetoothUuid;
import android.content.Context;
import android.content.SharedPreferences;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.ParcelUuid;
import android.os.SystemClock;
import android.text.TextUtils;
@@ -55,6 +58,7 @@
// Some Hearing Aids (especially the 2nd device) needs more time to do service discovery
private static final long MAX_HEARING_AIDS_DELAY_FOR_AUTO_CONNECT = 15000;
private static final long MAX_HOGP_DELAY_FOR_AUTO_CONNECT = 30000;
+ private static final long MAX_MEDIA_PROFILE_CONNECT_DELAY = 60000;
private final Context mContext;
private final BluetoothAdapter mLocalAdapter;
@@ -90,9 +94,35 @@
private boolean mIsActiveDeviceA2dp = false;
private boolean mIsActiveDeviceHeadset = false;
private boolean mIsActiveDeviceHearingAid = false;
+ // Media profile connect state
+ private boolean mIsA2dpProfileConnectedFail = false;
+ private boolean mIsHeadsetProfileConnectedFail = false;
+ private boolean mIsHearingAidProfileConnectedFail = false;
// Group second device for Hearing Aid
private CachedBluetoothDevice mSubDevice;
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case BluetoothProfile.A2DP:
+ mIsA2dpProfileConnectedFail = true;
+ break;
+ case BluetoothProfile.HEADSET:
+ mIsHeadsetProfileConnectedFail = true;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mIsHearingAidProfileConnectedFail = true;
+ break;
+ default:
+ Log.w(TAG, "handleMessage(): unknown message : " + msg.what);
+ break;
+ }
+ Log.w(TAG, "Connect to profile : " + msg.what + " timeout, show error message !");
+ refresh();
+ }
+ };
+
CachedBluetoothDevice(Context context, LocalBluetoothProfileManager profileManager,
BluetoothDevice device) {
mContext = context;
@@ -133,6 +163,35 @@
}
synchronized (mProfileLock) {
+ if (profile instanceof A2dpProfile || profile instanceof HeadsetProfile
+ || profile instanceof HearingAidProfile) {
+ setProfileConnectedStatus(profile.getProfileId(), false);
+ switch (newProfileState) {
+ case BluetoothProfile.STATE_CONNECTED:
+ mHandler.removeMessages(profile.getProfileId());
+ break;
+ case BluetoothProfile.STATE_CONNECTING:
+ mHandler.sendEmptyMessageDelayed(profile.getProfileId(),
+ MAX_MEDIA_PROFILE_CONNECT_DELAY);
+ break;
+ case BluetoothProfile.STATE_DISCONNECTING:
+ if (mHandler.hasMessages(profile.getProfileId())) {
+ mHandler.removeMessages(profile.getProfileId());
+ }
+ break;
+ case BluetoothProfile.STATE_DISCONNECTED:
+ if (mHandler.hasMessages(profile.getProfileId())) {
+ mHandler.removeMessages(profile.getProfileId());
+ setProfileConnectedStatus(profile.getProfileId(), true);
+ }
+ break;
+ default:
+ Log.w(TAG, "onProfileStateChanged(): unknown profile state : "
+ + newProfileState);
+ break;
+ }
+ }
+
if (newProfileState == BluetoothProfile.STATE_CONNECTED) {
if (profile instanceof MapProfile) {
profile.setPreferred(mDevice, true);
@@ -162,6 +221,24 @@
fetchActiveDevices();
}
+ @VisibleForTesting
+ void setProfileConnectedStatus(int profileId, boolean isFailed) {
+ switch (profileId) {
+ case BluetoothProfile.A2DP:
+ mIsA2dpProfileConnectedFail = isFailed;
+ break;
+ case BluetoothProfile.HEADSET:
+ mIsHeadsetProfileConnectedFail = isFailed;
+ break;
+ case BluetoothProfile.HEARING_AID:
+ mIsHearingAidProfileConnectedFail = isFailed;
+ break;
+ default:
+ Log.w(TAG, "setProfileConnectedStatus(): unknown profile id : " + profileId);
+ break;
+ }
+ }
+
public void disconnect() {
synchronized (mProfileLock) {
for (LocalBluetoothProfile profile : mProfiles) {
@@ -844,6 +921,10 @@
int leftBattery = -1;
int rightBattery = -1;
+ if (isProfileConnectedFail() && isConnected()) {
+ return mContext.getString(R.string.profile_connect_timeout_subtext);
+ }
+
synchronized (mProfileLock) {
for (LocalBluetoothProfile profile : getProfiles()) {
int connectionStatus = getProfileConnectionState(profile);
@@ -943,6 +1024,11 @@
return leftBattery >= 0 && rightBattery >= 0;
}
+ private boolean isProfileConnectedFail() {
+ return mIsA2dpProfileConnectedFail || mIsHearingAidProfileConnectedFail
+ || mIsHeadsetProfileConnectedFail;
+ }
+
/**
* @return resource for android auto string that describes the connection state of this device.
*/
diff --git a/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
index 4e052f1..69f1c17 100644
--- a/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/utils/ThreadUtils.java
@@ -18,6 +18,7 @@
import android.os.Handler;
import android.os.Looper;
+import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
@@ -64,11 +65,16 @@
* @Return A future of the task that can be monitored for updates or cancelled.
*/
public static Future postOnBackgroundThread(Runnable runnable) {
- if (sThreadExecutor == null) {
- sThreadExecutor = Executors.newFixedThreadPool(
- Runtime.getRuntime().availableProcessors());
- }
- return sThreadExecutor.submit(runnable);
+ return getThreadExecutor().submit(runnable);
+ }
+
+ /**
+ * Posts callable in background using shared background thread pool.
+ *
+ * @Return A future of the task that can be monitored for updates or cancelled.
+ */
+ public static Future postOnBackgroundThread(Callable callable) {
+ return getThreadExecutor().submit(callable);
}
/**
@@ -78,4 +84,11 @@
getUiThreadHandler().post(runnable);
}
+ private static synchronized ExecutorService getThreadExecutor() {
+ if (sThreadExecutor == null) {
+ sThreadExecutor = Executors.newFixedThreadPool(
+ Runtime.getRuntime().availableProcessors());
+ }
+ return sThreadExecutor;
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 93dcbfe..5c89a01 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -21,6 +21,7 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
@@ -31,6 +32,8 @@
import android.content.Context;
import android.media.AudioManager;
+import com.android.settingslib.R;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -922,4 +925,16 @@
assertThat(subCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_1);
assertThat(subCachedDevice.mDevice).isEqualTo(mDevice);
}
+
+ @Test
+ public void getConnectionSummary_profileConnectedFail_showErrorMessage() {
+ final A2dpProfile profle = mock(A2dpProfile.class);
+ mCachedDevice.onProfileStateChanged(profle, BluetoothProfile.STATE_CONNECTED);
+ mCachedDevice.setProfileConnectedStatus(BluetoothProfile.A2DP, true);
+
+ when(profle.getConnectionStatus(mDevice)).thenReturn(BluetoothProfile.STATE_CONNECTED);
+
+ assertThat(mCachedDevice.getConnectionSummary()).isEqualTo(
+ mContext.getString(R.string.profile_connect_timeout_subtext));
+ }
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index d28c1aa..55a51da 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -56,8 +56,6 @@
ConfigSettingsProto.CONNECTIVITY_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
ConfigSettingsProto.CONTENT_CAPTURE_SETTINGS);
- namespaceToFieldMap.put(DeviceConfig.NAMESPACE_DEX_BOOT,
- ConfigSettingsProto.DEX_BOOT_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_GAME_DRIVER,
ConfigSettingsProto.GAME_DRIVER_SETTINGS);
namespaceToFieldMap.put(DeviceConfig.NAMESPACE_INPUT_NATIVE_BOOT,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index fdc987f..7765935 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2115,10 +2115,7 @@
}
private static String getSettingPrefix(Bundle args) {
- String prefix = (args != null) ? args.getString(Settings.CALL_METHOD_PREFIX_KEY) : null;
- // Append '/' to ensure we only match properties with this exact prefix.
- // i.e. "foo" should match "foo/property" but not "foobar/property"
- return prefix != null ? prefix + "/" : null;
+ return (args != null) ? args.getString(Settings.CALL_METHOD_PREFIX_KEY) : null;
}
private static boolean getSettingMakeDefault(Bundle args) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 54e291f..c59f342 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -180,6 +180,8 @@
<uses-permission android:name="android.permission.MANAGE_WIFI_WHEN_WIRELESS_CONSENT_REQUIRED" />
<!-- Permission needed to invoke DynamicSystem (AOT) -->
<uses-permission android:name="android.permission.INSTALL_DYNAMIC_SYSTEM" />
+ <!-- Used to clean up heap dumps on boot. -->
+ <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
@@ -209,7 +211,7 @@
<!-- Permission required to test ExplicitHealthCheckServiceImpl. -->
<uses-permission android:name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE" />
-
+
<!-- Permission required for CTS test - CrossProfileAppsHostSideTest -->
<uses-permission android:name="android.permission.INTERACT_ACROSS_PROFILES"/>
@@ -239,6 +241,11 @@
</intent-filter>
</provider>
+ <provider android:name=".HeapDumpProvider"
+ android:authorities="com.android.shell.heapdump"
+ android:grantUriPermissions="true"
+ android:exported="true" />
+
<activity
android:name=".BugreportWarningActivity"
android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight"
@@ -246,6 +253,14 @@
android:excludeFromRecents="true"
android:exported="false" />
+ <activity android:name=".HeapDumpActivity"
+ android:theme="@*android:style/Theme.Translucent.NoTitleBar"
+ android:label="@*android:string/dump_heap_title"
+ android:finishOnCloseSystemDialogs="true"
+ android:noHistory="true"
+ android:excludeFromRecents="true"
+ android:exported="false" />
+
<receiver
android:name=".BugreportRequestedReceiver"
android:permission="android.permission.TRIGGER_SHELL_BUGREPORT">
@@ -254,6 +269,16 @@
</intent-filter>
</receiver>
+ <receiver
+ android:name=".HeapDumpReceiver"
+ android:permission="android.permission.DUMP">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ <action android:name="com.android.internal.intent.action.HEAP_DUMP_FINISHED" />
+ <action android:name="com.android.shell.action.DELETE_HEAP_DUMP" />
+ </intent-filter>
+ </receiver>
+
<service
android:name=".BugreportProgressService"
android:exported="false"/>
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 1b35770..30ad9c5 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -1560,7 +1560,7 @@
return false;
}
- private static boolean isTv(Context context) {
+ static boolean isTv(Context context) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpActivity.java b/packages/Shell/src/com/android/shell/HeapDumpActivity.java
new file mode 100644
index 0000000..0ff0d33
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpActivity.java
@@ -0,0 +1,142 @@
+/*
+ * 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.shell;
+
+import static com.android.shell.HeapDumpProvider.makeUri;
+import static com.android.shell.HeapDumpReceiver.ACTION_DELETE_HEAP_DUMP;
+import static com.android.shell.HeapDumpReceiver.EXTRA_IS_USER_INITIATED;
+import static com.android.shell.HeapDumpReceiver.EXTRA_PROCESS_NAME;
+import static com.android.shell.HeapDumpReceiver.EXTRA_REPORT_PACKAGE;
+import static com.android.shell.HeapDumpReceiver.EXTRA_SIZE_BYTES;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ClipData;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Process;
+import android.util.DebugUtils;
+import android.util.Log;
+
+import com.android.internal.R;
+
+/**
+ * This activity is displayed when the system has collected a heap dump.
+ */
+public class HeapDumpActivity extends Activity {
+ private static final String TAG = "HeapDumpActivity";
+
+ static final String KEY_URI = "uri";
+
+ private AlertDialog mDialog;
+ private Uri mDumpUri;
+ private boolean mHandled = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String process = getIntent().getStringExtra(EXTRA_PROCESS_NAME);
+ long size = getIntent().getLongExtra(EXTRA_SIZE_BYTES, 0);
+ final boolean isUserInitiated = getIntent().getBooleanExtra(EXTRA_IS_USER_INITIATED, false);
+ final int uid = getIntent().getIntExtra(Intent.EXTRA_UID, 0);
+ final boolean isSystemProcess = uid == Process.SYSTEM_UID;
+ mDumpUri = makeUri(process);
+ final String procDisplayName = isSystemProcess
+ ? getString(com.android.internal.R.string.android_system_label)
+ : process;
+
+ final Intent sendIntent = new Intent();
+ ClipData clip = ClipData.newUri(getContentResolver(), "Heap Dump", mDumpUri);
+ sendIntent.setClipData(clip);
+ sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ sendIntent.setType(clip.getDescription().getMimeType(0));
+ sendIntent.putExtra(Intent.EXTRA_STREAM, mDumpUri);
+
+ String directLaunchPackage = getIntent().getStringExtra(EXTRA_REPORT_PACKAGE);
+ if (directLaunchPackage != null) {
+ sendIntent.setAction(ActivityManager.ACTION_REPORT_HEAP_LIMIT);
+ sendIntent.setPackage(directLaunchPackage);
+ try {
+ startActivity(sendIntent);
+ mHandled = true;
+ finish();
+ return;
+ } catch (ActivityNotFoundException e) {
+ Log.e(TAG, "Unable to direct launch to " + directLaunchPackage, e);
+ }
+ }
+
+ final int messageId;
+ if (isUserInitiated) {
+ messageId = com.android.internal.R.string.dump_heap_ready_text;
+ } else if (isSystemProcess) {
+ messageId = com.android.internal.R.string.dump_heap_system_text;
+ } else {
+ messageId = com.android.internal.R.string.dump_heap_text;
+ }
+ mDialog = new AlertDialog.Builder(this, android.R.style.Theme_Material_Light_Dialog_Alert)
+ .setTitle(com.android.internal.R.string.dump_heap_title)
+ .setMessage(getString(messageId, procDisplayName,
+ DebugUtils.sizeValueToString(size, null)))
+ .setNegativeButton(android.R.string.cancel, (dialog, which) -> {
+ mHandled = true;
+ finish();
+ })
+ .setNeutralButton(R.string.delete, (dialog, which) -> {
+ mHandled = true;
+ Intent deleteIntent = new Intent(ACTION_DELETE_HEAP_DUMP);
+ deleteIntent.setClass(getApplicationContext(), HeapDumpReceiver.class);
+ deleteIntent.putExtra(KEY_URI, mDumpUri.toString());
+ sendBroadcast(deleteIntent);
+ finish();
+ })
+ .setPositiveButton(android.R.string.ok, (dialog, which) -> {
+ mHandled = true;
+ sendIntent.setAction(Intent.ACTION_SEND);
+ sendIntent.setPackage(null);
+ startActivity(Intent.createChooser(sendIntent,
+ getText(com.android.internal.R.string.dump_heap_title)));
+ finish();
+ })
+ .show();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ if (!isChangingConfigurations()) {
+ if (!mHandled) {
+ Intent deleteIntent = new Intent(ACTION_DELETE_HEAP_DUMP);
+ deleteIntent.setClass(getApplicationContext(), HeapDumpReceiver.class);
+ deleteIntent.putExtra(KEY_URI, mDumpUri.toString());
+ sendBroadcast(deleteIntent);
+ }
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
+ }
+}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpProvider.java b/packages/Shell/src/com/android/shell/HeapDumpProvider.java
new file mode 100644
index 0000000..3eceb91
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpProvider.java
@@ -0,0 +1,101 @@
+/*
+ * 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.shell;
+
+import android.annotation.NonNull;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/** ContentProvider to write and access heap dumps. */
+public class HeapDumpProvider extends ContentProvider {
+ private static final String FILENAME_SUFFIX = "_javaheap.bin";
+ private static final Object sLock = new Object();
+
+ private File mRoot;
+
+ @Override
+ public boolean onCreate() {
+ synchronized (sLock) {
+ mRoot = new File(getContext().createCredentialProtectedStorageContext().getFilesDir(),
+ "heapdumps");
+ return mRoot.mkdir();
+ }
+ }
+
+ @Override
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ return null;
+ }
+
+ @Override
+ public String getType(Uri uri) {
+ return "application/octet-stream";
+ }
+
+ @Override
+ public Uri insert(Uri uri, ContentValues values) {
+ throw new UnsupportedOperationException("Insert not allowed.");
+ }
+
+ @Override
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ String path = sanitizePath(uri.getEncodedPath());
+ String tag = Uri.decode(path);
+ return (new File(mRoot, tag)).delete() ? 1 : 0;
+ }
+
+ @Override
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException("Update not allowed.");
+ }
+
+ @Override
+ public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+ String path = sanitizePath(uri.getEncodedPath());
+ String tag = Uri.decode(path);
+ final int pMode;
+ if (Binder.getCallingUid() == Process.SYSTEM_UID) {
+ pMode = ParcelFileDescriptor.MODE_CREATE
+ | ParcelFileDescriptor.MODE_TRUNCATE
+ | ParcelFileDescriptor.MODE_WRITE_ONLY;
+ } else {
+ pMode = ParcelFileDescriptor.MODE_READ_ONLY;
+ }
+
+ synchronized (sLock) {
+ return ParcelFileDescriptor.open(new File(mRoot, tag), pMode);
+ }
+ }
+
+ @NonNull
+ static Uri makeUri(@NonNull String procName) {
+ return Uri.parse("content://com.android.shell.heapdump/" + procName + FILENAME_SUFFIX);
+ }
+
+ private String sanitizePath(String path) {
+ return path.replaceAll("[^a-zA-Z0-9_.]", "");
+ }
+}
diff --git a/packages/Shell/src/com/android/shell/HeapDumpReceiver.java b/packages/Shell/src/com/android/shell/HeapDumpReceiver.java
new file mode 100644
index 0000000..858c521
--- /dev/null
+++ b/packages/Shell/src/com/android/shell/HeapDumpReceiver.java
@@ -0,0 +1,188 @@
+/*
+ * 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.shell;
+
+import static com.android.shell.BugreportProgressService.isTv;
+
+import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.FileUtils;
+import android.os.Process;
+import android.text.format.DateUtils;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * Receiver that handles finished heap dumps.
+ */
+public class HeapDumpReceiver extends BroadcastReceiver {
+ private static final String TAG = "HeapDumpReceiver";
+
+ /**
+ * Broadcast action to determine when to delete a specific dump heap. Must include a {@link
+ * HeapDumpActivity#KEY_URI} String extra.
+ */
+ static final String ACTION_DELETE_HEAP_DUMP = "com.android.shell.action.DELETE_HEAP_DUMP";
+
+ /** Broadcast sent when heap dump collection has been completed. */
+ private static final String ACTION_HEAP_DUMP_FINISHED =
+ "com.android.internal.intent.action.HEAP_DUMP_FINISHED";
+
+ /** The process we are reporting */
+ static final String EXTRA_PROCESS_NAME = "com.android.internal.extra.heap_dump.PROCESS_NAME";
+
+ /** The size limit the process reached. */
+ static final String EXTRA_SIZE_BYTES = "com.android.internal.extra.heap_dump.SIZE_BYTES";
+
+ /** Whether the user initiated the dump or not. */
+ static final String EXTRA_IS_USER_INITIATED =
+ "com.android.internal.extra.heap_dump.IS_USER_INITIATED";
+
+ /** Optional name of package to directly launch. */
+ static final String EXTRA_REPORT_PACKAGE =
+ "com.android.internal.extra.heap_dump.REPORT_PACKAGE";
+
+ private static final String NOTIFICATION_CHANNEL_ID = "heapdumps";
+ private static final int NOTIFICATION_ID = 2019;
+
+ /**
+ * Always keep heap dumps taken in the last week.
+ */
+ private static final long MIN_KEEP_AGE_MS = DateUtils.WEEK_IN_MILLIS;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Log.d(TAG, "onReceive(): " + intent);
+ final String action = intent.getAction();
+ if (action == null) {
+ Log.e(TAG, "null action received");
+ return;
+ }
+ switch (action) {
+ case Intent.ACTION_BOOT_COMPLETED:
+ cleanupOldFiles(context);
+ break;
+ case ACTION_DELETE_HEAP_DUMP:
+ deleteHeapDump(context, intent.getStringExtra(HeapDumpActivity.KEY_URI));
+ break;
+ case ACTION_HEAP_DUMP_FINISHED:
+ showDumpNotification(context, intent);
+ break;
+ }
+ }
+
+ private void cleanupOldFiles(Context context) {
+ final PendingResult result = goAsync();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ try {
+ Log.d(TAG, "Deleting from " + new File(context.getFilesDir(), "heapdumps"));
+ FileUtils.deleteOlderFiles(new File(context.getFilesDir(), "heapdumps"), 0,
+ MIN_KEEP_AGE_MS);
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Couldn't delete old files", e);
+ }
+ result.finish();
+ return null;
+ }
+ }.execute();
+ }
+
+ private void deleteHeapDump(Context context, @Nullable final String uri) {
+ if (uri == null) {
+ Log.e(TAG, "null URI for delete heap dump intent");
+ return;
+ }
+ final PendingResult result = goAsync();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ context.getContentResolver().delete(Uri.parse(uri), null, null);
+ result.finish();
+ return null;
+ }
+ }.execute();
+ }
+
+ private void showDumpNotification(Context context, Intent intent) {
+ final boolean isUserInitiated = intent.getBooleanExtra(
+ EXTRA_IS_USER_INITIATED, false);
+ final String procName = intent.getStringExtra(EXTRA_PROCESS_NAME);
+ final int uid = intent.getIntExtra(Intent.EXTRA_UID, 0);
+
+ final String reportPackage = intent.getStringExtra(
+ EXTRA_REPORT_PACKAGE);
+ final long size = intent.getLongExtra(EXTRA_SIZE_BYTES, 0);
+
+ if (procName == null) {
+ Log.e(TAG, "No process name sent over");
+ return;
+ }
+
+ NotificationManager nm = NotificationManager.from(context);
+ nm.createNotificationChannel(
+ new NotificationChannel(NOTIFICATION_CHANNEL_ID,
+ "Heap dumps",
+ NotificationManager.IMPORTANCE_DEFAULT));
+
+ final int titleId = isUserInitiated
+ ? com.android.internal.R.string.dump_heap_ready_notification
+ : com.android.internal.R.string.dump_heap_notification;
+ final String procDisplayName = uid == Process.SYSTEM_UID
+ ? context.getString(com.android.internal.R.string.android_system_label)
+ : procName;
+ String text = context.getString(titleId, procDisplayName);
+
+ Intent shareIntent = new Intent();
+ shareIntent.setClassName(context, HeapDumpActivity.class.getName());
+ shareIntent.putExtra(EXTRA_PROCESS_NAME, procName);
+ shareIntent.putExtra(EXTRA_SIZE_BYTES, size);
+ shareIntent.putExtra(EXTRA_IS_USER_INITIATED, isUserInitiated);
+ shareIntent.putExtra(Intent.EXTRA_UID, uid);
+ if (reportPackage != null) {
+ shareIntent.putExtra(EXTRA_REPORT_PACKAGE, reportPackage);
+ }
+ final Notification.Builder builder = new Notification.Builder(context,
+ NOTIFICATION_CHANNEL_ID)
+ .setSmallIcon(
+ isTv(context) ? R.drawable.ic_bug_report_black_24dp
+ : com.android.internal.R.drawable.stat_sys_adb)
+ .setLocalOnly(true)
+ .setColor(context.getColor(
+ com.android.internal.R.color.system_notification_accent_color))
+ .setContentTitle(text)
+ .setTicker(text)
+ .setAutoCancel(true)
+ .setContentText(context.getText(
+ com.android.internal.R.string.dump_heap_notification_detail))
+ .setContentIntent(PendingIntent.getActivity(context, 2, shareIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT));
+
+ Log.v(TAG, "Creating share heap dump notification");
+ NotificationManager.from(context).notify(NOTIFICATION_ID, builder.build());
+ }
+}
diff --git a/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml b/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml
index ff89bbc..e9e8441 100644
--- a/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml
+++ b/packages/SystemUI/plugin/ExamplePlugin/AndroidManifest.xml
@@ -22,14 +22,16 @@
<application>
<activity android:name=".PluginSettings"
- android:label="@string/plugin_label">
+ android:label="@string/plugin_label"
+ android:exported="false">
<intent-filter>
<action android:name="com.android.systemui.action.PLUGIN_SETTINGS" />
</intent-filter>
</activity>
<service android:name=".SampleOverlayPlugin"
- android:label="@string/plugin_label">
+ android:label="@string/plugin_label"
+ android:exported="false">
<intent-filter>
<action android:name="com.android.systemui.action.PLUGIN_OVERLAY" />
</intent-filter>
diff --git a/packages/SystemUI/res/layout/home_controls.xml b/packages/SystemUI/res/layout/home_controls.xml
index b9a6a48..69a0e87 100644
--- a/packages/SystemUI/res/layout/home_controls.xml
+++ b/packages/SystemUI/res/layout/home_controls.xml
@@ -3,7 +3,7 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/home_controls_layout"
android:layout_width="match_parent"
- android:layout_height="125dp"
+ android:layout_height="wrap_content"
android:layout_gravity="@integer/notification_panel_layout_gravity"
android:visibility="gone"
android:padding="8dp"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
index 7d6ff3b1..69beffe 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_plugin_frame.xml
@@ -20,7 +20,7 @@
android:id="@+id/plugin_frame"
android:theme="@style/qs_theme"
android:layout_width="@dimen/qs_panel_width"
- android:layout_height="105dp"
+ android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/notification_side_paddings"
android:layout_marginLeft="@dimen/notification_side_paddings"
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentHelper.java b/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentHelper.java
index d6d1e41..37a447f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentHelper.java
@@ -20,6 +20,7 @@
import android.app.Service;
import com.android.systemui.SystemUI;
+import com.android.systemui.recents.RecentsImplementation;
/**
* Interface necessary to make Dagger happy. See {@link ContextComponentResolver}.
@@ -29,6 +30,9 @@
Activity resolveActivity(String className);
/** Turns a classname into an instance of the class or returns null. */
+ RecentsImplementation resolveRecents(String className);
+
+ /** Turns a classname into an instance of the class or returns null. */
Service resolveService(String className);
/** Turns a classname into an instance of the class or returns null. */
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentResolver.java b/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentResolver.java
index d7822c9..06339bd 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentResolver.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/ContextComponentResolver.java
@@ -20,6 +20,7 @@
import android.app.Service;
import com.android.systemui.SystemUI;
+import com.android.systemui.recents.RecentsImplementation;
import java.util.Map;
@@ -35,15 +36,17 @@
private final Map<Class<?>, Provider<Activity>> mActivityCreators;
private final Map<Class<?>, Provider<Service>> mServiceCreators;
private final Map<Class<?>, Provider<SystemUI>> mSystemUICreators;
+ private final Map<Class<?>, Provider<RecentsImplementation>> mRecentsCreators;
@Inject
- ContextComponentResolver(
- Map<Class<?>, Provider<Activity>> activityCreators,
+ ContextComponentResolver(Map<Class<?>, Provider<Activity>> activityCreators,
Map<Class<?>, Provider<Service>> serviceCreators,
- Map<Class<?>, Provider<SystemUI>> systemUICreators) {
+ Map<Class<?>, Provider<SystemUI>> systemUICreators,
+ Map<Class<?>, Provider<RecentsImplementation>> recentsCreators) {
mActivityCreators = activityCreators;
mServiceCreators = serviceCreators;
mSystemUICreators = systemUICreators;
+ mRecentsCreators = recentsCreators;
}
/**
@@ -55,6 +58,14 @@
}
/**
+ * Looks up the RecentsImplementation class name to see if Dagger has an instance of it.
+ */
+ @Override
+ public RecentsImplementation resolveRecents(String className) {
+ return resolve(className, mRecentsCreators);
+ }
+
+ /**
* Looks up the Service class name to see if Dagger has an instance of it.
*/
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 27c526b..c3d2a1f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -16,20 +16,89 @@
package com.android.systemui.dagger;
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.util.DisplayMetrics;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.systemui.ForegroundServiceController;
import com.android.systemui.LatencyTester;
import com.android.systemui.ScreenDecorations;
import com.android.systemui.SystemUI;
+import com.android.systemui.UiOffloadThread;
+import com.android.systemui.appops.AppOpsController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.bubbles.BubbleController;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.pip.PipUI;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.power.PowerUI;
import com.android.systemui.recents.Recents;
import com.android.systemui.recents.RecentsModule;
+import com.android.systemui.statusbar.FeatureFlags;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NewNotifPipeline;
+import com.android.systemui.statusbar.notification.NotificationAlertingManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotifLog;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.DozeScrimController;
+import com.android.systemui.statusbar.phone.DozeServiceHost;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
+import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.util.leak.GarbageMonitor;
import com.android.systemui.volume.VolumeUI;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
import dagger.Binds;
+import dagger.Lazy;
import dagger.Module;
+import dagger.Provides;
import dagger.multibindings.ClassKey;
import dagger.multibindings.IntoMap;
@@ -93,4 +162,139 @@
@ClassKey(VolumeUI.class)
public abstract SystemUI bindVolumeUI(VolumeUI sysui);
+ /**
+ * Provides our instance of StatusBar which is considered optional.
+ */
+ @Provides
+ @Singleton
+ static StatusBar provideStatusBar(
+ Context context,
+ FeatureFlags featureFlags,
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ DozeLog dozeLog,
+ InjectionInflationController injectionInflationController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowNotificationLongPress,
+ Lazy<NewNotifPipeline> newNotifPipeline,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationEntryManager notificationEntryManager,
+ NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ ForegroundServiceController foregroundServiceController,
+ AppOpsController appOpsController,
+ KeyguardViewMediator keyguardViewMediator,
+ ZenModeController zenModeController,
+ NotificationAlertingManager notificationAlertingManager,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ UiOffloadThread uiOffloadThread,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ NotificationGroupAlertTransferHelper groupAlertTransferHelper,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ AssistManager assistManager,
+ NotificationListener notificationListener,
+ ConfigurationController configurationController,
+ StatusBarWindowController statusBarWindowController,
+ StatusBarWindowViewController.Builder statusBarWindowViewControllerBuilder,
+ NotifLog notifLog,
+ DozeParameters dozeParameters,
+ ScrimController scrimController,
+ Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
+ Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
+ DozeServiceHost dozeServiceHost,
+ PowerManager powerManager,
+ DozeScrimController dozeScrimController) {
+ return new StatusBar(
+ context,
+ featureFlags,
+ lightBarController,
+ autoHideController,
+ keyguardUpdateMonitor,
+ statusBarIconController,
+ dozeLog,
+ injectionInflationController,
+ pulseExpansionHandler,
+ notificationWakeUpCoordinator,
+ keyguardBypassController,
+ keyguardStateController,
+ headsUpManagerPhone,
+ dynamicPrivacyController,
+ bypassHeadsUpNotifier,
+ allowNotificationLongPress,
+ newNotifPipeline,
+ falsingManager,
+ broadcastDispatcher,
+ remoteInputQuickSettingsDisabler,
+ notificationGutsManager,
+ notificationLogger,
+ notificationEntryManager,
+ notificationInterruptionStateProvider,
+ notificationViewHierarchyManager,
+ foregroundServiceController,
+ appOpsController,
+ keyguardViewMediator,
+ zenModeController,
+ notificationAlertingManager,
+ displayMetrics,
+ metricsLogger,
+ uiOffloadThread,
+ notificationMediaManager,
+ lockScreenUserManager,
+ remoteInputManager,
+ userSwitcherController,
+ networkController,
+ batteryController,
+ colorExtractor,
+ screenLifecycle,
+ wakefulnessLifecycle,
+ statusBarStateController,
+ vibratorHelper,
+ bubbleController,
+ groupManager,
+ groupAlertTransferHelper,
+ visualStabilityManager,
+ deviceProvisionedController,
+ navigationBarController,
+ assistManager,
+ notificationListener,
+ configurationController,
+ statusBarWindowController,
+ statusBarWindowViewControllerBuilder,
+ notifLog,
+ dozeParameters,
+ scrimController,
+ lockscreenWallpaperLazy,
+ biometricUnlockControllerLazy,
+ dozeServiceHost,
+ powerManager,
+ dozeScrimController);
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index ca8e53d..5f1455f 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -26,11 +26,13 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.people.PeopleHubModule;
import com.android.systemui.statusbar.phone.KeyguardLiftController;
+import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.util.sensors.AsyncSensorManager;
import javax.inject.Singleton;
import dagger.Binds;
+import dagger.BindsOptionalOf;
import dagger.Module;
import dagger.Provides;
@@ -65,4 +67,7 @@
static SysUiState provideSysUiState() {
return new SysUiState();
}
+
+ @BindsOptionalOf
+ abstract StatusBar optionalStatusBar();
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/RichEvent.java b/packages/SystemUI/src/com/android/systemui/log/RichEvent.java
index 89b7a818..acf761ed 100644
--- a/packages/SystemUI/src/com/android/systemui/log/RichEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/log/RichEvent.java
@@ -67,7 +67,7 @@
private B mBuilder = getBuilder();
protected int mType = UNINITIALIZED;
protected String mReason;
- protected @Level int mLogLevel;
+ protected @Level int mLogLevel = VERBOSE;
/**
* Get the log-specific builder.
diff --git a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
index a6e10e6..f094cb9 100644
--- a/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/SysuiLog.java
@@ -120,9 +120,9 @@
}
/**
- * @return user-readable string of the given event
+ * @return user-readable string of the given event with timestamp
*/
- public String eventToString(Event event) {
+ public String eventToTimestampedString(Event event) {
StringBuilder sb = new StringBuilder();
sb.append(SysuiLog.DATE_FORMAT.format(event.getTimestamp()));
sb.append(" ");
@@ -131,13 +131,20 @@
}
/**
+ * @return user-readable string of the given event without a timestamp
+ */
+ public String eventToString(Event event) {
+ return event.getMessage();
+ }
+
+ /**
* only call on this method if you have the mDataLock
*/
private void dumpTimelineLocked(PrintWriter pw) {
pw.println("\tTimeline:");
for (Event event : mTimeline) {
- pw.println("\t" + eventToString(event));
+ pw.println("\t" + eventToTimestampedString(event));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index a267bbb..a0ea7fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -14,7 +14,6 @@
package com.android.systemui.qs;
-import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.View.OnAttachStateChangeListener;
@@ -31,6 +30,7 @@
import com.android.systemui.qs.TouchAnimator.Listener;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
+import com.android.systemui.util.Utils;
import java.util.ArrayList;
import java.util.Collection;
@@ -270,9 +270,7 @@
}
- int flag = Settings.System.getInt(mQsPanel.getContext().getContentResolver(),
- "qs_media_player", 0);
- if (flag == 1) {
+ if (Utils.useQsMediaPlayer(mQsPanel.getContext())) {
View qsMediaView = mQsPanel.getMediaPanel();
View qqsMediaView = mQuickQsPanel.getMediaPlayer().getView();
translationXBuilder.addFloat(qsMediaView, "alpha", 0, 1);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index b48814b..39f0865 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -18,6 +18,7 @@
import static com.android.systemui.qs.tileimpl.QSTileImpl.getColorForState;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+import static com.android.systemui.util.Utils.useQsMediaPlayer;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -150,8 +151,7 @@
addDivider();
// Add media carousel
- int flag = Settings.System.getInt(context.getContentResolver(), "qs_media_player", 0);
- if (flag == 1) {
+ if (useQsMediaPlayer(context)) {
HorizontalScrollView mediaScrollView = new HorizontalScrollView(mContext);
mediaScrollView.setHorizontalScrollBarEnabled(false);
int playerHeight = (int) getResources().getDimension(R.dimen.qs_media_height);
@@ -201,8 +201,7 @@
*/
public void addMediaSession(MediaSession.Token token, Icon icon, int iconColor, int bgColor,
View actionsContainer, StatusBarNotification notif) {
- int flag = Settings.System.getInt(mContext.getContentResolver(), "qs_media_player", 0);
- if (flag != 1) {
+ if (!useQsMediaPlayer(mContext)) {
// Shouldn't happen, but just in case
Log.e(TAG, "Tried to add media session without player!");
return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index dcd4633..94a1cf0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
-import android.provider.Settings;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -36,6 +35,7 @@
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
+import com.android.systemui.util.Utils;
import java.util.ArrayList;
import java.util.Collection;
@@ -72,8 +72,7 @@
removeView((View) mTileLayout);
}
- int flag = Settings.System.getInt(context.getContentResolver(), "qs_media_player", 0);
- if (flag == 1) {
+ if (Utils.useQsMediaPlayer(context)) {
LinearLayout mHorizontalLinearLayout = new LinearLayout(mContext);
mHorizontalLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
mHorizontalLinearLayout.setClipChildren(false);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 592e388..16c61e6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -17,6 +17,7 @@
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+import static com.android.systemui.util.Utils.useQsMediaPlayer;
import android.annotation.ColorInt;
import android.app.ActivityManager;
@@ -393,11 +394,10 @@
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
- int flag = Settings.System.getInt(mContext.getContentResolver(), "qs_media_player", 0);
if (mQsDisabled) {
lp.height = resources.getDimensionPixelSize(
com.android.internal.R.dimen.quick_qs_offset_height);
- } else if (flag == 1) {
+ } else if (useQsMediaPlayer(mContext)) {
lp.height = Math.max(getMinimumHeight(),
resources.getDimensionPixelSize(
com.android.internal.R.dimen.quick_qs_total_height_with_media));
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
index 958695d..7f11e56 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyRecentsImpl.java
@@ -20,6 +20,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.trust.TrustManager;
import android.content.Context;
@@ -40,12 +41,22 @@
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.statusbar.phone.StatusBar;
+import java.util.Optional;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
/**
* An implementation of the Recents interface which proxies to the OverviewProxyService.
*/
+@Singleton
public class OverviewProxyRecentsImpl implements RecentsImplementation {
private final static String TAG = "OverviewProxyRecentsImpl";
+ @Nullable
+ private final Lazy<StatusBar> mStatusBarLazy;
private SysUiServiceProvider mSysUiServiceProvider;
private Context mContext;
@@ -53,6 +64,12 @@
private TrustManager mTrustManager;
private OverviewProxyService mOverviewProxyService;
+ @SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+ @Inject
+ public OverviewProxyRecentsImpl(Optional<Lazy<StatusBar>> statusBarLazy) {
+ mStatusBarLazy = statusBarLazy.orElse(null);
+ }
+
@Override
public void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {
mContext = context;
@@ -107,9 +124,8 @@
}
};
// Preload only if device for current user is unlocked
- final StatusBar statusBar = mSysUiServiceProvider.getComponent(StatusBar.class);
- if (statusBar != null && statusBar.isKeyguardShowing()) {
- statusBar.executeRunnableDismissingKeyguard(() -> {
+ if (mStatusBarLazy != null && mStatusBarLazy.get().isKeyguardShowing()) {
+ mStatusBarLazy.get().executeRunnableDismissingKeyguard(() -> {
// Flush trustmanager before checking device locked per user
mTrustManager.reportKeyguardShowingChanged();
mHandler.post(toggleRecents);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
index 3efed3f..8cd17e9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImplementation.java
@@ -23,7 +23,10 @@
import java.io.PrintWriter;
-interface RecentsImplementation {
+/**
+ * API for creating a Recents view.
+ */
+public interface RecentsImplementation {
default void onStart(Context context, SysUiServiceProvider sysUiServiceProvider) {}
default void onBootCompleted() {}
default void onAppTransitionFinished() {}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java
index 5555285..f57bfad 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsModule.java
@@ -19,35 +19,53 @@
import android.content.Context;
import com.android.systemui.R;
+import com.android.systemui.dagger.ContextComponentHelper;
+import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
/**
* Dagger injection module for {@link RecentsImplementation}
*/
@Module
-public class RecentsModule {
+public abstract class RecentsModule {
+
/**
* @return The {@link RecentsImplementation} from the config.
*/
@Provides
- public RecentsImplementation provideRecentsImpl(Context context) {
+ public static RecentsImplementation provideRecentsImpl(Context context,
+ ContextComponentHelper componentHelper) {
final String clsName = context.getString(R.string.config_recentsComponent);
if (clsName == null || clsName.length() == 0) {
throw new RuntimeException("No recents component configured", null);
}
- Class<?> cls = null;
- try {
- cls = context.getClassLoader().loadClass(clsName);
- } catch (Throwable t) {
- throw new RuntimeException("Error loading recents component: " + clsName, t);
+ RecentsImplementation impl = componentHelper.resolveRecents(clsName);
+
+ if (impl == null) {
+ Class<?> cls = null;
+ try {
+ cls = context.getClassLoader().loadClass(clsName);
+ } catch (Throwable t) {
+ throw new RuntimeException("Error loading recents component: " + clsName, t);
+ }
+ try {
+ impl = (RecentsImplementation) cls.newInstance();
+ } catch (Throwable t) {
+ throw new RuntimeException("Error creating recents component: " + clsName, t);
+ }
}
- try {
- RecentsImplementation impl = (RecentsImplementation) cls.newInstance();
- return impl;
- } catch (Throwable t) {
- throw new RuntimeException("Error creating recents component: " + clsName, t);
- }
+
+ return impl;
}
+
+ /** */
+ @Binds
+ @IntoMap
+ @ClassKey(OverviewProxyRecentsImpl.class)
+ public abstract RecentsImplementation bindOverviewProxyRecentsImpl(
+ OverviewProxyRecentsImpl impl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index d6b87af..20a3e35 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -21,7 +21,6 @@
import android.os.Handler;
import android.os.Trace;
import android.os.UserHandle;
-import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -40,6 +39,7 @@
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.util.Assert;
+import com.android.systemui.util.Utils;
import java.util.ArrayList;
import java.util.HashMap;
@@ -146,9 +146,7 @@
final int N = activeNotifications.size();
for (int i = 0; i < N; i++) {
NotificationEntry ent = activeNotifications.get(i);
- int flag = Settings.System.getInt(mContext.getContentResolver(),
- "qs_media_player", 0);
- boolean hideMedia = (flag == 1);
+ boolean hideMedia = Utils.useQsMediaPlayer(mContext);
if (ent.isRowDismissed() || ent.isRowRemoved()
|| (ent.isMediaNotification() && hideMedia)
|| mBubbleController.isBubbleNotificationSuppressedFromShade(ent.getKey())) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
index 9bc0ca4..d0122c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java
@@ -28,7 +28,6 @@
import android.media.session.PlaybackState;
import android.metrics.LogMaker;
import android.os.Handler;
-import android.provider.Settings;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
@@ -48,6 +47,7 @@
import com.android.systemui.statusbar.TransformableView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.util.Utils;
import java.util.Timer;
import java.util.TimerTask;
@@ -182,8 +182,7 @@
final MediaSession.Token token = mRow.getEntry().getSbn().getNotification().extras
.getParcelable(Notification.EXTRA_MEDIA_SESSION);
- int flag = Settings.System.getInt(mContext.getContentResolver(), "qs_media_player", 0);
- if (flag == 1) {
+ if (Utils.useQsMediaPlayer(mContext)) {
StatusBarWindowController ctrl = Dependency.get(StatusBarWindowController.class);
QuickQSPanel panel = ctrl.getStatusBarView().findViewById(
com.android.systemui.R.id.quick_qs_panel);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index e00cfb1..467df37 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -109,6 +109,7 @@
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.InjectionInflationController;
+import com.android.systemui.util.Utils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -769,8 +770,7 @@
int sideMargin = res.getDimensionPixelOffset(R.dimen.notification_side_paddings);
int topMargin =
res.getDimensionPixelOffset(com.android.internal.R.dimen.quick_qs_total_height);
- int flag = Settings.System.getInt(mContext.getContentResolver(), "qs_media_player", 0);
- if (flag == 1) {
+ if (Utils.useQsMediaPlayer(mContext)) {
topMargin = res.getDimensionPixelOffset(
com.android.internal.R.dimen.quick_qs_total_height_with_media);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 35039a0..f21a9a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -750,6 +750,11 @@
}
private void onFinished(Callback callback) {
+ if (mPendingFrameCallback != null) {
+ // No animations can finish while we're waiting on the blanking to finish
+ return;
+
+ }
if (isAnimating(mScrimBehind)
|| isAnimating(mScrimInFront)
|| isAnimating(mScrimForBubble)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index afc147a..001599f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -156,6 +156,7 @@
import com.android.systemui.charging.WirelessChargingAnimation;
import com.android.systemui.classifier.FalsingLog;
import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.dagger.SystemUIBinder;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.ExtensionFragmentListener;
@@ -246,14 +247,11 @@
import java.util.ArrayList;
import java.util.Map;
-import javax.inject.Inject;
import javax.inject.Named;
-import javax.inject.Singleton;
import dagger.Lazy;
import dagger.Subcomponent;
-@Singleton
public class StatusBar extends SystemUI implements DemoMode,
ActivityStarter, KeyguardStateController.Callback,
OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
@@ -626,7 +624,12 @@
AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION};
- @Inject
+ /**
+ * Public constructor for StatusBar.
+ *
+ * StatusBar is considered optional, and therefore can not be marked as @Inject directly.
+ * Instead, an @Provide method is included in {@link SystemUIBinder}.
+ */
public StatusBar(
Context context,
FeatureFlags featureFlags,
diff --git a/packages/SystemUI/src/com/android/systemui/util/Utils.java b/packages/SystemUI/src/com/android/systemui/util/Utils.java
index 92a8d84..aa9c5ac 100644
--- a/packages/SystemUI/src/com/android/systemui/util/Utils.java
+++ b/packages/SystemUI/src/com/android/systemui/util/Utils.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.provider.Settings;
import android.view.View;
import com.android.systemui.SysUiServiceProvider;
@@ -124,4 +125,13 @@
&& QuickStepContract.isGesturalMode(navMode);
}
+ /**
+ * Allow the media player to be shown in the QS area, controlled by 2 flags.
+ */
+ public static boolean useQsMediaPlayer(Context context) {
+ int flag = Settings.System.getInt(context.getContentResolver(), "qs_media_player", 0);
+ flag |= Settings.System.getInt(context.getContentResolver(), "npv_plugin_flag", 0);
+
+ return flag > 0;
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt
index a1822c7..f5d6f22 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/people/PeopleHubViewControllerTest.kt
@@ -50,19 +50,14 @@
fun testBindViewModelToViewBoundary() {
val fakePerson1 = fakePersonViewModel("name")
val fakeViewModel = PeopleHubViewModel(sequenceOf(fakePerson1), true)
-
val fakePersonViewAdapter1 = FakeDataListener<PersonViewModel?>()
val fakePersonViewAdapter2 = FakeDataListener<PersonViewModel?>()
-
val mockClickView = mock(View::class.java)
-
`when`(mockViewBoundary.associatedViewForClickAnimation).thenReturn(mockClickView)
`when`(mockViewBoundary.personViewAdapters)
.thenReturn(sequenceOf(fakePersonViewAdapter1, fakePersonViewAdapter2))
-
val mockFactory = mock(PeopleHubViewModelFactory::class.java)
`when`(mockFactory.createWithAssociatedClickView(any())).thenReturn(fakeViewModel)
-
val mockSubscription = mock(Subscription::class.java)
val fakeFactoryDataSource = object : DataSource<PeopleHubViewModelFactory> {
override fun registerListener(
@@ -82,6 +77,7 @@
verify(mockFactory).createWithAssociatedClickView(mockClickView)
}
+ @Test
fun testViewModelDataSourceTransformsModel() {
val fakeClickIntent = PendingIntent.getActivity(context, 0, Intent("action"), 0)
val fakePerson = fakePersonModel("id", "name", fakeClickIntent)
@@ -99,16 +95,17 @@
val mockClickView = mock(View::class.java)
factoryDataSource.registerListener(fakeListener)
+
val viewModel = (fakeListener.lastSeen as Maybe.Just).value
.createWithAssociatedClickView(mockClickView)
assertThat(viewModel.isVisible).isTrue()
-
val people = viewModel.people.toList()
assertThat(people.size).isEqualTo(1)
assertThat(people[0].name).isEqualTo("name")
assertThat(people[0].icon).isSameAs(fakePerson.avatar)
people[0].onClick()
+
verify(mockActivityStarter).startPendingIntentDismissingKeyguard(
same(fakeClickIntent),
any(),
@@ -117,16 +114,20 @@
}
}
+/** Works around Mockito matchers returning `null` and breaking non-nullable Kotlin code. */
private inline fun <reified T : Any> any(): T {
return Mockito.any() ?: createInstance(T::class)
}
+/** Works around Mockito matchers returning `null` and breaking non-nullable Kotlin code. */
private inline fun <reified T : Any> same(value: T): T {
return Mockito.same(value) ?: createInstance(T::class)
}
+/** Creates an instance of the given class. */
private fun <T : Any> createInstance(clazz: KClass<T>): T = castNull()
+/** Tricks the Kotlin compiler into assigning `null` to a non-nullable variable. */
@Suppress("UNCHECKED_CAST")
private fun <T> castNull(): T = null as T
diff --git a/packages/Tethering/Android.bp b/packages/Tethering/Android.bp
index 2bfe287..998572f 100644
--- a/packages/Tethering/Android.bp
+++ b/packages/Tethering/Android.bp
@@ -72,6 +72,7 @@
srcs: [
"src/com/android/server/connectivity/tethering/EntitlementManager.java",
"src/com/android/server/connectivity/tethering/TetheringConfiguration.java",
+ "src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java",
],
}
@@ -84,5 +85,6 @@
"src/android/net/ip/IpServer.java",
"src/android/net/ip/RouterAdvertisementDaemon.java",
"src/android/net/util/InterfaceSet.java",
+ "src/android/net/util/PrefixUtils.java",
],
}
diff --git a/packages/Tethering/AndroidManifestBase.xml b/packages/Tethering/AndroidManifestBase.xml
index b9cac19..dc013da 100644
--- a/packages/Tethering/AndroidManifestBase.xml
+++ b/packages/Tethering/AndroidManifestBase.xml
@@ -23,7 +23,6 @@
<application
android:label="Tethering"
android:defaultToDeviceProtectedStorage="true"
- android:directBootAware="true"
- android:usesCleartextTraffic="true">
+ android:directBootAware="true">
</application>
</manifest>
diff --git a/services/net/java/android/net/util/PrefixUtils.java b/packages/Tethering/src/android/net/util/PrefixUtils.java
similarity index 92%
rename from services/net/java/android/net/util/PrefixUtils.java
rename to packages/Tethering/src/android/net/util/PrefixUtils.java
index f60694a..f203e99 100644
--- a/services/net/java/android/net/util/PrefixUtils.java
+++ b/packages/Tethering/src/android/net/util/PrefixUtils.java
@@ -42,16 +42,19 @@
public static final IpPrefix DEFAULT_WIFI_P2P_PREFIX = pfx("192.168.49.0/24");
+ /** Get non forwardable prefixes. */
public static Set<IpPrefix> getNonForwardablePrefixes() {
final HashSet<IpPrefix> prefixes = new HashSet<>();
addNonForwardablePrefixes(prefixes);
return prefixes;
}
+ /** Add non forwardable prefixes. */
public static void addNonForwardablePrefixes(Set<IpPrefix> prefixes) {
Collections.addAll(prefixes, MIN_NON_FORWARDABLE_PREFIXES);
}
+ /** Get local prefixes from |lp|. */
public static Set<IpPrefix> localPrefixesFrom(LinkProperties lp) {
final HashSet<IpPrefix> localPrefixes = new HashSet<>();
if (lp == null) return localPrefixes;
@@ -66,10 +69,12 @@
return localPrefixes;
}
+ /** Convert LinkAddress |addr| to IpPrefix. */
public static IpPrefix asIpPrefix(LinkAddress addr) {
return new IpPrefix(addr.getAddress(), addr.getPrefixLength());
}
+ /** Convert InetAddress |ip| to IpPrefix. */
public static IpPrefix ipAddressAsPrefix(InetAddress ip) {
final int bitLength = (ip instanceof Inet4Address)
? NetworkConstants.IPV4_ADDR_BITS
diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
similarity index 93%
rename from services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
rename to packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
index 3a9e21f..9769596 100644
--- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
+++ b/packages/Tethering/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java
@@ -146,6 +146,7 @@
}
}
+ /** Listen all networks. */
public void startObserveAllNetworks() {
stop();
@@ -155,6 +156,13 @@
cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler);
}
+ /**
+ * Stop tracking candidate tethering upstreams and release mobile network request.
+ * Note: this function is used when tethering is stopped because tethering do not need to
+ * choose upstream anymore. But it would not stop default network tracking because
+ * EntitlementManager may need to know default network to decide whether to request entitlement
+ * check even tethering is not active yet.
+ */
public void stop() {
releaseMobileNetworkRequest();
@@ -165,6 +173,7 @@
mNetworkMap.clear();
}
+ /** Setup or teardown DUN connection according to |dunRequired|. */
public void updateMobileRequiresDun(boolean dunRequired) {
final boolean valueChanged = (mDunRequired != dunRequired);
mDunRequired = dunRequired;
@@ -174,10 +183,12 @@
}
}
+ /** Whether mobile network is requested. */
public boolean mobileNetworkRequested() {
return (mMobileNetworkCallback != null);
}
+ /** Request mobile network if mobile upstream is permitted. */
public void registerMobileNetworkRequest() {
if (!isCellularUpstreamPermitted()) {
mLog.i("registerMobileNetworkRequest() is not permitted");
@@ -209,6 +220,7 @@
cm().requestNetwork(mobileUpstreamRequest, mMobileNetworkCallback, 0, legacyType, mHandler);
}
+ /** Release mobile network request. */
public void releaseMobileNetworkRequest() {
if (mMobileNetworkCallback == null) return;
@@ -221,6 +233,9 @@
// becomes available and useful we (a) file a request to keep it up as
// necessary and (b) change all upstream tracking state accordingly (by
// passing LinkProperties up to Tethering).
+ /**
+ * Select the first available network from |perferredTypes|.
+ */
public NetworkState selectPreferredUpstreamType(Iterable<Integer> preferredTypes) {
final TypeStatePair typeStatePair = findFirstAvailableUpstreamByType(
mNetworkMap.values(), preferredTypes, isCellularUpstreamPermitted());
@@ -254,7 +269,11 @@
return typeStatePair.ns;
}
- // Returns null if no current upstream available.
+ /**
+ * Get current preferred upstream network. If default network is cellular and DUN is required,
+ * preferred upstream would be DUN otherwise preferred upstream is the same as default network.
+ * Returns null if no current upstream is available.
+ */
public NetworkState getCurrentPreferredUpstream() {
final NetworkState dfltState = (mDefaultInternetNetwork != null)
? mNetworkMap.get(mDefaultInternetNetwork)
@@ -270,10 +289,12 @@
return findFirstDunNetwork(mNetworkMap.values());
}
+ /** Tell UpstreamNetworkMonitor which network is the current upstream of tethering. */
public void setCurrentUpstream(Network upstream) {
mTetheringUpstreamNetwork = upstream;
}
+ /** Return local prefixes. */
public Set<IpPrefix> getLocalPrefixes() {
return (Set<IpPrefix>) mLocalPrefixes.clone();
}
@@ -501,8 +522,8 @@
try {
nc = ConnectivityManager.networkCapabilitiesForType(type);
} catch (IllegalArgumentException iae) {
- Log.e(TAG, "No NetworkCapabilities mapping for legacy type: " +
- ConnectivityManager.getNetworkTypeName(type));
+ Log.e(TAG, "No NetworkCapabilities mapping for legacy type: "
+ + ConnectivityManager.getNetworkTypeName(type));
continue;
}
if (!isCellularUpstreamPermitted && isCellular(nc)) {
@@ -547,18 +568,18 @@
}
private static boolean isCellular(NetworkCapabilities nc) {
- return (nc != null) && nc.hasTransport(TRANSPORT_CELLULAR) &&
- nc.hasCapability(NET_CAPABILITY_NOT_VPN);
+ return (nc != null) && nc.hasTransport(TRANSPORT_CELLULAR)
+ && nc.hasCapability(NET_CAPABILITY_NOT_VPN);
}
private static boolean hasCapability(NetworkState ns, int netCap) {
- return (ns != null) && (ns.networkCapabilities != null) &&
- ns.networkCapabilities.hasCapability(netCap);
+ return (ns != null) && (ns.networkCapabilities != null)
+ && ns.networkCapabilities.hasCapability(netCap);
}
private static boolean isNetworkUsableAndNotCellular(NetworkState ns) {
- return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null) &&
- !isCellular(ns.networkCapabilities);
+ return (ns != null) && (ns.networkCapabilities != null) && (ns.linkProperties != null)
+ && !isCellular(ns.networkCapabilities);
}
private static NetworkState findFirstDunNetwork(Iterable<NetworkState> netStates) {
diff --git a/packages/Tethering/tests/unit/Android.bp b/packages/Tethering/tests/unit/Android.bp
index 5564bd6..7c06e5f 100644
--- a/packages/Tethering/tests/unit/Android.bp
+++ b/packages/Tethering/tests/unit/Android.bp
@@ -47,6 +47,7 @@
srcs: [
"src/com/android/server/connectivity/tethering/EntitlementManagerTest.java",
"src/com/android/server/connectivity/tethering/TetheringConfigurationTest.java",
+ "src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java",
"src/android/net/dhcp/DhcpServingParamsParcelExtTest.java",
"src/android/net/ip/IpServerTest.java",
"src/android/net/util/InterfaceSetTest.java",
diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
similarity index 94%
rename from tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
rename to packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
index 0d276cb..c028d6d 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
+++ b/packages/Tethering/tests/unit/src/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java
@@ -87,7 +87,7 @@
// Actual contents of the request don't matter for this test. The lack of
// any specific TRANSPORT_* is sufficient to identify this request.
- private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build();
+ private static final NetworkRequest sDefaultRequest = new NetworkRequest.Builder().build();
@Mock private Context mContext;
@Mock private EntitlementManager mEntitleMgr;
@@ -140,7 +140,7 @@
@Test
public void testDefaultNetworkIsTracked() throws Exception {
assertTrue(mCM.hasNoCallbacks());
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
assertEquals(1, mCM.trackingDefault.size());
@@ -153,7 +153,7 @@
public void testListensForAllNetworks() throws Exception {
assertTrue(mCM.listening.isEmpty());
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
assertFalse(mCM.listening.isEmpty());
assertTrue(mCM.isListeningForAll());
@@ -164,9 +164,9 @@
@Test
public void testCallbacksRegistered() {
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
verify(mCM, times(1)).requestNetwork(
- eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class));
+ eq(sDefaultRequest), any(NetworkCallback.class), any(Handler.class));
mUNM.startObserveAllNetworks();
verify(mCM, times(1)).registerNetworkCallback(
any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class));
@@ -191,7 +191,7 @@
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(mCM.isDunRequested());
+ assertFalse(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -217,7 +217,7 @@
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
// Try a few things that must not result in any state change.
mUNM.registerMobileNetworkRequest();
@@ -226,7 +226,7 @@
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
mUNM.stop();
verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class));
@@ -250,7 +250,7 @@
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -266,17 +266,17 @@
mUNM.registerMobileNetworkRequest();
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(mCM.isDunRequested());
+ assertFalse(isDunRequested());
mUNM.updateMobileRequiresDun(true);
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_DUN);
- assertTrue(mCM.isDunRequested());
+ assertTrue(isDunRequested());
// Test going from DUN to no-DUN correctly re-registers callbacks.
mUNM.updateMobileRequiresDun(false);
assertTrue(mUNM.mobileNetworkRequested());
assertUpstreamTypeRequested(TYPE_MOBILE_HIPRI);
- assertFalse(mCM.isDunRequested());
+ assertFalse(isDunRequested());
mUNM.stop();
assertFalse(mUNM.mobileNetworkRequested());
@@ -287,7 +287,7 @@
final Collection<Integer> preferredTypes = new ArrayList<>();
preferredTypes.add(TYPE_WIFI);
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// There are no networks, so there is nothing to select.
assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes));
@@ -369,7 +369,7 @@
@Test
public void testGetCurrentPreferredUpstream() throws Exception {
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
mUNM.updateMobileRequiresDun(false);
@@ -418,7 +418,7 @@
@Test
public void testLocalPrefixes() throws Exception {
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// [0] Test minimum set of local prefixes.
@@ -431,13 +431,13 @@
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
final LinkProperties wifiLp = wifiAgent.linkProperties;
wifiLp.setInterfaceName("wlan0");
- final String[] WIFI_ADDRS = {
+ final String[] wifi_addrs = {
"fe80::827a:bfff:fe6f:374d", "100.112.103.18",
"2001:db8:4:fd00:827a:bfff:fe6f:374d",
"2001:db8:4:fd00:6dea:325a:fdae:4ef4",
"fd6a:a640:60bf:e985::123", // ULA address for good measure.
};
- for (String addrStr : WIFI_ADDRS) {
+ for (String addrStr : wifi_addrs) {
final String cidr = addrStr.contains(":") ? "/64" : "/20";
wifiLp.addLinkAddress(new LinkAddress(addrStr + cidr));
}
@@ -458,10 +458,10 @@
final TestNetworkAgent cellAgent = new TestNetworkAgent(mCM, TRANSPORT_CELLULAR);
final LinkProperties cellLp = cellAgent.linkProperties;
cellLp.setInterfaceName("rmnet_data0");
- final String[] CELL_ADDRS = {
+ final String[] cell_addrs = {
"10.102.211.48", "2001:db8:0:1:b50e:70d9:10c9:433d",
};
- for (String addrStr : CELL_ADDRS) {
+ for (String addrStr : cell_addrs) {
final String cidr = addrStr.contains(":") ? "/64" : "/27";
cellLp.addLinkAddress(new LinkAddress(addrStr + cidr));
}
@@ -481,10 +481,10 @@
dunAgent.networkCapabilities.removeCapability(NET_CAPABILITY_INTERNET);
final LinkProperties dunLp = dunAgent.linkProperties;
dunLp.setInterfaceName("rmnet_data1");
- final String[] DUN_ADDRS = {
+ final String[] dun_addrs = {
"192.0.2.48", "2001:db8:1:2:b50e:70d9:10c9:433d",
};
- for (String addrStr : DUN_ADDRS) {
+ for (String addrStr : dun_addrs) {
final String cidr = addrStr.contains(":") ? "/64" : "/27";
dunLp.addLinkAddress(new LinkAddress(addrStr + cidr));
}
@@ -525,7 +525,7 @@
// Mobile has higher pirority than wifi.
preferredTypes.add(TYPE_MOBILE_HIPRI);
preferredTypes.add(TYPE_WIFI);
- mUNM.startTrackDefaultNetwork(mDefaultRequest, mEntitleMgr);
+ mUNM.startTrackDefaultNetwork(sDefaultRequest, mEntitleMgr);
mUNM.startObserveAllNetworks();
// Setup wifi and make wifi as default network.
final TestNetworkAgent wifiAgent = new TestNetworkAgent(mCM, TRANSPORT_WIFI);
@@ -556,6 +556,15 @@
mCM.legacyTypeMap.values().iterator().next());
}
+ private boolean isDunRequested() {
+ for (NetworkRequest req : mCM.requested.values()) {
+ if (req.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static class TestConnectivityManager extends ConnectivityManager {
public Map<NetworkCallback, Handler> allCallbacks = new HashMap<>();
public Set<NetworkCallback> trackingDefault = new HashSet<>();
@@ -598,17 +607,10 @@
return false;
}
- boolean isDunRequested() {
- for (NetworkRequest req : requested.values()) {
- if (req.networkCapabilities.hasCapability(NET_CAPABILITY_DUN)) {
- return true;
- }
- }
- return false;
+ int getNetworkId() {
+ return ++mNetworkId;
}
- int getNetworkId() { return ++mNetworkId; }
-
void makeDefaultNetwork(TestNetworkAgent agent) {
if (Objects.equals(defaultNetwork, agent)) return;
@@ -630,7 +632,7 @@
public void requestNetwork(NetworkRequest req, NetworkCallback cb, Handler h) {
assertFalse(allCallbacks.containsKey(cb));
allCallbacks.put(cb, h);
- if (mDefaultRequest.equals(req)) {
+ if (sDefaultRequest.equals(req)) {
assertFalse(trackingDefault.contains(cb));
trackingDefault.add(cb);
} else {
@@ -749,9 +751,13 @@
private final State mLoggingState = new LoggingState();
class LoggingState extends State {
- @Override public void enter() { messages.clear(); }
+ @Override public void enter() {
+ messages.clear();
+ }
- @Override public void exit() { messages.clear(); }
+ @Override public void exit() {
+ messages.clear();
+ }
@Override public boolean processMessage(Message msg) {
messages.add(msg);
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 68e11df32..6f43529 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -67,8 +67,6 @@
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.provider.Settings;
-import android.provider.SettingsStringUtil;
-import android.provider.SettingsStringUtil.ComponentNameSet;
import android.provider.SettingsStringUtil.SettingStringHelper;
import android.text.TextUtils;
import android.text.TextUtils.SimpleStringSplitter;
@@ -2219,12 +2217,12 @@
* Enables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void enableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- final SettingStringHelper setting =
- new SettingStringHelper(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- userId);
- setting.write(ComponentNameSet.add(setting.read(), componentName));
+ mTempComponentNameSet.clear();
+ readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId, mTempComponentNameSet);
+ mTempComponentNameSet.add(componentName);
+ persistComponentNamesToSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mTempComponentNameSet, userId);
AccessibilityUserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.add(componentName)) {
@@ -2236,12 +2234,12 @@
* Disables accessibility service specified by {@param componentName} for the {@param userId}.
*/
private void disableAccessibilityServiceLocked(ComponentName componentName, int userId) {
- final SettingsStringUtil.SettingStringHelper setting =
- new SettingStringHelper(
- mContext.getContentResolver(),
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- userId);
- setting.write(ComponentNameSet.remove(setting.read(), componentName));
+ mTempComponentNameSet.clear();
+ readComponentNamesFromSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ userId, mTempComponentNameSet);
+ mTempComponentNameSet.remove(componentName);
+ persistComponentNamesToSettingLocked(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ mTempComponentNameSet, userId);
AccessibilityUserState userState = getUserStateLocked(userId);
if (userState.mEnabledServices.remove(componentName)) {
diff --git a/services/core/Android.bp b/services/core/Android.bp
index c865384..770de09 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -115,7 +115,6 @@
"android.hardware.contexthub-V1.0-java",
"android.hidl.manager-V1.2-java",
"dnsresolver_aidl_interface-V2-java",
- "netd_aidl_interface-java",
"netd_event_listener_interface-java",
],
}
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index ff0044f..e757b4e 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -154,7 +154,7 @@
static final int TICK_HISTORY_DEPTH = 10;
static final long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
- // Indices into the APP_STANDBY_MIN_DELAYS and KEYS_APP_STANDBY_DELAY arrays
+ // Indices into the KEYS_APP_STANDBY_QUOTAS array.
static final int ACTIVE_INDEX = 0;
static final int WORKING_INDEX = 1;
static final int FREQUENT_INDEX = 2;
@@ -401,8 +401,6 @@
static final String KEY_LISTENER_TIMEOUT = "listener_timeout";
@VisibleForTesting
static final String KEY_MAX_ALARMS_PER_UID = "max_alarms_per_uid";
- @VisibleForTesting
- static final String KEY_APP_STANDBY_QUOTAS_ENABLED = "app_standby_quotas_enabled";
private static final String KEY_APP_STANDBY_WINDOW = "app_standby_window";
@VisibleForTesting
final String[] KEYS_APP_STANDBY_QUOTAS = {
@@ -413,15 +411,6 @@
"standby_never_quota",
};
- // Keys for specifying throttling delay based on app standby bucketing
- private final String[] KEYS_APP_STANDBY_DELAY = {
- "standby_active_delay",
- "standby_working_delay",
- "standby_frequent_delay",
- "standby_rare_delay",
- "standby_never_delay",
- };
-
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
private static final long DEFAULT_MAX_INTERVAL = 365 * DateUtils.DAY_IN_MILLIS;
@@ -430,7 +419,6 @@
private static final long DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION = 10*1000;
private static final long DEFAULT_LISTENER_TIMEOUT = 5 * 1000;
private static final int DEFAULT_MAX_ALARMS_PER_UID = 500;
- private static final boolean DEFAULT_APP_STANDBY_QUOTAS_ENABLED = true;
private static final long DEFAULT_APP_STANDBY_WINDOW = 60 * 60 * 1000; // 1 hr
/**
* Max number of times an app can receive alarms in {@link #APP_STANDBY_WINDOW}
@@ -442,13 +430,6 @@
1, // Rare
0 // Never
};
- private final long[] DEFAULT_APP_STANDBY_DELAYS = {
- 0, // Active
- 6 * 60_000, // Working
- 30 * 60_000, // Frequent
- 2 * 60 * 60_000, // Rare
- 10 * 24 * 60 * 60_000 // Never
- };
// Minimum futurity of a new alarm
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
@@ -473,10 +454,7 @@
public long LISTENER_TIMEOUT = DEFAULT_LISTENER_TIMEOUT;
public int MAX_ALARMS_PER_UID = DEFAULT_MAX_ALARMS_PER_UID;
- public boolean APP_STANDBY_QUOTAS_ENABLED = DEFAULT_APP_STANDBY_QUOTAS_ENABLED;
-
public long APP_STANDBY_WINDOW = DEFAULT_APP_STANDBY_WINDOW;
- public long[] APP_STANDBY_MIN_DELAYS = new long[DEFAULT_APP_STANDBY_DELAYS.length];
public int[] APP_STANDBY_QUOTAS = new int[DEFAULT_APP_STANDBY_QUOTAS.length];
private ContentResolver mResolver;
@@ -532,16 +510,6 @@
DEFAULT_ALLOW_WHILE_IDLE_WHITELIST_DURATION);
LISTENER_TIMEOUT = mParser.getLong(KEY_LISTENER_TIMEOUT,
DEFAULT_LISTENER_TIMEOUT);
- APP_STANDBY_MIN_DELAYS[ACTIVE_INDEX] = mParser.getDurationMillis(
- KEYS_APP_STANDBY_DELAY[ACTIVE_INDEX],
- DEFAULT_APP_STANDBY_DELAYS[ACTIVE_INDEX]);
- for (int i = WORKING_INDEX; i < KEYS_APP_STANDBY_DELAY.length; i++) {
- APP_STANDBY_MIN_DELAYS[i] = mParser.getDurationMillis(KEYS_APP_STANDBY_DELAY[i],
- Math.max(APP_STANDBY_MIN_DELAYS[i - 1], DEFAULT_APP_STANDBY_DELAYS[i]));
- }
-
- APP_STANDBY_QUOTAS_ENABLED = mParser.getBoolean(KEY_APP_STANDBY_QUOTAS_ENABLED,
- DEFAULT_APP_STANDBY_QUOTAS_ENABLED);
APP_STANDBY_WINDOW = mParser.getLong(KEY_APP_STANDBY_WINDOW,
DEFAULT_APP_STANDBY_WINDOW);
@@ -614,15 +582,6 @@
pw.print(KEY_MAX_ALARMS_PER_UID); pw.print("=");
pw.println(MAX_ALARMS_PER_UID);
- for (int i = 0; i < KEYS_APP_STANDBY_DELAY.length; i++) {
- pw.print(KEYS_APP_STANDBY_DELAY[i]); pw.print("=");
- TimeUtils.formatDuration(APP_STANDBY_MIN_DELAYS[i], pw);
- pw.println();
- }
-
- pw.print(KEY_APP_STANDBY_QUOTAS_ENABLED); pw.print("=");
- pw.println(APP_STANDBY_QUOTAS_ENABLED);
-
pw.print(KEY_APP_STANDBY_WINDOW); pw.print("=");
TimeUtils.formatDuration(APP_STANDBY_WINDOW, pw);
pw.println();
@@ -1826,27 +1785,6 @@
}
/**
- * Return the minimum time that should elapse before an app in the specified bucket
- * can receive alarms again
- */
- @VisibleForTesting
- long getMinDelayForBucketLocked(int bucket) {
- // UsageStats bucket values are treated as floors of their behavioral range.
- // In other words, a bucket value between WORKING and ACTIVE is treated as
- // WORKING, not as ACTIVE. The ACTIVE and NEVER bucket apply only at specific
- // values.
- final int index;
-
- if (bucket == UsageStatsManager.STANDBY_BUCKET_NEVER) index = NEVER_INDEX;
- else if (bucket > UsageStatsManager.STANDBY_BUCKET_FREQUENT) index = RARE_INDEX;
- else if (bucket > UsageStatsManager.STANDBY_BUCKET_WORKING_SET) index = FREQUENT_INDEX;
- else if (bucket > UsageStatsManager.STANDBY_BUCKET_ACTIVE) index = WORKING_INDEX;
- else index = ACTIVE_INDEX;
-
- return mConstants.APP_STANDBY_MIN_DELAYS[index];
- }
-
- /**
* Adjusts the alarm delivery time based on the current app standby bucket.
* @param alarm The alarm to adjust
* @return true if the alarm delivery time was updated.
@@ -1872,50 +1810,34 @@
final int standbyBucket = mUsageStatsManagerInternal.getAppStandbyBucket(
sourcePackage, sourceUserId, mInjector.getElapsedRealtime());
- if (mConstants.APP_STANDBY_QUOTAS_ENABLED) {
- // Quota deferring implementation:
- final int wakeupsInWindow = mAppWakeupHistory.getTotalWakeupsInWindow(sourcePackage,
- sourceUserId);
- final int quotaForBucket = getQuotaForBucketLocked(standbyBucket);
- boolean deferred = false;
- if (wakeupsInWindow >= quotaForBucket) {
- final long minElapsed;
- if (quotaForBucket <= 0) {
- // Just keep deferring for a day till the quota changes
- minElapsed = mInjector.getElapsedRealtime() + MILLIS_IN_DAY;
- } else {
- // Suppose the quota for window was q, and the qth last delivery time for this
- // package was t(q) then the next delivery must be after t(q) + <window_size>
- final long t = mAppWakeupHistory.getLastWakeupForPackage(sourcePackage,
- sourceUserId, quotaForBucket);
- minElapsed = t + 1 + mConstants.APP_STANDBY_WINDOW;
- }
- if (alarm.expectedWhenElapsed < minElapsed) {
- alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed;
- deferred = true;
- }
+ // Quota deferring implementation:
+ final int wakeupsInWindow = mAppWakeupHistory.getTotalWakeupsInWindow(sourcePackage,
+ sourceUserId);
+ final int quotaForBucket = getQuotaForBucketLocked(standbyBucket);
+ boolean deferred = false;
+ if (wakeupsInWindow >= quotaForBucket) {
+ final long minElapsed;
+ if (quotaForBucket <= 0) {
+ // Just keep deferring for a day till the quota changes
+ minElapsed = mInjector.getElapsedRealtime() + MILLIS_IN_DAY;
+ } else {
+ // Suppose the quota for window was q, and the qth last delivery time for this
+ // package was t(q) then the next delivery must be after t(q) + <window_size>
+ final long t = mAppWakeupHistory.getLastWakeupForPackage(sourcePackage,
+ sourceUserId, quotaForBucket);
+ minElapsed = t + 1 + mConstants.APP_STANDBY_WINDOW;
}
- if (!deferred) {
- // Restore original requirements in case they were changed earlier.
- alarm.whenElapsed = alarm.expectedWhenElapsed;
- alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
- }
- } else {
- // Minimum delay deferring implementation:
- final long lastElapsed = mAppWakeupHistory.getLastWakeupForPackage(sourcePackage,
- sourceUserId, 1);
- if (lastElapsed > 0) {
- final long minElapsed = lastElapsed + getMinDelayForBucketLocked(standbyBucket);
- if (alarm.expectedWhenElapsed < minElapsed) {
- alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed;
- } else {
- // app is now eligible to run alarms at the originally requested window.
- // Restore original requirements in case they were changed earlier.
- alarm.whenElapsed = alarm.expectedWhenElapsed;
- alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
- }
+ if (alarm.expectedWhenElapsed < minElapsed) {
+ alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed;
+ deferred = true;
}
}
+ if (!deferred) {
+ // Restore original requirements in case they were changed earlier.
+ alarm.whenElapsed = alarm.expectedWhenElapsed;
+ alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
+ }
+
return (oldWhenElapsed != alarm.whenElapsed || oldMaxWhenElapsed != alarm.maxWhenElapsed);
}
@@ -4446,7 +4368,8 @@
}
final class UidObserver extends IUidObserver.Stub {
- @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) {
}
@Override public void onUidGone(int uid, boolean disabled) {
diff --git a/services/core/java/com/android/server/AppStateTracker.java b/services/core/java/com/android/server/AppStateTracker.java
index 5eff2c5..486cd5f 100644
--- a/services/core/java/com/android/server/AppStateTracker.java
+++ b/services/core/java/com/android/server/AppStateTracker.java
@@ -632,7 +632,7 @@
private final class UidObserver extends IUidObserver.Stub {
@Override
- public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
mHandler.onUidStateChanged(uid, procState);
}
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index aeb3e7f..028d412 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -23,6 +23,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.Uri;
@@ -40,11 +41,13 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
+import android.service.dropbox.DropBoxManagerServiceDumpProto;
import android.text.TextUtils;
import android.text.format.TimeMigrationUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -65,6 +68,7 @@
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.zip.GZIPOutputStream;
@@ -85,6 +89,9 @@
private static final boolean PROFILE_DUMP = false;
+ // Max number of bytes of a dropbox entry to write into protobuf.
+ private static final int PROTO_MAX_DATA_BYTES = 256 * 1024;
+
// TODO: This implementation currently uses one file per entry, which is
// inefficient for smallish entries -- consider using a single queue file
// per tag (or even globally) instead.
@@ -464,6 +471,14 @@
}
private boolean checkPermission(int callingUid, String callingPackage) {
+ // If callers have this permission, then we don't need to check
+ // USAGE_STATS, because they are part of the system and have agreed to
+ // check USAGE_STATS before passing the data along.
+ if (getContext().checkCallingPermission(android.Manifest.permission.PEEK_DROPBOX_DATA)
+ == PackageManager.PERMISSION_GRANTED) {
+ return true;
+ }
+
// Callers always need this permission
getContext().enforceCallingOrSelfPermission(
android.Manifest.permission.READ_LOGS, TAG);
@@ -547,18 +562,22 @@
StringBuilder out = new StringBuilder();
boolean doPrint = false, doFile = false;
+ boolean dumpProto = false;
ArrayList<String> searchArgs = new ArrayList<String>();
for (int i = 0; args != null && i < args.length; i++) {
if (args[i].equals("-p") || args[i].equals("--print")) {
doPrint = true;
} else if (args[i].equals("-f") || args[i].equals("--file")) {
doFile = true;
+ } else if (args[i].equals("--proto")) {
+ dumpProto = true;
} else if (args[i].equals("-h") || args[i].equals("--help")) {
pw.println("Dropbox (dropbox) dump options:");
pw.println(" [-h|--help] [-p|--print] [-f|--file] [timestamp]");
pw.println(" -h|--help: print this help");
pw.println(" -p|--print: print full contents of each entry");
pw.println(" -f|--file: print path of each entry's file");
+ pw.println(" --proto: dump data to proto");
pw.println(" [timestamp] optionally filters to only those entries.");
return;
} else if (args[i].startsWith("-")) {
@@ -568,6 +587,11 @@
}
}
+ if (dumpProto) {
+ dumpProtoLocked(fd, searchArgs);
+ return;
+ }
+
out.append("Drop box contents: ").append(mAllFiles.contents.size()).append(" entries\n");
out.append("Max entries: ").append(mMaxFiles).append("\n");
@@ -581,19 +605,15 @@
out.append("\n");
}
- int numFound = 0, numArgs = searchArgs.size();
+ int numFound = 0;
out.append("\n");
for (EntryFile entry : mAllFiles.contents) {
- String date = TimeMigrationUtils.formatMillisWithFixedFormat(entry.timestampMillis);
- boolean match = true;
- for (int i = 0; i < numArgs && match; i++) {
- String arg = searchArgs.get(i);
- match = (date.contains(arg) || arg.equals(entry.tag));
- }
- if (!match) continue;
+ if (!matchEntry(entry, searchArgs)) continue;
numFound++;
if (doPrint) out.append("========================================\n");
+
+ String date = TimeMigrationUtils.formatMillisWithFixedFormat(entry.timestampMillis);
out.append(date).append(" ").append(entry.tag == null ? "(no tag)" : entry.tag);
final File file = entry.getFile(mDropBoxDir);
@@ -679,6 +699,55 @@
if (PROFILE_DUMP) Debug.stopMethodTracing();
}
+ private boolean matchEntry(EntryFile entry, ArrayList<String> searchArgs) {
+ String date = TimeMigrationUtils.formatMillisWithFixedFormat(entry.timestampMillis);
+ boolean match = true;
+ int numArgs = searchArgs.size();
+ for (int i = 0; i < numArgs && match; i++) {
+ String arg = searchArgs.get(i);
+ match = (date.contains(arg) || arg.equals(entry.tag));
+ }
+ return match;
+ }
+
+ private void dumpProtoLocked(FileDescriptor fd, ArrayList<String> searchArgs) {
+ final ProtoOutputStream proto = new ProtoOutputStream(fd);
+
+ for (EntryFile entry : mAllFiles.contents) {
+ if (!matchEntry(entry, searchArgs)) continue;
+
+ final File file = entry.getFile(mDropBoxDir);
+ if ((file == null) || ((entry.flags & DropBoxManager.IS_EMPTY) != 0)) {
+ continue;
+ }
+
+ final long bToken = proto.start(DropBoxManagerServiceDumpProto.ENTRIES);
+ proto.write(DropBoxManagerServiceDumpProto.Entry.TIME_MS, entry.timestampMillis);
+ try (
+ DropBoxManager.Entry dbe = new DropBoxManager.Entry(
+ entry.tag, entry.timestampMillis, file, entry.flags);
+ InputStream is = dbe.getInputStream();
+ ) {
+ if (is != null) {
+ byte[] buf = new byte[PROTO_MAX_DATA_BYTES];
+ int readBytes = 0;
+ int n = 0;
+ while (n >= 0 && (readBytes += n) < PROTO_MAX_DATA_BYTES) {
+ n = is.read(buf, readBytes, PROTO_MAX_DATA_BYTES - readBytes);
+ }
+ proto.write(DropBoxManagerServiceDumpProto.Entry.DATA,
+ Arrays.copyOf(buf, readBytes));
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Can't read: " + file, e);
+ }
+
+ proto.end(bToken);
+ }
+
+ proto.flush();
+ }
+
///////////////////////////////////////////////////////////////////////////
/** Chronologically sorted list of {@link EntryFile} */
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 0a63bf8..39f039a 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -128,6 +128,32 @@
* updates and alerts.
*/
public class LocationManagerService extends ILocationManager.Stub {
+
+ /**
+ * Controls lifecycle of LocationManagerService.
+ */
+ public static class Lifecycle extends SystemService {
+
+ private LocationManagerService mService;
+
+ public Lifecycle(Context context) {
+ super(context);
+ mService = new LocationManagerService(context);
+ }
+
+ @Override
+ public void onStart() {
+ publishBinderService(Context.LOCATION_SERVICE, mService);
+ }
+
+ @Override
+ public void onBootPhase(int phase) {
+ if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
+ mService.systemRunning();
+ }
+ }
+ }
+
private static final String TAG = "LocationManagerService";
public static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
@@ -234,8 +260,7 @@
@GuardedBy("mLock")
private final LocationUsageLogger mLocationUsageLogger;
- public LocationManagerService(Context context) {
- super();
+ private LocationManagerService(Context context) {
mContext = context;
mHandler = FgThread.getHandler();
mLocationUsageLogger = new LocationUsageLogger();
@@ -254,7 +279,7 @@
// most startup is deferred until systemRunning()
}
- public void systemRunning() {
+ private void systemRunning() {
synchronized (mLock) {
initializeLocked();
}
@@ -1453,6 +1478,16 @@
return true;
}
+ public void callRemovedLocked() {
+ if (mListener != null) {
+ try {
+ mListener.onRemoved();
+ } catch (RemoteException e) {
+ // doesn't matter
+ }
+ }
+ }
+
@Override
public void binderDied() {
if (D) Log.d(TAG, "Remote " + mListenerName + " died.");
@@ -2051,6 +2086,18 @@
* Note: must be constructed with lock held.
*/
private UpdateRecord(String provider, LocationRequest request, Receiver receiver) {
+ // translate expireIn value into expireAt
+ long elapsedRealtime = SystemClock.elapsedRealtime();
+ long expireAt;
+ // Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
+ if (request.getExpireIn() > Long.MAX_VALUE - elapsedRealtime) {
+ expireAt = Long.MAX_VALUE;
+ } else {
+ expireAt = Math.max(request.getExpireIn() + elapsedRealtime, 0);
+ }
+ request.setExpireAt(Math.min(request.getExpireAt(), expireAt));
+ request.setExpireIn(Long.MAX_VALUE);
+
mProvider = provider;
mRealRequest = request;
mRequest = request;
@@ -3054,6 +3101,8 @@
// track expired records
if (r.mRealRequest.getNumUpdates() <= 0 || r.mRealRequest.getExpireAt() < now) {
+ // notify the client it can remove this listener
+ r.mReceiver.callRemovedLocked();
if (deadUpdateRecords == null) {
deadUpdateRecords = new ArrayList<>();
}
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
index 49ef164..d5f7956 100644
--- a/services/core/java/com/android/server/PinnerService.java
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -333,8 +333,8 @@
}
@Override
- public void onUidStateChanged(int uid, int procState, long procStateSeq)
- throws RemoteException {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) throws RemoteException {
}
@Override
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/ServiceWatcher.java
index e3dc3b7..7f51aa9 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/ServiceWatcher.java
@@ -51,6 +51,8 @@
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* Find the best Service, and bind to it.
@@ -64,6 +66,7 @@
public static final String EXTRA_SERVICE_VERSION = "serviceVersion";
public static final String EXTRA_SERVICE_IS_MULTIUSER = "serviceIsMultiuser";
+ private static final long BLOCKING_BINDER_TIMEOUT_MS = 30 * 1000;
/** Function to run on binder interface. */
public interface BinderRunner {
@@ -402,7 +405,7 @@
return defaultValue;
}
});
- } catch (InterruptedException e) {
+ } catch (InterruptedException | TimeoutException e) {
return defaultValue;
}
}
@@ -439,7 +442,8 @@
}
}
- private <T> T runOnHandlerBlocking(Callable<T> c) throws InterruptedException {
+ private <T> T runOnHandlerBlocking(Callable<T> c)
+ throws InterruptedException, TimeoutException {
if (Looper.myLooper() == mHandler.getLooper()) {
try {
return c.call();
@@ -451,7 +455,12 @@
FutureTask<T> task = new FutureTask<>(c);
mHandler.post(task);
try {
- return task.get();
+ // timeout will unblock callers, in particular if the caller is a binder thread to
+ // help reduce binder contention. this will still result in blocking the handler
+ // thread which may result in ANRs, but should make problems slightly more rare.
+ // the underlying solution is simply not to use this API at all, but that would
+ // require large refactors to very legacy code.
+ return task.get(BLOCKING_BINDER_TIMEOUT_MS, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
// Function cannot throw exception, this should never happen
throw new IllegalStateException(e);
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index d622fb4..b8acd7a 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -174,7 +174,8 @@
static native long vibratorGetCapabilities();
private final IUidObserver mUidObserver = new IUidObserver.Stub() {
- @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) {
mProcStatesCache.put(uid, procState);
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 4f54e64..b5cab1f 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -3248,7 +3248,7 @@
UserAccounts accounts = getUserAccounts(userId);
logRecordWithUid(
accounts, AccountsDb.DEBUG_ACTION_CALLED_ACCOUNT_ADD, AccountsDb.TABLE_ACCOUNTS,
- userId);
+ uid);
new Session(accounts, response, accountType, expectActivityLaunch,
true /* stripAuthTokenFromResult */, null /* accountName */,
false /* authDetailsRequired */, true /* updateLastAuthenticationTime */) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5df4543..d6ecdea 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -139,6 +139,7 @@
import android.Manifest;
import android.Manifest.permission;
+import android.annotation.BroadcastBehavior;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -299,10 +300,8 @@
import android.view.WindowManager;
import android.view.autofill.AutofillManagerInternal;
-import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.DumpHeapActivity;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.internal.app.ProcessMap;
@@ -503,6 +502,41 @@
static final int PERSISTENT_MASK =
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
+ // Intent sent when remote bugreport collection has been completed
+ private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
+ "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
+
+ /**
+ * Broadcast sent when heap dump collection has been completed.
+ */
+ @BroadcastBehavior(includeBackground = true, protectedBroadcast = true)
+ private static final String ACTION_HEAP_DUMP_FINISHED =
+ "com.android.internal.intent.action.HEAP_DUMP_FINISHED";
+
+ /**
+ * The process we are reporting
+ */
+ private static final String EXTRA_HEAP_DUMP_PROCESS_NAME =
+ "com.android.internal.extra.heap_dump.PROCESS_NAME";
+
+ /**
+ * The size limit the process reached.
+ */
+ private static final String EXTRA_HEAP_DUMP_SIZE_BYTES =
+ "com.android.internal.extra.heap_dump.SIZE_BYTES";
+
+ /**
+ * Whether the user initiated the dump or not.
+ */
+ private static final String EXTRA_HEAP_DUMP_IS_USER_INITIATED =
+ "com.android.internal.extra.heap_dump.IS_USER_INITIATED";
+
+ /**
+ * Optional name of package to directly launch.
+ */
+ private static final String EXTRA_HEAP_DUMP_REPORT_PACKAGE =
+ "com.android.internal.extra.heap_dump.REPORT_PACKAGE";
+
// If set, we will push process association information in to procstats.
static final boolean TRACK_PROCSTATS_ASSOCIATIONS = true;
@@ -1332,7 +1366,7 @@
int mProfileType = 0;
final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
String mMemWatchDumpProcName;
- String mMemWatchDumpFile;
+ Uri mMemWatchDumpUri;
int mMemWatchDumpPid;
int mMemWatchDumpUid;
private boolean mMemWatchIsUserInitiated;
@@ -1344,10 +1378,12 @@
static final class ProcessChangeItem {
static final int CHANGE_ACTIVITIES = 1<<0;
static final int CHANGE_FOREGROUND_SERVICES = 1<<1;
+ static final int CHANGE_CAPABILITY = 1<<2;
int changes;
int uid;
int pid;
int processState;
+ int capability;
boolean foregroundActivities;
int foregroundServiceTypes;
}
@@ -1519,7 +1555,7 @@
static final int UPDATE_TIME_PREFERENCE_MSG = 41;
static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
- static final int DELETE_DUMPHEAP_MSG = 51;
+ static final int ABORT_DUMPHEAP_MSG = 51;
static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
@@ -1788,11 +1824,7 @@
final boolean isUserInitiated;
synchronized (ActivityManagerService.this) {
uid = mMemWatchDumpUid;
- if (uid == SYSTEM_UID) {
- procName = mContext.getString(R.string.android_system_label);
- } else {
- procName = mMemWatchDumpProcName;
- }
+ procName = mMemWatchDumpProcName;
Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
if (val == null) {
val = mMemWatchProcesses.get(procName, 0);
@@ -1805,6 +1837,11 @@
reportPackage = null;
}
isUserInitiated = mMemWatchIsUserInitiated;
+
+ mMemWatchDumpUri = null;
+ mMemWatchDumpProcName = null;
+ mMemWatchDumpPid = -1;
+ mMemWatchDumpUid = -1;
}
if (procName == null) {
return;
@@ -1813,65 +1850,29 @@
if (DEBUG_PSS) Slog.d(TAG_PSS,
"Showing dump heap notification from " + procName + "/" + uid);
- INotificationManager inm = NotificationManager.getService();
- if (inm == null) {
- return;
- }
+ Intent dumpFinishedIntent = new Intent(ACTION_HEAP_DUMP_FINISHED);
+ // Send this only to the Shell package.
+ dumpFinishedIntent.setPackage("com.android.shell");
+ dumpFinishedIntent.putExtra(Intent.EXTRA_UID, uid);
+ dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_IS_USER_INITIATED, isUserInitiated);
+ dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_SIZE_BYTES, memLimit);
+ dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_REPORT_PACKAGE, reportPackage);
+ dumpFinishedIntent.putExtra(EXTRA_HEAP_DUMP_PROCESS_NAME, procName);
- final int titleId = isUserInitiated
- ? R.string.dump_heap_ready_notification : R.string.dump_heap_notification;
- String text = mContext.getString(titleId, procName);
-
- Intent deleteIntent = new Intent();
- deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
- Intent intent = new Intent();
- intent.setClassName("android", DumpHeapActivity.class.getName());
- intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
- intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
- intent.putExtra(DumpHeapActivity.KEY_IS_USER_INITIATED, isUserInitiated);
- intent.putExtra(DumpHeapActivity.KEY_IS_SYSTEM_PROCESS, uid == SYSTEM_UID);
- if (reportPackage != null) {
- intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
- }
- int userId = UserHandle.getUserId(uid);
- Notification notification =
- new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
- .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
- .setAutoCancel(true)
- .setTicker(text)
- .setColor(mContext.getColor(
- com.android.internal.R.color.system_notification_accent_color))
- .setContentTitle(text)
- .setContentText(
- mContext.getText(R.string.dump_heap_notification_detail))
- .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
- intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
- new UserHandle(userId)))
- .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
- deleteIntent, 0, UserHandle.SYSTEM))
- .build();
-
- try {
- inm.enqueueNotificationWithTag("android", "android", null,
- SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
- notification, userId);
- } catch (RuntimeException e) {
- Slog.w(ActivityManagerService.TAG,
- "Error showing notification for dump heap", e);
- } catch (RemoteException e) {
- }
+ mContext.sendBroadcastAsUser(dumpFinishedIntent,
+ UserHandle.getUserHandleForUid(uid));
} break;
- case DELETE_DUMPHEAP_MSG: {
- revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
- null, DumpHeapActivity.JAVA_URI,
- Intent.FLAG_GRANT_READ_URI_PERMISSION
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
- UserHandle.myUserId());
- synchronized (ActivityManagerService.this) {
- mMemWatchDumpFile = null;
- mMemWatchDumpProcName = null;
- mMemWatchDumpPid = -1;
- mMemWatchDumpUid = -1;
+ case ABORT_DUMPHEAP_MSG: {
+ String procName = (String) msg.obj;
+ if (procName != null) {
+ synchronized (ActivityManagerService.this) {
+ if (procName.equals(mMemWatchDumpProcName)) {
+ mMemWatchDumpProcName = null;
+ mMemWatchDumpUri = null;
+ mMemWatchDumpPid = -1;
+ mMemWatchDumpUid = -1;
+ }
+ }
}
} break;
case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
@@ -3337,6 +3338,7 @@
validateUid.idle = false;
}
validateUid.setCurProcState(validateUid.setProcState = item.processState);
+ validateUid.curCapability = validateUid.setCapability = item.capability;
validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
}
}
@@ -3402,7 +3404,7 @@
if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
"UID CHANGED uid=" + item.uid
- + ": " + item.processState);
+ + ": " + item.processState + ": " + item.capability);
boolean doReport = true;
if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
final int lastState = reg.lastProcStates.get(item.uid,
@@ -3420,7 +3422,7 @@
reg.lastProcStates.put(item.uid, item.processState);
}
observer.onUidStateChanged(item.uid, item.processState,
- item.procStateSeq);
+ item.procStateSeq, item.capability);
}
}
}
@@ -5245,17 +5247,6 @@
}
}, pkgFilter);
- IntentFilter dumpheapFilter = new IntentFilter();
- dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
- mContext.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final long delay = intent.getBooleanExtra(
- DumpHeapActivity.EXTRA_DELAY_DELETE, false) ? 5 * 60 * 1000 : 0;
- mHandler.sendEmptyMessageDelayed(DELETE_DUMPHEAP_MSG, delay);
- }
- }, dumpheapFilter);
-
// Inform checkpointing systems of success
try {
// This line is needed to CTS test for the correct exception handling
@@ -10953,7 +10944,7 @@
}
}
pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
- pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
+ pw.print(" mMemWatchDumpUri="); pw.println(mMemWatchDumpUri);
pw.print(" mMemWatchDumpPid="); pw.println(mMemWatchDumpPid);
pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
pw.print(" mMemWatchIsUserInitiated="); pw.println(mMemWatchIsUserInitiated);
@@ -11250,10 +11241,14 @@
}
final long dtoken = proto.start(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.DUMP);
- proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME, mMemWatchDumpProcName);
- proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.FILE, mMemWatchDumpFile);
- proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID, mMemWatchDumpPid);
- proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID, mMemWatchDumpUid);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PROC_NAME,
+ mMemWatchDumpProcName);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.URI,
+ mMemWatchDumpUri.toString());
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.PID,
+ mMemWatchDumpPid);
+ proto.write(ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.UID,
+ mMemWatchDumpUid);
proto.write(
ActivityManagerServiceDumpProcessesProto.MemWatchProcess.Dump.IS_USER_INITIATED,
mMemWatchIsUserInitiated);
@@ -16366,9 +16361,10 @@
}
}
- void noteUidProcessState(final int uid, final int state) {
+ void noteUidProcessState(final int uid, final int state,
+ final @ActivityManager.ProcessCapability int capability) {
mBatteryStatsService.noteUidProcessState(uid, state);
- mAppOpsService.updateUidProcState(uid, state);
+ mAppOpsService.updateUidProcState(uid, state, capability);
if (mTrackingAssociations) {
for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
@@ -16395,56 +16391,44 @@
}
}
- private static final class RecordPssRunnable implements Runnable {
- private final ActivityManagerService mService;
- private final ProcessRecord mProc;
- private final File mHeapdumpFile;
+ /** @hide */
+ public static Uri makeHeapDumpUri(String procName) {
+ return Uri.parse("content://com.android.shell.heapdump/" + procName + "_javaheap.bin");
+ }
- RecordPssRunnable(ActivityManagerService service, ProcessRecord proc, File heapdumpFile) {
- this.mService = service;
- this.mProc = proc;
- this.mHeapdumpFile = heapdumpFile;
+ private final class RecordPssRunnable implements Runnable {
+ private final ProcessRecord mProc;
+ private final Uri mDumpUri;
+ private final ContentResolver mContentResolver;
+
+ RecordPssRunnable(ProcessRecord proc, Uri dumpUri, ContentResolver contentResolver) {
+ mProc = proc;
+ mDumpUri = dumpUri;
+ mContentResolver = contentResolver;
}
@Override
public void run() {
- mService.revokeUriPermission(ActivityThread.currentActivityThread()
- .getApplicationThread(),
- null, DumpHeapActivity.JAVA_URI,
- Intent.FLAG_GRANT_READ_URI_PERMISSION
- | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
- UserHandle.myUserId());
- ParcelFileDescriptor fd = null;
- try {
- mHeapdumpFile.delete();
- fd = ParcelFileDescriptor.open(mHeapdumpFile,
- ParcelFileDescriptor.MODE_CREATE
- | ParcelFileDescriptor.MODE_TRUNCATE
- | ParcelFileDescriptor.MODE_WRITE_ONLY
- | ParcelFileDescriptor.MODE_APPEND);
+ try (ParcelFileDescriptor fd = mContentResolver.openFileDescriptor(mDumpUri, "rw")) {
IApplicationThread thread = mProc.thread;
if (thread != null) {
try {
if (DEBUG_PSS) {
Slog.d(TAG_PSS, "Requesting dump heap from "
- + mProc + " to " + mHeapdumpFile);
+ + mProc + " to " + mDumpUri.getPath());
}
thread.dumpHeap(/* managed= */ true,
/* mallocInfo= */ false, /* runGc= */ false,
- mHeapdumpFile.toString(), fd,
+ mDumpUri.getPath(), fd,
/* finishCallback= */ null);
} catch (RemoteException e) {
}
}
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } finally {
- if (fd != null) {
- try {
- fd.close();
- } catch (IOException e) {
- }
- }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to dump heap", e);
+ // Need to clear the heap dump variables, otherwise no further heap dumps will be
+ // attempted.
+ abortHeapDump(mProc.processName);
}
}
}
@@ -16513,13 +16497,20 @@
}
private void startHeapDumpLocked(ProcessRecord proc, boolean isUserInitiated) {
- final File heapdumpFile = DumpHeapProvider.getJavaFile();
mMemWatchDumpProcName = proc.processName;
- mMemWatchDumpFile = heapdumpFile.toString();
+ mMemWatchDumpUri = makeHeapDumpUri(proc.processName);
mMemWatchDumpPid = proc.pid;
mMemWatchDumpUid = proc.uid;
mMemWatchIsUserInitiated = isUserInitiated;
- BackgroundThread.getHandler().post(new RecordPssRunnable(this, proc, heapdumpFile));
+ Context ctx;
+ try {
+ ctx = mContext.createPackageContextAsUser("android", 0,
+ UserHandle.getUserHandleForUid(mMemWatchDumpUid));
+ } catch (NameNotFoundException e) {
+ throw new RuntimeException("android package not found.");
+ }
+ BackgroundThread.getHandler().post(
+ new RecordPssRunnable(proc, mMemWatchDumpUri, ctx.getContentResolver()));
}
/**
@@ -16891,6 +16882,7 @@
}
pendingChange.change = change;
pendingChange.processState = uidRec != null ? uidRec.setProcState : PROCESS_STATE_NONEXISTENT;
+ pendingChange.capability = uidRec != null ? uidRec.setCapability : 0;
pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
if (uidRec != null) {
@@ -17715,9 +17707,9 @@
+ " does not match last pid " + mMemWatchDumpPid);
return;
}
- if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
+ if (mMemWatchDumpUri == null || !mMemWatchDumpUri.getPath().equals(path)) {
Slog.w(TAG, "dumpHeapFinished: Calling path " + path
- + " does not match last path " + mMemWatchDumpFile);
+ + " does not match last path " + mMemWatchDumpUri);
return;
}
if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
@@ -17728,6 +17720,13 @@
}
}
+ /** Clear the currently executing heap dump variables so a new heap dump can be started. */
+ private void abortHeapDump(String procName) {
+ Message msg = mHandler.obtainMessage(ABORT_DUMPHEAP_MSG);
+ msg.obj = procName;
+ mHandler.sendMessage(msg);
+ }
+
/** In this method we try to acquire our lock to make sure that we have not deadlocked */
public void monitor() {
synchronized (this) { }
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 8be2438..59acdcf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -1470,7 +1470,8 @@
}
@Override
- public void onUidStateChanged(int uid, int procState, long procStateSeq) throws RemoteException {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability)
+ throws RemoteException {
synchronized (this) {
final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
try {
@@ -1478,7 +1479,9 @@
mPw.print(" procstate ");
mPw.print(ProcessList.makeProcStateString(procState));
mPw.print(" seq ");
- mPw.println(procStateSeq);
+ mPw.print(procStateSeq);
+ mPw.print(" capability ");
+ mPw.println(capability);
mPw.flush();
} finally {
StrictMode.setThreadPolicy(oldPolicy);
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 6a29c75..8095020 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -383,7 +383,11 @@
// and then the delayed summary kill will be a no-op.
final ProcessRecord p = proc;
mService.mHandler.postDelayed(
- () -> killAppImmediateLocked(p, "forced", "killed for invalid state"),
+ () -> {
+ synchronized (mService) {
+ killAppImmediateLocked(p, "forced", "killed for invalid state");
+ }
+ },
5000L);
}
}
diff --git a/services/core/java/com/android/server/am/DumpHeapProvider.java b/services/core/java/com/android/server/am/DumpHeapProvider.java
deleted file mode 100644
index a8b639e..0000000
--- a/services/core/java/com/android/server/am/DumpHeapProvider.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.am;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.ParcelFileDescriptor;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-
-public class DumpHeapProvider extends ContentProvider {
- static final Object sLock = new Object();
- static File sHeapDumpJavaFile;
-
- static public File getJavaFile() {
- synchronized (sLock) {
- return sHeapDumpJavaFile;
- }
- }
-
- @Override
- public boolean onCreate() {
- synchronized (sLock) {
- File dataDir = Environment.getDataDirectory();
- File systemDir = new File(dataDir, "system");
- File heapdumpDir = new File(systemDir, "heapdump");
- heapdumpDir.mkdir();
- sHeapDumpJavaFile = new File(heapdumpDir, "javaheap.bin");
- }
- return true;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return "application/octet-stream";
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
- synchronized (sLock) {
- String path = uri.getEncodedPath();
- final String tag = Uri.decode(path);
- if (tag.equals("/java")) {
- return ParcelFileDescriptor.open(sHeapDumpJavaFile,
- ParcelFileDescriptor.MODE_READ_ONLY);
- } else {
- throw new FileNotFoundException("Invalid path for " + uri);
- }
- }
- }
-}
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index 78a9efc..f610d7d 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -16,6 +16,9 @@
package com.android.server.am;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
@@ -23,7 +26,6 @@
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
-import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
@@ -65,6 +67,7 @@
import android.app.usage.UsageEvents;
import android.content.Context;
import android.content.pm.ServiceInfo;
+import android.os.Build;
import android.os.Debug;
import android.os.Handler;
import android.os.IBinder;
@@ -471,6 +474,7 @@
app.containsCycle = false;
app.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY);
app.setCurRawAdj(ProcessList.UNKNOWN_ADJ);
+ app.setCapability = PROCESS_CAPABILITY_NONE;
app.resetCachedInfo();
}
for (int i = numProc - 1; i >= 0; i--) {
@@ -788,6 +792,7 @@
if (app.hasForegroundServices()) {
uidRec.foregroundServices = true;
}
+ uidRec.curCapability |= app.curCapability;
}
}
@@ -804,10 +809,13 @@
int uidChange = UidRecord.CHANGE_PROCSTATE;
if (uidRec.getCurProcState() != PROCESS_STATE_NONEXISTENT
&& (uidRec.setProcState != uidRec.getCurProcState()
+ || uidRec.setCapability != uidRec.curCapability
|| uidRec.setWhitelist != uidRec.curWhitelist)) {
if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec
+ ": proc state from " + uidRec.setProcState + " to "
- + uidRec.getCurProcState() + ", whitelist from " + uidRec.setWhitelist
+ + uidRec.getCurProcState() + ", capability from "
+ + uidRec.setCapability + " to " + uidRec.curCapability
+ + ", whitelist from " + uidRec.setWhitelist
+ " to " + uidRec.curWhitelist);
if (ActivityManager.isProcStateBackground(uidRec.getCurProcState())
&& !uidRec.curWhitelist) {
@@ -845,11 +853,13 @@
uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
}
uidRec.setProcState = uidRec.getCurProcState();
+ uidRec.setCapability = uidRec.curCapability;
uidRec.setWhitelist = uidRec.curWhitelist;
uidRec.setIdle = uidRec.idle;
mService.mAtmInternal.onUidProcStateChanged(uidRec.uid, uidRec.setProcState);
mService.enqueueUidChangeLocked(uidRec, -1, uidChange);
- mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
+ mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState(),
+ uidRec.curCapability);
if (uidRec.foregroundServices) {
mService.mServices.foregroundServiceProcStateChangedLocked(uidRec);
}
@@ -1016,6 +1026,7 @@
app.curAdj = ProcessList.CACHED_APP_MAX_ADJ;
app.setCurRawAdj(ProcessList.CACHED_APP_MAX_ADJ);
app.completedAdjSeq = app.adjSeq;
+ app.curCapability = PROCESS_CAPABILITY_NONE;
return false;
}
@@ -1030,6 +1041,7 @@
int prevAppAdj = app.curAdj;
int prevProcState = app.getCurProcState();
+ int prevCapability = app.curCapability;
if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
// The max adjustment doesn't allow this app to be anything
@@ -1087,6 +1099,7 @@
int schedGroup;
int procState;
int cachedAdjSeq;
+ int capability = 0;
boolean foregroundActivities = false;
if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
@@ -1185,19 +1198,17 @@
}
}
+ if (app.hasLocationForegroundServices()) {
+ capability |= PROCESS_CAPABILITY_FOREGROUND_LOCATION;
+ }
+
if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
- || procState > PROCESS_STATE_FOREGROUND_SERVICE_LOCATION) {
+ || procState > PROCESS_STATE_FOREGROUND_SERVICE) {
if (app.hasForegroundServices()) {
// The user is aware of this app, so make it visible.
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
- if (app.hasLocationForegroundServices()) {
- procState = PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
- app.adjType = "fg-service-location";
-
- } else {
- procState = PROCESS_STATE_FOREGROUND_SERVICE;
- app.adjType = "fg-service";
- }
+ procState = PROCESS_STATE_FOREGROUND_SERVICE;
+ app.adjType = "fg-service";
app.cached = false;
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
@@ -1437,6 +1448,10 @@
continue;
}
+ if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
+ capability |= client.curCapability;
+ }
+
int clientAdj = client.getCurRawAdj();
int clientProcState = client.getCurRawProcState();
@@ -1549,25 +1564,31 @@
// processes). These should not bring the current process
// into the top state, since they are not on top. Instead
// give them the best bound state after that.
- final int bestState = cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)
- ? PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
- : PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
- if ((cr.flags & Context.BIND_FOREGROUND_SERVICE) != 0) {
- clientProcState = bestState;
+ if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) {
+ clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; ;
} else if (mService.mWakefulness
== PowerManagerInternal.WAKEFULNESS_AWAKE
&& (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
!= 0) {
- clientProcState = bestState;
+ clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
} else {
clientProcState =
PROCESS_STATE_IMPORTANT_FOREGROUND;
}
} else if (clientProcState == PROCESS_STATE_TOP) {
- if (cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
- // Go at most to BOUND_TOP, unless requested to elevate
- // to client's state.
- clientProcState = PROCESS_STATE_BOUND_TOP;
+ // Go at most to BOUND_TOP, unless requested to elevate
+ // to client's state.
+ clientProcState = PROCESS_STATE_BOUND_TOP;
+ if (client.info.targetSdkVersion >= Build.VERSION_CODES.R) {
+ if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) {
+ // TOP process passes all capabilities to the service.
+ capability = PROCESS_CAPABILITY_ALL;
+ } else {
+ // TOP process passes no capability to the service.
+ }
+ } else {
+ // TOP process passes all capabilities to the service.
+ capability = PROCESS_CAPABILITY_ALL;
}
} else if (clientProcState
<= PROCESS_STATE_FOREGROUND_SERVICE) {
@@ -1852,12 +1873,18 @@
}
}
+ // TOP process has all capabilities.
+ if (procState <= PROCESS_STATE_TOP) {
+ capability = PROCESS_CAPABILITY_ALL;
+ }
+
// Do final modification to adj. Everything we do between here and applying
// the final setAdj must be done in this function, because we will also use
// it when computing the final cached adj later. Note that we don't need to
// worry about this for max adj above, since max adj will always be used to
// keep it out of the cached vaues.
app.curAdj = app.modifyRawOomAdj(adj);
+ app.curCapability = capability;
app.setCurrentSchedulingGroup(schedGroup);
app.setCurProcState(procState);
app.setCurRawProcState(procState);
@@ -1865,7 +1892,8 @@
app.completedAdjSeq = mAdjSeq;
// if curAdj or curProcState improved, then this process was promoted
- return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState;
+ return app.curAdj < prevAppAdj || app.getCurProcState() < prevProcState
+ || app.curCapability != prevCapability ;
}
/**
@@ -2175,6 +2203,11 @@
maybeUpdateUsageStatsLocked(app, nowElapsed);
}
+ if (app.curCapability != app.setCapability) {
+ changes |= ActivityManagerService.ProcessChangeItem.CHANGE_CAPABILITY;
+ app.setCapability = app.curCapability;
+ }
+
if (changes != 0) {
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
"Changes in " + app + ": " + changes);
@@ -2182,12 +2215,13 @@
mService.enqueueProcessChangeItemLocked(app.pid, app.info.uid);
item.changes = changes;
item.foregroundActivities = app.repForegroundActivities;
+ item.capability = app.setCapability;
if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
"Item " + Integer.toHexString(System.identityHashCode(item))
+ " " + app.toShortString() + ": changes=" + item.changes
+ " foreground=" + item.foregroundActivities
+ " type=" + app.adjType + " source=" + app.adjSource
- + " target=" + app.adjTarget);
+ + " target=" + app.adjTarget + " capability=" + item.capability);
}
return success;
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 8163a6d..f2f1e02 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -810,9 +810,6 @@
case ActivityManager.PROCESS_STATE_TOP:
procState = "TOP ";
break;
- case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
- procState = "FGSL";
- break;
case ActivityManager.PROCESS_STATE_BOUND_TOP:
procState = "BTOP";
break;
@@ -882,8 +879,6 @@
return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI;
case ActivityManager.PROCESS_STATE_TOP:
return AppProtoEnums.PROCESS_STATE_TOP;
- case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION:
- return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE;
case ActivityManager.PROCESS_STATE_BOUND_TOP:
return AppProtoEnums.PROCESS_STATE_BOUND_TOP;
case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE:
@@ -1014,7 +1009,6 @@
PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP
- PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP
PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
@@ -2303,7 +2297,8 @@
uidRec.updateHasInternetPermission();
mActiveUids.put(proc.uid, uidRec);
EventLogTags.writeAmUidRunning(uidRec.uid);
- mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState());
+ mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState(),
+ uidRec.curCapability);
}
proc.uidRecord = uidRec;
@@ -2405,7 +2400,8 @@
mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
EventLogTags.writeAmUidStopped(uid);
mActiveUids.remove(uid);
- mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
+ mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
}
old.uidRecord = null;
}
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index bf43f3b..1e0693f 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -151,6 +151,9 @@
int curAdj; // Current OOM adjustment for this process
int setAdj; // Last set OOM adjustment for this process
int verifiedAdj; // The last adjustment that was verified as actually being set
+ int curCapability; // Current capability flags of this process. For example,
+ // PROCESS_CAPABILITY_FOREGROUND_LOCATION is one capability.
+ int setCapability; // Last set capability flags.
long lastCompactTime; // The last time that this process was compacted
int reqCompactAction; // The most recent compaction action requested for this app.
int lastCompactAction; // The most recent compaction action performed for this app.
@@ -425,6 +428,8 @@
pw.print(" mRepProcState="); pw.print(mRepProcState);
pw.print(" pssProcState="); pw.print(pssProcState);
pw.print(" setProcState="); pw.print(setProcState);
+ pw.print(" curCapability="); pw.print(curCapability);
+ pw.print(" setCapability="); pw.print(setCapability);
pw.print(" lastStateTime=");
TimeUtils.formatDuration(lastStateTime, nowUptime, pw);
pw.println();
@@ -1097,6 +1102,10 @@
&& (mFgServiceTypes & ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION) != 0;
}
+ boolean hasLocationCapability() {
+ return (setCapability & ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0;
+ }
+
int getForegroundServiceTypes() {
return mHasForegroundServices ? mFgServiceTypes : 0;
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 22a7de7..e6cf287 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -34,6 +34,8 @@
final int uid;
private int mCurProcState;
int setProcState = ActivityManager.PROCESS_STATE_NONEXISTENT;
+ int curCapability;
+ int setCapability;
long lastBackgroundTime;
boolean ephemeral;
boolean foregroundServices;
@@ -108,6 +110,7 @@
int uid;
int change;
int processState;
+ int capability;
boolean ephemeral;
long procStateSeq;
}
@@ -132,6 +135,8 @@
public void reset() {
setCurProcState(ActivityManager.PROCESS_STATE_CACHED_EMPTY);
foregroundServices = false;
+ curCapability = 0;
+
}
public void updateHasInternetPermission() {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 8575068..2e36a43 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -16,6 +16,7 @@
package com.android.server.appop;
+import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
import static android.app.AppOpsManager.MAX_PRIORITY_UID_STATE;
import static android.app.AppOpsManager.MIN_PRIORITY_UID_STATE;
import static android.app.AppOpsManager.OP_CAMERA;
@@ -27,7 +28,6 @@
import static android.app.AppOpsManager.UID_STATE_CACHED;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
-import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE_LOCATION;
import static android.app.AppOpsManager.UID_STATE_MAX_LAST_NON_RESTRICTED;
import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
import static android.app.AppOpsManager.UID_STATE_TOP;
@@ -119,12 +119,6 @@
import com.android.server.LocalServices;
import com.android.server.LockGuard;
-import libcore.util.EmptyArray;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
@@ -144,6 +138,12 @@
import java.util.Map;
import java.util.Objects;
+import libcore.util.EmptyArray;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
public class AppOpsService extends IAppOpsService.Stub {
static final String TAG = "AppOps";
static final boolean DEBUG = false;
@@ -164,12 +164,10 @@
UID_STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT
UID_STATE_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI
UID_STATE_TOP, // ActivityManager.PROCESS_STATE_TOP
- UID_STATE_FOREGROUND_SERVICE_LOCATION,
- // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION
UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_TOP
UID_STATE_FOREGROUND_SERVICE, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
- UID_STATE_FOREGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+ UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
UID_STATE_BACKGROUND, // ActivityManager.PROCESS_STATE_BACKUP
@@ -364,7 +362,8 @@
public int state = UID_STATE_CACHED;
public int pendingState = UID_STATE_CACHED;
public long pendingStateCommitTime;
-
+ public int capability;
+ public int pendingCapability;
// For all features combined
public int startNesting;
@@ -393,8 +392,25 @@
int evalMode(int op, int mode) {
if (mode == AppOpsManager.MODE_FOREGROUND) {
- return state <= AppOpsManager.resolveFirstUnrestrictedUidState(op)
- ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
+ if (state <= UID_STATE_TOP) {
+ // process is in foreground.
+ return AppOpsManager.MODE_ALLOWED;
+ } else if (state <= AppOpsManager.resolveFirstUnrestrictedUidState(op)) {
+ // process is in foreground, check its capability.
+ switch (op) {
+ case AppOpsManager.OP_FINE_LOCATION:
+ case AppOpsManager.OP_COARSE_LOCATION:
+ case AppOpsManager.OP_MONITOR_LOCATION:
+ case AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION:
+ return ((capability & PROCESS_CAPABILITY_FOREGROUND_LOCATION) != 0)
+ ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED;
+ default:
+ return AppOpsManager.MODE_ALLOWED;
+ }
+ } else {
+ // process is not in foreground.
+ return AppOpsManager.MODE_IGNORED;
+ }
}
return mode;
}
@@ -1062,13 +1078,16 @@
}
}
- public void updateUidProcState(int uid, int procState) {
+ public void updateUidProcState(int uid, int procState,
+ @ActivityManager.ProcessCapability int capability) {
synchronized (this) {
final UidState uidState = getUidStateLocked(uid, true);
- int newState = PROCESS_STATE_TO_UID_STATE[procState];
- if (uidState != null && uidState.pendingState != newState) {
+ final int newState = PROCESS_STATE_TO_UID_STATE[procState];
+ if (uidState != null && (uidState.pendingState != newState
+ || uidState.pendingCapability != capability)) {
final int oldPendingState = uidState.pendingState;
uidState.pendingState = newState;
+ uidState.pendingCapability = capability;
if (newState < uidState.state
|| (newState <= UID_STATE_MAX_LAST_NON_RESTRICTED
&& uidState.state > UID_STATE_MAX_LAST_NON_RESTRICTED)) {
@@ -1076,6 +1095,9 @@
// foreground and the old state is in the background, then always do it
// immediately.
commitUidPendingStateLocked(uidState);
+ } else if (newState == uidState.state && capability != uidState.capability) {
+ // No change on process state, but process capability has changed.
+ commitUidPendingStateLocked(uidState);
} else if (uidState.pendingStateCommitTime == 0) {
// We are moving to a less important state for the first time,
// delay the application for a bit.
@@ -1182,8 +1204,8 @@
}
} else {
for (int j=0; j<ops.length; j++) {
- int code = uidState.opModes.keyAt(j);
- if (code >= 0) {
+ int code = ops[j];
+ if (uidState.opModes.indexOfKey(code) >= 0) {
if (resOps == null) {
resOps = new ArrayList<>();
}
@@ -2857,6 +2879,7 @@
}
}
uidState.state = uidState.pendingState;
+ uidState.capability = uidState.pendingCapability;
uidState.pendingStateCommitTime = 0;
}
@@ -4494,6 +4517,12 @@
pw.print(" pendingState=");
pw.println(AppOpsManager.getUidStateName(uidState.pendingState));
}
+ pw.print(" capability=");
+ pw.println(uidState.capability);
+ if (uidState.capability != uidState.pendingCapability) {
+ pw.print(" pendingCapability=");
+ pw.println(uidState.pendingCapability);
+ }
if (uidState.pendingStateCommitTime != 0) {
pw.print(" pendingStateCommitTime=");
TimeUtils.formatDuration(uidState.pendingStateCommitTime, nowElapsed, pw);
diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING
index e9d2b31..9c03a36 100644
--- a/services/core/java/com/android/server/appop/TEST_MAPPING
+++ b/services/core/java/com/android/server/appop/TEST_MAPPING
@@ -35,6 +35,9 @@
"include-filter": "android.permission.cts.SharedUidPermissionsTest"
}
]
+ },
+ {
+ "name": "CtsAppTestCases:ActivityManagerApi29Test"
}
]
}
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 0d493b8..4feaeae 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -580,7 +580,8 @@
}
final private IUidObserver mUidObserver = new IUidObserver.Stub() {
- @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) {
}
@Override public void onUidGone(int uid, boolean disabled) {
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index bc5973d..8762435 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -20,6 +20,7 @@
import android.compat.annotation.EnabledAfter;
import android.content.pm.ApplicationInfo;
+import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.server.compat.config.Change;
import java.util.HashMap;
@@ -35,12 +36,8 @@
*
* <p>Note, this class is not thread safe so callers must ensure thread safety.
*/
-public final class CompatChange {
+public final class CompatChange extends CompatibilityChangeInfo {
- private final long mChangeId;
- @Nullable private final String mName;
- private final int mEnableAfterTargetSdk;
- private final boolean mDisabled;
private Map<String, Boolean> mPackageOverrides;
public CompatChange(long changeId) {
@@ -56,29 +53,15 @@
*/
public CompatChange(long changeId, @Nullable String name, int enableAfterTargetSdk,
boolean disabled) {
- mChangeId = changeId;
- mName = name;
- mEnableAfterTargetSdk = enableAfterTargetSdk;
- mDisabled = disabled;
+ super(changeId, name, enableAfterTargetSdk, disabled);
}
/**
* @param change an object generated by services/core/xsd/platform-compat-config.xsd
*/
public CompatChange(Change change) {
- mChangeId = change.getId();
- mName = change.getName();
- mEnableAfterTargetSdk = change.getEnableAfterTargetSdk();
- mDisabled = change.getDisabled();
- }
-
- long getId() {
- return mChangeId;
- }
-
- @Nullable
- String getName() {
- return mName;
+ super(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
+ change.getDisabled());
}
/**
@@ -121,11 +104,11 @@
if (mPackageOverrides != null && mPackageOverrides.containsKey(app.packageName)) {
return mPackageOverrides.get(app.packageName);
}
- if (mDisabled) {
+ if (getDisabled()) {
return false;
}
- if (mEnableAfterTargetSdk != -1) {
- return app.targetSdkVersion > mEnableAfterTargetSdk;
+ if (getEnableAfterTargetSdk() != -1) {
+ return app.targetSdkVersion > getEnableAfterTargetSdk();
}
return true;
}
@@ -133,14 +116,14 @@
@Override
public String toString() {
StringBuilder sb = new StringBuilder("ChangeId(")
- .append(mChangeId);
- if (mName != null) {
- sb.append("; name=").append(mName);
+ .append(getId());
+ if (getName() != null) {
+ sb.append("; name=").append(getName());
}
- if (mEnableAfterTargetSdk != -1) {
- sb.append("; enableAfterTargetSdk=").append(mEnableAfterTargetSdk);
+ if (getEnableAfterTargetSdk() != -1) {
+ sb.append("; enableAfterTargetSdk=").append(getEnableAfterTargetSdk());
}
- if (mDisabled) {
+ if (getDisabled()) {
sb.append("; disabled");
}
if (mPackageOverrides != null && mPackageOverrides.size() > 0) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 0fabd9a..d6ec22b 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -16,6 +16,7 @@
package com.android.server.compat;
+import android.compat.Compatibility.ChangeConfig;
import android.content.pm.ApplicationInfo;
import android.os.Environment;
import android.text.TextUtils;
@@ -26,6 +27,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.server.compat.config.Change;
import com.android.server.compat.config.XmlParser;
@@ -37,6 +39,8 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
import javax.xml.datatype.DatatypeConfigurationException;
/**
@@ -243,6 +247,49 @@
}
}
+ /**
+ * Get the config for a given app.
+ *
+ * @param applicationInfo the {@link ApplicationInfo} for which the info should be dumped.
+ * @return A {@link CompatibilityChangeConfig} which contains the compat config info for the
+ * given app.
+ */
+
+ public CompatibilityChangeConfig getAppConfig(ApplicationInfo applicationInfo) {
+ Set<Long> enabled = new HashSet<>();
+ Set<Long> disabled = new HashSet<>();
+ synchronized (mChanges) {
+ for (int i = 0; i < mChanges.size(); ++i) {
+ CompatChange c = mChanges.valueAt(i);
+ if (c.isEnabled(applicationInfo)) {
+ enabled.add(c.getId());
+ } else {
+ disabled.add(c.getId());
+ }
+ }
+ }
+ return new CompatibilityChangeConfig(new ChangeConfig(enabled, disabled));
+ }
+
+ /**
+ * Dumps all the compatibility change information.
+ *
+ * @return An array of {@link CompatibilityChangeInfo} with the current changes.
+ */
+ public CompatibilityChangeInfo[] dumpChanges() {
+ synchronized (mChanges) {
+ CompatibilityChangeInfo[] changeInfos = new CompatibilityChangeInfo[mChanges.size()];
+ for (int i = 0; i < mChanges.size(); ++i) {
+ CompatChange change = mChanges.valueAt(i);
+ changeInfos[i] = new CompatibilityChangeInfo(change.getId(),
+ change.getName(),
+ change.getEnableAfterTargetSdk(),
+ change.getDisabled());
+ }
+ return changeInfos;
+ }
+ }
+
CompatConfig initConfigFromLib(File libraryDir) {
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Slog.e(TAG, "No directory " + libraryDir + ", skipping");
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 9ac9955..75e2d22 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -25,6 +25,7 @@
import com.android.internal.compat.ChangeReporter;
import com.android.internal.compat.CompatibilityChangeConfig;
+import com.android.internal.compat.CompatibilityChangeInfo;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.util.DumpUtils;
@@ -114,6 +115,16 @@
}
@Override
+ public CompatibilityChangeConfig getAppConfig(ApplicationInfo appInfo) {
+ return CompatConfig.get().getAppConfig(appInfo);
+ }
+
+ @Override
+ public CompatibilityChangeInfo[] listAllChanges() {
+ return CompatConfig.get().dumpChanges();
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
CompatConfig.get().dumpConfig(pw);
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index 362955d..2c23c51 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1810,8 +1810,9 @@
}
// Native callback.
- private long notifyANR(IBinder token, String reason) {
- return mWindowManagerCallbacks.notifyANR(
+ private long notifyANR(InputApplicationHandle inputApplicationHandle, IBinder token,
+ String reason) {
+ return mWindowManagerCallbacks.notifyANR(inputApplicationHandle,
token, reason);
}
@@ -2055,7 +2056,12 @@
public void notifyInputChannelBroken(IBinder token);
- public long notifyANR(IBinder token, String reason);
+ /**
+ * Notifies the window manager about an application that is not responding.
+ * Returns a new timeout to continue waiting in nanoseconds, or 0 to abort dispatch.
+ */
+ long notifyANR(InputApplicationHandle inputApplicationHandle, IBinder token,
+ String reason);
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags);
diff --git a/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java b/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
new file mode 100644
index 0000000..c1567bc
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/parser/RuleBinaryParser.java
@@ -0,0 +1,37 @@
+/*
+ * 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.integrity.parser;
+
+import com.android.server.integrity.model.Rule;
+
+import java.io.InputStream;
+
+/** A helper class to parse rules into the {@link Rule} model from Binary representation. */
+public class RuleBinaryParser implements RuleParser {
+
+ @Override
+ public Rule parse(String ruleText) {
+ // TODO: Implement binary text parser.
+ return null;
+ }
+
+ @Override
+ public Rule parse(InputStream inputStream) {
+ // TODO: Implement stream parser.
+ return null;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/parser/RuleParser.java b/services/core/java/com/android/server/integrity/parser/RuleParser.java
new file mode 100644
index 0000000..96ed5993
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/parser/RuleParser.java
@@ -0,0 +1,31 @@
+/*
+ * 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.integrity.parser;
+
+import com.android.server.integrity.model.Rule;
+
+import java.io.InputStream;
+
+/** A helper class to parse rules into the {@link Rule} model. */
+public interface RuleParser {
+
+ /** Parse rules from a string. */
+ Rule parse(String ruleText);
+
+ /** Parse rules from an input stream. */
+ Rule parse(InputStream inputStream);
+}
diff --git a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
new file mode 100644
index 0000000..8b1bec9
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java
@@ -0,0 +1,37 @@
+/*
+ * 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.integrity.parser;
+
+import com.android.server.integrity.model.Rule;
+
+import java.io.InputStream;
+
+/** A helper class to parse rules into the {@link Rule} model from Xml representation. */
+public final class RuleXmlParser implements RuleParser {
+
+ @Override
+ public Rule parse(String ruleText) {
+ // TODO: Implement text parser.
+ return null;
+ }
+
+ @Override
+ public Rule parse(InputStream inputStream) {
+ // TODO: Implement stream parser.
+ return null;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
new file mode 100644
index 0000000..ecb00a4
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/serializer/RuleBinarySerializer.java
@@ -0,0 +1,36 @@
+/*
+ * 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.integrity.serializer;
+
+import com.android.server.integrity.model.Rule;
+
+import java.io.OutputStream;
+
+/** A helper class to serialize rules from the {@link Rule} model to Xml representation. */
+public class RuleBinarySerializer implements RuleSerializer {
+
+ @Override
+ public void serialize(Rule rule, OutputStream outputStream) {
+ // TODO: Implement stream serializer.
+ }
+
+ @Override
+ public String serialize(Rule rule) {
+ // TODO: Implement text serializer.
+ return null;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleSerializer.java
new file mode 100644
index 0000000..07a912f
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/serializer/RuleSerializer.java
@@ -0,0 +1,31 @@
+/*
+ * 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.integrity.serializer;
+
+import com.android.server.integrity.model.Rule;
+
+import java.io.OutputStream;
+
+/** A helper class to serialize rules from the {@link Rule} model. */
+public interface RuleSerializer {
+
+ /** Serialize a rule to an output stream */
+ void serialize(Rule rule, OutputStream outputStream);
+
+ /** Serialize a rule to a string. */
+ String serialize(Rule rule);
+}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
new file mode 100644
index 0000000..62973e2
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
@@ -0,0 +1,36 @@
+/*
+ * 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.integrity.serializer;
+
+import com.android.server.integrity.model.Rule;
+
+import java.io.OutputStream;
+
+/** A helper class to serialize rules from the {@link Rule} model to Xml representation. */
+public class RuleXmlSerializer implements RuleSerializer {
+
+ @Override
+ public void serialize(Rule rule, OutputStream outputStream) {
+ // TODO: Implement stream serializer.
+ }
+
+ @Override
+ public String serialize(Rule rule) {
+ // TODO: Implement text serializer.
+ return null;
+ }
+}
diff --git a/services/core/java/com/android/server/location/GeocoderProxy.java b/services/core/java/com/android/server/location/GeocoderProxy.java
index d9602b8..e6f0ed9 100644
--- a/services/core/java/com/android/server/location/GeocoderProxy.java
+++ b/services/core/java/com/android/server/location/GeocoderProxy.java
@@ -21,7 +21,7 @@
import android.location.GeocoderParams;
import android.location.IGeocodeProvider;
-import com.android.server.FgThread;
+import com.android.internal.os.BackgroundThread;
import com.android.server.ServiceWatcher;
import java.util.List;
@@ -53,7 +53,7 @@
int initialPackageNamesResId) {
mServiceWatcher = new ServiceWatcher(context, TAG, SERVICE_ACTION, overlaySwitchResId,
defaultServicePackageNameResId, initialPackageNamesResId,
- FgThread.getHandler());
+ BackgroundThread.getHandler());
}
private boolean bind() {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 388214b..32d4b72 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -912,7 +912,8 @@
}
final private IUidObserver mUidObserver = new IUidObserver.Stub() {
- @Override public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ @Override public void onUidStateChanged(int uid, int procState, long procStateSeq,
+ int capability) {
mUidEventHandler.obtainMessage(UID_MSG_STATE_CHANGED,
uid, procState, procStateSeq).sendToTarget();
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 8253b392..f0a1c70 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -495,7 +495,7 @@
final private IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override
- public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
injectPostToHandler(() -> handleOnUidStateChanged(uid, procState));
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a2aeaf1..5c9b9c9 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1593,6 +1593,7 @@
/** @return a specific user restriction that's in effect currently. */
@Override
public boolean hasUserRestriction(String restrictionKey, @UserIdInt int userId) {
+ checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "hasUserRestriction");
return mLocalService.hasUserRestriction(restrictionKey, userId);
}
@@ -1717,6 +1718,7 @@
*/
@Override
public Bundle getUserRestrictions(@UserIdInt int userId) {
+ checkManageOrInteractPermIfCallerInOtherProfileGroup(userId, "getUserRestrictions");
return UserRestrictionsUtils.clone(getEffectiveUserRestrictions(userId));
}
@@ -4000,9 +4002,14 @@
long now = System.currentTimeMillis();
final long nowRealtime = SystemClock.elapsedRealtime();
- final int currentUser = LocalServices.getService(ActivityManagerInternal.class)
- .getCurrentUserId();
- pw.print("Current user: "); pw.println(currentUser);
+ final ActivityManagerInternal amInternal = LocalServices
+ .getService(ActivityManagerInternal.class);
+ pw.print("Current user: ");
+ if (amInternal != null) {
+ pw.println(amInternal.getCurrentUserId());
+ } else {
+ pw.println("N/A");
+ }
StringBuilder sb = new StringBuilder();
synchronized (mPackagesLock) {
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index f56231f..41dcaa5 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -16,8 +16,6 @@
package com.android.server.pm.dex;
-import static android.provider.DeviceConfig.NAMESPACE_DEX_BOOT;
-
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.dex.PackageDexUsage.DexUseInfo;
import static com.android.server.pm.dex.PackageDexUsage.PackageUseInfo;
@@ -31,7 +29,6 @@
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
-import android.provider.DeviceConfig;
import android.util.Log;
import android.util.Slog;
import android.util.jar.StrictJarFile;
@@ -72,10 +69,6 @@
private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST =
"pm.dexopt.priv-apps-oob-list";
- // flags for Device Config API
- private static final String PRIV_APPS_OOB_ENABLED = "priv_apps_oob_enabled";
- private static final String PRIV_APPS_OOB_WHITELIST = "priv_apps_oob_whitelist";
-
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Context mContext;
@@ -717,24 +710,16 @@
return isPackageSelectedToRunOobInternal(
SystemProperties.getBoolean(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB, false),
SystemProperties.get(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST, "ALL"),
- DeviceConfig.getProperty(NAMESPACE_DEX_BOOT, PRIV_APPS_OOB_ENABLED),
- DeviceConfig.getProperty(NAMESPACE_DEX_BOOT, PRIV_APPS_OOB_WHITELIST),
packageNamesInSameProcess);
}
@VisibleForTesting
- /* package */ static boolean isPackageSelectedToRunOobInternal(
- boolean isDefaultEnabled, String defaultWhitelist, String overrideEnabled,
- String overrideWhitelist, Collection<String> packageNamesInSameProcess) {
- // Allow experiment (if exists) to override device configuration.
- boolean enabled = overrideEnabled != null ? overrideEnabled.equals("true")
- : isDefaultEnabled;
- if (!enabled) {
+ /* package */ static boolean isPackageSelectedToRunOobInternal(boolean isEnabled,
+ String whitelist, Collection<String> packageNamesInSameProcess) {
+ if (!isEnabled) {
return false;
}
- // Similarly, experiment flag can override the whitelist.
- String whitelist = overrideWhitelist != null ? overrideWhitelist : defaultWhitelist;
if ("ALL".equals(whitelist)) {
return true;
}
diff --git a/services/core/java/com/android/server/updates/EmergencyNumberDbInstallReceiver.java b/services/core/java/com/android/server/updates/EmergencyNumberDbInstallReceiver.java
index 852f707..cb0b45c 100644
--- a/services/core/java/com/android/server/updates/EmergencyNumberDbInstallReceiver.java
+++ b/services/core/java/com/android/server/updates/EmergencyNumberDbInstallReceiver.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.Intent;
+import android.telephony.TelephonyManager;
import android.util.Slog;
/**
@@ -34,6 +35,11 @@
@Override
protected void postInstall(Context context, Intent intent) {
Slog.i(TAG, "Emergency number database is updated in file partition");
- // TODO Send a notification to EmergencyNumberTracker for updating of emergency number db.
+
+ // Notify EmergencyNumberTracker for emergency number installation complete.
+ Intent notifyInstallComplete = new Intent(
+ TelephonyManager.ACTION_OTA_EMERGENCY_NUMBER_DB_INSTALLED);
+ context.sendBroadcast(
+ notifyInstallComplete, android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
}
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 5e4f75c..c57ac11 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -132,17 +132,20 @@
return false;
}
- if (mWindowsForAccessibilityObserver.get(displayId) != null) {
- final Display display = dc.getDisplay();
- if (display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null) {
- // The window observer of this embedded display had been set from
- // window manager after setting its parent window.
- return false;
- } else {
- throw new IllegalStateException(
- "Windows for accessibility callback of display "
- + displayId + " already set!");
+ final Display display = dc.getDisplay();
+ if (display.getType() == Display.TYPE_VIRTUAL && dc.getParentWindow() != null) {
+ // If this display is an embedded one, its window observer should have been set from
+ // window manager after setting its parent window. But if its window observer is
+ // empty, that means this mapping didn't be set, and needs to do this again.
+ // This happened when accessibility window observer is disabled and enabled again.
+ if (mWindowsForAccessibilityObserver.get(displayId) == null) {
+ handleWindowObserverOfEmbeddedDisplayLocked(displayId, dc.getParentWindow());
}
+ return false;
+ } else if (mWindowsForAccessibilityObserver.get(displayId) != null) {
+ throw new IllegalStateException(
+ "Windows for accessibility callback of display "
+ + displayId + " already set!");
}
mWindowsForAccessibilityObserver.put(displayId,
new WindowsForAccessibilityObserver(mService, displayId, callback));
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 9d41d97..ff2c671 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -403,8 +403,7 @@
if (launchedActivity != null && launchedActivity.mDrawn) {
// Launched activity is already visible. We cannot measure windows drawn delay.
- reset(true /* abort */, info, "launched activity already visible",
- 0L /* timestampNs */);
+ abort(info, "launched activity already visible");
return;
}
@@ -422,8 +421,7 @@
if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
|| windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
// Failed to launch or it was not a process switch, so we don't care about the timing.
- reset(true /* abort */, info, "failed to launch or not a process switch",
- 0L /* timestampNs */);
+ abort(info, "failed to launch or not a process switch");
return;
} else if (otherWindowModesLaunching) {
// Don't log this windowing mode but continue with the other windowing modes.
@@ -469,8 +467,7 @@
final WindowingModeTransitionInfoSnapshot infoSnapshot =
new WindowingModeTransitionInfoSnapshot(info);
if (allWindowsDrawn() && mLoggedTransitionStarting) {
- reset(false /* abort */, info, "notifyWindowsDrawn - all windows drawn",
- timestampNs /* timestampNs */);
+ reset(false /* abort */, info, "notifyWindowsDrawn - all windows drawn", timestampNs);
}
return infoSnapshot;
}
@@ -478,13 +475,13 @@
/**
* Notifies the tracker that the starting window was drawn.
*/
- void notifyStartingWindowDrawn(@WindowingMode int windowingMode, long timestamp) {
+ void notifyStartingWindowDrawn(@WindowingMode int windowingMode, long timestampNs) {
final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
if (info == null || info.loggedStartingWindowDrawn) {
return;
}
info.loggedStartingWindowDrawn = true;
- info.startingWindowDelayMs = calculateDelay(timestamp);
+ info.startingWindowDelayMs = calculateDelay(timestampNs);
}
/**
@@ -544,10 +541,11 @@
mHandler.obtainMessage(MSG_CHECK_VISIBILITY, args).sendToTarget();
}
- private boolean hasVisibleNonFinishingActivity(TaskRecord t) {
+ /** @return {@code true} if the given task has an activity will be drawn. */
+ private static boolean hasActivityToBeDrawn(TaskRecord t) {
for (int i = t.getChildCount() - 1; i >= 0; --i) {
final ActivityRecord r = t.getChildAt(i);
- if (r.visible && !r.finishing) {
+ if (r.visible && !r.mDrawn && !r.finishing) {
return true;
}
}
@@ -574,19 +572,20 @@
return;
}
- // Check if there is any activity in the task that is visible and not finishing. If the
- // launched activity finished before it is drawn and if there is another activity in
- // the task then that activity will be draw on screen.
- if (hasVisibleNonFinishingActivity(t)) {
+ // If the task of the launched activity contains any activity to be drawn, then the
+ // window drawn event should report later to complete the transition. Otherwise all
+ // activities in this task may be finished, invisible or drawn, so the transition event
+ // should be cancelled.
+ if (hasActivityToBeDrawn(t)) {
return;
}
if (DEBUG_METRICS) Slog.i(TAG, "notifyVisibilityChanged to invisible activity=" + r);
logAppTransitionCancel(info);
- mWindowingModeTransitionInfo.remove(r.getWindowingMode());
- if (mWindowingModeTransitionInfo.size() == 0) {
- reset(true /* abort */, info, "notifyVisibilityChanged to invisible",
- 0L /* timestampNs */);
+ // Abort if this is the only one active transition.
+ if (mWindowingModeTransitionInfo.size() == 1
+ && mWindowingModeTransitionInfo.get(r.getWindowingMode()) != null) {
+ abort(info, "notifyVisibilityChanged to invisible");
}
}
}
@@ -622,19 +621,25 @@
&& mWindowingModeTransitionInfo.size() > 0;
}
+ /** Aborts tracking of current launch metrics. */
+ private void abort(WindowingModeTransitionInfo info, String cause) {
+ reset(true /* abort */, info, cause, 0L /* timestampNs */);
+ }
+
private void reset(boolean abort, WindowingModeTransitionInfo info, String cause,
- long timestampNs) {
+ long timestampNs) {
+ final boolean isAnyTransitionActive = isAnyTransitionActive();
if (DEBUG_METRICS) {
- Slog.i(TAG,
- "reset abort=" + abort + ",cause=" + cause + ",timestamp=" + timestampNs);
+ Slog.i(TAG, "reset abort=" + abort + " cause=" + cause + " timestamp=" + timestampNs
+ + " active=" + isAnyTransitionActive);
}
- if (!abort && isAnyTransitionActive()) {
+ if (!abort && isAnyTransitionActive) {
logAppTransitionMultiEvents();
}
stopLaunchTrace(info);
// Ignore reset-after reset.
- if (isAnyTransitionActive()) {
+ if (isAnyTransitionActive) {
// LaunchObserver callbacks.
if (abort) {
launchObserverNotifyActivityLaunchCancelled(info);
@@ -818,7 +823,14 @@
return StatsLog.APP_START_OCCURRED__TYPE__HOT;
}
return StatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
- }
+ }
+
+ /** @return the last known window drawn delay of the given windowing mode. */
+ int getLastDrawnDelayMs(@WindowingMode int windowingMode) {
+ final WindowingModeTransitionInfo info = mLastWindowingModeTransitionInfo.get(
+ windowingMode);
+ return info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
+ }
WindowingModeTransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r,
boolean restoredFromBundle) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index ec0900f..76ac539 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -179,7 +179,7 @@
import static com.android.server.wm.AppWindowTokenProto.FROZEN_BOUNDS;
import static com.android.server.wm.AppWindowTokenProto.HIDDEN_REQUESTED;
import static com.android.server.wm.AppWindowTokenProto.HIDDEN_SET_FROM_TRANSFERRED_STARTING_WINDOW;
-import static com.android.server.wm.AppWindowTokenProto.IS_REALLY_ANIMATING;
+import static com.android.server.wm.AppWindowTokenProto.IS_ANIMATING;
import static com.android.server.wm.AppWindowTokenProto.IS_WAITING_FOR_TRANSITION_START;
import static com.android.server.wm.AppWindowTokenProto.LAST_ALL_DRAWN;
import static com.android.server.wm.AppWindowTokenProto.LAST_SURFACE_SHOWING;
@@ -205,16 +205,17 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.TaskPersister.DEBUG;
import static com.android.server.wm.TaskPersister.IMAGE_EXTENSION;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
-import static com.android.server.wm.WindowManagerService.logWithStack;
import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
-import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
@@ -291,16 +292,17 @@
import android.view.InputApplicationHandle;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationDefinition;
+import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.view.animation.Animation;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.ReferrerIntent;
-import com.android.internal.R;
import com.android.internal.util.ToBooleanFunction;
import com.android.internal.util.XmlUtils;
import com.android.server.AttributeCache;
@@ -315,6 +317,7 @@
import com.android.server.wm.ActivityMetricsLogger.WindowingModeTransitionInfoSnapshot;
import com.android.server.wm.ActivityStack.ActivityState;
import com.android.server.wm.WindowManagerService.H;
+import com.android.server.wm.utils.InsetUtils;
import com.google.android.collect.Sets;
@@ -332,7 +335,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
-import java.util.function.Consumer;
/**
* An entry in the history stack, representing an activity.
@@ -374,6 +376,7 @@
* Value to increment the z-layer when boosting a layer during animations. BOOST in l33tsp34k.
*/
@VisibleForTesting static final int Z_BOOST_BASE = 800570000;
+ static final int INVALID_PID = -1;
final ActivityTaskManagerService mAtmService;
final ActivityInfo info; // activity info provided by developer in AndroidManifest
@@ -551,24 +554,6 @@
private boolean mCurrentLaunchCanTurnScreenOn = true;
/**
- * This gets used during some open/close transitions as well as during a change transition
- * where it represents the starting-state snapshot.
- */
- private AppWindowThumbnail mThumbnail;
- private final Rect mTransitStartRect = new Rect();
-
- /**
- * If we are running an animation, this determines the transition type. Must be one of
- * AppTransition.TRANSIT_* constants.
- */
- private int mTransit;
-
- /**
- * If we are running an animation, this determines the flags during this animation. Must be a
- * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
- */
- private int mTransitFlags;
- /**
* This leash is used to "freeze" the app surface in place after the state change, but before
* the animation is ready to start.
*/
@@ -664,7 +649,6 @@
// TODO: Have a WindowContainer state for tracking exiting/deferred removal.
boolean mIsExiting;
- boolean mLaunchTaskBehind;
boolean mEnteringAnimation;
boolean mAppStopped;
@@ -676,15 +660,6 @@
ArrayDeque<Rect> mFrozenBounds = new ArrayDeque<>();
ArrayDeque<Configuration> mFrozenMergedConfig = new ArrayDeque<>();
- /** Whether this token should be boosted at the top of all app window tokens. */
- @VisibleForTesting boolean mNeedsZBoost;
-
- /** Layer used to constrain the animation to a token's stack bounds. */
- SurfaceControl mAnimationBoundsLayer;
-
- /** Whether this token needs to create mAnimationBoundsLayer for cropping animations. */
- boolean mNeedsAnimationBoundsLayer;
-
private AppSaturationInfo mLastAppSaturationInfo;
private final ColorDisplayService.ColorTransformController mColorTransformController =
@@ -710,10 +685,6 @@
private final Configuration mTmpConfig = new Configuration();
private final Rect mTmpBounds = new Rect();
- private final Point mTmpPoint = new Point();
- private final Rect mTmpRect = new Rect();
- private final Rect mTmpPrevBounds = new Rect();
-
// Token for targeting this activity for assist purposes.
final Binder assistToken = new Binder();
@@ -2305,7 +2276,7 @@
* 2. App is delayed closing since it might enter PIP.
*/
boolean isClosingOrEnteringPip() {
- return (isAnimating() && hiddenRequested) || mWillCloseOrEnterPip;
+ return (isAnimating(TRANSITION | PARENTS) && hiddenRequested) || mWillCloseOrEnterPip;
}
/**
* @return Whether AppOps allows this package to enter picture-in-picture.
@@ -3114,7 +3085,7 @@
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"Removing app %s delayed=%b animation=%s animating=%b", this, delayed,
- getAnimation(), isSelfAnimating());
+ getAnimation(), isAnimating(TRANSITION));
ProtoLog.v(WM_DEBUG_ADD_REMOVE, "removeAppToken: %s"
+ " delayed=%b Callers=%s", this, delayed, Debug.getCallers(4));
@@ -3126,7 +3097,7 @@
// If this window was animating, then we need to ensure that the app transition notifies
// that animations have completed in DisplayContent.handleAnimatingStoppedAndTransition(),
// so add to that list now
- if (isSelfAnimating()) {
+ if (isAnimating(TRANSITION)) {
getDisplayContent().mNoAnimationNotifyOnTransitionFinished.add(token);
}
@@ -3474,7 +3445,7 @@
* color mode set to avoid jank in the middle of the transition.
*/
boolean canShowWindows() {
- return allDrawn && !(isReallyAnimating() && hasNonDefaultColorWindow());
+ return allDrawn && !(isAnimating() && hasNonDefaultColorWindow());
}
/**
@@ -3536,17 +3507,17 @@
return forAllWindowsUnchecked(callback, traverseTopToBottom);
}
- @Override
- void forAllActivities(Consumer<ActivityRecord> callback) {
- callback.accept(this);
- }
-
boolean forAllWindowsUnchecked(ToBooleanFunction<WindowState> callback,
boolean traverseTopToBottom) {
return super.forAllWindows(callback, traverseTopToBottom);
}
@Override
+ boolean forAllActivities(ToBooleanFunction<ActivityRecord> callback) {
+ return callback.apply(this);
+ }
+
+ @Override
protected void setLayer(Transaction t, int layer) {
if (!mSurfaceAnimator.hasLeash()) {
t.setLayer(mSurfaceControl, layer);
@@ -4127,8 +4098,8 @@
if (transit != WindowManager.TRANSIT_UNSET) {
if (mUseTransferredAnimation) {
- runningAppAnimation = isReallyAnimating();
- } else if (applyAnimationLocked(lp, transit, visible, isVoiceInteraction)) {
+ runningAppAnimation = isAnimating();
+ } else if (applyAnimation(lp, transit, visible, isVoiceInteraction)) {
runningAppAnimation = true;
}
delayed = runningAppAnimation;
@@ -4179,21 +4150,14 @@
}
mUseTransferredAnimation = false;
- if (isReallyAnimating()) {
- delayed = true;
- } else {
+ delayed = isAnimating(CHILDREN);
+ if (!delayed) {
// We aren't animating anything, but exiting windows rely on the animation finished
// callback being called in case the ActivityRecord was pretending to be animating,
// which we might have done because we were in closing/opening apps list.
onAnimationFinished();
}
- for (int i = mChildren.size() - 1; i >= 0 && !delayed; i--) {
- if ((mChildren.get(i)).isSelfOrChildAnimating()) {
- delayed = true;
- }
- }
-
if (visibilityChanged) {
if (visible && !delayed) {
// The token was made immediately visible, there will be no entrance animation.
@@ -4208,7 +4172,7 @@
// updated.
// If we're becoming invisible, update the client visibility if we are not running an
// animation. Otherwise, we'll update client visibility in onAnimationFinished.
- if (visible || !isReallyAnimating()) {
+ if (visible || !isAnimating()) {
setClientHidden(!visible);
}
@@ -5122,7 +5086,7 @@
final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
windowsDrawnDelayMs, launchState);
- mStackSupervisor.stopWaitingForActivityVisible(this);
+ mStackSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs);
finishLaunchTickingLocked();
if (task != null) {
task.hasBeenVisible = true;
@@ -5288,13 +5252,13 @@
if (!allDrawn && w.mightAffectAllDrawn()) {
if (DEBUG_VISIBILITY || WM_DEBUG_ORIENTATION.isLogToLogcat()) {
Slog.v(TAG, "Eval win " + w + ": isDrawn=" + w.isDrawnLw()
- + ", isAnimationSet=" + isSelfAnimating());
+ + ", isAnimationSet=" + isAnimating(TRANSITION));
if (!w.isDrawnLw()) {
Slog.v(TAG, "Not displayed: s=" + winAnimator.mSurfaceController
+ " pv=" + w.isVisibleByPolicy()
+ " mDrawState=" + winAnimator.drawStateToString()
+ " ph=" + w.isParentWindowHidden() + " th=" + hiddenRequested
- + " a=" + isSelfAnimating());
+ + " a=" + isAnimating(TRANSITION));
}
}
@@ -5318,7 +5282,7 @@
}
}
} else if (w.isDrawnLw()) {
- onStartingWindowDrawn(SystemClock.uptimeMillis());
+ onStartingWindowDrawn(SystemClock.elapsedRealtimeNanos());
startingDisplayed = true;
}
}
@@ -5327,10 +5291,10 @@
}
/** Called when the starting window for this container is drawn. */
- private void onStartingWindowDrawn(long timestamp) {
+ private void onStartingWindowDrawn(long timestampNs) {
synchronized (mAtmService.mGlobalLock) {
mAtmService.mStackSupervisor.getActivityMetricsLogger().notifyStartingWindowDrawn(
- getWindowingMode(), timestamp);
+ getWindowingMode(), timestampNs);
}
}
@@ -5350,7 +5314,7 @@
anrActivity = getWaitingHistoryRecordLocked();
anrApp = app;
windowFromSameProcessAsActivity =
- !hasProcess() || app.getPid() == windowPid || windowPid == -1;
+ !hasProcess() || app.getPid() == windowPid || windowPid == INVALID_PID;
}
if (windowFromSameProcessAsActivity) {
@@ -5722,28 +5686,44 @@
}
}
-
@VisibleForTesting
boolean shouldAnimate(int transit) {
+ final Task task = getTask();
+ if (task != null && !task.shouldAnimate()) {
+ return false;
+ }
final boolean isSplitScreenPrimary =
getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
final boolean allowSplitScreenPrimaryAnimation = transit != TRANSIT_WALLPAPER_OPEN;
- // Don't animate while the task runs recents animation but only if we are in the mode
- // where we cancel with deferred screenshot, which means that the controller has
- // transformed the task.
- final RecentsAnimationController controller = mWmService.getRecentsAnimationController();
- if (controller != null && controller.isAnimatingTask(getTask())
- && controller.shouldDeferCancelUntilNextTransition()) {
- return false;
- }
-
// We animate always if it's not split screen primary, and only some special cases in split
// screen primary because it causes issues with stack clipping when we run an un-minimize
// animation at the same time.
return !isSplitScreenPrimary || allowSplitScreenPrimaryAnimation;
}
+ @Override
+ boolean isChangingAppTransition() {
+ final Task task = getTask();
+ if (task != null) {
+ return task.isChangingAppTransition();
+ }
+ return super.isChangingAppTransition();
+ }
+
+ @Override
+ boolean applyAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
+ boolean isVoiceInteraction) {
+ if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: transition animation is disabled or skipped. "
+ + "container=%s", this);
+ cancelAnimation();
+ return false;
+ }
+ return super.applyAnimation(lp, transit, enter, isVoiceInteraction);
+ }
+
/**
* Creates a layer to apply crop to an animation.
*/
@@ -5757,171 +5737,6 @@
return boundsLayer;
}
- boolean applyAnimationLocked(WindowManager.LayoutParams lp, int transit, boolean enter,
- boolean isVoiceInteraction) {
-
- if (mWmService.mDisableTransitionAnimation || !shouldAnimate(transit)) {
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: transition animation is disabled or skipped. "
- + "atoken=%s", this);
- cancelAnimation();
- return false;
- }
-
- // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
- // to animate and it can cause strange artifacts when we unfreeze the display if some
- // different animation is running.
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "AWT#applyAnimationLocked");
- if (okToAnimate()) {
- final AnimationAdapter adapter;
- AnimationAdapter thumbnailAdapter = null;
-
- final int appStackClipMode =
- getDisplayContent().mAppTransition.getAppStackClipMode();
-
- // Separate position and size for use in animators.
- mTmpRect.set(getAnimationBounds(appStackClipMode));
- mTmpPoint.set(mTmpRect.left, mTmpRect.top);
- mTmpRect.offsetTo(0, 0);
-
- final boolean isChanging = AppTransition.isChangeTransit(transit) && enter
- && getDisplayContent().mChangingApps.contains(this);
-
- // Delaying animation start isn't compatible with remote animations at all.
- if (getDisplayContent().mAppTransition.getRemoteAnimationController() != null
- && !mSurfaceAnimator.isAnimationStartDelayed()) {
- RemoteAnimationController.RemoteAnimationRecord adapters =
- getDisplayContent().mAppTransition.getRemoteAnimationController()
- .createRemoteAnimationRecord(this, mTmpPoint, mTmpRect,
- (isChanging ? mTransitStartRect : null));
- adapter = adapters.mAdapter;
- thumbnailAdapter = adapters.mThumbnailAdapter;
- } else if (isChanging) {
- final float durationScale = mWmService.getTransitionAnimationScaleLocked();
- mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y);
- adapter = new LocalAnimationAdapter(
- new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect,
- getDisplayContent().getDisplayInfo(), durationScale,
- true /* isAppAnimation */, false /* isThumbnail */),
- mWmService.mSurfaceAnimationRunner);
- if (mThumbnail != null) {
- thumbnailAdapter = new LocalAnimationAdapter(
- new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect,
- getDisplayContent().getDisplayInfo(), durationScale,
- true /* isAppAnimation */, true /* isThumbnail */),
- mWmService.mSurfaceAnimationRunner);
- }
- mTransit = transit;
- mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
- } else {
- mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
-
- final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
- if (a != null) {
- // Only apply corner radius to animation if we're not in multi window mode.
- // We don't want rounded corners when in pip or split screen.
- final float windowCornerRadius = !inMultiWindowMode()
- ? getDisplayContent().getWindowCornerRadius()
- : 0;
- adapter = new LocalAnimationAdapter(
- new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
- getDisplayContent().mAppTransition.canSkipFirstFrame(),
- appStackClipMode,
- true /* isAppAnimation */,
- windowCornerRadius),
- mWmService.mSurfaceAnimationRunner);
- if (a.getZAdjustment() == Animation.ZORDER_TOP) {
- mNeedsZBoost = true;
- }
- mTransit = transit;
- mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
- } else {
- adapter = null;
- }
- }
- if (adapter != null) {
- startAnimation(getPendingTransaction(), adapter, !isVisible());
- if (adapter.getShowWallpaper()) {
- mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- }
- if (thumbnailAdapter != null) {
- mThumbnail.startAnimation(
- getPendingTransaction(), thumbnailAdapter, !isVisible());
- }
- }
- } else {
- cancelAnimation();
- }
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
-
- return isReallyAnimating();
- }
-
- private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
- boolean isVoiceInteraction) {
- final DisplayContent displayContent = getTask().getDisplayContent();
- final DisplayInfo displayInfo = displayContent.getDisplayInfo();
- final int width = displayInfo.appWidth;
- final int height = displayInfo.appHeight;
- ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
- "applyAnimation: atoken=%s", this);
-
- // Determine the visible rect to calculate the thumbnail clip
- final WindowState win = findMainWindow();
- final Rect frame = new Rect(0, 0, width, height);
- final Rect displayFrame = new Rect(0, 0,
- displayInfo.logicalWidth, displayInfo.logicalHeight);
- final Rect insets = new Rect();
- final Rect stableInsets = new Rect();
- Rect surfaceInsets = null;
- final boolean freeform = win != null && win.inFreeformWindowingMode();
- if (win != null) {
- // Containing frame will usually cover the whole screen, including dialog windows.
- // For freeform workspace windows it will not cover the whole screen and it also
- // won't exactly match the final freeform window frame (e.g. when overlapping with
- // the status bar). In that case we need to use the final frame.
- if (freeform) {
- frame.set(win.getFrameLw());
- } else if (win.isLetterboxedAppWindow()) {
- frame.set(getTask().getBounds());
- } else if (win.isDockedResizing()) {
- // If we are animating while docked resizing, then use the stack bounds as the
- // animation target (which will be different than the task bounds)
- frame.set(getTask().getParent().getBounds());
- } else {
- frame.set(win.getContainingFrame());
- }
- surfaceInsets = win.getAttrs().surfaceInsets;
- // XXX(b/72757033): These are insets relative to the window frame, but we're really
- // interested in the insets relative to the frame we chose in the if-blocks above.
- win.getContentInsets(insets);
- win.getStableInsets(stableInsets);
- }
-
- if (mLaunchTaskBehind) {
- // Differentiate the two animations. This one which is briefly on the screen
- // gets the !enter animation, and the other activity which remains on the
- // screen gets the enter animation. Both appear in the mOpeningApps set.
- enter = false;
- }
- ProtoLog.d(WM_DEBUG_APP_TRANSITIONS,
- "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s "
- + "surfaceInsets=%s",
- AppTransition.appTransitionToString(transit), enter, frame, insets, surfaceInsets);
- final Configuration displayConfig = displayContent.getConfiguration();
- final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
- displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
- surfaceInsets, stableInsets, isVoiceInteraction, freeform, getTask().mTaskId);
- if (a != null) {
- if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
- final int containingWidth = frame.width();
- final int containingHeight = frame.height();
- a.initialize(containingWidth, containingHeight, width, height);
- a.scaleCurrentDuration(mWmService.getTransitionAnimationScaleLocked());
- }
- return a;
- }
-
@Override
public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
return mAnimatingActivityRegistry != null
@@ -5941,6 +5756,7 @@
return (prevWinMode == WINDOWING_MODE_FREEFORM) != (newWinMode == WINDOWING_MODE_FREEFORM);
}
+ @Override
boolean isWaitingForTransitionStart() {
final DisplayContent dc = getDisplayContent();
// TODO: Test for null can be removed once unification is done.
@@ -6069,10 +5885,7 @@
@Override
void prepareSurfaces() {
- // isSelfAnimating also returns true when we are about to start a transition, so we need
- // to check super here.
- final boolean reallyAnimating = super.isSelfAnimating();
- final boolean show = !isHidden() || reallyAnimating;
+ final boolean show = !isHidden() || isAnimating();
if (mSurfaceControl != null) {
if (show && !mLastSurfaceShowing) {
@@ -6100,14 +5913,13 @@
}
void attachThumbnailAnimation() {
- if (!isReallyAnimating()) {
+ if (!isAnimating()) {
return;
}
- final int taskId = getTask().mTaskId;
final GraphicBuffer thumbnailHeader =
- getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(taskId);
+ getDisplayContent().mAppTransition.getAppTransitionThumbnailHeader(getTask());
if (thumbnailHeader == null) {
- ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "No thumbnail header bitmap for: %d", taskId);
+ ProtoLog.d(WM_DEBUG_APP_TRANSITIONS, "No thumbnail header bitmap for: %s", getTask());
return;
}
clearThumbnail();
@@ -6121,7 +5933,7 @@
* {@link android.app.ActivityOptions#ANIM_OPEN_CROSS_PROFILE_APPS} animation.
*/
void attachCrossProfileAppsThumbnailAnimation() {
- if (!isReallyAnimating()) {
+ if (!isAnimating()) {
return;
}
clearThumbnail();
@@ -6161,22 +5973,11 @@
final Rect insets = win != null ? win.getContentInsets() : null;
final Configuration displayConfig = mDisplayContent.getConfiguration();
return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(
- appRect, insets, thumbnailHeader, getTask().mTaskId, displayConfig.uiMode,
+ appRect, insets, thumbnailHeader, getTask(), displayConfig.uiMode,
displayConfig.orientation);
}
@Override
- boolean isAppAnimating() {
- return isSelfAnimating();
- }
-
- @Override
- boolean isSelfAnimating() {
- // If we are about to start a transition, we also need to be considered animating.
- return isWaitingForTransitionStart() || isReallyAnimating();
- }
-
- @Override
public void onAnimationLeashLost(Transaction t) {
super.onAnimationLeashLost(t);
if (mAnimationBoundsLayer != null) {
@@ -6281,15 +6082,6 @@
}
}
- /**
- * @return True if and only if we are actually running an animation. Note that
- * {@link #isSelfAnimating} also returns true if we are waiting for an animation to
- * start.
- */
- private boolean isReallyAnimating() {
- return super.isSelfAnimating();
- }
-
@Override
void cancelAnimation() {
cancelAnimationOnly();
@@ -6691,6 +6483,7 @@
}
@VisibleForTesting
+ @Override
Rect getAnimationBounds(int appStackClipMode) {
if (appStackClipMode == STACK_CLIP_BEFORE_ANIM && getStack() != null) {
// Using the stack bounds here effectively applies the clipping before animation.
@@ -7643,7 +7436,7 @@
super.writeToProto(proto, WINDOW_TOKEN, logLevel);
proto.write(LAST_SURFACE_SHOWING, mLastSurfaceShowing);
proto.write(IS_WAITING_FOR_TRANSITION_START, isWaitingForTransitionStart());
- proto.write(IS_REALLY_ANIMATING, isReallyAnimating());
+ proto.write(IS_ANIMATING, isAnimating());
if (mThumbnail != null){
mThumbnail.writeToProto(proto, THUMBNAIL);
}
@@ -7765,4 +7558,35 @@
System.arraycopy(translation, 0, mTranslation, 0, mTranslation.length);
}
}
+
+ @Override
+ RemoteAnimationTarget createRemoteAnimationTarget(
+ RemoteAnimationController.RemoteAnimationRecord record) {
+ final Task task = getTask();
+ final WindowState mainWindow = findMainWindow();
+ if (task == null || mainWindow == null) {
+ return null;
+ }
+ final Rect insets = new Rect();
+ mainWindow.getContentInsets(insets);
+ InsetUtils.addInsets(insets, getLetterboxInsets());
+ return new RemoteAnimationTarget(task.mTaskId, record.getMode(),
+ record.mAdapter.mCapturedLeash, !task.fillsParent(),
+ mainWindow.mWinAnimator.mLastClipRect, insets,
+ getPrefixOrderIndex(), record.mAdapter.mPosition,
+ record.mAdapter.mStackBounds, task.getWindowConfiguration(),
+ false /*isNotInRecents*/,
+ record.mThumbnailAdapter != null ? record.mThumbnailAdapter.mCapturedLeash : null,
+ record.mStartBounds);
+ }
+
+ @Override
+ void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
+ Rect outSurfaceInsets) {
+ final WindowState win = findMainWindow();
+ if (win == null) {
+ return;
+ }
+ win.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 64351fb..dc3d263 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -82,6 +82,7 @@
import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import android.Manifest;
import android.app.Activity;
@@ -561,8 +562,8 @@
return candidateTaskId;
}
- void waitActivityVisible(ComponentName name, WaitResult result, long startTimeMs) {
- final WaitInfo waitInfo = new WaitInfo(name, result, startTimeMs);
+ void waitActivityVisible(ComponentName name, WaitResult result) {
+ final WaitInfo waitInfo = new WaitInfo(name, result);
mWaitingForActivityVisible.add(waitInfo);
}
@@ -572,10 +573,15 @@
// down to the max limit while they are still waiting to finish.
mFinishingActivities.remove(r);
- stopWaitingForActivityVisible(r);
+ stopWaitingForActivityVisible(r, WaitResult.INVALID_DELAY);
}
void stopWaitingForActivityVisible(ActivityRecord r) {
+ stopWaitingForActivityVisible(r,
+ getActivityMetricsLogger().getLastDrawnDelayMs(r.getWindowingMode()));
+ }
+
+ void stopWaitingForActivityVisible(ActivityRecord r, long totalTime) {
boolean changed = false;
for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) {
final WaitInfo w = mWaitingForActivityVisible.get(i);
@@ -584,7 +590,7 @@
changed = true;
result.timeout = false;
result.who = w.getComponent();
- result.totalTime = SystemClock.uptimeMillis() - w.getStartTime();
+ result.totalTime = totalTime;
mWaitingForActivityVisible.remove(w);
}
}
@@ -2127,7 +2133,7 @@
for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) {
ActivityRecord s = mStoppingActivities.get(activityNdx);
- final boolean animating = s.isSelfAnimating();
+ final boolean animating = s.isAnimating(TRANSITION);
if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible
+ " animating=" + animating + " finishing=" + s.finishing);
@@ -2823,13 +2829,10 @@
static class WaitInfo {
private final ComponentName mTargetComponent;
private final WaitResult mResult;
- /** Time stamp when we started to wait for {@link WaitResult}. */
- private final long mStartTimeMs;
- WaitInfo(ComponentName targetComponent, WaitResult result, long startTimeMs) {
+ WaitInfo(ComponentName targetComponent, WaitResult result) {
this.mTargetComponent = targetComponent;
this.mResult = result;
- this.mStartTimeMs = startTimeMs;
}
public boolean matches(ComponentName targetComponent) {
@@ -2840,10 +2843,6 @@
return mResult;
}
- public long getStartTime() {
- return mStartTimeMs;
- }
-
public ComponentName getComponent() {
return mTargetComponent;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index f87175d..d1bb255 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -107,7 +107,6 @@
import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
@@ -764,9 +763,7 @@
mRequest.waitResult.who = r.mActivityComponent;
mRequest.waitResult.totalTime = 0;
} else {
- final long startTimeMs = SystemClock.uptimeMillis();
- mSupervisor.waitActivityVisible(r.mActivityComponent, mRequest.waitResult,
- startTimeMs);
+ mSupervisor.waitActivityVisible(r.mActivityComponent, mRequest.waitResult);
// Note: the timeout variable is not currently not ever set.
do {
try {
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c1143c8..cb9a200 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -219,7 +219,7 @@
private int mNextAppTransitionExit;
private int mNextAppTransitionInPlace;
- // Keyed by task id.
+ // Keyed by WindowContainer hashCode.
private final SparseArray<AppTransitionAnimationSpec> mNextAppTransitionAnimationsSpecs
= new SparseArray<>();
private IAppTransitionAnimationSpecsFuture mNextAppTransitionAnimationsSpecsFuture;
@@ -372,8 +372,9 @@
setAppTransitionState(APP_STATE_TIMEOUT);
}
- GraphicBuffer getAppTransitionThumbnailHeader(int taskId) {
- AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+ GraphicBuffer getAppTransitionThumbnailHeader(WindowContainer container) {
+ AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
+ container.hashCode());
if (spec == null) {
spec = mDefaultNextAppTransitionAnimationSpec;
}
@@ -789,14 +790,15 @@
}
}
- void getNextAppTransitionStartRect(int taskId, Rect rect) {
- AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(taskId);
+ void getNextAppTransitionStartRect(WindowContainer container, Rect rect) {
+ AppTransitionAnimationSpec spec = mNextAppTransitionAnimationsSpecs.get(
+ container.hashCode());
if (spec == null) {
spec = mDefaultNextAppTransitionAnimationSpec;
}
if (spec == null || spec.rect == null) {
- Slog.e(TAG, "Starting rect for task: " + taskId + " requested, but not available",
- new Throwable());
+ Slog.e(TAG, "Starting rect for container: " + container
+ + " requested, but not available", new Throwable());
rect.setEmpty();
} else {
rect.set(spec.rect);
@@ -1065,7 +1067,7 @@
* when a thumbnail is specified with the pending animation override.
*/
Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets,
- GraphicBuffer thumbnailHeader, final int taskId, int uiMode, int orientation) {
+ GraphicBuffer thumbnailHeader, WindowContainer container, int uiMode, int orientation) {
Animation a;
final int thumbWidthI = thumbnailHeader.getWidth();
final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
@@ -1073,7 +1075,7 @@
final int appWidth = appRect.width();
float scaleW = appWidth / thumbWidth;
- getNextAppTransitionStartRect(taskId, mTmpRect);
+ getNextAppTransitionStartRect(container, mTmpRect);
final float fromX;
float fromY;
final float toX;
@@ -1226,7 +1228,7 @@
Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState,
int uiMode, int orientation, int transit, Rect containingFrame, Rect contentInsets,
@Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean freeform,
- int taskId) {
+ WindowContainer container) {
Animation a;
final int appWidth = containingFrame.width();
final int appHeight = containingFrame.height();
@@ -1244,10 +1246,10 @@
final boolean scaleUp = thumbTransitState == THUMBNAIL_TRANSITION_ENTER_SCALE_UP;
if (freeform && scaleUp) {
a = createAspectScaledThumbnailEnterFreeformAnimationLocked(
- containingFrame, surfaceInsets, taskId);
+ containingFrame, surfaceInsets, container);
} else if (freeform) {
a = createAspectScaledThumbnailExitFreeformAnimationLocked(
- containingFrame, surfaceInsets, taskId);
+ containingFrame, surfaceInsets, container);
} else {
AnimationSet set = new AnimationSet(true);
@@ -1359,15 +1361,15 @@
}
private Animation createAspectScaledThumbnailEnterFreeformAnimationLocked(Rect frame,
- @Nullable Rect surfaceInsets, int taskId) {
- getNextAppTransitionStartRect(taskId, mTmpRect);
+ @Nullable Rect surfaceInsets, WindowContainer container) {
+ getNextAppTransitionStartRect(container, mTmpRect);
return createAspectScaledThumbnailFreeformAnimationLocked(mTmpRect, frame, surfaceInsets,
true);
}
private Animation createAspectScaledThumbnailExitFreeformAnimationLocked(Rect frame,
- @Nullable Rect surfaceInsets, int taskId) {
- getNextAppTransitionStartRect(taskId, mTmpRect);
+ @Nullable Rect surfaceInsets, WindowContainer container) {
+ getNextAppTransitionStartRect(container, mTmpRect);
return createAspectScaledThumbnailFreeformAnimationLocked(frame, mTmpRect, surfaceInsets,
false);
}
@@ -1469,10 +1471,10 @@
* leaving, and the activity that is entering.
*/
Animation createThumbnailEnterExitAnimationLocked(int thumbTransitState, Rect containingFrame,
- int transit, int taskId) {
+ int transit, WindowContainer container) {
final int appWidth = containingFrame.width();
final int appHeight = containingFrame.height();
- final GraphicBuffer thumbnailHeader = getAppTransitionThumbnailHeader(taskId);
+ final GraphicBuffer thumbnailHeader = getAppTransitionThumbnailHeader(container);
Animation a;
getDefaultNextAppTransitionStartRect(mTmpRect);
final int thumbWidthI = thumbnailHeader != null ? thumbnailHeader.getWidth() : appWidth;
@@ -1615,7 +1617,7 @@
Animation loadAnimation(LayoutParams lp, int transit, boolean enter, int uiMode,
int orientation, Rect frame, Rect displayFrame, Rect insets,
@Nullable Rect surfaceInsets, @Nullable Rect stableInsets, boolean isVoiceInteraction,
- boolean freeform, int taskId) {
+ boolean freeform, WindowContainer container) {
Animation a;
if (isKeyguardGoingAwayTransit(transit) && enter) {
a = loadKeyguardExitAnimation(transit);
@@ -1679,7 +1681,7 @@
mNextAppTransitionScaleUp =
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_UP);
a = createThumbnailEnterExitAnimationLocked(getThumbnailTransitionState(enter),
- frame, transit, taskId);
+ frame, transit, container);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
+ "Callers=%s",
@@ -1692,7 +1694,7 @@
(mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP);
a = createAspectScaledThumbnailEnterExitAnimationLocked(
getThumbnailTransitionState(enter), uiMode, orientation, transit, frame,
- insets, surfaceInsets, stableInsets, freeform, taskId);
+ insets, surfaceInsets, stableInsets, freeform, container);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
"applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b "
+ "Callers=%s",
@@ -1895,7 +1897,11 @@
for (int i = 0; i < specs.length; i++) {
AppTransitionAnimationSpec spec = specs[i];
if (spec != null) {
- mNextAppTransitionAnimationsSpecs.put(spec.taskId, spec);
+ final WindowContainer container = findTask(spec.taskId);
+ if (container == null) {
+ continue;
+ }
+ mNextAppTransitionAnimationsSpecs.put(container.hashCode(), spec);
if (i == 0) {
// In full screen mode, the transition code depends on the default spec
// to be set.
@@ -1912,6 +1918,19 @@
}
}
+ private Task findTask(int taskId) {
+ if (taskId < 0) {
+ return null;
+ }
+ ArrayList<Task> tasks = new ArrayList<>();
+ mDisplayContent.forAllTasks(task -> {
+ if (task.mTaskId == taskId) {
+ tasks.add(task);
+ }
+ });
+ return tasks.size() == 1 ? tasks.get(0) : null;
+ }
+
void overridePendingAppTransitionMultiThumbFuture(
IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
boolean scaleUp) {
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 3bda0c2..bef6af3 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -410,7 +410,7 @@
ActivityRecord activity = apps.valueAt(i);
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS, "Now changing app %s", activity);
activity.cancelAnimationOnly();
- activity.applyAnimationLocked(null, transit, true, false);
+ activity.applyAnimation(null, transit, true, false);
activity.updateReportedVisibilityLocked();
mService.openSurfaceTransaction();
try {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2d1d297..89568eb 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -106,6 +106,8 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_SCREEN_ON;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
@@ -2363,7 +2365,7 @@
@Override
void removeIfPossible() {
- if (isAnimating()) {
+ if (isAnimating(TRANSITION | PARENTS)) {
mDeferredRemoval = true;
return;
}
@@ -3165,13 +3167,15 @@
// to look at all windows below the current target that are in this app, finding the
// highest visible one in layering.
WindowState highestTarget = null;
- if (activity.isSelfAnimating()) {
+ if (activity.isAnimating(TRANSITION)) {
highestTarget = activity.getHighestAnimLayerWindow(curTarget);
}
if (highestTarget != null) {
- if (DEBUG_INPUT_METHOD) Slog.v(TAG_WM, mAppTransition + " " + highestTarget
- + " animating=" + highestTarget.isAnimating());
+ if (DEBUG_INPUT_METHOD) {
+ Slog.v(TAG_WM, mAppTransition + " " + highestTarget + " animating="
+ + highestTarget.isAnimating(TRANSITION | PARENTS));
+ }
if (mAppTransition.isTransitionSet()) {
// If we are currently setting up for an animation, hold everything until we
@@ -4322,7 +4326,7 @@
// The split screen divider anchor is located above the split screen window.
layerForSplitScreenDividerAnchor = layer++;
}
- if (s.isTaskAnimating() || s.isAppAnimating()) {
+ if (s.isTaskAnimating() || s.isAppTransitioning()) {
// The animation layer is located above the highest animating stack and no
// higher.
layerForAnimationLayer = layer++;
@@ -4651,7 +4655,8 @@
// so it get's layered above the starting window.
if (imeTarget != null
&& !(imeTarget.mActivityRecord != null && imeTarget.mActivityRecord.hasStartingWindow())
- && (!(imeTarget.inSplitScreenWindowingMode() || imeTarget.mToken.isAppAnimating())
+ && (!(imeTarget.inSplitScreenWindowingMode()
+ || imeTarget.mToken.isAppTransitioning())
&& (imeTarget.getSurfaceControl() != null))) {
mImeWindowsContainers.assignRelativeLayer(t, imeTarget.getSurfaceControl(),
// TODO: We need to use an extra level on the app surface to ensure
diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java
index 7f9e76b..1ebbb02 100644
--- a/services/core/java/com/android/server/wm/InputManagerCallback.java
+++ b/services/core/java/com/android/server/wm/InputManagerCallback.java
@@ -4,6 +4,7 @@
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static com.android.server.wm.ActivityRecord.INVALID_PID;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -14,6 +15,7 @@
import android.os.RemoteException;
import android.util.Slog;
import android.view.IWindow;
+import android.view.InputApplicationHandle;
import android.view.KeyEvent;
import android.view.WindowManager;
@@ -80,7 +82,8 @@
* Called by the InputManager.
*/
@Override
- public long notifyANR(IBinder token, String reason) {
+ public long notifyANR(InputApplicationHandle inputApplicationHandle,
+ IBinder token, String reason) {
ActivityRecord activity = null;
WindowState windowState = null;
boolean aboveSystem = false;
@@ -93,6 +96,10 @@
}
}
+ if (activity == null && inputApplicationHandle != null) {
+ activity = ActivityRecord.forTokenLocked(inputApplicationHandle.token);
+ }
+
if (windowState != null) {
Slog.i(TAG_WM, "Input event dispatching timed out "
+ "sending to " + windowState.mAttrs.getTitle()
@@ -122,7 +129,7 @@
// Notify the activity manager about the timeout and let it decide whether
// to abort dispatching or keep waiting.
final boolean abort = activity.keyDispatchingTimedOut(reason,
- windowState.mSession.mPid);
+ (windowState != null) ? windowState.mSession.mPid : INVALID_PID);
if (!abort) {
// The activity manager declined to abort dispatching.
// Wait a bit longer and timeout again later.
diff --git a/services/core/java/com/android/server/wm/RefreshRatePolicy.java b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
index 0c0cf92..e0a7b18 100644
--- a/services/core/java/com/android/server/wm/RefreshRatePolicy.java
+++ b/services/core/java/com/android/server/wm/RefreshRatePolicy.java
@@ -16,6 +16,9 @@
package com.android.server.wm;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
+
import android.util.ArraySet;
import android.view.Display.Mode;
import android.view.DisplayInfo;
@@ -67,7 +70,7 @@
// If app is animating, it's not able to control refresh rate because we want the animation
// to run in default refresh rate.
- if (w.isAnimating()) {
+ if (w.isAnimating(TRANSITION | PARENTS)) {
return 0;
}
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index c23ffd9..efd1241 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -41,7 +41,6 @@
import com.android.server.protolog.ProtoLogImpl;
import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
-import com.android.server.wm.utils.InsetUtils;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -76,20 +75,20 @@
}
/**
- * Creates an animation record for each individual {@link ActivityRecord}.
+ * Creates an animation record for each individual {@link WindowContainer}.
*
- * @param activity The app to animate.
+ * @param windowContainer The windows to animate.
* @param position The position app bounds, in screen coordinates.
* @param stackBounds The stack bounds of the app relative to position.
* @param startBounds The stack bounds before the transition, in screen coordinates
* @return The record representing animation(s) to run on the app.
*/
- RemoteAnimationRecord createRemoteAnimationRecord(ActivityRecord activity, Point position,
- Rect stackBounds, Rect startBounds) {
- ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): token=%s",
- activity);
+ RemoteAnimationRecord createRemoteAnimationRecord(WindowContainer windowContainer,
+ Point position, Rect stackBounds, Rect startBounds) {
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "createAnimationAdapter(): container=%s",
+ windowContainer);
final RemoteAnimationRecord adapters =
- new RemoteAnimationRecord(activity, position, stackBounds, startBounds);
+ new RemoteAnimationRecord(windowContainer, position, stackBounds, startBounds);
mPendingAnimations.add(adapters);
return adapters;
}
@@ -169,11 +168,12 @@
final RemoteAnimationRecord wrappers = mPendingAnimations.get(i);
final RemoteAnimationTarget target = wrappers.createRemoteAnimationTarget();
if (target != null) {
- ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tAdd token=%s", wrappers.mActivityRecord);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tAdd container=%s",
+ wrappers.mWindowContainer);
targets.add(target);
} else {
- ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tRemove token=%s",
- wrappers.mActivityRecord);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tRemove container=%s",
+ wrappers.mWindowContainer);
// We can't really start an animation but we still need to make sure to finish the
// pending animation that was started by SurfaceAnimator
@@ -228,7 +228,8 @@
.onAnimationFinished(adapters.mThumbnailAdapter);
}
mPendingAnimations.remove(i);
- ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tapp=%s", adapters.mActivityRecord);
+ ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "\tcontainer=%s",
+ adapters.mWindowContainer);
}
for (int i = mPendingWallpaperAnimations.size() - 1; i >= 0; i--) {
@@ -332,7 +333,7 @@
};
/**
- * Contains information about a remote-animation for one AppWindowToken. This keeps track of,
+ * Contains information about a remote-animation for one WindowContainer. This keeps track of,
* potentially, multiple animating surfaces (AdapterWrappers) associated with one
* Window/Transition. For example, a change transition has an adapter controller for the
* main window and an adapter controlling the start-state snapshot.
@@ -345,12 +346,12 @@
RemoteAnimationAdapterWrapper mAdapter;
RemoteAnimationAdapterWrapper mThumbnailAdapter = null;
RemoteAnimationTarget mTarget;
- final ActivityRecord mActivityRecord;
+ final WindowContainer mWindowContainer;
final Rect mStartBounds;
- RemoteAnimationRecord(ActivityRecord activityRecord, Point endPos, Rect endBounds,
+ RemoteAnimationRecord(WindowContainer windowContainer, Point endPos, Rect endBounds,
Rect startBounds) {
- mActivityRecord = activityRecord;
+ mWindowContainer = windowContainer;
mAdapter = new RemoteAnimationAdapterWrapper(this, endPos, endBounds);
if (startBounds != null) {
mStartBounds = new Rect(startBounds);
@@ -366,31 +367,20 @@
}
RemoteAnimationTarget createRemoteAnimationTarget() {
- final Task task = mActivityRecord.getTask();
- final WindowState mainWindow = mActivityRecord.findMainWindow();
- if (task == null || mainWindow == null || mAdapter == null
+ if (mAdapter == null
|| mAdapter.mCapturedFinishCallback == null
|| mAdapter.mCapturedLeash == null) {
return null;
}
- final Rect insets = new Rect();
- mainWindow.getContentInsets(insets);
- InsetUtils.addInsets(insets, mActivityRecord.getLetterboxInsets());
- mTarget = new RemoteAnimationTarget(task.mTaskId, getMode(),
- mAdapter.mCapturedLeash, !mActivityRecord.fillsParent(),
- mainWindow.mWinAnimator.mLastClipRect, insets,
- mActivityRecord.getPrefixOrderIndex(), mAdapter.mPosition,
- mAdapter.mStackBounds, task.getWindowConfiguration(), false /*isNotInRecents*/,
- mThumbnailAdapter != null ? mThumbnailAdapter.mCapturedLeash : null,
- mStartBounds);
+ mTarget = mWindowContainer.createRemoteAnimationTarget(this);
return mTarget;
}
- private int getMode() {
- final DisplayContent dc = mActivityRecord.getDisplayContent();
- if (dc.mOpeningApps.contains(mActivityRecord)) {
+ int getMode() {
+ final DisplayContent dc = mWindowContainer.getDisplayContent();
+ if (dc.mOpeningApps.contains(mWindowContainer)) {
return RemoteAnimationTarget.MODE_OPENING;
- } else if (dc.mChangingApps.contains(mActivityRecord)) {
+ } else if (dc.mChangingApps.contains(mWindowContainer)) {
return RemoteAnimationTarget.MODE_CHANGING;
} else {
return RemoteAnimationTarget.MODE_CLOSING;
@@ -398,12 +388,12 @@
}
}
- private class RemoteAnimationAdapterWrapper implements AnimationAdapter {
+ class RemoteAnimationAdapterWrapper implements AnimationAdapter {
private final RemoteAnimationRecord mRecord;
SurfaceControl mCapturedLeash;
private OnAnimationFinishedCallback mCapturedFinishCallback;
- private final Point mPosition = new Point();
- private final Rect mStackBounds = new Rect();
+ final Point mPosition = new Point();
+ final Rect mStackBounds = new Rect();
RemoteAnimationAdapterWrapper(RemoteAnimationRecord record, Point position,
Rect stackBounds) {
@@ -423,7 +413,7 @@
ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation");
// Restore z-layering, position and stack crop until client has a chance to modify it.
- t.setLayer(animationLeash, mRecord.mActivityRecord.getPrefixOrderIndex());
+ t.setLayer(animationLeash, mRecord.mWindowContainer.getPrefixOrderIndex());
if (mRecord.mStartBounds != null) {
t.setPosition(animationLeash, mRecord.mStartBounds.left, mRecord.mStartBounds.top);
t.setWindowCrop(animationLeash, mRecord.mStartBounds.width(),
@@ -464,7 +454,7 @@
@Override
public void dump(PrintWriter pw, String prefix) {
- pw.print(prefix); pw.print("token="); pw.println(mRecord.mActivityRecord);
+ pw.print(prefix); pw.print("container="); pw.println(mRecord.mWindowContainer);
if (mRecord.mTarget != null) {
pw.print(prefix); pw.println("Target:");
mRecord.mTarget.dump(pw, prefix + " ");
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 9db6dc2..51a3e720 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -1154,7 +1154,7 @@
// activity is started and resumed, and no recursion occurs.
final ActivityStack focusedStack = display.getFocusedStack();
if (focusedStack != null) {
- focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
+ result |= focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
}
}
}
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 17f5abd..f5d3aff 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -787,7 +787,7 @@
}
}
- if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppAnimating()) {
+ if (curDisplay.mAppTransition.isRunning() && !curDisplay.isAppTransitioning()) {
// We have finished the animation of an app transition. To do this, we have
// delayed a lot of operations like showing and hiding apps, moving apps in
// Z-order, etc.
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index bf7dd57..634990b 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -28,13 +28,14 @@
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.TaskProto.APP_WINDOW_TOKENS;
import static com.android.server.wm.TaskProto.BOUNDS;
-import static com.android.server.wm.TaskProto.DEFER_REMOVAL;
import static com.android.server.wm.TaskProto.DISPLAYED_BOUNDS;
import static com.android.server.wm.TaskProto.FILLS_PARENT;
import static com.android.server.wm.TaskProto.ID;
import static com.android.server.wm.TaskProto.SURFACE_HEIGHT;
import static com.android.server.wm.TaskProto.SURFACE_WIDTH;
import static com.android.server.wm.TaskProto.WINDOW_CONTAINER;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -50,6 +51,7 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
+import android.view.RemoteAnimationTarget;
import android.view.Surface;
import android.view.SurfaceControl;
@@ -204,7 +206,7 @@
// No reason to defer removal of a Task that doesn't have any child.
return false;
}
- return hasWindowsAlive() && mStack.isSelfOrChildAnimating();
+ return hasWindowsAlive() && mStack.isAnimating(TRANSITION | CHILDREN);
}
@Override
@@ -469,6 +471,17 @@
}
}
+ @Override
+ void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
+ Rect outSurfaceInsets) {
+ final WindowState windowState = getTopVisibleAppMainWindow();
+ if (windowState != null) {
+ windowState.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+ } else {
+ super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+ }
+ }
+
/**
* Calculate the maximum visible area of this task. If the task has only one app,
* the result will be visible frame of that app. If the task has more than one apps,
@@ -645,6 +658,18 @@
return getAppAnimationLayer(ANIMATION_LAYER_HOME);
}
+ boolean shouldAnimate() {
+ // Don't animate while the task runs recents animation but only if we are in the mode
+ // where we cancel with deferred screenshot, which means that the controller has
+ // transformed the task.
+ final RecentsAnimationController controller = mWmService.getRecentsAnimationController();
+ if (controller != null && controller.isAnimatingTask(this)
+ && controller.shouldDeferCancelUntilNextTransition()) {
+ return false;
+ }
+ return true;
+ }
+
@Override
SurfaceControl.Builder makeSurface() {
return super.makeSurface().setMetadata(METADATA_TASK_ID, mTaskId);
@@ -660,6 +685,22 @@
return false;
}
+ /**
+ * @return {@code true} if changing app transition is running.
+ */
+ @Override
+ boolean isChangingAppTransition() {
+ final ActivityRecord activity = getTopVisibleActivity();
+ return activity != null && getDisplayContent().mChangingApps.contains(activity);
+ }
+
+ @Override
+ RemoteAnimationTarget createRemoteAnimationTarget(
+ RemoteAnimationController.RemoteAnimationRecord record) {
+ final ActivityRecord activity = getTopVisibleActivity();
+ return activity != null ? activity.createRemoteAnimationTarget(record) : null;
+ }
+
WindowState getTopVisibleAppMainWindow() {
final ActivityRecord activity = getTopVisibleActivity();
return activity != null ? activity.findMainWindow() : null;
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 3552245..56211e2 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -52,6 +52,8 @@
import static com.android.server.wm.StackProto.MINIMIZE_AMOUNT;
import static com.android.server.wm.StackProto.TASKS;
import static com.android.server.wm.StackProto.WINDOW_CONTAINER;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -69,6 +71,7 @@
import android.util.proto.ProtoOutputStream;
import android.view.DisplayCutout;
import android.view.DisplayInfo;
+import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import com.android.internal.annotations.VisibleForTesting;
@@ -934,7 +937,7 @@
@Override
void removeIfPossible() {
- if (isSelfOrChildAnimating()) {
+ if (isAnimating(TRANSITION | CHILDREN)) {
mDeferRemoval = true;
return;
}
@@ -1792,7 +1795,7 @@
/** Returns true if a removal action is still being deferred. */
boolean checkCompleteDeferredRemoval() {
- if (isSelfOrChildAnimating()) {
+ if (isAnimating(TRANSITION | CHILDREN)) {
return true;
}
if (mDeferRemoval) {
@@ -1866,4 +1869,22 @@
AnimatingActivityRegistry getAnimatingActivityRegistry() {
return mAnimatingActivityRegistry;
}
+
+ @Override
+ void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
+ Rect outSurfaceInsets) {
+ final Task task = getTopChild();
+ if (task != null) {
+ task.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+ } else {
+ super.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
+ }
+ }
+
+ @Override
+ RemoteAnimationTarget createRemoteAnimationTarget(
+ RemoteAnimationController.RemoteAnimationRecord record) {
+ final Task task = getTopChild();
+ return task != null ? task.createRemoteAnimationTarget(record) : null;
+ }
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 1e13aef..3632284 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -24,6 +24,8 @@
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
@@ -118,7 +120,8 @@
}
mFindResults.resetTopWallpaper = true;
- if (w.mActivityRecord != null && w.mActivityRecord.isHidden() && !w.mActivityRecord.isSelfAnimating()) {
+ if (w.mActivityRecord != null && w.mActivityRecord.isHidden()
+ && !w.mActivityRecord.isAnimating(TRANSITION)) {
// If this window's app token is hidden and not animating, it is of no interest to us.
if (DEBUG_WALLPAPER) Slog.v(TAG, "Skipping hidden and not animating token: " + w);
@@ -136,7 +139,7 @@
}
final boolean keyguardGoingAwayWithWallpaper = (w.mActivityRecord != null
- && w.mActivityRecord.isSelfAnimating()
+ && w.mActivityRecord.isAnimating(TRANSITION)
&& AppTransition.isKeyguardGoingAwayTransit(w.mActivityRecord.getTransit())
&& (w.mActivityRecord.getTransitFlags()
& TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);
@@ -159,7 +162,8 @@
final RecentsAnimationController recentsAnimationController =
mService.getRecentsAnimationController();
- final boolean animationWallpaper = w.mActivityRecord != null && w.mActivityRecord.getAnimation() != null
+ final boolean animationWallpaper = w.mActivityRecord != null
+ && w.mActivityRecord.getAnimation() != null
&& w.mActivityRecord.getAnimation().getShowWallpaper();
final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
|| animationWallpaper;
@@ -173,7 +177,7 @@
&& (mWallpaperTarget == w || w.isDrawFinishedLw())) {
if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);
mFindResults.setWallpaperTarget(w);
- if (w == mWallpaperTarget && w.isAnimating()) {
+ if (w == mWallpaperTarget && w.isAnimating(TRANSITION | PARENTS)) {
// The current wallpaper target is animating, so we'll look behind it for
// another possible target and figure out what is going on later.
if (DEBUG_WALLPAPER) Slog.v(TAG,
@@ -224,19 +228,19 @@
if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
+ (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
+ " animating=" + ((wallpaperTarget != null && wallpaperTarget.mActivityRecord != null)
- ? wallpaperTarget.mActivityRecord.isSelfAnimating() : null)
+ ? wallpaperTarget.mActivityRecord.isAnimating(TRANSITION) : null)
+ " prev=" + mPrevWallpaperTarget
+ " recentsAnimationWallpaperVisible=" + isAnimatingWithRecentsComponent);
return (wallpaperTarget != null
&& (!wallpaperTarget.mObscured
|| isAnimatingWithRecentsComponent
|| (wallpaperTarget.mActivityRecord != null
- && wallpaperTarget.mActivityRecord.isSelfAnimating())))
+ && wallpaperTarget.mActivityRecord.isAnimating(TRANSITION))))
|| mPrevWallpaperTarget != null;
}
boolean isWallpaperTargetAnimating() {
- return mWallpaperTarget != null && mWallpaperTarget.isAnimating()
+ return mWallpaperTarget != null && mWallpaperTarget.isAnimating(TRANSITION | PARENTS)
&& (mWallpaperTarget.mActivityRecord == null
|| !mWallpaperTarget.mActivityRecord.isWaitingForTransitionStart());
}
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 3a1d6e0..f7525a9 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -17,6 +17,8 @@
package com.android.server.wm;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -192,7 +194,7 @@
mService.mWindowPlacerLocked.requestTraversal();
}
- final boolean rootAnimating = mService.mRoot.isSelfOrChildAnimating();
+ final boolean rootAnimating = mService.mRoot.isAnimating(TRANSITION | CHILDREN);
if (rootAnimating && !mLastRootAnimating) {
// Usually app transitions but quite a load onto the system already (with all the
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index a620a7c..7ce2b5e 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -24,8 +24,15 @@
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_UNDEFINED;
+import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.view.SurfaceControl.Transaction;
+import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_APP_TRANSITIONS_ANIM;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainerProto.CONFIGURATION_CONTAINER;
import static com.android.server.wm.WindowContainerProto.ORIENTATION;
import static com.android.server.wm.WindowContainerProto.SURFACE_ANIMATOR;
@@ -33,7 +40,9 @@
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+import static com.android.server.wm.WindowManagerService.logWithStack;
import static com.android.server.wm.WindowStateAnimator.DRAW_PENDING;
+import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import android.annotation.CallSuper;
import android.annotation.IntDef;
@@ -45,17 +54,24 @@
import android.graphics.Rect;
import android.os.Debug;
import android.os.IBinder;
+import android.os.Trace;
+import android.util.Pair;
import android.util.Pools;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import android.view.DisplayInfo;
import android.view.MagnificationSpec;
+import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Builder;
import android.view.SurfaceSession;
+import android.view.WindowManager;
+import android.view.animation.Animation;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ToBooleanFunction;
import com.android.server.policy.WindowManagerPolicy;
+import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.SurfaceAnimator.Animatable;
import java.io.PrintWriter;
@@ -155,6 +171,29 @@
private final Configuration mTmpConfig = new Configuration();
+ /** Interface for {@link #isAnimating} to check which cases for the container is animating. */
+ public interface AnimationFlags {
+ /**
+ * A bit flag indicates that {@link #isAnimating} should also return {@code true}
+ * even though the container is not yet animating, but the window container or its
+ * relatives as specified by PARENTS or CHILDREN are part of an {@link AppTransition}
+ * that is pending so an animation starts soon.
+ */
+ int TRANSITION = 1;
+
+ /**
+ * A bit flag indicates that {@link #isAnimating} should also check if one of the
+ * ancestors of the container are animating in addition to the container itself.
+ */
+ int PARENTS = 2;
+
+ /**
+ * A bit flag indicates that {@link #isAnimating} should also check if one of the
+ * descendants of the container are animating in addition to the container itself.
+ */
+ int CHILDREN = 4;
+ }
+
/**
* Callback which is triggered while changing the parent, after setting up the surface but
* before asking the parent to assign child layers.
@@ -163,6 +202,47 @@
void onPreAssignChildLayers();
}
+ /**
+ * True if this an AppWindowToken and the activity which created this was launched with
+ * ActivityOptions.setLaunchTaskBehind.
+ *
+ * TODO(b/142617871): We run a special animation when the activity was launched with that
+ * flag, but it's not necessary anymore. Keep the window invisible until the task is explicitly
+ * selected to suppress an animation, and remove this flag.
+ */
+ boolean mLaunchTaskBehind;
+
+ /**
+ * If we are running an animation, this determines the transition type. Must be one of
+ * {@link AppTransition#TransitionFlags}.
+ */
+ int mTransit;
+
+ /**
+ * If we are running an animation, this determines the flags during this animation. Must be a
+ * bitwise combination of AppTransition.TRANSIT_FLAG_* constants.
+ */
+ int mTransitFlags;
+
+ /** Whether this container should be boosted at the top of all its siblings. */
+ @VisibleForTesting boolean mNeedsZBoost;
+
+ /** Layer used to constrain the animation to a container's stack bounds. */
+ SurfaceControl mAnimationBoundsLayer;
+
+ /** Whether this container needs to create mAnimationBoundsLayer for cropping animations. */
+ boolean mNeedsAnimationBoundsLayer;
+
+ /**
+ * This gets used during some open/close transitions as well as during a change transition
+ * where it represents the starting-state snapshot.
+ */
+ AppWindowThumbnail mThumbnail;
+ final Rect mTransitStartRect = new Rect();
+ final Point mTmpPoint = new Point();
+ protected final Rect mTmpRect = new Rect();
+ final Rect mTmpPrevBounds = new Rect();
+
WindowContainer(WindowManagerService wms) {
mWmService = wms;
mPendingTransaction = wms.mTransactionFactory.get();
@@ -642,51 +722,78 @@
}
/**
- * @return Whether our own container is running an animation or any child, no matter how deep in
- * the hierarchy, is animating.
+ * @return {@code true} when this container or its related containers are running an
+ * animation, {@code false} otherwise.
+ *
+ * By default this predicate only checks if this container itself is actually running an
+ * animation, but you can extend the check target over its relatives, or relax the condition
+ * so that this can return {@code true} if an animation starts soon by giving a combination
+ * of {@link #AnimationFlags}.
+ *
+ * Note that you can give a combination of bitmask flags to specify targets and condition for
+ * checking animating status.
+ * e.g. {@code isAnimating(TRANSITION | PARENT)} returns {@code true} if either this
+ * container itself or one of its parents is running an animation or waiting for an app
+ * transition.
+ *
+ * Note that TRANSITION propagates to parents and children as well.
+ *
+ * {@see AnimationFlags#TRANSITION}
+ * {@see AnimationFlags#PARENTS}
+ * {@see AnimationFlags#CHILDREN}
*/
- boolean isSelfOrChildAnimating() {
- if (isSelfAnimating()) {
+ final boolean isAnimating(int flags) {
+ if (mSurfaceAnimator.isAnimating()) {
return true;
}
- for (int j = mChildren.size() - 1; j >= 0; j--) {
- final WindowContainer wc = mChildren.get(j);
- if (wc.isSelfOrChildAnimating()) {
+ if ((flags & TRANSITION) != 0 && isWaitingForTransitionStart()) {
+ return true;
+ }
+ if ((flags & PARENTS) != 0) {
+ final WindowContainer parent = getParent();
+ if (parent != null && parent.isAnimating(flags & ~CHILDREN)) {
return true;
}
}
+ if ((flags & CHILDREN) != 0) {
+ for (int i = 0; i < mChildren.size(); ++i) {
+ final WindowContainer wc = mChildren.get(i);
+ if (wc.isAnimating(flags & ~PARENTS)) {
+ return true;
+ }
+ }
+ }
return false;
}
/**
- * @return Whether our own container is running an animation or our parent is animating. This
- * doesn't consider whether children are animating.
+ * @return {@code true} when the container is waiting the app transition start, {@code false}
+ * otherwise.
*/
- boolean isAnimating() {
-
- // We are animating if we ourselves are animating or if our parent is animating.
- return isSelfAnimating() || mParent != null && mParent.isAnimating();
+ boolean isWaitingForTransitionStart() {
+ return false;
}
/**
- * @return {@code true} if in this subtree of the hierarchy we have an {@link AppWindowToken}
- * that is {@link #isSelfAnimating}; {@code false} otherwise.
+ * @return {@code true} if in this subtree of the hierarchy we have an
+ * {@ode ActivityRecord#isAnimating(TRANSITION)}, {@code false} otherwise.
*/
- boolean isAppAnimating() {
- for (int j = mChildren.size() - 1; j >= 0; j--) {
- final WindowContainer wc = mChildren.get(j);
- if (wc.isAppAnimating()) {
- return true;
- }
- }
- return false;
+ boolean isAppTransitioning() {
+ return forAllActivities(app -> app.isAnimating(TRANSITION));
}
/**
* @return Whether our own container running an animation at the moment.
*/
- boolean isSelfAnimating() {
- return mSurfaceAnimator.isAnimating();
+ final boolean isAnimating() {
+ return isAnimating(0 /* self only */);
+ }
+
+ /**
+ * @return {@code true} if the container is in changing app transition.
+ */
+ boolean isChangingAppTransition() {
+ return false;
}
void sendAppVisibilityToClients() {
@@ -988,10 +1095,13 @@
wrapper.release();
}
- void forAllActivities(Consumer<ActivityRecord> callback) {
+ boolean forAllActivities(ToBooleanFunction<ActivityRecord> callback) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
- mChildren.get(i).forAllActivities(callback);
+ if (mChildren.get(i).forAllActivities(callback)) {
+ return true;
+ }
}
+ return false;
}
void forAllWallpaperWindows(Consumer<WallpaperWindowToken> callback) {
@@ -1374,6 +1484,203 @@
return null;
}
+ // TODO: Remove this and use #getBounds() instead once we set an app transition animation
+ // on TaskStack.
+ Rect getAnimationBounds(int appStackClipMode) {
+ return getBounds();
+ }
+
+ /**
+ * Applies the app transition animation according the given the layout properties in the
+ * window hierarchy.
+ *
+ * @param lp The layout parameters of the window.
+ * @param transit The app transition type indicates what kind of transition to be applied.
+ * @param enter Whether the app transition is entering transition or not.
+ * @param isVoiceInteraction Whether the container is participating in voice interaction or not.
+ *
+ * @return {@code true} when the container applied the app transition, {@code false} if the
+ * app transition is disabled or skipped.
+ *
+ * @see #getAnimationAdapter
+ */
+ boolean applyAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
+ boolean isVoiceInteraction) {
+ if (mWmService.mDisableTransitionAnimation) {
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM,
+ "applyAnimation: transition animation is disabled or skipped. "
+ + "container=%s", this);
+ cancelAnimation();
+ return false;
+ }
+
+ // Only apply an animation if the display isn't frozen. If it is frozen, there is no reason
+ // to animate and it can cause strange artifacts when we unfreeze the display if some
+ // different animation is running.
+ try {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "WC#applyAnimation");
+ if (okToAnimate()) {
+ Pair<AnimationAdapter, AnimationAdapter> adapters = getAnimationAdapter(lp, transit,
+ enter, isVoiceInteraction);
+ AnimationAdapter adapter = adapters.first;
+ AnimationAdapter thumbnailAdapter = adapters.second;
+ if (adapter != null) {
+ startAnimation(getPendingTransaction(), adapter, !isVisible());
+ if (adapter.getShowWallpaper()) {
+ mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ }
+ if (thumbnailAdapter != null) {
+ mThumbnail.startAnimation(
+ getPendingTransaction(), thumbnailAdapter, !isVisible());
+ }
+ }
+ } else {
+ cancelAnimation();
+ }
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+
+ return isAnimating();
+ }
+
+ /**
+ * Gets the {@link AnimationAdapter} according the given window layout properties in the window
+ * hierarchy.
+ *
+ * @return The return value will always contain two elements, one for normal animations and the
+ * other for thumbnail animation, both can be {@code null}.
+ *
+ * @See com.android.server.wm.RemoteAnimationController.RemoteAnimationRecord
+ * @See LocalAnimationAdapter
+ */
+ Pair<AnimationAdapter, AnimationAdapter> getAnimationAdapter(WindowManager.LayoutParams lp,
+ int transit, boolean enter, boolean isVoiceInteraction) {
+ final Pair<AnimationAdapter, AnimationAdapter> resultAdapters;
+ final int appStackClipMode = getDisplayContent().mAppTransition.getAppStackClipMode();
+
+ // Separate position and size for use in animators.
+ mTmpRect.set(getAnimationBounds(appStackClipMode));
+ mTmpPoint.set(mTmpRect.left, mTmpRect.top);
+ mTmpRect.offsetTo(0, 0);
+
+ final RemoteAnimationController controller =
+ getDisplayContent().mAppTransition.getRemoteAnimationController();
+ final boolean isChanging = AppTransition.isChangeTransit(transit) && enter
+ && isChangingAppTransition();
+
+ // Delaying animation start isn't compatible with remote animations at all.
+ if (controller != null && !mSurfaceAnimator.isAnimationStartDelayed()) {
+ final RemoteAnimationController.RemoteAnimationRecord adapters =
+ controller.createRemoteAnimationRecord(this, mTmpPoint, mTmpRect,
+ (isChanging ? mTransitStartRect : null));
+ resultAdapters = new Pair<>(adapters.mAdapter, adapters.mThumbnailAdapter);
+ } else if (isChanging) {
+ final float durationScale = mWmService.getTransitionAnimationScaleLocked();
+ final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
+ mTmpRect.offsetTo(mTmpPoint.x, mTmpPoint.y);
+
+ AnimationAdapter adapter = new LocalAnimationAdapter(
+ new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo,
+ durationScale, true /* isAppAnimation */, false /* isThumbnail */),
+ getSurfaceAnimationRunner());
+
+ AnimationAdapter thumbnailAdapter = null;
+ if (mThumbnail != null) {
+ thumbnailAdapter = new LocalAnimationAdapter(
+ new WindowChangeAnimationSpec(mTransitStartRect, mTmpRect, displayInfo,
+ durationScale, true /* isAppAnimation */, true /* isThumbnail */),
+ getSurfaceAnimationRunner());
+ }
+ resultAdapters = new Pair<>(adapter, thumbnailAdapter);
+ mTransit = transit;
+ mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
+ } else {
+ mNeedsAnimationBoundsLayer = (appStackClipMode == STACK_CLIP_AFTER_ANIM);
+ final Animation a = loadAnimation(lp, transit, enter, isVoiceInteraction);
+
+ if (a != null) {
+ // Only apply corner radius to animation if we're not in multi window mode.
+ // We don't want rounded corners when in pip or split screen.
+ final float windowCornerRadius = !inMultiWindowMode()
+ ? getDisplayContent().getWindowCornerRadius()
+ : 0;
+ AnimationAdapter adapter = new LocalAnimationAdapter(
+ new WindowAnimationSpec(a, mTmpPoint, mTmpRect,
+ getDisplayContent().mAppTransition.canSkipFirstFrame(),
+ appStackClipMode, true /* isAppAnimation */, windowCornerRadius),
+ getSurfaceAnimationRunner());
+
+ resultAdapters = new Pair<>(adapter, null);
+ mNeedsZBoost = a.getZAdjustment() == Animation.ZORDER_TOP;
+ mTransit = transit;
+ mTransitFlags = getDisplayContent().mAppTransition.getTransitFlags();
+ } else {
+ resultAdapters = new Pair<>(null, null);
+ }
+ }
+ return resultAdapters;
+ }
+
+ final SurfaceAnimationRunner getSurfaceAnimationRunner() {
+ return mWmService.mSurfaceAnimationRunner;
+ }
+
+ private Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter,
+ boolean isVoiceInteraction) {
+ final DisplayContent displayContent = getDisplayContent();
+ final DisplayInfo displayInfo = displayContent.getDisplayInfo();
+ final int width = displayInfo.appWidth;
+ final int height = displayInfo.appHeight;
+ ProtoLog.v(WM_DEBUG_APP_TRANSITIONS_ANIM, "applyAnimation: container=%s", this);
+
+ // Determine the visible rect to calculate the thumbnail clip with
+ // getAnimationFrames.
+ final Rect frame = new Rect(0, 0, width, height);
+ final Rect displayFrame = new Rect(0, 0,
+ displayInfo.logicalWidth, displayInfo.logicalHeight);
+ final Rect insets = new Rect();
+ final Rect stableInsets = new Rect();
+ final Rect surfaceInsets = new Rect();
+ getAnimationFrames(frame, insets, stableInsets, surfaceInsets);
+
+ if (mLaunchTaskBehind) {
+ // Differentiate the two animations. This one which is briefly on the screen
+ // gets the !enter animation, and the other one which remains on the
+ // screen gets the enter animation. Both appear in the mOpeningApps set.
+ enter = false;
+ }
+ ProtoLog.d(WM_DEBUG_APP_TRANSITIONS,
+ "Loading animation for app transition. transit=%s enter=%b frame=%s insets=%s "
+ + "surfaceInsets=%s",
+ AppTransition.appTransitionToString(transit), enter, frame, insets, surfaceInsets);
+ final Configuration displayConfig = displayContent.getConfiguration();
+ final Animation a = getDisplayContent().mAppTransition.loadAnimation(lp, transit, enter,
+ displayConfig.uiMode, displayConfig.orientation, frame, displayFrame, insets,
+ surfaceInsets, stableInsets, isVoiceInteraction, inFreeformWindowingMode(), this);
+ if (a != null) {
+ if (DEBUG_ANIM) logWithStack(TAG, "Loaded animation " + a + " for " + this);
+ final int containingWidth = frame.width();
+ final int containingHeight = frame.height();
+ a.initialize(containingWidth, containingHeight, width, height);
+ a.scaleCurrentDuration(mWmService.getTransitionAnimationScaleLocked());
+ }
+ return a;
+ }
+
+ RemoteAnimationTarget createRemoteAnimationTarget(
+ RemoteAnimationController.RemoteAnimationRecord record) {
+ return null;
+ }
+
+ boolean okToDisplay() {
+ return mDisplayContent != null && mDisplayContent.okToDisplay();
+ }
+
+ boolean okToAnimate() {
+ return mDisplayContent != null && mDisplayContent.okToAnimate();
+ }
+
@Override
public void commitPendingTransaction() {
scheduleAnimation();
@@ -1473,6 +1780,26 @@
return getBounds();
}
+ /**
+ * The {@code outFrame} retrieved by this method specifies where the animation will finish
+ * the entrance animation, as the next frame will display the window at these coordinates. In
+ * case of exit animation, this is where the animation will start, as the frame before the
+ * animation is displaying the window at these bounds.
+ *
+ * @param outFrame The bounds where entrance animation finishes or exit animation starts.
+ * @param outInsets Insets that are covered by system windows.
+ * @param outStableInsets Insets that determine the area covered by the stable system windows.
+ * @param outSurfaceInsets Positive insets between the drawing surface and window content.
+ */
+ void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
+ Rect outSurfaceInsets) {
+ final DisplayInfo displayInfo = getDisplayContent().getDisplayInfo();
+ outFrame.set(0, 0, displayInfo.appWidth, displayInfo.appHeight);
+ outInsets.setEmpty();
+ outStableInsets.setEmpty();
+ outSurfaceInsets.setEmpty();
+ }
+
void getRelativeDisplayedPosition(Point outPos) {
final Rect dispBounds = getDisplayedBounds();
outPos.set(dispBounds.left, dispBounds.top);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 085b0f6..ab937e0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -94,6 +94,9 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
import static com.android.server.wm.ProtoLogGroup.WM_ERROR;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_INPUT_METHOD;
@@ -2418,7 +2421,7 @@
if (win.isWinVisibleLw() && winAnimator.applyAnimationLocked(transit, false)) {
focusMayChange = true;
win.mAnimatingExit = true;
- } else if (win.isAnimating()) {
+ } else if (win.isAnimating(TRANSITION | PARENTS)) {
// Currently in a hide animation... turn this into
// an exit.
win.mAnimatingExit = true;
@@ -7618,7 +7621,7 @@
private void waitForAnimationsToComplete() {
synchronized (mGlobalLock) {
long timeoutRemaining = ANIMATION_COMPLETED_TIMEOUT_MS;
- while (mRoot.isSelfOrChildAnimating() && timeoutRemaining > 0) {
+ while (mRoot.isAnimating(TRANSITION | CHILDREN) && timeoutRemaining > 0) {
long startTime = System.currentTimeMillis();
try {
mGlobalLock.wait(timeoutRemaining);
@@ -7627,7 +7630,7 @@
timeoutRemaining -= (System.currentTimeMillis() - startTime);
}
- if (mRoot.isSelfOrChildAnimating()) {
+ if (mRoot.isAnimating(TRANSITION | CHILDREN)) {
Log.w(TAG, "Timed out waiting for animations to complete.");
}
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f0ea13d..f7402e1 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -98,6 +98,8 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ORIENTATION;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_RESIZE;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
@@ -1492,7 +1494,8 @@
@Override
boolean hasContentToDisplay() {
if (!mAppFreezing && isDrawnLw() && (mViewVisibility == View.VISIBLE
- || (isAnimating() && !getDisplayContent().mAppTransition.isTransitionSet()))) {
+ || (isAnimating(TRANSITION | PARENTS)
+ && !getDisplayContent().mAppTransition.isTransitionSet()))) {
return true;
}
@@ -1550,8 +1553,8 @@
*/
// TODO: Can we consolidate this with #isVisible() or have a more appropriate name for this?
boolean isWinVisibleLw() {
- return (mActivityRecord == null || !mActivityRecord.hiddenRequested || mActivityRecord.isSelfAnimating())
- && isVisible();
+ return (mActivityRecord == null || !mActivityRecord.hiddenRequested
+ || mActivityRecord.isAnimating(TRANSITION)) && isVisible();
}
/**
@@ -1597,9 +1600,9 @@
final ActivityRecord atoken = mActivityRecord;
if (atoken != null) {
return ((!isParentWindowHidden() && !atoken.hiddenRequested)
- || isAnimating());
+ || isAnimating(TRANSITION | PARENTS));
}
- return !isParentWindowHidden() || isAnimating();
+ return !isParentWindowHidden() || isAnimating(TRANSITION | PARENTS);
}
/**
@@ -1634,7 +1637,7 @@
final boolean parentAndClientVisible = !isParentWindowHidden()
&& mViewVisibility == View.VISIBLE && !mToken.isHidden();
return mHasSurface && isVisibleByPolicy() && !mDestroying
- && (parentAndClientVisible || isAnimating());
+ && (parentAndClientVisible || isAnimating(TRANSITION | PARENTS));
}
// TODO: Another visibility method that was added late in the release to minimize risk.
@@ -1664,7 +1667,7 @@
final ActivityRecord atoken = mActivityRecord;
return isDrawnLw() && isVisibleByPolicy()
&& ((!isParentWindowHidden() && (atoken == null || !atoken.hiddenRequested))
- || isAnimating());
+ || isAnimating(TRANSITION | PARENTS));
}
/**
@@ -1672,7 +1675,7 @@
*/
@Override
public boolean isAnimatingLw() {
- return isAnimating();
+ return isAnimating(TRANSITION | PARENTS);
}
@Override
@@ -1718,7 +1721,7 @@
// to determine if it's occluding apps.
return ((!mIsWallpaper && mAttrs.format == PixelFormat.OPAQUE)
|| (mIsWallpaper && mWallpaperVisible))
- && isDrawnLw() && !isAnimating();
+ && isDrawnLw() && !isAnimating(TRANSITION | PARENTS);
}
@Override
@@ -1740,7 +1743,7 @@
// Starting window that's exiting will be removed when the animation finishes.
// Mark all relevant flags for that onExitAnimationDone will proceed all the way
// to actually remove it.
- if (!visible && isVisibleNow() && mActivityRecord.isSelfAnimating()) {
+ if (!visible && isVisibleNow() && mActivityRecord.isAnimating(TRANSITION)) {
mAnimatingExit = true;
mRemoveOnExit = true;
mWindowRemovalAllowed = true;
@@ -2016,8 +2019,10 @@
+ "mWillReplaceWindow=%b inPendingTransaction=%b mDisplayFrozen=%b "
+ "callers=%s",
this, mWinAnimator.mSurfaceController, mAnimatingExit, mRemoveOnExit,
- mHasSurface, mWinAnimator.getShown(), isAnimating(),
- mActivityRecord != null && mActivityRecord.isSelfAnimating(), mWillReplaceWindow,
+ mHasSurface, mWinAnimator.getShown(),
+ isAnimating(TRANSITION | PARENTS),
+ mActivityRecord != null && mActivityRecord.isAnimating(TRANSITION),
+ mWillReplaceWindow,
mActivityRecord != null && mActivityRecord.inPendingTransaction,
mWmService.mDisplayFrozen, Debug.getCallers(6));
@@ -2076,7 +2081,7 @@
mWmService.mAccessibilityController.onWindowTransitionLocked(this, transit);
}
}
- final boolean isAnimating = isAnimating()
+ final boolean isAnimating = isAnimating(TRANSITION | PARENTS)
&& (mActivityRecord == null || !mActivityRecord.isWaitingForTransitionStart());
final boolean lastWindowIsStartingWindow = startingWindow && mActivityRecord != null
&& mActivityRecord.isLastWindow(this);
@@ -2683,10 +2688,11 @@
if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
if (doAnimation) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
- + isLegacyPolicyVisibility() + " animating=" + isAnimating());
+ + isLegacyPolicyVisibility()
+ + " animating=" + isAnimating(TRANSITION | PARENTS));
if (!mToken.okToAnimate()) {
doAnimation = false;
- } else if (isLegacyPolicyVisibility() && !isAnimating()) {
+ } else if (isLegacyPolicyVisibility() && !isAnimating(TRANSITION | PARENTS)) {
// Check for the case where we are currently visible and
// not animating; we do not want to do animation at such a
// point to become visible when we already are.
@@ -2726,7 +2732,7 @@
}
if (doAnimation) {
mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false);
- if (!isAnimating()) {
+ if (!isAnimating(TRANSITION | PARENTS)) {
doAnimation = false;
}
}
@@ -4163,9 +4169,9 @@
+ " tok.hiddenRequested="
+ (mActivityRecord != null && mActivityRecord.hiddenRequested)
+ " tok.hidden=" + (mActivityRecord != null && mActivityRecord.isHidden())
- + " animating=" + isAnimating()
+ + " animating=" + isAnimating(TRANSITION | PARENTS)
+ " tok animating="
- + (mActivityRecord != null && mActivityRecord.isSelfAnimating())
+ + (mActivityRecord != null && mActivityRecord.isAnimating(TRANSITION))
+ " Callers=" + Debug.getCallers(4));
}
}
@@ -4392,7 +4398,7 @@
void onExitAnimationDone() {
if (DEBUG_ANIM) Slog.v(TAG, "onExitAnimationDone in " + this
+ ": exiting=" + mAnimatingExit + " remove=" + mRemoveOnExit
- + " selfAnimating=" + isSelfAnimating());
+ + " selfAnimating=" + isAnimating());
if (!mChildren.isEmpty()) {
// Copying to a different list as multiple children can be removed.
@@ -4415,7 +4421,7 @@
}
}
- if (isSelfAnimating()) {
+ if (isAnimating()) {
return;
}
if (mWmService.mAccessibilityController != null) {
@@ -4563,25 +4569,25 @@
}
if (DEBUG_VISIBILITY) {
Slog.v(TAG, "Win " + this + ": isDrawn=" + isDrawnLw()
- + ", animating=" + isAnimating());
+ + ", animating=" + isAnimating(TRANSITION | PARENTS));
if (!isDrawnLw()) {
Slog.v(TAG, "Not displayed: s=" + mWinAnimator.mSurfaceController
+ " pv=" + isVisibleByPolicy()
+ " mDrawState=" + mWinAnimator.mDrawState
+ " ph=" + isParentWindowHidden()
+ " th=" + (mActivityRecord != null ? mActivityRecord.hiddenRequested : false)
- + " a=" + isAnimating());
+ + " a=" + isAnimating(TRANSITION | PARENTS));
}
}
results.numInteresting++;
if (isDrawnLw()) {
results.numDrawn++;
- if (!isAnimating()) {
+ if (!isAnimating(TRANSITION | PARENTS)) {
results.numVisible++;
}
results.nowGone = false;
- } else if (isAnimating()) {
+ } else if (isAnimating(TRANSITION | PARENTS)) {
results.nowGone = false;
}
}
@@ -4718,7 +4724,7 @@
+ mRemoveOnExit + ", mDestroying=" + mDestroying);
// Cancel the existing exit animation for the next enter animation.
- if (isSelfAnimating()) {
+ if (isAnimating()) {
cancelAnimation();
destroySurfaceUnchecked();
}
@@ -5398,4 +5404,29 @@
}
return mKeyInterceptionInfo;
}
+
+ @Override
+ void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
+ Rect outSurfaceInsets) {
+ // Containing frame will usually cover the whole screen, including dialog windows.
+ // For freeform workspace windows it will not cover the whole screen and it also
+ // won't exactly match the final freeform window frame (e.g. when overlapping with
+ // the status bar). In that case we need to use the final frame.
+ if (inFreeformWindowingMode()) {
+ outFrame.set(getFrameLw());
+ } else if (isLetterboxedAppWindow()) {
+ outFrame.set(getTask().getBounds());
+ } else if (isDockedResizing()) {
+ // If we are animating while docked resizing, then use the stack bounds as the
+ // animation target (which will be different than the task bounds)
+ outFrame.set(getTask().getParent().getBounds());
+ } else {
+ outFrame.set(getContainingFrame());
+ }
+ outSurfaceInsets.set(getAttrs().surfaceInsets);
+ // TODO(b/72757033): These are insets relative to the window frame, but we're really
+ // interested in the insets relative to the frame we chose in the if-blocks above.
+ getContentInsets(outInsets);
+ getStableInsets(outStableInsets);
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3f25f89..fef3a9d 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -32,6 +32,8 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
import static com.android.server.wm.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS;
@@ -435,7 +437,7 @@
return;
}
- if (!mWin.mActivityRecord.isSelfAnimating()) {
+ if (!mWin.mActivityRecord.isAnimating(TRANSITION)) {
mWin.mActivityRecord.clearAllDrawn();
} else {
// Currently animating, persist current state of allDrawn until animation
@@ -1169,7 +1171,7 @@
w.mToken.hasVisible = true;
}
} else {
- if (DEBUG_ANIM && mWin.isAnimating()) {
+ if (DEBUG_ANIM && mWin.isAnimating(TRANSITION | PARENTS)) {
Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
}
displayed = true;
@@ -1332,7 +1334,7 @@
* @return true if an animation has been loaded.
*/
boolean applyAnimationLocked(int transit, boolean isEntrance) {
- if (mWin.isSelfAnimating() && mAnimationIsEntrance == isEntrance) {
+ if (mWin.isAnimating() && mAnimationIsEntrance == isEntrance) {
// If we are trying to apply an animation, but already running
// an animation of the same type, then just leave that one alone.
return true;
@@ -1400,7 +1402,7 @@
mWin.getDisplayContent().adjustForImeIfNeeded();
}
- return mWin.isAnimating();
+ return mWin.isAnimating(TRANSITION | PARENTS);
}
void writeToProto(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index ad71237..88a1458 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -22,6 +22,9 @@
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_FOCUS;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
@@ -159,13 +162,10 @@
final int count = mChildren.size();
boolean changed = false;
- boolean delayed = false;
+ final boolean delayed = isAnimating(TRANSITION | PARENTS | CHILDREN);
for (int i = 0; i < count; i++) {
final WindowState win = mChildren.get(i);
- if (win.isAnimating()) {
- delayed = true;
- }
changed |= win.onSetAppExiting();
}
@@ -321,14 +321,6 @@
return toString();
}
- boolean okToDisplay() {
- return mDisplayContent != null && mDisplayContent.okToDisplay();
- }
-
- boolean okToAnimate() {
- return mDisplayContent != null && mDisplayContent.okToAnimate();
- }
-
/**
* Return whether windows from this token can layer above the
* system bars, or in other words extend outside of the "Decor Frame"
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index dd2629d..35e2436 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -709,6 +709,18 @@
checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
}
+static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
+ const sp<InputApplicationHandle>& inputApplicationHandle) {
+ if (inputApplicationHandle == nullptr) {
+ return nullptr;
+ }
+ NativeInputApplicationHandle* handle =
+ static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get());
+
+ return handle->getInputApplicationHandleObjLocalRef(env);
+}
+
+
nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
const sp<IBinder>& token, const std::string& reason) {
#if DEBUG_INPUT_DISPATCHER_POLICY
@@ -719,12 +731,15 @@
JNIEnv* env = jniEnv();
ScopedLocalFrame localFrame(env);
+ jobject inputApplicationHandleObj =
+ getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
+
jobject tokenObj = javaObjectForIBinder(env, token);
jstring reasonObj = env->NewStringUTF(reason.c_str());
jlong newTimeout = env->CallLongMethod(mServiceObj,
- gServiceClassInfo.notifyANR, tokenObj,
- reasonObj);
+ gServiceClassInfo.notifyANR, inputApplicationHandleObj, tokenObj,
+ reasonObj);
if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
newTimeout = 0; // abort dispatch
} else {
@@ -1865,7 +1880,7 @@
GET_METHOD_ID(gServiceClassInfo.notifyANR, clazz,
"notifyANR",
- "(Landroid/os/IBinder;Ljava/lang/String;)J");
+ "(Landroid/view/InputApplicationHandle;Landroid/os/IBinder;Ljava/lang/String;)J");
GET_METHOD_ID(gServiceClassInfo.filterInputEvent, clazz,
"filterInputEvent", "(Landroid/view/InputEvent;I)Z");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 5e49c7a..a39cc20 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -8105,15 +8105,7 @@
mSecurityLogMonitor.stop();
setNetworkLoggingActiveInternal(false);
deleteTransferOwnershipBundleLocked(userId);
-
- try {
- if (mInjector.getIBackupManager() != null) {
- // Reactivate backup service.
- mInjector.getIBackupManager().setBackupServiceActive(UserHandle.USER_SYSTEM, true);
- }
- } catch (RemoteException e) {
- throw new IllegalStateException("Failed reactivating backup service.", e);
- }
+ toggleBackupServiceActive(UserHandle.USER_SYSTEM, true);
}
@Override
@@ -8173,7 +8165,6 @@
}
}
-
private void toggleBackupServiceActive(int userId, boolean makeActive) {
long ident = mInjector.binderClearCallingIdentity();
try {
@@ -8182,7 +8173,8 @@
.setBackupServiceActive(userId, makeActive);
}
} catch (RemoteException e) {
- throw new IllegalStateException("Failed deactivating backup service.", e);
+ throw new IllegalStateException(String.format("Failed %s backup service.",
+ makeActive ? "activating" : "deactivating"), e);
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
@@ -8233,6 +8225,7 @@
mOwners.removeProfileOwner(userId);
mOwners.writeProfileOwner(userId);
deleteTransferOwnershipBundleLocked(userId);
+ toggleBackupServiceActive(userId, true);
}
@Override
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5883048..2009dbd 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -27,6 +27,7 @@
import android.annotation.NonNull;
import android.annotation.StringRes;
import android.app.ActivityThread;
+import android.app.AppCompatCallbacks;
import android.app.INotificationManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ComponentName;
@@ -646,6 +647,7 @@
ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
new PlatformCompatNative(platformCompat));
+ AppCompatCallbacks.install(new long[0]);
t.traceEnd();
// Wait for installd to finish starting up so that it has a chance to
@@ -1133,7 +1135,6 @@
StatusBarManagerService statusBar = null;
INotificationManager notification = null;
- LocationManagerService location = null;
CountryDetectorService countryDetector = null;
ILockSettings lockSettings = null;
MediaRouterService mediaRouter = null;
@@ -1430,12 +1431,7 @@
t.traceEnd();
t.traceBegin("StartLocationManagerService");
- try {
- location = new LocationManagerService(context);
- ServiceManager.addService(Context.LOCATION_SERVICE, location);
- } catch (Throwable e) {
- reportWtf("starting Location Manager", e);
- }
+ mSystemServiceManager.startService(LocationManagerService.Lifecycle.class);
t.traceEnd();
t.traceBegin("StartCountryDetectorService");
@@ -2019,7 +2015,6 @@
final NetworkStatsService networkStatsF = networkStats;
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
- final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
final InputManagerService inputManagerF = inputManager;
@@ -2175,16 +2170,6 @@
}
t.traceEnd();
-
- t.traceBegin("MakeLocationServiceReady");
- try {
- if (locationF != null) {
- locationF.systemRunning();
- }
- } catch (Throwable e) {
- reportWtf("Notifying Location Service running", e);
- }
- t.traceEnd();
t.traceBegin("MakeCountryDetectionServiceReady");
try {
if (countryDetectorF != null) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
index 9e7b805..485f436 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AlarmManagerServiceTest.java
@@ -38,7 +38,6 @@
import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_LONG_TIME;
import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_SHORT_TIME;
import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION;
-import static com.android.server.AlarmManagerService.Constants.KEY_APP_STANDBY_QUOTAS_ENABLED;
import static com.android.server.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT;
import static com.android.server.AlarmManagerService.Constants.KEY_MAX_INTERVAL;
import static com.android.server.AlarmManagerService.Constants.KEY_MIN_FUTURITY;
@@ -305,6 +304,8 @@
argThat((filter) -> filter.hasAction(BatteryManager.ACTION_CHARGING)
&& filter.hasAction(BatteryManager.ACTION_DISCHARGING)));
mChargingReceiver = chargingReceiverCaptor.getValue();
+
+ setTestableQuotas();
}
private void setTestAlarm(int type, long triggerTime, PendingIntent operation) {
@@ -342,9 +343,10 @@
}
/**
+ * Lowers quotas to make testing feasible.
* Careful while calling as this will replace any existing settings for the calling test.
*/
- private void setQuotasEnabled(boolean enabled) {
+ private void setTestableQuotas() {
final StringBuilder constantsBuilder = new StringBuilder();
constantsBuilder.append(KEY_MIN_FUTURITY);
constantsBuilder.append("=0,");
@@ -353,14 +355,9 @@
constantsBuilder.append("=8,");
constantsBuilder.append(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[WORKING_INDEX]);
constantsBuilder.append("=5,");
- if (!enabled) {
- constantsBuilder.append(KEY_APP_STANDBY_QUOTAS_ENABLED);
- constantsBuilder.append("=false,");
- }
doReturn(constantsBuilder.toString()).when(() -> Settings.Global.getString(mMockResolver,
Settings.Global.ALARM_MANAGER_CONSTANTS));
mService.mConstants.onChange(false, null);
- assertEquals(mService.mConstants.APP_STANDBY_QUOTAS_ENABLED, enabled);
}
@Test
@@ -481,67 +478,6 @@
assertEquals(mNowElapsedTest + 9, mTestTimer.getElapsed());
}
- @Test
- public void testStandbyBucketDelay_workingSet() throws Exception {
- setQuotasEnabled(false);
- setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, getNewMockPendingIntent());
- setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, getNewMockPendingIntent());
- assertEquals(mNowElapsedTest + 5, mTestTimer.getElapsed());
-
- when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
- anyLong())).thenReturn(STANDBY_BUCKET_WORKING_SET);
-
- mNowElapsedTest = mTestTimer.getElapsed();
- mTestTimer.expire();
-
- verify(mUsageStatsManagerInternal, atLeastOnce())
- .getAppStandbyBucket(eq(TEST_CALLING_PACKAGE),
- eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong());
- final long expectedNextTrigger = mNowElapsedTest
- + mService.getMinDelayForBucketLocked(STANDBY_BUCKET_WORKING_SET);
- assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed());
- }
-
- @Test
- public void testStandbyBucketDelay_frequent() throws Exception {
- setQuotasEnabled(false);
- setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, getNewMockPendingIntent());
- setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, getNewMockPendingIntent());
- assertEquals(mNowElapsedTest + 5, mTestTimer.getElapsed());
-
- when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
- anyLong())).thenReturn(STANDBY_BUCKET_FREQUENT);
- mNowElapsedTest = mTestTimer.getElapsed();
- mTestTimer.expire();
-
- verify(mUsageStatsManagerInternal, atLeastOnce())
- .getAppStandbyBucket(eq(TEST_CALLING_PACKAGE),
- eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong());
- final long expectedNextTrigger = mNowElapsedTest
- + mService.getMinDelayForBucketLocked(STANDBY_BUCKET_FREQUENT);
- assertEquals("Incorrect next alarm trigger.", expectedNextTrigger, mTestTimer.getElapsed());
- }
-
- @Test
- public void testStandbyBucketDelay_rare() throws Exception {
- setQuotasEnabled(false);
- setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, getNewMockPendingIntent());
- setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, getNewMockPendingIntent());
- assertEquals(mNowElapsedTest + 5, mTestTimer.getElapsed());
-
- when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
- anyLong())).thenReturn(STANDBY_BUCKET_RARE);
- mNowElapsedTest = mTestTimer.getElapsed();
- mTestTimer.expire();
-
- verify(mUsageStatsManagerInternal, atLeastOnce())
- .getAppStandbyBucket(eq(TEST_CALLING_PACKAGE),
- eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong());
- final long expectedNextTrigger = mNowElapsedTest
- + mService.getMinDelayForBucketLocked(STANDBY_BUCKET_RARE);
- assertEquals("Incorrect next alarm trigger.", expectedNextTrigger, mTestTimer.getElapsed());
- }
-
private void testQuotasDeferralOnSet(int standbyBucket) throws Exception {
final int quota = mService.getQuotaForBucketLocked(standbyBucket);
when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
@@ -601,73 +537,61 @@
@Test
public void testActiveQuota_deferredOnSet() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnSet(STANDBY_BUCKET_ACTIVE);
}
@Test
public void testActiveQuota_deferredOnExpiration() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnExpiration(STANDBY_BUCKET_ACTIVE);
}
@Test
public void testActiveQuota_notDeferred() throws Exception {
- setQuotasEnabled(true);
testQuotasNoDeferral(STANDBY_BUCKET_ACTIVE);
}
@Test
public void testWorkingQuota_deferredOnSet() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnSet(STANDBY_BUCKET_WORKING_SET);
}
@Test
public void testWorkingQuota_deferredOnExpiration() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnExpiration(STANDBY_BUCKET_WORKING_SET);
}
@Test
public void testWorkingQuota_notDeferred() throws Exception {
- setQuotasEnabled(true);
testQuotasNoDeferral(STANDBY_BUCKET_WORKING_SET);
}
@Test
public void testFrequentQuota_deferredOnSet() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnSet(STANDBY_BUCKET_FREQUENT);
}
@Test
public void testFrequentQuota_deferredOnExpiration() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnExpiration(STANDBY_BUCKET_FREQUENT);
}
@Test
public void testFrequentQuota_notDeferred() throws Exception {
- setQuotasEnabled(true);
testQuotasNoDeferral(STANDBY_BUCKET_FREQUENT);
}
@Test
public void testRareQuota_deferredOnSet() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnSet(STANDBY_BUCKET_RARE);
}
@Test
public void testRareQuota_deferredOnExpiration() throws Exception {
- setQuotasEnabled(true);
testQuotasDeferralOnExpiration(STANDBY_BUCKET_RARE);
}
@Test
public void testRareQuota_notDeferred() throws Exception {
- setQuotasEnabled(true);
testQuotasNoDeferral(STANDBY_BUCKET_RARE);
}
@@ -686,7 +610,6 @@
@Test
public void testQuotaDowngrade() throws Exception {
- setQuotasEnabled(true);
final int workingQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_WORKING_SET);
when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
anyLong())).thenReturn(STANDBY_BUCKET_WORKING_SET);
@@ -714,7 +637,6 @@
@Test
public void testQuotaUpgrade() throws Exception {
- setQuotasEnabled(true);
final int frequentQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_FREQUENT);
when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
anyLong())).thenReturn(STANDBY_BUCKET_FREQUENT);
@@ -752,7 +674,6 @@
@Test
public void testCharging() throws Exception {
- setQuotasEnabled(true);
final int workingQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_WORKING_SET);
when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
anyLong())).thenReturn(STANDBY_BUCKET_WORKING_SET);
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 1f4656a..1e27007 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -513,7 +513,8 @@
mIUidObserver.onUidStateChanged(UID_2,
- ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 0);
+ ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
waitUntilMainHandlerDrain();
assertTrue(instance.isUidActive(UID_1));
@@ -530,7 +531,8 @@
mIUidObserver.onUidStateChanged(UID_1,
- ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+ ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
waitUntilMainHandlerDrain();
assertTrue(instance.isUidActive(UID_1));
@@ -564,7 +566,8 @@
assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
mIUidObserver.onUidStateChanged(UID_1,
- ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0);
+ ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
waitUntilMainHandlerDrain();
assertFalse(instance.isUidActive(UID_1));
@@ -576,7 +579,8 @@
assertTrue(instance.isUidInForeground(Process.SYSTEM_UID));
mIUidObserver.onUidStateChanged(UID_1,
- ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0);
+ ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
waitUntilMainHandlerDrain();
assertFalse(instance.isUidActive(UID_1));
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 6dd1bd8..57f55e3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -23,7 +23,6 @@
import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY;
import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
-import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
import static android.app.ActivityManager.PROCESS_STATE_HOME;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
@@ -368,7 +367,7 @@
sService.mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE);
- assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION, PERCEPTIBLE_APP_ADJ,
+ assertProcStates(app, PROCESS_STATE_FOREGROUND_SERVICE, PERCEPTIBLE_APP_ADJ,
SCHED_GROUP_DEFAULT);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index b6a7b09..fa209a7a 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -16,7 +16,6 @@
package com.android.server.appop;
import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
-import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_ERRORED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
@@ -338,18 +337,22 @@
public void testUidProcStateChange_cachedToTopToCached() throws Exception {
setupProcStateTests();
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
+ ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
// Second time to make sure that settle time is overcome
Thread.sleep(50);
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
}
@@ -357,12 +360,13 @@
@Test
public void testUidProcStateChange_cachedToFgs() {
setupProcStateTests();
-
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
}
@@ -371,12 +375,13 @@
public void testUidProcStateChange_cachedToFgsLocation() {
setupProcStateTests();
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid,
- PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isEqualTo(MODE_ALLOWED);
}
@@ -385,18 +390,22 @@
public void testUidProcStateChange_topToFgs() throws Exception {
setupProcStateTests();
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
+ ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
// Second time to make sure that settle time is overcome
Thread.sleep(50);
- mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
}
@@ -405,25 +414,31 @@
public void testUidProcStateChange_topToFgsLocationToFgs() throws Exception {
setupProcStateTests();
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_CACHED_EMPTY,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP);
+ mAppOpsService.updateUidProcState(mMyUid, ActivityManager.PROCESS_STATE_TOP,
+ ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
// Second time to make sure that settle time is overcome
Thread.sleep(50);
- mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isEqualTo(MODE_ALLOWED);
- mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
// Second time to make sure that settle time is overcome
Thread.sleep(50);
- mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE);
+ mAppOpsService.updateUidProcState(mMyUid, PROCESS_STATE_FOREGROUND_SERVICE,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
assertThat(mAppOpsService.noteOperation(OP_COARSE_LOCATION, mMyUid, sMyPackageName, null))
.isNotEqualTo(MODE_ALLOWED);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 8863d5a..5bd08c0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -233,7 +233,8 @@
doReturn(procState).when(mActivityMangerInternal).getUidProcessState(uid);
SparseBooleanArray foregroundUids = mQuotaController.getForegroundUids();
spyOn(foregroundUids);
- mUidObserver.onUidStateChanged(uid, procState, 0);
+ mUidObserver.onUidStateChanged(uid, procState, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
verify(foregroundUids, timeout(2 * SECOND_IN_MILLIS).times(1))
.put(eq(uid), eq(true));
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 1edc953..49412bc0c 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -571,7 +571,8 @@
verifyObserverReceivedChanges(observerToTest, changesToVerify, changeItems,
(observer, changeItem) -> {
verify(observer).onUidStateChanged(changeItem.uid,
- changeItem.processState, changeItem.procStateSeq);
+ changeItem.processState, changeItem.procStateSeq,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
});
}
// Verify there are no other callbacks for this observer.
@@ -619,7 +620,8 @@
// First process state message is always delivered regardless of whether the process state
// change is above or below the cutpoint (PROCESS_STATE_SERVICE).
verify(observer).onUidStateChanged(TEST_UID,
- changeItem.processState, changeItem.procStateSeq);
+ changeItem.processState, changeItem.procStateSeq,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
verifyNoMoreInteractions(observer);
changeItem.processState = ActivityManager.PROCESS_STATE_RECEIVER;
@@ -636,7 +638,8 @@
// the current process state change is above cutpoint, so callback will be invoked with the
// current process state change.
verify(observer).onUidStateChanged(TEST_UID,
- changeItem.processState, changeItem.procStateSeq);
+ changeItem.processState, changeItem.procStateSeq,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
verifyNoMoreInteractions(observer);
changeItem.processState = ActivityManager.PROCESS_STATE_TOP;
@@ -653,7 +656,8 @@
// the current process state change is below cutpoint, so callback will be invoked with the
// current process state change.
verify(observer).onUidStateChanged(TEST_UID,
- changeItem.processState, changeItem.procStateSeq);
+ changeItem.processState, changeItem.procStateSeq,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
verifyNoMoreInteractions(observer);
}
diff --git a/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java b/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java
index d3bcff5..d12d804 100644
--- a/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/OomAdjusterTests.java
@@ -181,7 +181,7 @@
@Test
public void testMaybeUpdateUsageStats_ProcStateFGSLocation() {
final long elapsedTime = ZERO;
- mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION);
+ mProcessRecord.setCurProcState(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
sService.mOomAdjuster.maybeUpdateUsageStats(mProcessRecord, elapsedTime);
assertProcessRecordState(elapsedTime, false, ZERO);
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index aeccfc5..f571411 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -943,10 +943,6 @@
verify(getServices().iactivityManager, times(1)).updateDeviceOwner(
eq(admin1.getPackageName()));
- // TODO We should check if the caller has called clearCallerIdentity().
- verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
- eq(UserHandle.USER_SYSTEM), eq(false));
-
verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
@@ -1175,6 +1171,37 @@
// TODO Check other calls.
}
+ public void testDeviceOwnerBackupActivateDeactivate() throws Exception {
+ mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
+ mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+
+ // Set admin1 as a DA to the secondary user.
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+ setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
+ dpm.setActiveAdmin(admin1, /* replace =*/ false);
+ assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
+
+ verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
+ eq(UserHandle.USER_SYSTEM), eq(false));
+
+ dpm.clearDeviceOwnerApp(admin1.getPackageName());
+
+ verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
+ eq(UserHandle.USER_SYSTEM), eq(true));
+ }
+
+ public void testProfileOwnerBackupActivateDeactivate() throws Exception {
+ setAsProfileOwner(admin1);
+
+ verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
+ eq(DpmMockContext.CALLER_USER_HANDLE), eq(false));
+
+ dpm.clearProfileOwner(admin1);
+
+ verify(getServices().ibackupManager, times(1)).setBackupServiceActive(
+ eq(DpmMockContext.CALLER_USER_HANDLE), eq(true));
+ }
+
public void testClearDeviceOwner_fromDifferentUser() throws Exception {
mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
mContext.callerPermissions.add(permission.MANAGE_USERS);
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 64bd2c7..51bae16 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -1362,7 +1362,8 @@
private void callOnUidStateChanged(int uid, int procState, long procStateSeq)
throws Exception {
- mUidObserver.onUidStateChanged(uid, procState, procStateSeq);
+ mUidObserver.onUidStateChanged(uid, procState, procStateSeq,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
final CountDownLatch latch = new CountDownLatch(1);
mService.mUidEventHandler.post(() -> {
latch.countDown();
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index b806180..f9fc3a1 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -2222,7 +2222,8 @@
protected void makeUidForeground(int uid) {
try {
mService.mUidObserver.onUidStateChanged(
- uid, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+ uid, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
@@ -2235,7 +2236,8 @@
protected void makeUidBackground(int uid) {
try {
mService.mUidObserver.onUidStateChanged(
- uid, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
+ uid, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
} catch (RemoteException e) {
e.rethrowAsRuntimeException();
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
index fd3678d..7b101c7 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -1647,7 +1647,8 @@
// State changed, but not foreground, so no resetting.
mService.mUidObserver.onUidStateChanged(
- CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
+ CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
@@ -1671,7 +1672,8 @@
// State changed, package1 foreground, reset.
mService.mUidObserver.onUidStateChanged(
- CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+ CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(3, mManager.getRemainingCallCount());
});
@@ -1691,16 +1693,19 @@
MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
});
mService.mUidObserver.onUidStateChanged(
- CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
+ CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
mInjectedCurrentTimeMillis++;
// Different app comes to foreground briefly, and goes back to background.
// Now, make sure package 2's counter is reset, even in this case.
mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(3, mManager.getRemainingCallCount());
@@ -1731,9 +1736,11 @@
});
mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0);
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(3, mManager.getRemainingCallCount());
@@ -1760,7 +1767,8 @@
// Now, also try calling some APIs and make sure foreground apps don't get throttled.
mService.mUidObserver.onUidStateChanged(
UserHandle.getUid(USER_10, CALLING_UID_1),
- ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0);
+ ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(3, mManager.getRemainingCallCount());
assertFalse(mManager.isRateLimitingActive());
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 0196279..f08044c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -691,35 +691,16 @@
}
}
- private boolean shouldPackageRunOob(
- boolean isDefaultEnabled, String defaultWhitelist, String overrideEnabled,
- String overrideWhitelist, Collection<String> packageNamesInSameProcess) {
+ private boolean shouldPackageRunOob(boolean isDefaultEnabled, String whitelist,
+ Collection<String> packageNamesInSameProcess) {
return DexManager.isPackageSelectedToRunOobInternal(
- isDefaultEnabled, defaultWhitelist, overrideEnabled, overrideWhitelist,
- packageNamesInSameProcess);
+ isDefaultEnabled, whitelist, packageNamesInSameProcess);
}
@Test
- public void testOobPackageSelectionSwitch() {
+ public void testOobPackageSelectionDefault() {
// Feature is off by default, not overriden
- assertFalse(shouldPackageRunOob(false, "ALL", null, null, null));
-
- // Feature is off by default, overriden
- assertTrue(shouldPackageRunOob(false, "ALL", "true", "ALL", null));
- assertFalse(shouldPackageRunOob(false, "ALL", "false", null, null));
- assertFalse(shouldPackageRunOob(false, "ALL", "false", "ALL", null));
- assertFalse(shouldPackageRunOob(false, "ALL", "false", null, null));
-
- // Feature is on by default, not overriden
- assertTrue(shouldPackageRunOob(true, "ALL", null, null, null));
- assertTrue(shouldPackageRunOob(true, "ALL", null, null, null));
- assertTrue(shouldPackageRunOob(true, "ALL", null, "ALL", null));
-
- // Feature is on by default, overriden
- assertTrue(shouldPackageRunOob(true, "ALL", "true", null, null));
- assertTrue(shouldPackageRunOob(true, "ALL", "true", "ALL", null));
- assertFalse(shouldPackageRunOob(true, "ALL", "false", null, null));
- assertFalse(shouldPackageRunOob(true, "ALL", "false", "ALL", null));
+ assertFalse(shouldPackageRunOob(false, "ALL", null));
}
@Test
@@ -734,24 +715,19 @@
final Collection<String> runningPackages = Arrays.asList("com.priv.app1", "com.priv.app2");
// Feature is off, whitelist does not matter
- assertFalse(shouldPackageRunOob(false, kWhitelistApp0, null, null, runningPackages));
- assertFalse(shouldPackageRunOob(false, kWhitelistApp1, null, null, runningPackages));
- assertFalse(shouldPackageRunOob(false, "", null, kWhitelistApp1, runningPackages));
- assertFalse(shouldPackageRunOob(false, "", null, "ALL", runningPackages));
- assertFalse(shouldPackageRunOob(false, "ALL", null, "ALL", runningPackages));
- assertFalse(shouldPackageRunOob(false, "ALL", null, "", runningPackages));
+ assertFalse(shouldPackageRunOob(false, kWhitelistApp0, runningPackages));
+ assertFalse(shouldPackageRunOob(false, kWhitelistApp1, runningPackages));
+ assertFalse(shouldPackageRunOob(false, "", runningPackages));
+ assertFalse(shouldPackageRunOob(false, "ALL", runningPackages));
- // Feature is on, app not in default or overridden whitelist
- assertFalse(shouldPackageRunOob(true, kWhitelistApp0, null, null, runningPackages));
- assertFalse(shouldPackageRunOob(true, "", null, kWhitelistApp0, runningPackages));
- assertFalse(shouldPackageRunOob(true, "ALL", null, kWhitelistApp0, runningPackages));
+ // Feature is on, app not in whitelist
+ assertFalse(shouldPackageRunOob(true, kWhitelistApp0, runningPackages));
+ assertFalse(shouldPackageRunOob(true, "", runningPackages));
- // Feature is on, app in default or overridden whitelist
- assertTrue(shouldPackageRunOob(true, kWhitelistApp1, null, null, runningPackages));
- assertTrue(shouldPackageRunOob(true, kWhitelistApp2, null, null, runningPackages));
- assertTrue(shouldPackageRunOob(true, kWhitelistApp1AndApp2, null, null, runningPackages));
- assertTrue(shouldPackageRunOob(true, kWhitelistApp1, null, "ALL", runningPackages));
- assertTrue(shouldPackageRunOob(true, "", null, kWhitelistApp1, runningPackages));
- assertTrue(shouldPackageRunOob(true, "ALL", null, kWhitelistApp1, runningPackages));
+ // Feature is on, app in whitelist
+ assertTrue(shouldPackageRunOob(true, kWhitelistApp1, runningPackages));
+ assertTrue(shouldPackageRunOob(true, kWhitelistApp2, runningPackages));
+ assertTrue(shouldPackageRunOob(true, kWhitelistApp1AndApp2, runningPackages));
+ assertTrue(shouldPackageRunOob(true, "ALL", runningPackages));
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 03367db..7c867b6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -149,9 +149,7 @@
public void testOnActivityLaunchFinished() {
onActivityLaunched();
- mActivityMetricsLogger.notifyTransitionStarting(new SparseIntArray(),
- SystemClock.elapsedRealtimeNanos());
-
+ notifyTransitionStarting();
notifyWindowsDrawn(mTopActivity);
verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
@@ -159,10 +157,10 @@
}
@Test
- public void testOnActivityLaunchCancelled() {
+ public void testOnActivityLaunchCancelled_hasDrawn() {
onActivityLaunched();
- mTopActivity.mDrawn = true;
+ mTopActivity.visible = mTopActivity.mDrawn = true;
// Cannot time already-visible activities.
mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT, mTopActivity);
@@ -172,6 +170,28 @@
}
@Test
+ public void testOnActivityLaunchCancelled_finishedBeforeDrawn() {
+ mTopActivity.visible = mTopActivity.mDrawn = true;
+
+ // Suppress resume when creating the record because we want to notify logger manually.
+ mSupervisor.beginDeferResume();
+ // Create an activity with different process that meets process switch.
+ final ActivityRecord noDrawnActivity = new ActivityBuilder(mService)
+ .setTask(mTopActivity.getTaskRecord())
+ .setProcessName("other")
+ .build();
+ mSupervisor.readyToResume();
+
+ mActivityMetricsLogger.notifyActivityLaunching(noDrawnActivity.intent);
+ mActivityMetricsLogger.notifyActivityLaunched(START_SUCCESS, noDrawnActivity);
+
+ noDrawnActivity.destroyIfPossible("test");
+ mActivityMetricsLogger.notifyVisibilityChanged(noDrawnActivity);
+
+ verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(noDrawnActivity));
+ }
+
+ @Test
public void testOnReportFullyDrawn() {
onActivityLaunched();
@@ -184,16 +204,21 @@
private void onActivityLaunchedTrampoline() {
onIntentStarted();
- mActivityMetricsLogger.notifyActivityLaunched(START_SUCCESS, mTopActivity);
-
- verifyAsync(mLaunchObserver).onActivityLaunched(eqProto(mTopActivity), anyInt());
-
- // A second, distinct, activity launch is coalesced into the the current app launch sequence
mActivityMetricsLogger.notifyActivityLaunched(START_SUCCESS, mTrampolineActivity);
+ verifyAsync(mLaunchObserver).onActivityLaunched(eqProto(mTrampolineActivity), anyInt());
+
+ // A second, distinct, activity launch is coalesced into the current app launch sequence.
+ mActivityMetricsLogger.notifyActivityLaunched(START_SUCCESS, mTopActivity);
+
verifyNoMoreInteractions(mLaunchObserver);
}
+ private void notifyTransitionStarting() {
+ mActivityMetricsLogger.notifyTransitionStarting(new SparseIntArray(),
+ SystemClock.elapsedRealtimeNanos());
+ }
+
private void notifyWindowsDrawn(ActivityRecord r) {
mActivityMetricsLogger.notifyWindowsDrawn(r.getWindowingMode(),
SystemClock.elapsedRealtimeNanos());
@@ -203,15 +228,12 @@
public void testOnActivityLaunchFinishedTrampoline() {
onActivityLaunchedTrampoline();
- mActivityMetricsLogger.notifyTransitionStarting(new SparseIntArray(),
- SystemClock.elapsedRealtimeNanos());
-
+ notifyTransitionStarting();
notifyWindowsDrawn(mTrampolineActivity);
notifyWindowsDrawn(mTopActivity);
- verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTrampolineActivity),
- anyLong());
+ verifyAsync(mLaunchObserver).onActivityLaunchFinished(eqProto(mTopActivity), anyLong());
verifyNoMoreInteractions(mLaunchObserver);
}
@@ -219,12 +241,12 @@
public void testOnActivityLaunchCancelledTrampoline() {
onActivityLaunchedTrampoline();
- mTrampolineActivity.mDrawn = true;
+ mTopActivity.mDrawn = true;
// Cannot time already-visible activities.
- mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT, mTrampolineActivity);
+ mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT, mTopActivity);
- verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(mTrampolineActivity));
+ verifyAsync(mLaunchObserver).onActivityLaunchCancelled(eqProto(mTopActivity));
verifyNoMoreInteractions(mLaunchObserver);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 99ecdcb..38d6c9c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -836,6 +836,14 @@
// Set process to 'null' to allow immediate removal, but don't call mActivity.setProcess() -
// this will cause NPE when updating task's process.
mActivity.app = null;
+
+ // Put a visible activity on top, so the finishing activity doesn't have to wait until the
+ // next activity reports idle to destroy it.
+ final ActivityRecord topActivity = new ActivityBuilder(mService).setTask(mTask).build();
+ topActivity.visible = true;
+ topActivity.nowVisible = true;
+ topActivity.setState(RESUMED, "test");
+
assertEquals("Activity outside of task/stack cannot be finished", FINISH_RESULT_REMOVED,
mActivity.finishIfPossible("test", false /* oomAdj */));
assertTrue(mActivity.finishing);
@@ -1131,8 +1139,11 @@
// Add another stack to become focused and make the activity there visible. This way it
// simulates finishing in non-focused stack in split-screen.
final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
- stack.getChildAt(0).getChildAt(0).nowVisible = true;
- stack.getChildAt(0).getChildAt(0).visible = true;
+ final ActivityRecord focusedActivity = stack.getChildAt(0).getChildAt(0);
+ focusedActivity.nowVisible = true;
+ focusedActivity.visible = true;
+ focusedActivity.setState(RESUMED, "test");
+ stack.mResumedActivity = focusedActivity;
topActivity.completeFinishing("test");
@@ -1180,6 +1191,30 @@
}
/**
+ * Verify that complete finish request for visible activity must resume next home stack before
+ * destroying it immediately if it is the last running activity on a display with a home stack.
+ * We must wait for home activity to come up to avoid a black flash in this case.
+ */
+ @Test
+ public void testCompleteFinishing_lastActivityAboveEmptyHomeStack() {
+ // Empty the home stack.
+ final ActivityStack homeStack = mActivity.getDisplay().getHomeStack();
+ for (TaskRecord t : homeStack.getAllTasks()) {
+ homeStack.removeTask(t, "test", REMOVE_TASK_MODE_DESTROYING);
+ }
+ mActivity.finishing = true;
+ spyOn(mStack);
+
+ // Try to finish the last activity above the home stack.
+ mActivity.completeFinishing("test");
+
+ // Verify that the activity is not destroyed immediately, but waits for next one to come up.
+ verify(mActivity, never()).destroyImmediately(eq(true) /* removeFromApp */, anyString());
+ assertEquals(FINISHING, mActivity.getState());
+ assertTrue(mActivity.mStackSupervisor.mFinishingActivities.contains(mActivity));
+ }
+
+ /**
* Test that the activity will be moved to destroying state and the message to destroy will be
* sent to the client.
*/
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 80f0851..78db6c9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -118,7 +118,8 @@
private ComponentName mComponent;
private String mTargetActivity;
private TaskRecord mTaskRecord;
- private int mUid;
+ private String mProcessName = "name";
+ private int mUid = 12345;
private boolean mCreateTask;
private ActivityStack mStack;
private int mActivityFlags;
@@ -175,6 +176,11 @@
return this;
}
+ ActivityBuilder setProcessName(String name) {
+ mProcessName = name;
+ return this;
+ }
+
ActivityBuilder setUid(int uid) {
mUid = uid;
return this;
@@ -235,6 +241,7 @@
aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
aInfo.applicationInfo.packageName = mComponent.getPackageName();
aInfo.applicationInfo.uid = mUid;
+ aInfo.processName = mProcessName;
aInfo.packageName = mComponent.getPackageName();
if (mTargetActivity != null) {
aInfo.targetActivity = mTargetActivity;
@@ -268,7 +275,7 @@
}
final WindowProcessController wpc = new WindowProcessController(mService,
- mService.mContext.getApplicationInfo(), "name", 12345,
+ mService.mContext.getApplicationInfo(), mProcessName, mUid,
UserHandle.getUserId(12345), mock(Object.class),
mock(WindowProcessListener.class));
wpc.setThread(mock(IApplicationThread.class));
diff --git a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
index 77f9f04..b6eaab7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingActivityRegistryTest.java
@@ -21,6 +21,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -69,8 +70,8 @@
activity1.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */);
activity2.startAnimation(activity1.getPendingTransaction(), mAdapter, false /* hidden */);
- assertTrue(activity1.isSelfAnimating());
- assertTrue(activity2.isSelfAnimating());
+ assertTrue(activity1.isAnimating(TRANSITION));
+ assertTrue(activity2.isAnimating(TRANSITION));
// Make sure that first animation finish is deferred, second one is not deferred, and first
// one gets cancelled.
@@ -92,8 +93,8 @@
window1.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
window2.startAnimation(window1.getPendingTransaction(), mAdapter, false /* hidden */);
- assertTrue(window1.isSelfAnimating());
- assertTrue(window2.isSelfAnimating());
+ assertTrue(window1.isAnimating(TRANSITION));
+ assertTrue(window2.isAnimating(TRANSITION));
// Make sure that first animation finish is deferred, and removing the second window stops
// finishes all pending deferred finishings.
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
index 06afce2..5f42d23 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java
@@ -147,8 +147,8 @@
// Make sure each display is in animating stage.
assertTrue(dc1.mOpeningApps.size() > 0);
assertTrue(dc2.mClosingApps.size() > 0);
- assertTrue(dc1.isAppAnimating());
- assertTrue(dc2.isAppAnimating());
+ assertTrue(dc1.isAppTransitioning());
+ assertTrue(dc2.isAppTransitioning());
}
@Test
@@ -219,10 +219,10 @@
assertTrue(dc.mClosingApps.size() > 0);
// Make sure window is in animating stage before freeze, and cancel after freeze.
- assertTrue(dc.isAppAnimating());
+ assertTrue(dc.isAppTransitioning());
assertFalse(runner.mCancelled);
dc.mAppTransition.freeze();
- assertFalse(dc.isAppAnimating());
+ assertFalse(dc.isAppTransitioning());
assertTrue(runner.mCancelled);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
index 2fc03c7..164d28d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackTests.java
@@ -23,12 +23,13 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import android.graphics.Rect;
@@ -141,7 +142,7 @@
final Task task = createTaskInStack(stack, 0 /* userId */);
// Stack removal is deferred if one of its child is animating.
- doReturn(true).when(task).isSelfAnimating();
+ doReturn(true).when(task).isAnimating(TRANSITION | CHILDREN);
stack.removeIfPossible();
// For the case of deferred removal the task controller will still be connected to the its
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
index 85aff7f..8536448 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java
@@ -24,13 +24,18 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyFloat;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.never;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
+import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN;
+import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
+import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
@@ -335,7 +340,53 @@
}
@Test
- public void testIsAnimating() {
+ public void testIsAnimating_TransitionFlag() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
+ final TestWindowContainer root = builder.setLayer(0).build();
+ final TestWindowContainer child1 = root.addChildWindow(
+ builder.setWaitForTransitionStart(true));
+
+ assertFalse(root.isAnimating(TRANSITION));
+ assertTrue(child1.isAnimating(TRANSITION));
+ }
+
+ @Test
+ public void testIsAnimating_ParentsFlag() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
+ final TestWindowContainer root = builder.setLayer(0).build();
+ final TestWindowContainer child1 = root.addChildWindow(builder);
+ final TestWindowContainer child2 = root.addChildWindow(builder.setIsAnimating(true));
+ final TestWindowContainer child21 = child2.addChildWindow(builder.setIsAnimating(false));
+
+ assertFalse(root.isAnimating());
+ assertFalse(child1.isAnimating());
+ assertFalse(child1.isAnimating(PARENTS));
+ assertTrue(child2.isAnimating());
+ assertTrue(child2.isAnimating(PARENTS));
+ assertFalse(child21.isAnimating());
+ assertTrue(child21.isAnimating(PARENTS));
+ }
+
+ @Test
+ public void testIsAnimating_ChildrenFlag() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
+ final TestWindowContainer root = builder.setLayer(0).build();
+ final TestWindowContainer child1 = root.addChildWindow(builder);
+ final TestWindowContainer child2 = root.addChildWindow(builder.setIsAnimating(true));
+ final TestWindowContainer child11 = child1.addChildWindow(builder.setIsAnimating(true));
+
+ assertFalse(root.isAnimating());
+ assertTrue(root.isAnimating(CHILDREN));
+ assertFalse(child1.isAnimating());
+ assertTrue(child1.isAnimating(CHILDREN));
+ assertTrue(child2.isAnimating());
+ assertTrue(child2.isAnimating(CHILDREN));
+ assertTrue(child11.isAnimating());
+ assertTrue(child11.isAnimating(CHILDREN));
+ }
+
+ @Test
+ public void testIsAnimating_combineFlags() {
final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
@@ -345,19 +396,19 @@
final TestWindowContainer child12 = child1.addChildWindow(builder.setIsAnimating(true));
final TestWindowContainer child21 = child2.addChildWindow();
- assertFalse(root.isAnimating());
- assertTrue(child1.isAnimating());
- assertTrue(child11.isAnimating());
- assertTrue(child12.isAnimating());
- assertFalse(child2.isAnimating());
- assertFalse(child21.isAnimating());
+ assertFalse(root.isAnimating(TRANSITION | PARENTS));
+ assertTrue(child1.isAnimating(TRANSITION | PARENTS));
+ assertTrue(child11.isAnimating(TRANSITION | PARENTS));
+ assertTrue(child12.isAnimating(TRANSITION | PARENTS));
+ assertFalse(child2.isAnimating(TRANSITION | PARENTS));
+ assertFalse(child21.isAnimating(TRANSITION | PARENTS));
- assertTrue(root.isSelfOrChildAnimating());
- assertTrue(child1.isSelfOrChildAnimating());
- assertFalse(child11.isSelfOrChildAnimating());
- assertTrue(child12.isSelfOrChildAnimating());
- assertFalse(child2.isSelfOrChildAnimating());
- assertFalse(child21.isSelfOrChildAnimating());
+ assertTrue(root.isAnimating(TRANSITION | CHILDREN));
+ assertTrue(child1.isAnimating(TRANSITION | CHILDREN));
+ assertFalse(child11.isAnimating(TRANSITION | CHILDREN));
+ assertTrue(child12.isAnimating(TRANSITION | CHILDREN));
+ assertFalse(child2.isAnimating(TRANSITION | CHILDREN));
+ assertFalse(child21.isAnimating(TRANSITION | CHILDREN));
}
@Test
@@ -716,6 +767,7 @@
private boolean mIsAnimating;
private boolean mIsVisible;
private boolean mFillsParent;
+ private boolean mWaitForTransitStart;
private Integer mOrientation;
private boolean mOnParentChangedCalled;
@@ -738,7 +790,7 @@
};
TestWindowContainer(WindowManagerService wm, int layer, boolean isAnimating,
- boolean isVisible, Integer orientation) {
+ boolean isVisible, boolean waitTransitStart, Integer orientation) {
super(wm);
mLayer = layer;
@@ -746,6 +798,9 @@
mIsVisible = isVisible;
mFillsParent = true;
mOrientation = orientation;
+ mWaitForTransitStart = waitTransitStart;
+ spyOn(mSurfaceAnimator);
+ doReturn(mIsAnimating).when(mSurfaceAnimator).isAnimating();
}
TestWindowContainer getParentWindow() {
@@ -783,11 +838,6 @@
}
@Override
- boolean isSelfAnimating() {
- return mIsAnimating;
- }
-
- @Override
boolean isVisible() {
return mIsVisible;
}
@@ -810,6 +860,11 @@
void setFillsParent(boolean fillsParent) {
mFillsParent = fillsParent;
}
+
+ @Override
+ boolean isWaitingForTransitionStart() {
+ return mWaitForTransitStart;
+ }
}
private static class TestWindowContainerBuilder {
@@ -817,6 +872,7 @@
private int mLayer;
private boolean mIsAnimating;
private boolean mIsVisible;
+ private boolean mIsWaitTransitStart;
private Integer mOrientation;
TestWindowContainerBuilder(WindowManagerService wm) {
@@ -847,8 +903,14 @@
return this;
}
+ TestWindowContainerBuilder setWaitForTransitionStart(boolean waitTransitStart) {
+ mIsWaitTransitStart = waitTransitStart;
+ return this;
+ }
+
TestWindowContainer build() {
- return new TestWindowContainer(mWm, mLayer, mIsAnimating, mIsVisible, mOrientation);
+ return new TestWindowContainer(mWm, mLayer, mIsAnimating, mIsVisible,
+ mIsWaitTransitStart, mOrientation);
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 6a80568..f9b3659 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -400,7 +400,7 @@
private final IUidObserver mUidObserver = new IUidObserver.Stub() {
@Override
- public void onUidStateChanged(int uid, int procState, long procStateSeq) {
+ public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) {
mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget();
}
@@ -411,7 +411,8 @@
@Override
public void onUidGone(int uid, boolean disabled) {
- onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 0);
+ onUidStateChanged(uid, ActivityManager.PROCESS_STATE_NONEXISTENT, 0,
+ ActivityManager.PROCESS_CAPABILITY_NONE);
}
@Override
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index fa16b84..20abe77 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -858,7 +858,7 @@
}
/** @hide */
- public abstract static class Listener {
+ abstract static class Listener {
public void onStateChanged(Connection c, int state) {}
public void onAddressChanged(Connection c, Uri newAddress, int presentation) {}
public void onCallerDisplayNameChanged(
@@ -2006,7 +2006,7 @@
*
* @hide
*/
- public final Connection addConnectionListener(Listener l) {
+ final Connection addConnectionListener(Listener l) {
mListeners.add(l);
return this;
}
@@ -2019,7 +2019,7 @@
*
* @hide
*/
- public final Connection removeConnectionListener(Listener l) {
+ final Connection removeConnectionListener(Listener l) {
if (l != null) {
mListeners.remove(l);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7bab223..b564502 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1838,6 +1838,13 @@
"support_direct_fdn_dialing_bool";
/**
+ * Int indicating the max number length for FDN
+ * @hide
+ */
+ public static final String KEY_FDN_NUMBER_LENGTH_LIMIT_INT =
+ "fdn_number_length_limit_int";
+
+ /**
* Report IMEI as device id even if it's a CDMA/LTE phone.
*
* @hide
@@ -3434,6 +3441,7 @@
sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
+ sDefaults.putInt(KEY_FDN_NUMBER_LENGTH_LIMIT_INT, 20);
sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_ENHANCED_CALL_BLOCKING_BOOL, true);
diff --git a/telephony/java/android/telephony/CellBroadcastService.java b/telephony/java/android/telephony/CellBroadcastService.java
index 46eb9df..60281ad 100644
--- a/telephony/java/android/telephony/CellBroadcastService.java
+++ b/telephony/java/android/telephony/CellBroadcastService.java
@@ -17,12 +17,18 @@
package android.telephony;
import android.annotation.CallSuper;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
+import android.os.Bundle;
import android.os.IBinder;
+import android.os.RemoteCallback;
import android.telephony.cdma.CdmaSmsCbProgramData;
+import java.util.List;
+import java.util.function.Consumer;
+
/**
* A service which exposes the cell broadcast handling module to the system.
* <p>
@@ -46,6 +52,7 @@
* </service>
* </manifest>
* }</pre>
+ *
* @hide
*/
@SystemApi
@@ -62,21 +69,38 @@
/**
* Handle a GSM cell broadcast SMS message forwarded from the system.
+ *
* @param slotIndex the index of the slot which received the message
- * @param message the SMS PDU
+ * @param message the SMS PDU
*/
public abstract void onGsmCellBroadcastSms(int slotIndex, byte[] message);
/**
* Handle a CDMA cell broadcast SMS message forwarded from the system.
- * @param slotIndex the index of the slot which received the message
- * @param bearerData the CDMA SMS bearer data
+ *
+ * @param slotIndex the index of the slot which received the message
+ * @param bearerData the CDMA SMS bearer data
* @param serviceCategory the CDMA SCPT service category
*/
public abstract void onCdmaCellBroadcastSms(int slotIndex, byte[] bearerData,
@CdmaSmsCbProgramData.Category int serviceCategory);
/**
+ * Handle a CDMA cell broadcast SMS message forwarded from the system.
+ *
+ * @param slotIndex the index of the slot which received the message
+ * @param smsCbProgramData the SMS CB program data of the message
+ * @param originatingAddress the originating address of the message, as a non-separated dial
+ * string
+ * @param callback a callback to run after each cell broadcast receiver has handled
+ * the SCP message. The bundle will contain a non-separated
+ * dial string as and an ArrayList of {@link CdmaSmsCbProgramResults}.
+ */
+ public abstract void onCdmaScpMessage(int slotIndex,
+ @NonNull List<CdmaSmsCbProgramData> smsCbProgramData,
+ @NonNull String originatingAddress, @NonNull Consumer<Bundle> callback);
+
+ /**
* If overriding this method, call through to the super method for any unknown actions.
* {@inheritDoc}
*/
@@ -89,13 +113,15 @@
/**
* A wrapper around ICellBroadcastService that forwards calls to implementations of
* {@link CellBroadcastService}.
+ *
* @hide
*/
public class ICellBroadcastServiceWrapper extends ICellBroadcastService.Stub {
/**
* Handle a GSM cell broadcast SMS.
+ *
* @param slotIndex the index of the slot which received the broadcast
- * @param message the SMS message PDU
+ * @param message the SMS message PDU
*/
@Override
public void handleGsmCellBroadcastSms(int slotIndex, byte[] message) {
@@ -104,8 +130,9 @@
/**
* Handle a CDMA cell broadcast SMS.
- * @param slotIndex the index of the slot which received the broadcast
- * @param bearerData the CDMA SMS bearer data
+ *
+ * @param slotIndex the index of the slot which received the broadcast
+ * @param bearerData the CDMA SMS bearer data
* @param serviceCategory the CDMA SCPT service category
*/
@Override
@@ -114,5 +141,25 @@
CellBroadcastService.this.onCdmaCellBroadcastSms(slotIndex, bearerData,
serviceCategory);
}
+
+ /**
+ * Handle a CDMA Service Category Program message.
+ *
+ * @param slotIndex the index of the slot which received the message
+ * @param smsCbProgramData the SMS CB program data of the message
+ * @param originatingAddress the originating address of the message
+ * @param callback a callback to run after each cell broadcast receiver has
+ * handled the SCP message
+ */
+ @Override
+ public void handleCdmaScpMessage(int slotIndex,
+ List<CdmaSmsCbProgramData> smsCbProgramData, String originatingAddress,
+ RemoteCallback callback) {
+ Consumer<Bundle> consumer = bundle -> {
+ callback.sendResult(bundle);
+ };
+ CellBroadcastService.this.onCdmaScpMessage(slotIndex, smsCbProgramData,
+ originatingAddress, consumer);
+ }
}
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 1912c60..f9b7f6d 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -194,13 +194,13 @@
/** @hide */
@Override
public void updateLevel(PersistableBundle cc, ServiceState ss) {
- if (mCsiRsrp == CellInfo.UNAVAILABLE) {
+ if (mSsRsrp == CellInfo.UNAVAILABLE) {
mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- } else if (mCsiRsrp >= SIGNAL_GREAT_THRESHOLD) {
+ } else if (mSsRsrp >= SIGNAL_GREAT_THRESHOLD) {
mLevel = SIGNAL_STRENGTH_GREAT;
- } else if (mCsiRsrp >= SIGNAL_GOOD_THRESHOLD) {
+ } else if (mSsRsrp >= SIGNAL_GOOD_THRESHOLD) {
mLevel = SIGNAL_STRENGTH_GOOD;
- } else if (mCsiRsrp >= SIGNAL_MODERATE_THRESHOLD) {
+ } else if (mSsRsrp >= SIGNAL_MODERATE_THRESHOLD) {
mLevel = SIGNAL_STRENGTH_MODERATE;
} else {
mLevel = SIGNAL_STRENGTH_POOR;
@@ -212,7 +212,7 @@
*
* Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
*
- * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
+ * @return RSRP in ASU 0..97, 255, or UNAVAILABLE
*/
@Override
public int getAsuLevel() {
@@ -231,11 +231,11 @@
}
/**
- * Get the CSI-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}.
+ * Get the SS-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}.
*/
@Override
public int getDbm() {
- return mCsiRsrp;
+ return mSsRsrp;
}
/** @hide */
diff --git a/telephony/java/android/telephony/ICellBroadcastService.aidl b/telephony/java/android/telephony/ICellBroadcastService.aidl
index bcd6cc5..11263d9 100644
--- a/telephony/java/android/telephony/ICellBroadcastService.aidl
+++ b/telephony/java/android/telephony/ICellBroadcastService.aidl
@@ -16,6 +16,9 @@
package android.telephony;
+import android.os.RemoteCallback;
+import android.telephony.cdma.CdmaSmsCbProgramData;
+
/**
* Service bound to by the system to allow custom handling of cell broadcast messages.
* <p>
@@ -29,4 +32,8 @@
/** @see android.telephony.CellBroadcastService#onCdmaCellBroadcastSms */
oneway void handleCdmaCellBroadcastSms(int slotId, in byte[] bearerData, int serviceCategory);
+
+ /** @see android.telephony.CellBroadcastService#onCdmaScpMessage */
+ oneway void handleCdmaScpMessage(int slotId, in List<CdmaSmsCbProgramData> programData,
+ String originatingAddress, in RemoteCallback callback);
}
diff --git a/telephony/java/android/telephony/ImsiEncryptionInfo.java b/telephony/java/android/telephony/ImsiEncryptionInfo.java
index ef2f121..75a79d6 100644
--- a/telephony/java/android/telephony/ImsiEncryptionInfo.java
+++ b/telephony/java/android/telephony/ImsiEncryptionInfo.java
@@ -15,9 +15,11 @@
*/
package android.telephony;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import java.util.Date;
import android.util.Log;
import java.security.KeyFactory;
@@ -25,18 +27,18 @@
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
+import java.util.Date;
/**
* Class to represent information sent by the carrier, which will be used to encrypt
* the IMSI + IMPI. The ecryption is being done by WLAN, and the modem.
- *
* @hide
*/
+@SystemApi
public final class ImsiEncryptionInfo implements Parcelable {
private static final String LOG_TAG = "ImsiEncryptionInfo";
-
private final String mcc;
private final String mnc;
private final PublicKey publicKey;
@@ -45,11 +47,13 @@
//Date-Time in UTC when the key will expire.
private final Date expirationTime;
+ /** @hide */
public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
byte[] key, Date expirationTime) {
this(mcc, mnc, keyType, keyIdentifier, makeKeyObject(key), expirationTime);
}
+ /** @hide */
public ImsiEncryptionInfo(String mcc, String mnc, int keyType, String keyIdentifier,
PublicKey publicKey, Date expirationTime) {
// todo need to validate that ImsiEncryptionInfo is being created with the correct params.
@@ -63,6 +67,7 @@
this.expirationTime = expirationTime;
}
+ /** @hide */
public ImsiEncryptionInfo(Parcel in) {
int length = in.readInt();
byte b[] = new byte[length];
@@ -75,26 +80,40 @@
expirationTime = new Date(in.readLong());
}
+ /** @hide */
public String getMnc() {
return this.mnc;
}
+ /** @hide */
public String getMcc() {
return this.mcc;
}
+ /**
+ * Returns key identifier, a string that helps the authentication server to locate the
+ * private key to decrypt the permanent identity, or {@code null} when uavailable.
+ */
+ @Nullable
public String getKeyIdentifier() {
return this.keyIdentifier;
}
+ /** @hide */
public int getKeyType() {
return this.keyType;
}
+ /**
+ * Returns the carrier public key that is used for the IMSI encryption,
+ * or {@code null} when uavailable.
+ */
+ @Nullable
public PublicKey getPublicKey() {
return this.publicKey;
}
+ /** @hide */
public Date getExpirationTime() {
return this.expirationTime;
}
@@ -115,7 +134,7 @@
return 0;
}
- public static final @android.annotation.NonNull Parcelable.Creator<ImsiEncryptionInfo> CREATOR =
+ public static final @NonNull Parcelable.Creator<ImsiEncryptionInfo> CREATOR =
new Parcelable.Creator<ImsiEncryptionInfo>() {
@Override
public ImsiEncryptionInfo createFromParcel(Parcel in) {
@@ -129,7 +148,7 @@
};
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
byte[] b = publicKey.getEncoded();
dest.writeInt(b.length);
dest.writeByteArray(b);
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index ee291fa..2c16110 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -2669,4 +2669,74 @@
}
return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
}
+
+ /**
+ * Gets the SMSC address from (U)SIM.
+ *
+ * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
+ * default SMS application, or READ_PRIVILEGED_PHONE_STATE permission, or has the carrier
+ * privileges.</p>
+ *
+ * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
+ * dialog. If this method is called on a device that has multiple active subscriptions, this
+ * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
+ * default subscription is defined, the subscription ID associated with this method will be
+ * INVALID, which will result in the operation being completed on the subscription associated
+ * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
+ * is performed on the correct subscription.
+ * </p>
+ *
+ * @return the SMSC address string, null if failed.
+ */
+ @SuppressAutoDoc // for carrier privileges and default SMS application.
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @Nullable
+ public String getSmscAddress() {
+ String smsc = null;
+
+ try {
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ smsc = iSms.getSmscAddressFromIccEfForSubscriber(
+ getSubscriptionId(), ActivityThread.currentPackageName());
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+ return smsc;
+ }
+
+ /**
+ * Sets the SMSC address on (U)SIM.
+ *
+ * <p class="note"><strong>Note:</strong> Using this method requires that your app is the
+ * default SMS application, or has {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+ * permission, or has the carrier privileges.</p>
+ *
+ * <p class="note"><strong>Note:</strong> This method will never trigger an SMS disambiguation
+ * dialog. If this method is called on a device that has multiple active subscriptions, this
+ * {@link SmsManager} instance has been created with {@link #getDefault()}, and no user-defined
+ * default subscription is defined, the subscription ID associated with this method will be
+ * INVALID, which will result in the operation being completed on the subscription associated
+ * with logical slot 0. Use {@link #getSmsManagerForSubscriptionId(int)} to ensure the operation
+ * is performed on the correct subscription.
+ * </p>
+ *
+ * @param smsc the SMSC address string.
+ * @return true for success, false otherwise.
+ */
+ @SuppressAutoDoc // for carrier privileges and default SMS application.
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ public boolean setSmscAddress(@NonNull String smsc) {
+ try {
+ ISms iSms = getISmsService();
+ if (iSms != null) {
+ return iSms.setSmscAddressOnIccEfForSubscriber(
+ smsc, getSubscriptionId(), ActivityThread.currentPackageName());
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+ return false;
+ }
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 8425ec1..b5e91d0 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -49,7 +49,6 @@
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
-import android.os.Message;
import android.os.ParcelUuid;
import android.os.Process;
import android.os.RemoteException;
@@ -2053,13 +2052,13 @@
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
public static boolean isValidSlotIndex(int slotIndex) {
- return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSupportedModemCount();
+ return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getActiveModemCount();
}
/** @hide */
@UnsupportedAppUsage
public static boolean isValidPhoneId(int phoneId) {
- return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getSupportedModemCount();
+ return phoneId >= 0 && phoneId < TelephonyManager.getDefault().getActiveModemCount();
}
/** @hide */
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8455e3d..3c22a07 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -197,12 +197,29 @@
/** @hide */
static public final int OTASP_SIM_UNPROVISIONED = 5;
- /** @hide */
+ /**
+ * Used in carrier Wi-Fi for IMSI + IMPI encryption, this indicates a public key that's
+ * available for use in ePDG links.
+ *
+ * @hide
+ */
+ @SystemApi
static public final int KEY_TYPE_EPDG = 1;
- /** @hide */
+ /**
+ * Used in carrier Wi-Fi for IMSI + IMPI encryption, this indicates a public key that's
+ * available for use in WLAN links.
+ *
+ * @hide
+ */
+ @SystemApi
static public final int KEY_TYPE_WLAN = 2;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"KEY_TYPE_"}, value = {KEY_TYPE_EPDG, KEY_TYPE_WLAN})
+ public @interface KeyType {}
+
/**
* No Single Radio Voice Call Continuity (SRVCC) handover is active.
* See TS 23.216 for more information.
@@ -3874,25 +3891,27 @@
}
/**
- * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
- * This includes the public key and the key identifier. For multi-sim devices, if no subId
- * has been specified, we will return the value for the dafault data sim.
- * Return null if it is unavailable.
+ * Returns carrier specific information that will be used to encrypt the IMSI and IMPI,
+ * including the public key and the key identifier; or {@code null} if not available.
* <p>
- * Requires Permission:
- * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- * @param keyType whether the key is being used for wlan or epdg. Valid key types are
- * {@link TelephonyManager#KEY_TYPE_EPDG} or
- * {@link TelephonyManager#KEY_TYPE_WLAN}.
+ * For a multi-sim device, the dafault data sim is used if not specified.
+ * <p>
+ * Requires Permission: READ_PRIVILEGED_PHONE_STATE.
+ *
+ * @param keyType whether the key is being used for EPDG or WLAN. Valid values are
+ * {@link #KEY_TYPE_EPDG} or {@link #KEY_TYPE_WLAN}.
* @return ImsiEncryptionInfo Carrier specific information that will be used to encrypt the
* IMSI and IMPI. This includes the public key and the key identifier. This information
- * will be stored in the device keystore. The system will return a null when no key was
- * found, and the carrier does not require a key. The system will throw
- * IllegalArgumentException when an invalid key is sent or when key is required but
+ * will be stored in the device keystore. {@code null} will be returned when no key is
+ * found, and the carrier does not require a key.
+ * @throws IllegalArgumentException when an invalid key is found or when key is required but
* not found.
* @hide
*/
- public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType) {
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @SystemApi
+ @Nullable
+ public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(@KeyType int keyType) {
try {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null) {
@@ -3920,14 +3939,21 @@
}
/**
- * Resets the Carrier Keys in the database. This involves 2 steps:
+ * Resets the carrier keys used to encrypt the IMSI and IMPI.
+ * <p>
+ * This involves 2 steps:
* 1. Delete the keys from the database.
* 2. Send an intent to download new Certificates.
* <p>
- * Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
+ * For a multi-sim device, the dafault data sim is used if not specified.
+ * <p>
+ * Requires Permission: MODIFY_PHONE_STATE.
+ *
+ * @see #getCarrierInfoForImsiEncryption
* @hide
*/
+ @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ @SystemApi
public void resetCarrierKeysForImsiEncryption() {
try {
IPhoneSubInfo info = getSubscriberInfo();
@@ -3954,7 +3980,7 @@
* @return true if the digit at position keyType is 1, else false.
* @hide
*/
- private static boolean isKeyEnabled(int keyAvailability, int keyType) {
+ private static boolean isKeyEnabled(int keyAvailability, @KeyType int keyType) {
int returnValue = (keyAvailability >> (keyType - 1)) & 1;
return (returnValue == 1) ? true : false;
}
@@ -3963,7 +3989,7 @@
* If Carrier requires Imsi to be encrypted.
* @hide
*/
- private boolean isImsiEncryptionRequired(int subId, int keyType) {
+ private boolean isImsiEncryptionRequired(int subId, @KeyType int keyType) {
CarrierConfigManager configManager =
(CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
if (configManager == null) {
@@ -9498,16 +9524,28 @@
return returnValue;
}
- private int getSubIdForPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) {
+ /**
+ * Returns the subscription ID for the given phone account handle.
+ *
+ * @param phoneAccountHandle the phone account handle for outgoing calls
+ * @return subscription ID for the given phone account handle; or
+ * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}
+ * if not available; or throw a SecurityException if the caller doesn't have the
+ * permission.
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+ public int getSubIdForPhoneAccountHandle(@NonNull PhoneAccountHandle phoneAccountHandle) {
int retval = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
try {
- ITelecomService service = getTelecomService();
+ ITelephony service = getITelephony();
if (service != null) {
- retval = getSubIdForPhoneAccount(service.getPhoneAccount(phoneAccountHandle));
+ retval = service.getSubIdForPhoneAccountHandle(
+ phoneAccountHandle, mContext.getOpPackageName());
}
- } catch (RemoteException e) {
+ } catch (RemoteException ex) {
+ Log.e(TAG, "getSubIdForPhoneAccountHandle RemoteException", ex);
+ ex.rethrowAsRuntimeException();
}
-
return retval;
}
@@ -10876,6 +10914,16 @@
}
/**
+ * Broadcast intent action for Ota emergency number database installation complete.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ @SystemApi
+ public static final String ACTION_OTA_EMERGENCY_NUMBER_DB_INSTALLED =
+ "android.telephony.action.OTA_EMERGENCY_NUMBER_DB_INSTALLED";
+
+ /**
* Returns whether {@link TelephonyManager#ACTION_EMERGENCY_ASSISTANCE emergency assistance} is
* available on the device.
* <p>
diff --git a/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.aidl b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.aidl
new file mode 100644
index 0000000..a648a0e
--- /dev/null
+++ b/telephony/java/android/telephony/cdma/CdmaSmsCbProgramData.aidl
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+/** @hide */
+package android.telephony.cdma;
+
+parcelable CdmaSmsCbProgramData;
+
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index ed292be..7cafa1e 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -25,7 +25,6 @@
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
-import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -34,11 +33,9 @@
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
-import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.MmTelFeature;
import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IIntegerConsumer;
@@ -46,8 +43,6 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -63,7 +58,7 @@
* @hide
*/
@SystemApi
-public class ImsMmTelManager {
+public class ImsMmTelManager implements RegistrationManager {
/**
* @hide
@@ -96,94 +91,18 @@
* Callback class for receiving IMS network Registration callback events.
* @see #registerImsRegistrationCallback(Executor, RegistrationCallback) (RegistrationCallback)
* @see #unregisterImsRegistrationCallback(RegistrationCallback)
+ * @deprecated Use {@link RegistrationManager.RegistrationCallback} instead.
*/
- public static class RegistrationCallback {
-
- private static class RegistrationBinder extends IImsRegistrationCallback.Stub {
-
- // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN
- // and WWAN are more accurate constants.
- private static final Map<Integer, Integer> IMS_REG_TO_ACCESS_TYPE_MAP =
- new HashMap<Integer, Integer>() {{
- // Map NONE to -1 to make sure that we handle the REGISTRATION_TECH_NONE
- // case, since it is defined.
- put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE, -1);
- put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
- AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
- put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
- AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
- }};
-
- private final RegistrationCallback mLocalCallback;
- private Executor mExecutor;
-
- RegistrationBinder(RegistrationCallback localCallback) {
- mLocalCallback = localCallback;
- }
-
- @Override
- public void onRegistered(int imsRadioTech) {
- if (mLocalCallback == null) return;
-
- Binder.withCleanCallingIdentity(() -> mExecutor.execute(() ->
- mLocalCallback.onRegistered(getAccessType(imsRadioTech))));
- }
-
- @Override
- public void onRegistering(int imsRadioTech) {
- if (mLocalCallback == null) return;
-
- Binder.withCleanCallingIdentity(() -> mExecutor.execute(() ->
- mLocalCallback.onRegistering(getAccessType(imsRadioTech))));
- }
-
- @Override
- public void onDeregistered(ImsReasonInfo info) {
- if (mLocalCallback == null) return;
-
- Binder.withCleanCallingIdentity(() ->
- mExecutor.execute(() -> mLocalCallback.onUnregistered(info)));
- }
-
- @Override
- public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) {
- if (mLocalCallback == null) return;
-
- Binder.withCleanCallingIdentity(() ->
- mExecutor.execute(() -> mLocalCallback.onTechnologyChangeFailed(
- getAccessType(imsRadioTech), info)));
- }
-
- @Override
- public void onSubscriberAssociatedUriChanged(Uri[] uris) {
- if (mLocalCallback == null) return;
-
- Binder.withCleanCallingIdentity(() ->
- mExecutor.execute(() ->
- mLocalCallback.onSubscriberAssociatedUriChanged(uris)));
- }
-
- private void setExecutor(Executor executor) {
- mExecutor = executor;
- }
-
- private static int getAccessType(int regType) {
- if (!IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regType)) {
- Log.w("ImsMmTelManager", "RegistrationBinder - invalid regType returned: "
- + regType);
- return -1;
- }
- return IMS_REG_TO_ACCESS_TYPE_MAP.get(regType);
- }
- }
-
- private final RegistrationBinder mBinder = new RegistrationBinder(this);
+ // Do not add to this class, add to RegistrationManager.RegistrationCallback instead.
+ @Deprecated
+ public static class RegistrationCallback extends RegistrationManager.RegistrationCallback {
/**
* Notifies the framework when the IMS Provider is registered to the IMS network.
*
* @param imsTransportType the radio access technology.
*/
+ @Override
public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
}
@@ -192,6 +111,7 @@
*
* @param imsTransportType the radio access technology.
*/
+ @Override
public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
}
@@ -200,6 +120,7 @@
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
+ @Override
public void onUnregistered(@Nullable ImsReasonInfo info) {
}
@@ -209,33 +130,11 @@
* @param imsTransportType The transport type that has failed to handover registration to.
* @param info A {@link ImsReasonInfo} that identifies the reason for failure.
*/
+ @Override
public void onTechnologyChangeFailed(
@AccessNetworkConstants.TransportType int imsTransportType,
@Nullable ImsReasonInfo info) {
}
-
- /**
- * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
- * it changes. Per RFC3455, an associated URI is a URI that the service provider has
- * allocated to a user for their own usage. A user's phone number is typically one of the
- * associated URIs.
- * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
- * subscription.
- * @hide
- */
- public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
- }
-
- /**@hide*/
- public final IImsRegistrationCallback getBinder() {
- return mBinder;
- }
-
- /**@hide*/
- //Only exposed as public for compatibility with deprecated ImsManager APIs.
- public void setExecutor(Executor executor) {
- mBinder.setExecutor(executor);
- }
}
/**
@@ -355,7 +254,10 @@
* the {@link ImsService} associated with the subscription is not available. This can happen if
* the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
* reason.
+ * @deprecated Use {@link #registerImsRegistrationCallback(
+ * RegistrationManager.RegistrationCallback, Executor)} instead.
*/
+ @Deprecated
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull RegistrationCallback c) throws ImsException {
@@ -380,6 +282,28 @@
}
}
+ /**{@inheritDoc}*/
+ @Override
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void registerImsRegistrationCallback(
+ @NonNull RegistrationManager.RegistrationCallback c,
+ @NonNull @CallbackExecutor Executor executor) throws ImsException {
+ if (c == null) {
+ throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ c.setExecutor(executor);
+ try {
+ getITelephony().registerImsRegistrationCallback(mSubId, c.getBinder());
+ } catch (ServiceSpecificException e) {
+ throw new ImsException(e.getMessage(), e.errorCode);
+ } catch (RemoteException | IllegalStateException e) {
+ throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
+ }
+ }
+
/**
* Removes an existing {@link RegistrationCallback}.
*
@@ -390,7 +314,10 @@
* @param c The {@link RegistrationCallback} to be removed.
* @see SubscriptionManager.OnSubscriptionsChangedListener
* @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
+ * @deprecated Use {@link #unregisterImsRegistrationCallback(
+ * RegistrationManager.RegistrationCallback)}.
*/
+ @Deprecated
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c) {
if (c == null) {
@@ -403,6 +330,69 @@
}
}
+ /**{@inheritDoc}*/
+ @Override
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void unregisterImsRegistrationCallback(
+ @NonNull RegistrationManager.RegistrationCallback c) {
+ if (c == null) {
+ throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+ }
+ try {
+ getITelephony().unregisterImsRegistrationCallback(mSubId, c.getBinder());
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**{@inheritDoc}*/
+ @Override
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void getRegistrationState(@NonNull @ImsRegistrationState Consumer<Integer> stateCallback,
+ @NonNull @CallbackExecutor Executor executor) {
+ if (stateCallback == null) {
+ throw new IllegalArgumentException("Must include a non-null callback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ try {
+ getITelephony().getImsMmTelRegistrationState(mSubId, new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> stateCallback.accept(result));
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
+ /**{@inheritDoc}*/
+ @Override
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public void getRegistrationTransportType(
+ @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback,
+ @NonNull @CallbackExecutor Executor executor) {
+ if (transportTypeCallback == null) {
+ throw new IllegalArgumentException("Must include a non-null callback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ try {
+ getITelephony().getImsMmTelRegistrationTransportType(mSubId,
+ new IIntegerConsumer.Stub() {
+ @Override
+ public void accept(int result) {
+ executor.execute(() -> transportTypeCallback.accept(result));
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowAsRuntimeException();
+ }
+ }
+
/**
* Registers a {@link CapabilityCallback} with the system, which will provide MmTel service
* availability updates for the subscription specified in
@@ -411,7 +401,7 @@
*
* Use {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to
* subscription changed events and call
- * {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up.
+ * {@link #unregisterMmTelCapabilityCallback(CapabilityCallback)} to clean up.
*
* When the callback is registered, it will initiate the callback c to be called with the
* current capabilities.
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 3c343dd..25bd1ca 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -22,12 +22,14 @@
import android.annotation.RequiresPermission;
import android.content.Context;
import android.os.Binder;
+import android.telephony.AccessNetworkConstants;
import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
import android.telephony.ims.feature.ImsFeature;
import android.telephony.ims.feature.RcsFeature;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
/**
* Manager for interfacing with the framework RCS services, including the User Capability Exchange
@@ -36,7 +38,7 @@
* Use {@link #createForSubscriptionId(Context, int)} to create an instance of this manager.
* @hide
*/
-public class ImsRcsManager {
+public class ImsRcsManager implements RegistrationManager {
/**
* Receives RCS availability status updates from the ImsService.
@@ -136,6 +138,64 @@
mSubId = subId;
}
+ /**{@inheritDoc}*/
+ @Override
+ public void registerImsRegistrationCallback(
+ @NonNull RegistrationManager.RegistrationCallback c,
+ @NonNull @CallbackExecutor Executor executor)
+ throws ImsException {
+ if (c == null) {
+ throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ c.setExecutor(executor);
+ throw new UnsupportedOperationException("registerImsRegistrationCallback is not"
+ + "supported.");
+ }
+
+ /**{@inheritDoc}*/
+ @Override
+ public void unregisterImsRegistrationCallback(
+ @NonNull RegistrationManager.RegistrationCallback c) {
+ if (c == null) {
+ throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
+ }
+ throw new UnsupportedOperationException("unregisterImsRegistrationCallback is not"
+ + "supported.");
+ }
+
+ /**{@inheritDoc}*/
+ @Override
+ public void getRegistrationState(@NonNull @ImsRegistrationState Consumer<Integer> stateCallback,
+ @NonNull @CallbackExecutor Executor executor) {
+ if (stateCallback == null) {
+ throw new IllegalArgumentException("Must include a non-null stateCallback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ throw new UnsupportedOperationException("getRegistrationState is not"
+ + "supported.");
+ }
+
+ /**{@inheritDoc}*/
+ @Override
+ public void getRegistrationTransportType(
+ @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback,
+ @NonNull @CallbackExecutor Executor executor) {
+ if (transportTypeCallback == null) {
+ throw new IllegalArgumentException("Must include a non-null transportTypeCallback.");
+ }
+ if (executor == null) {
+ throw new IllegalArgumentException("Must include a non-null Executor.");
+ }
+ throw new UnsupportedOperationException("getRegistrationTransportType is not"
+ + "supported.");
+ }
+
+
/**
* Registers an {@link AvailabilityCallback} with the system, which will provide RCS
* availability updates for the subscription specified.
diff --git a/telephony/java/android/telephony/ims/RegistrationManager.java b/telephony/java/android/telephony/ims/RegistrationManager.java
new file mode 100644
index 0000000..b4c11e3
--- /dev/null
+++ b/telephony/java/android/telephony/ims/RegistrationManager.java
@@ -0,0 +1,285 @@
+/*
+ * 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.telephony.ims;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.net.Uri;
+import android.os.Binder;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.ims.aidl.IImsRegistrationCallback;
+import android.telephony.ims.feature.ImsFeature;
+import android.telephony.ims.stub.ImsRegistrationImplBase;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Manages IMS Service registration state for associated {@link ImsFeature}s.
+ * @hide
+ */
+@SystemApi
+public interface RegistrationManager {
+
+ /**
+ * @hide
+ */
+ // Defines the underlying radio technology type that we have registered for IMS over.
+ @IntDef(prefix = "REGISTRATION_STATE_",
+ value = {
+ REGISTRATION_STATE_NOT_REGISTERED,
+ REGISTRATION_STATE_REGISTERING,
+ REGISTRATION_STATE_REGISTERED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ImsRegistrationState {}
+
+ /**
+ * The IMS service is currently not registered to the carrier network.
+ */
+ int REGISTRATION_STATE_NOT_REGISTERED = 0;
+
+ /**
+ * The IMS service is currently in the process of registering to the carrier network.
+ */
+ int REGISTRATION_STATE_REGISTERING = 1;
+
+ /**
+ * The IMS service is currently registered to the carrier network.
+ */
+ int REGISTRATION_STATE_REGISTERED = 2;
+
+
+ /**@hide*/
+ // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN
+ // and WWAN are more accurate constants.
+ Map<Integer, Integer> IMS_REG_TO_ACCESS_TYPE_MAP =
+ new HashMap<Integer, Integer>() {{
+ // Map NONE to -1 to make sure that we handle the REGISTRATION_TECH_NONE
+ // case, since it is defined.
+ put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE, -1);
+ put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
+ AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+ put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
+ AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+ }};
+
+ /**
+ * Callback class for receiving IMS network Registration callback events.
+ * @see #registerImsRegistrationCallback(RegistrationCallback, Executor)
+ * @see #unregisterImsRegistrationCallback(RegistrationCallback)
+ */
+ class RegistrationCallback {
+
+ private static class RegistrationBinder extends IImsRegistrationCallback.Stub {
+
+ private final RegistrationCallback mLocalCallback;
+ private Executor mExecutor;
+
+ RegistrationBinder(RegistrationCallback localCallback) {
+ mLocalCallback = localCallback;
+ }
+
+ @Override
+ public void onRegistered(int imsRadioTech) {
+ if (mLocalCallback == null) return;
+
+ Binder.withCleanCallingIdentity(() -> mExecutor.execute(() ->
+ mLocalCallback.onRegistered(getAccessType(imsRadioTech))));
+ }
+
+ @Override
+ public void onRegistering(int imsRadioTech) {
+ if (mLocalCallback == null) return;
+
+ Binder.withCleanCallingIdentity(() -> mExecutor.execute(() ->
+ mLocalCallback.onRegistering(getAccessType(imsRadioTech))));
+ }
+
+ @Override
+ public void onDeregistered(ImsReasonInfo info) {
+ if (mLocalCallback == null) return;
+
+ Binder.withCleanCallingIdentity(() ->
+ mExecutor.execute(() -> mLocalCallback.onUnregistered(info)));
+ }
+
+ @Override
+ public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) {
+ if (mLocalCallback == null) return;
+
+ Binder.withCleanCallingIdentity(() ->
+ mExecutor.execute(() -> mLocalCallback.onTechnologyChangeFailed(
+ getAccessType(imsRadioTech), info)));
+ }
+
+ @Override
+ public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+ if (mLocalCallback == null) return;
+
+ Binder.withCleanCallingIdentity(() ->
+ mExecutor.execute(() ->
+ mLocalCallback.onSubscriberAssociatedUriChanged(uris)));
+ }
+
+ private void setExecutor(Executor executor) {
+ mExecutor = executor;
+ }
+
+ private static int getAccessType(int regType) {
+ if (!RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regType)) {
+ Log.w("RegistrationManager", "RegistrationBinder - invalid regType returned: "
+ + regType);
+ return -1;
+ }
+ return RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(regType);
+ }
+ }
+
+ private final RegistrationBinder mBinder = new RegistrationBinder(this);
+
+ /**
+ * Notifies the framework when the IMS Provider is registered to the IMS network.
+ *
+ * @param imsTransportType the radio access technology.
+ */
+ public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
+ }
+
+ /**
+ * Notifies the framework when the IMS Provider is trying to register the IMS network.
+ *
+ * @param imsTransportType the radio access technology.
+ */
+ public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
+ }
+
+ /**
+ * Notifies the framework when the IMS Provider is deregistered from the IMS network.
+ *
+ * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
+ */
+ public void onUnregistered(@Nullable ImsReasonInfo info) {
+ }
+
+ /**
+ * A failure has occurred when trying to handover registration to another technology type.
+ *
+ * @param imsTransportType The transport type that has failed to handover registration to.
+ * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
+ */
+ public void onTechnologyChangeFailed(
+ @AccessNetworkConstants.TransportType int imsTransportType,
+ @Nullable ImsReasonInfo info) {
+ }
+
+ /**
+ * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
+ * it changes. Per RFC3455, an associated URI is a URI that the service provider has
+ * allocated to a user for their own usage. A user's phone number is typically one of the
+ * associated URIs.
+ * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
+ * subscription.
+ * @hide
+ */
+ public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
+ }
+
+ /**@hide*/
+ public final IImsRegistrationCallback getBinder() {
+ return mBinder;
+ }
+
+ /**@hide*/
+ //Only exposed as public for compatibility with deprecated ImsManager APIs.
+ public void setExecutor(Executor executor) {
+ mBinder.setExecutor(executor);
+ }
+ }
+
+ /**
+ * Registers a {@link RegistrationCallback} with the system. Use
+ * {@link SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
+ * events and call {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up.
+ *
+ * When the callback is registered, it will initiate the callback c to be called with the
+ * current registration state.
+ *
+ * @param c The {@link RegistrationCallback} to be added.
+ * @param executor The executor the callback events should be run on.
+ * @see #unregisterImsRegistrationCallback(RegistrationCallback)
+ * @throws ImsException if the subscription associated with this callback is valid, but
+ * the {@link ImsService} associated with the subscription is not available. This can happen if
+ * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
+ * reason.
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ void registerImsRegistrationCallback(@NonNull RegistrationCallback c,
+ @NonNull @CallbackExecutor Executor executor) throws ImsException;
+
+ /**
+ * Removes an existing {@link RegistrationCallback}.
+ *
+ * When the subscription associated with this callback is removed (SIM removed, ESIM swap,
+ * etc...), this callback will automatically be removed. If this method is called for an
+ * inactive subscription, it will result in a no-op.
+ *
+ * @param c The {@link RegistrationCallback} to be removed.
+ * @see SubscriptionManager.OnSubscriptionsChangedListener
+ * @see #registerImsRegistrationCallback(RegistrationCallback, Executor)
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c);
+
+ /**
+ * Gets the registration state of the IMS service.
+ * @param stateCallback A callback called on the supplied {@link Executor} that will contain the
+ * registration state of the IMS service, which will be one of the
+ * following: {@link #REGISTRATION_STATE_NOT_REGISTERED},
+ * {@link #REGISTRATION_STATE_REGISTERING}, or
+ * {@link #REGISTRATION_STATE_REGISTERED}.
+ * @param executor The {@link Executor} that will be used to call the IMS registration state
+ * callback.
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ void getRegistrationState(@NonNull @ImsRegistrationState Consumer<Integer> stateCallback,
+ @NonNull @CallbackExecutor Executor executor);
+
+ /**
+ * Gets the Transport Type associated with the current IMS registration.
+ * @param transportTypeCallback The transport type associated with the current IMS registration,
+ * which will be one of following:
+ * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN},
+ * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, or
+ * {@link AccessNetworkConstants#TRANSPORT_TYPE_INVALID}.
+ * @param executor The {@link Executor} that will be used to call the transportTypeCallback.
+ */
+ @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ void getRegistrationTransportType(
+ @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback,
+ @NonNull @CallbackExecutor Executor executor);
+}
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index a08e031..b455c2e 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -22,6 +22,7 @@
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.telephony.ims.ImsReasonInfo;
+import android.telephony.ims.RegistrationManager;
import android.telephony.ims.aidl.IImsRegistration;
import android.telephony.ims.aidl.IImsRegistrationCallback;
import android.util.Log;
@@ -72,9 +73,6 @@
// with NOT_REGISTERED in the case where the ImsService has not updated the registration state
// yet.
private static final int REGISTRATION_STATE_UNKNOWN = -1;
- private static final int REGISTRATION_STATE_NOT_REGISTERED = 0;
- private static final int REGISTRATION_STATE_REGISTERING = 1;
- private static final int REGISTRATION_STATE_REGISTERED = 2;
private final IImsRegistration mBinder = new IImsRegistration.Stub() {
@@ -128,7 +126,7 @@
* {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}.
*/
public final void onRegistered(@ImsRegistrationTech int imsRadioTech) {
- updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERED);
+ updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERED);
mCallbacks.broadcast((c) -> {
try {
c.onRegistered(imsRadioTech);
@@ -146,7 +144,7 @@
* {@link #REGISTRATION_TECH_LTE} and {@link #REGISTRATION_TECH_IWLAN}.
*/
public final void onRegistering(@ImsRegistrationTech int imsRadioTech) {
- updateToState(imsRadioTech, REGISTRATION_STATE_REGISTERING);
+ updateToState(imsRadioTech, RegistrationManager.REGISTRATION_STATE_REGISTERING);
mCallbacks.broadcast((c) -> {
try {
c.onRegistering(imsRadioTech);
@@ -230,7 +228,8 @@
private void updateToDisconnectedState(ImsReasonInfo info) {
synchronized (mLock) {
- updateToState(REGISTRATION_TECH_NONE, REGISTRATION_STATE_NOT_REGISTERED);
+ updateToState(REGISTRATION_TECH_NONE,
+ RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED);
if (info != null) {
mLastDisconnectCause = info;
} else {
@@ -264,15 +263,15 @@
disconnectInfo = mLastDisconnectCause;
}
switch (state) {
- case REGISTRATION_STATE_NOT_REGISTERED: {
+ case RegistrationManager.REGISTRATION_STATE_NOT_REGISTERED: {
c.onDeregistered(disconnectInfo);
break;
}
- case REGISTRATION_STATE_REGISTERING: {
+ case RegistrationManager.REGISTRATION_STATE_REGISTERING: {
c.onRegistering(getConnectionType());
break;
}
- case REGISTRATION_STATE_REGISTERED: {
+ case RegistrationManager.REGISTRATION_STATE_REGISTERED: {
c.onRegistered(getConnectionType());
break;
}
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index f3a335d..91aa3ce 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -574,4 +574,23 @@
* @param destAddress the destination address to test for possible short code
*/
int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso);
+
+ /**
+ * Gets the SMSC address from (U)SIM.
+ *
+ * @param subId the subscription Id.
+ * @param callingPackage the package name of the calling app.
+ * @return the SMSC address string, null if failed.
+ */
+ String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage);
+
+ /**
+ * Sets the SMSC address on (U)SIM.
+ *
+ * @param smsc the SMSC address string.
+ * @param subId the subscription Id.
+ * @param callingPackage the package name of the calling app.
+ * @return true for success, false otherwise.
+ */
+ boolean setSmscAddressOnIccEfForSubscriber(String smsc, int subId, String callingPackage);
}
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index 2096325..d9d4b60 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -201,4 +201,15 @@
int subid, String callingApk, String destAddress, String countryIso) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean setSmscAddressOnIccEfForSubscriber(
+ String smsc, int subId, String callingPackage) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index b2f9add..3163102 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1313,6 +1313,12 @@
int getSubIdForPhoneAccount(in PhoneAccount phoneAccount);
/**
+ * Returns the subscription ID associated with the specified PhoneAccountHandle.
+ */
+ int getSubIdForPhoneAccountHandle(in PhoneAccountHandle phoneAccountHandle,
+ String callingPackage);
+
+ /**
* Returns the PhoneAccountHandle associated with a subscription ID.
*/
PhoneAccountHandle getPhoneAccountHandleForSubscriptionId(int subscriptionId);
@@ -1800,6 +1806,16 @@
void unregisterImsRegistrationCallback(int subId, IImsRegistrationCallback c);
/**
+ * Get the IMS service registration state for the MmTelFeature associated with this sub id.
+ */
+ void getImsMmTelRegistrationState(int subId, IIntegerConsumer consumer);
+
+ /**
+ * Get the transport type for the IMS service registration state.
+ */
+ void getImsMmTelRegistrationTransportType(int subId, IIntegerConsumer consumer);
+
+ /**
* Adds an IMS MmTel capabilities callback for the subscription specified.
*/
void registerMmTelCapabilityCallback(int subId, IImsCapabilityCallback c);
diff --git a/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
index 81937e6..ead4a28 100644
--- a/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
+++ b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
@@ -94,6 +94,8 @@
boolean sawServices = false;
for (String line : res.split("\n")) {
if (line.contains("framework.jar")) {
+ sawFramework = true; // Legacy
+ } else if (line.contains("framework-minus-apex.jar")) {
sawFramework = true;
} else if (line.contains("services.jar")) {
sawServices = true;
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index c10169b..e3d9c35 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -24,8 +24,7 @@
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import org.junit.After;
-import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -50,20 +49,6 @@
phase));
}
- @Before
- public void setUp() throws Exception {
- // Disconnect internet so we can test network health triggered rollbacks
- getDevice().executeShellCommand("svc wifi disable");
- getDevice().executeShellCommand("svc data disable");
- }
-
- @After
- public void tearDown() throws Exception {
- // Reconnect internet after testing network health triggered rollbacks
- getDevice().executeShellCommand("svc wifi enable");
- getDevice().executeShellCommand("svc data enable");
- }
-
/**
* Tests watchdog triggered staged rollbacks involving only apks.
*/
@@ -121,6 +106,10 @@
*/
@Test
public void testNetworkFailedRollback() throws Exception {
+ // Disconnect internet so we can test network health triggered rollbacks
+ getDevice().executeShellCommand("svc wifi disable");
+ getDevice().executeShellCommand("svc data disable");
+
// Remove available rollbacks and uninstall NetworkStack on /data/
runPhase("testNetworkFailedRollback_Phase1");
// Reduce health check deadline
@@ -148,6 +137,7 @@
* Tests passed network health check does not trigger watchdog staged rollbacks.
*/
@Test
+ @Ignore("b/143514090")
public void testNetworkPassedDoesNotRollback() throws Exception {
// Remove available rollbacks and uninstall NetworkStack on /data/
runPhase("testNetworkPassedDoesNotRollback_Phase1");
diff --git a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
index 629f720..99a26dc 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ProtoLogTool.kt
@@ -24,6 +24,7 @@
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
+import java.io.OutputStream
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.jar.JarOutputStream
@@ -42,9 +43,10 @@
}
private fun processClasses(command: CommandOptions) {
- val groups = ProtoLogGroupReader()
- .loadFromJar(command.protoLogGroupsJarArg, command.protoLogGroupsClassNameArg)
- val out = FileOutputStream(command.outputSourceJarArg)
+ val groups = injector.readLogGroups(
+ command.protoLogGroupsJarArg,
+ command.protoLogGroupsClassNameArg)
+ val out = injector.fileOutputStream(command.outputSourceJarArg)
val outJar = JarOutputStream(out)
val processor = ProtoLogCallProcessor(command.protoLogClassNameArg,
command.protoLogGroupsClassNameArg, groups)
@@ -56,18 +58,18 @@
val transformer = SourceTransformer(command.protoLogImplClassNameArg,
command.protoLogCacheClassNameArg, processor)
val file = File(path)
- val text = file.readText()
+ val text = injector.readText(file)
val outSrc = try {
val code = tryParse(text, path)
if (containsProtoLogText(text, command.protoLogClassNameArg)) {
- transformer.processClass(text, path, code)
+ transformer.processClass(text, path, packagePath(file, code), code)
} else {
text
}
} catch (ex: ParsingException) {
// If we cannot parse this file, skip it (and log why). Compilation will fail
// in a subsequent build step.
- println("\n${ex.message}\n")
+ injector.reportParseError(ex)
text
}
path to outSrc
@@ -142,8 +144,9 @@
}
private fun viewerConf(command: CommandOptions) {
- val groups = ProtoLogGroupReader()
- .loadFromJar(command.protoLogGroupsJarArg, command.protoLogGroupsClassNameArg)
+ val groups = injector.readLogGroups(
+ command.protoLogGroupsJarArg,
+ command.protoLogGroupsClassNameArg)
val processor = ProtoLogCallProcessor(command.protoLogClassNameArg,
command.protoLogGroupsClassNameArg, groups)
val builder = ViewerConfigBuilder(processor)
@@ -153,18 +156,15 @@
command.javaSourceArgs.map { path ->
executor.submitCallable {
val file = File(path)
- val text = file.readText()
+ val text = injector.readText(file)
if (containsProtoLogText(text, command.protoLogClassNameArg)) {
try {
val code = tryParse(text, path)
- val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
- .get().nameAsString else ""
- val newPath = pack.replace('.', '/') + '/' + file.name
- builder.findLogCalls(code, newPath)
+ builder.findLogCalls(code, path, packagePath(file, code))
} catch (ex: ParsingException) {
// If we cannot parse this file, skip it (and log why). Compilation will fail
// in a subsequent build step.
- println("\n${ex.message}\n")
+ injector.reportParseError(ex)
null
}
} else {
@@ -177,11 +177,18 @@
executor.shutdown()
- val out = FileOutputStream(command.viewerConfigJsonArg)
+ val out = injector.fileOutputStream(command.viewerConfigJsonArg)
out.write(builder.build().toByteArray())
out.close()
}
+ private fun packagePath(file: File, code: CompilationUnit): String {
+ val pack = if (code.packageDeclaration.isPresent) code.packageDeclaration
+ .get().nameAsString else ""
+ val packagePath = pack.replace('.', '/') + '/' + file.name
+ return packagePath
+ }
+
private fun read(command: CommandOptions) {
LogParser(ViewerConfigParser())
.parse(FileInputStream(command.logProtofileArg),
@@ -190,18 +197,9 @@
@JvmStatic
fun main(args: Array<String>) {
- StaticJavaParser.setConfiguration(ParserConfiguration().apply {
- setLanguageLevel(ParserConfiguration.LanguageLevel.RAW)
- setAttributeComments(false)
- })
-
try {
val command = CommandOptions(args)
- when (command.command) {
- CommandOptions.TRANSFORM_CALLS_CMD -> processClasses(command)
- CommandOptions.GENERATE_CONFIG_CMD -> viewerConf(command)
- CommandOptions.READ_LOG_CMD -> read(command)
- }
+ invoke(command)
} catch (ex: InvalidCommandException) {
println("\n${ex.message}\n")
showHelpAndExit()
@@ -210,6 +208,36 @@
exitProcess(1)
}
}
+
+ fun invoke(command: CommandOptions) {
+ StaticJavaParser.setConfiguration(ParserConfiguration().apply {
+ setLanguageLevel(ParserConfiguration.LanguageLevel.RAW)
+ setAttributeComments(false)
+ })
+
+ when (command.command) {
+ CommandOptions.TRANSFORM_CALLS_CMD -> processClasses(command)
+ CommandOptions.GENERATE_CONFIG_CMD -> viewerConf(command)
+ CommandOptions.READ_LOG_CMD -> read(command)
+ }
+ }
+
+ var injector = object : Injector {
+ override fun fileOutputStream(file: String) = FileOutputStream(file)
+ override fun readText(file: File) = file.readText()
+ override fun readLogGroups(jarPath: String, className: String) =
+ ProtoLogGroupReader().loadFromJar(jarPath, className)
+ override fun reportParseError(ex: ParsingException) {
+ println("\n${ex.message}\n")
+ }
+ }
+
+ interface Injector {
+ fun fileOutputStream(file: String): OutputStream
+ fun readText(file: File): String
+ fun readLogGroups(jarPath: String, className: String): Map<String, LogGroup>
+ fun reportParseError(ex: ParsingException)
+ }
}
private fun <T> ExecutorService.submitCallable(f: () -> T) = submit(f)
diff --git a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
index 0ad8091..36ea411 100644
--- a/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/SourceTransformer.kt
@@ -72,7 +72,7 @@
}
val ifStmt: IfStmt
if (group.enabled) {
- val hash = CodeUtils.hash(fileName, messageString, level, group)
+ val hash = CodeUtils.hash(packagePath, messageString, level, group)
val newCall = call.clone()
if (!group.textEnabled) {
// Remove message string if text logging is not enabled by default.
@@ -97,7 +97,7 @@
if (argTypes.size != call.arguments.size - 2) {
throw InvalidProtoLogCallException(
"Number of arguments (${argTypes.size} does not mach format" +
- " string in: $call", ParsingContext(fileName, call))
+ " string in: $call", ParsingContext(path, call))
}
val blockStmt = BlockStmt()
if (argTypes.isNotEmpty()) {
@@ -214,18 +214,23 @@
StaticJavaParser.parseExpression<FieldAccessExpr>(protoLogCacheClassName)
private var processedCode: MutableList<String> = mutableListOf()
private var offsets: IntArray = IntArray(0)
- private var fileName: String = ""
+ /** The path of the file being processed, relative to $ANDROID_BUILD_TOP */
+ private var path: String = ""
+ /** The path of the file being processed, relative to the root package */
+ private var packagePath: String = ""
fun processClass(
code: String,
path: String,
+ packagePath: String,
compilationUnit: CompilationUnit =
StaticJavaParser.parse(code)
): String {
- fileName = path
+ this.path = path
+ this.packagePath = packagePath
processedCode = code.split('\n').toMutableList()
offsets = IntArray(processedCode.size)
- protoLogCallProcessor.process(compilationUnit, this, fileName)
+ protoLogCallProcessor.process(compilationUnit, this, path)
return processedCode.joinToString("\n")
}
}
diff --git a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt
index c100826..175c71f 100644
--- a/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt
+++ b/tools/protologtool/src/com/android/protolog/tool/ViewerConfigBuilder.kt
@@ -46,7 +46,11 @@
private val statements: MutableMap<Int, LogCall> = mutableMapOf()
private val groups: MutableSet<LogGroup> = mutableSetOf()
- fun findLogCalls(unit: CompilationUnit, fileName: String): List<Pair<LogCall, ParsingContext>> {
+ fun findLogCalls(
+ unit: CompilationUnit,
+ path: String,
+ packagePath: String
+ ): List<Pair<LogCall, ParsingContext>> {
val calls = mutableListOf<Pair<LogCall, ParsingContext>>()
val visitor = object : ProtoLogCallVisitor {
override fun processCall(
@@ -55,12 +59,12 @@
level: LogLevel,
group: LogGroup
) {
- val logCall = LogCall(messageString, level, group, fileName)
- val context = ParsingContext(fileName, call)
+ val logCall = LogCall(messageString, level, group, packagePath)
+ val context = ParsingContext(path, call)
calls.add(logCall to context)
}
}
- processor.process(unit, visitor, fileName)
+ processor.process(unit, visitor, path)
return calls
}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
new file mode 100644
index 0000000..dd8a0b1
--- /dev/null
+++ b/tools/protologtool/tests/com/android/protolog/tool/EndToEndTest.kt
@@ -0,0 +1,144 @@
+/*
+ * 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.protolog.tool
+
+import org.junit.Assert
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.FileNotFoundException
+import java.io.OutputStream
+import java.util.jar.JarInputStream
+
+class EndToEndTest {
+
+ @Test
+ fun e2e_transform() {
+ val output = run(
+ src = "frameworks/base/org/example/Example.java" to """
+ package org.example;
+ import com.android.server.protolog.common.ProtoLog;
+ import static com.android.server.wm.ProtoLogGroup.GROUP;
+
+ class Example {
+ void method() {
+ String argString = "hello";
+ int argInt = 123;
+ ProtoLog.d(GROUP, "Example: %s %d", argString, argInt);
+ }
+ }
+ """.trimIndent(),
+ logGroup = LogGroup("GROUP", true, false, "TAG_GROUP"),
+ commandOptions = CommandOptions(arrayOf("transform-protolog-calls",
+ "--protolog-class", "com.android.server.protolog.common.ProtoLog",
+ "--protolog-impl-class", "com.android.server.protolog.ProtoLogImpl",
+ "--protolog-cache-class",
+ "com.android.server.protolog.ProtoLog${"\$\$"}Cache",
+ "--loggroups-class", "com.android.server.wm.ProtoLogGroup",
+ "--loggroups-jar", "not_required.jar",
+ "--output-srcjar", "out.srcjar",
+ "frameworks/base/org/example/Example.java"))
+ )
+ val outSrcJar = assertLoadSrcJar(output, "out.srcjar")
+ assertTrue(" 2066303299," in outSrcJar["frameworks/base/org/example/Example.java"]!!)
+ }
+
+ @Test
+ fun e2e_viewerConfig() {
+ val output = run(
+ src = "frameworks/base/org/example/Example.java" to """
+ package org.example;
+ import com.android.server.protolog.common.ProtoLog;
+ import static com.android.server.wm.ProtoLogGroup.GROUP;
+
+ class Example {
+ void method() {
+ String argString = "hello";
+ int argInt = 123;
+ ProtoLog.d(GROUP, "Example: %s %d", argString, argInt);
+ }
+ }
+ """.trimIndent(),
+ logGroup = LogGroup("GROUP", true, false, "TAG_GROUP"),
+ commandOptions = CommandOptions(arrayOf("generate-viewer-config",
+ "--protolog-class", "com.android.server.protolog.common.ProtoLog",
+ "--loggroups-class", "com.android.server.wm.ProtoLogGroup",
+ "--loggroups-jar", "not_required.jar",
+ "--viewer-conf", "out.json",
+ "frameworks/base/org/example/Example.java"))
+ )
+ val viewerConfigJson = assertLoadText(output, "out.json")
+ assertTrue("\"2066303299\"" in viewerConfigJson)
+ }
+
+ private fun assertLoadSrcJar(
+ outputs: Map<String, ByteArray>,
+ path: String
+ ): Map<String, String> {
+ val out = outputs[path] ?: fail("$path not in outputs (${outputs.keys})")
+
+ val sources = mutableMapOf<String, String>()
+ JarInputStream(ByteArrayInputStream(out)).use { jarStream ->
+ var entry = jarStream.nextJarEntry
+ while (entry != null) {
+ if (entry.name.endsWith(".java")) {
+ sources[entry.name] = jarStream.reader().readText()
+ }
+ entry = jarStream.nextJarEntry
+ }
+ }
+ return sources
+ }
+
+ private fun assertLoadText(outputs: Map<String, ByteArray>, path: String): String {
+ val out = outputs[path] ?: fail("$path not in outputs (${outputs.keys})")
+ return out.toString(Charsets.UTF_8)
+ }
+
+ fun run(
+ src: Pair<String, String>,
+ logGroup: LogGroup,
+ commandOptions: CommandOptions
+ ): Map<String, ByteArray> {
+ val outputs = mutableMapOf<String, ByteArrayOutputStream>()
+
+ ProtoLogTool.injector = object : ProtoLogTool.Injector {
+ override fun fileOutputStream(file: String): OutputStream =
+ ByteArrayOutputStream().also { outputs[file] = it }
+
+ override fun readText(file: File): String {
+ if (file.path == src.first) {
+ return src.second
+ }
+ throw FileNotFoundException("expected: ${src.first}, but was $file")
+ }
+
+ override fun readLogGroups(jarPath: String, className: String) = mapOf(
+ logGroup.name to logGroup)
+
+ override fun reportParseError(ex: ParsingException) = throw AssertionError(ex)
+ }
+
+ ProtoLogTool.invoke(commandOptions)
+
+ return outputs.mapValues { it.value.toByteArray() }
+ }
+
+ fun fail(message: String): Nothing = Assert.fail(message) as Nothing
+}
diff --git a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
index 6f5955c..4f2be328 100644
--- a/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
+++ b/tools/protologtool/tests/com/android/protolog/tool/SourceTransformerTest.kt
@@ -186,7 +186,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
@@ -228,7 +228,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE_MULTICALLS, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE_MULTICALLS, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
@@ -266,7 +266,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
@@ -303,7 +303,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE_NO_PARAMS, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE_NO_PARAMS, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
@@ -337,7 +337,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
@@ -375,7 +375,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
@@ -413,7 +413,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
@@ -439,7 +439,7 @@
invocation.arguments[0] as CompilationUnit
}
- val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, code)
+ val out = sourceJarWriter.processClass(TEST_CODE_MULTILINE, PATH, PATH, code)
code = StaticJavaParser.parse(out)
val ifStmts = code.findAll(IfStmt::class.java)
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index c0c0361..ac86778 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -465,9 +465,16 @@
public static final int EID_VHT_OPERATION = 192;
@UnsupportedAppUsage
public static final int EID_VSA = 221;
+ public static final int EID_EXTENSION_PRESENT = 255;
+
+ /**
+ * Extension IDs
+ */
+ public static final int EID_EXT_HE_OPERATION = 36;
@UnsupportedAppUsage
public int id;
+ public int idExt;
@UnsupportedAppUsage
public byte[] bytes;
@@ -476,6 +483,7 @@
public InformationElement(InformationElement rhs) {
this.id = rhs.id;
+ this.idExt = rhs.idExt;
this.bytes = rhs.bytes.clone();
}
}
@@ -717,6 +725,7 @@
dest.writeInt(informationElements.length);
for (int i = 0; i < informationElements.length; i++) {
dest.writeInt(informationElements[i].id);
+ dest.writeInt(informationElements[i].idExt);
dest.writeInt(informationElements[i].bytes.length);
dest.writeByteArray(informationElements[i].bytes);
}
@@ -799,6 +808,7 @@
for (int i = 0; i < n; i++) {
sr.informationElements[i] = new InformationElement();
sr.informationElements[i].id = in.readInt();
+ sr.informationElements[i].idExt = in.readInt();
int len = in.readInt();
sr.informationElements[i].bytes = new byte[len];
in.readByteArray(sr.informationElements[i].bytes);
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 380ebf1..07831c7 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -5240,16 +5240,18 @@
/**
* Add a listener for Scan Results. See {@link ScanResultsListener}.
* Caller will receive the event when scan results are available.
- * Caller should use {@link WifiManager#getScanResults()} to get the scan results.
+ * Caller should use {@link WifiManager#getScanResults()} requires
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} to get the scan results.
* Caller can remove a previously registered listener using
* {@link WifiManager#removeScanResultsListener(ScanResultsListener)}
+ * Same caller can add multiple listeners.
* <p>
* Applications should have the
* {@link android.Manifest.permission#ACCESS_WIFI_STATE} permission. Callers
* without the permission will trigger a {@link java.lang.SecurityException}.
* <p>
*
- * @param executor The executor to execute the listener of the {@code listener} object.
+ * @param executor The executor to execute the listener of the {@code listener} object.
* @param listener listener for Scan Results events
*/
@@ -5267,7 +5269,7 @@
iWifiManager.registerScanResultsListener(
new Binder(),
new ScanResultsListenerProxy(executor, listener),
- mContext.getOpPackageName().hashCode());
+ listener.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -5289,7 +5291,7 @@
if (iWifiManager == null) {
throw new RemoteException("Wifi service is not running");
}
- iWifiManager.unregisterScanResultsListener(mContext.getOpPackageName().hashCode());
+ iWifiManager.unregisterScanResultsListener(listener.hashCode());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 21189a4..67993e1 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -19,7 +19,6 @@
import android.Manifest;
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -134,14 +133,14 @@
* @hide
*/
@SystemApi
- @Nullable
+ @NonNull
@RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
public List<Integer> getAvailableChannels(@WifiBand int band) {
try {
Bundle bundle = mService.getAvailableChannels(band, mContext.getOpPackageName());
return bundle.getIntegerArrayList(GET_AVAILABLE_CHANNELS_EXTRA);
} catch (RemoteException e) {
- return null;
+ throw e.rethrowFromSystemServer();
}
}
@@ -344,7 +343,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<ScanSettings> CREATOR =
+ public static final @NonNull Creator<ScanSettings> CREATOR =
new Creator<ScanSettings>() {
public ScanSettings createFromParcel(Parcel in) {
ScanSettings settings = new ScanSettings();
@@ -492,7 +491,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<ScanData> CREATOR =
+ public static final @NonNull Creator<ScanData> CREATOR =
new Creator<ScanData>() {
public ScanData createFromParcel(Parcel in) {
int id = in.readInt();
@@ -541,7 +540,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<ParcelableScanData> CREATOR =
+ public static final @NonNull Creator<ParcelableScanData> CREATOR =
new Creator<ParcelableScanData>() {
public ParcelableScanData createFromParcel(Parcel in) {
int n = in.readInt();
@@ -589,7 +588,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<ParcelableScanResults> CREATOR =
+ public static final @NonNull Creator<ParcelableScanResults> CREATOR =
new Creator<ParcelableScanResults>() {
public ParcelableScanResults createFromParcel(Parcel in) {
int n = in.readInt();
@@ -720,7 +719,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<PnoSettings> CREATOR =
+ public static final @NonNull Creator<PnoSettings> CREATOR =
new Creator<PnoSettings>() {
public PnoSettings createFromParcel(Parcel in) {
PnoSettings settings = new PnoSettings();
@@ -1068,7 +1067,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<WifiChangeSettings> CREATOR =
+ public static final @NonNull Creator<WifiChangeSettings> CREATOR =
new Creator<WifiChangeSettings>() {
public WifiChangeSettings createFromParcel(Parcel in) {
return new WifiChangeSettings();
@@ -1179,7 +1178,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<HotlistSettings> CREATOR =
+ public static final @NonNull Creator<HotlistSettings> CREATOR =
new Creator<HotlistSettings>() {
public HotlistSettings createFromParcel(Parcel in) {
HotlistSettings settings = new HotlistSettings();
@@ -1412,7 +1411,7 @@
}
/** Implement the Parcelable interface {@hide} */
- public static final @android.annotation.NonNull Creator<OperationResult> CREATOR =
+ public static final @NonNull Creator<OperationResult> CREATOR =
new Creator<OperationResult>() {
public OperationResult createFromParcel(Parcel in) {
int reason = in.readInt();
diff --git a/wifi/tests/src/android/net/wifi/ScanResultTest.java b/wifi/tests/src/android/net/wifi/ScanResultTest.java
index 54ec325..4973c4c 100644
--- a/wifi/tests/src/android/net/wifi/ScanResultTest.java
+++ b/wifi/tests/src/android/net/wifi/ScanResultTest.java
@@ -21,6 +21,7 @@
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.validateMockitoUsage;
+import android.net.wifi.ScanResult.InformationElement;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -124,6 +125,25 @@
}
/**
+ * Verify parcel read/write for ScanResult with Information Element
+ */
+ @Test
+ public void verifyScanResultParcelWithInformationElement() throws Exception {
+ ScanResult writeScanResult = createScanResult();
+ writeScanResult.informationElements = new ScanResult.InformationElement[2];
+ writeScanResult.informationElements[0] = new ScanResult.InformationElement();
+ writeScanResult.informationElements[0].id = InformationElement.EID_HT_OPERATION;
+ writeScanResult.informationElements[0].idExt = 0;
+ writeScanResult.informationElements[0].bytes = new byte[]{0x11, 0x22, 0x33};
+ writeScanResult.informationElements[1] = new ScanResult.InformationElement();
+ writeScanResult.informationElements[1].id = InformationElement.EID_EXTENSION_PRESENT;
+ writeScanResult.informationElements[1].idExt = InformationElement.EID_EXT_HE_OPERATION;
+ writeScanResult.informationElements[1].bytes = new byte[]{0x44, 0x55, 0x66};
+ ScanResult readScanResult = new ScanResult(writeScanResult);
+ assertScanResultEquals(writeScanResult, readScanResult);
+ }
+
+ /**
* Verify toString for ScanResult.
*/
@Test
@@ -188,5 +208,6 @@
assertEquals(expected.frequency, actual.frequency);
assertEquals(expected.timestamp, actual.timestamp);
assertArrayEquals(expected.radioChainInfos, actual.radioChainInfos);
+ assertArrayEquals(expected.informationElements, actual.informationElements);
}
}