diff options
39 files changed, 1176 insertions, 560 deletions
diff --git a/apex/appsearch/framework/api/current.txt b/apex/appsearch/framework/api/current.txt index cc79f6bf9682..168c7c2f13cd 100644 --- a/apex/appsearch/framework/api/current.txt +++ b/apex/appsearch/framework/api/current.txt @@ -148,7 +148,7 @@ package android.app.appsearch { method public void remove(@NonNull android.app.appsearch.RemoveByUriRequest, @NonNull java.util.concurrent.Executor, @NonNull android.app.appsearch.BatchResultCallback<java.lang.String,java.lang.Void>); method public void remove(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>); method public void reportUsage(@NonNull android.app.appsearch.ReportUsageRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.lang.Void>>); - method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor); + method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec); method public void setSchema(@NonNull android.app.appsearch.SetSchemaRequest, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<android.app.appsearch.SetSchemaResponse>>); } @@ -217,7 +217,7 @@ package android.app.appsearch { public class GlobalSearchSession implements java.io.Closeable { method public void close(); - method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec, @NonNull java.util.concurrent.Executor); + method @NonNull public android.app.appsearch.SearchResults search(@NonNull String, @NonNull android.app.appsearch.SearchSpec); } public class PackageIdentifier { @@ -287,7 +287,7 @@ package android.app.appsearch { public class SearchResults implements java.io.Closeable { method public void close(); - method public void getNextPage(@NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.List<android.app.appsearch.SearchResult>>>); + method public void getNextPage(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.app.appsearch.AppSearchResult<java.util.List<android.app.appsearch.SearchResult>>>); } public final class SearchSpec { diff --git a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java index 54f33509072b..24cc60e5eef5 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java +++ b/apex/appsearch/framework/java/android/app/appsearch/AppSearchSession.java @@ -395,21 +395,15 @@ public final class AppSearchSession implements Closeable { * @param queryExpression query string to search. * @param searchSpec spec for setting document filters, adding projection, setting term match * type, etc. - * @param executor Executor on which to invoke the callback of the following request - * {@link SearchResults#getNextPage}. * @return a {@link SearchResults} object for retrieved matched documents. */ @NonNull - public SearchResults search( - @NonNull String queryExpression, - @NonNull SearchSpec searchSpec, - @NonNull @CallbackExecutor Executor executor) { + public SearchResults search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec) { Objects.requireNonNull(queryExpression); Objects.requireNonNull(searchSpec); - Objects.requireNonNull(executor); Preconditions.checkState(!mIsClosed, "AppSearchSession has already been closed"); return new SearchResults(mService, mPackageName, mDatabaseName, queryExpression, - searchSpec, mUserId, executor); + searchSpec, mUserId); } /** diff --git a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java index 93b102b864f4..8dd9dc1be312 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java +++ b/apex/appsearch/framework/java/android/app/appsearch/GlobalSearchSession.java @@ -106,21 +106,15 @@ public class GlobalSearchSession implements Closeable { * @param queryExpression query string to search. * @param searchSpec spec for setting document filters, adding projection, setting term match * type, etc. - * @param executor Executor on which to invoke the callback of the following request - * {@link SearchResults#getNextPage}. * @return a {@link SearchResults} object for retrieved matched documents. */ @NonNull - public SearchResults search( - @NonNull String queryExpression, - @NonNull SearchSpec searchSpec, - @NonNull @CallbackExecutor Executor executor) { + public SearchResults search(@NonNull String queryExpression, @NonNull SearchSpec searchSpec) { Objects.requireNonNull(queryExpression); Objects.requireNonNull(searchSpec); - Objects.requireNonNull(executor); Preconditions.checkState(!mIsClosed, "GlobalSearchSession has already been closed"); return new SearchResults(mService, mPackageName, /*databaseName=*/null, queryExpression, - searchSpec, mUserId, executor); + searchSpec, mUserId); } /** Closes the {@link GlobalSearchSession}. */ diff --git a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java index e9e978eea943..531c98425288 100644 --- a/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java +++ b/apex/appsearch/framework/java/android/app/appsearch/SearchResults.java @@ -65,8 +65,6 @@ public class SearchResults implements Closeable { @UserIdInt private final int mUserId; - private final Executor mExecutor; - private long mNextPageToken; private boolean mIsFirstLoad = true; @@ -79,15 +77,13 @@ public class SearchResults implements Closeable { @Nullable String databaseName, @NonNull String queryExpression, @NonNull SearchSpec searchSpec, - @UserIdInt int userId, - @NonNull @CallbackExecutor Executor executor) { + @UserIdInt int userId) { mService = Objects.requireNonNull(service); mPackageName = packageName; mDatabaseName = databaseName; mQueryExpression = Objects.requireNonNull(queryExpression); mSearchSpec = Objects.requireNonNull(searchSpec); mUserId = userId; - mExecutor = Objects.requireNonNull(executor); } /** @@ -98,9 +94,14 @@ public class SearchResults implements Closeable { * <p>Continue calling this method to access results until it returns an empty list, signifying * there are no more results. * + * @param executor Executor on which to invoke the callback. * @param callback Callback to receive the pending result of performing this operation. */ - public void getNextPage(@NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) { + public void getNextPage( + @NonNull @CallbackExecutor Executor executor, + @NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) { + Objects.requireNonNull(executor); + Objects.requireNonNull(callback); Preconditions.checkState(!mIsClosed, "SearchResults has already been closed"); try { if (mIsFirstLoad) { @@ -108,14 +109,14 @@ public class SearchResults implements Closeable { if (mDatabaseName == null) { // Global query, there's no one package-database combination to check. mService.globalQuery(mPackageName, mQueryExpression, - mSearchSpec.getBundle(), mUserId, wrapCallback(callback)); + mSearchSpec.getBundle(), mUserId, wrapCallback(executor, callback)); } else { // Normal local query, pass in specified database. mService.query(mPackageName, mDatabaseName, mQueryExpression, - mSearchSpec.getBundle(), mUserId, wrapCallback(callback)); + mSearchSpec.getBundle(), mUserId, wrapCallback(executor, callback)); } } else { - mService.getNextPage(mNextPageToken, mUserId, wrapCallback(callback)); + mService.getNextPage(mNextPageToken, mUserId, wrapCallback(executor, callback)); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -135,10 +136,11 @@ public class SearchResults implements Closeable { } private IAppSearchResultCallback wrapCallback( + @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<AppSearchResult<List<SearchResult>>> callback) { return new IAppSearchResultCallback.Stub() { public void onResult(AppSearchResult result) { - mExecutor.execute(() -> invokeCallback(result, callback)); + executor.execute(() -> invokeCallback(result, callback)); } }; } diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java index afa633a48b2b..9ef6e0b2dee8 100644 --- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java +++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/AppSearchSessionShimImpl.java @@ -124,8 +124,7 @@ public class AppSearchSessionShimImpl implements AppSearchSessionShim { @NonNull public SearchResultsShim search( @NonNull String queryExpression, @NonNull SearchSpec searchSpec) { - SearchResults searchResults = - mAppSearchSession.search(queryExpression, searchSpec, mExecutor); + SearchResults searchResults = mAppSearchSession.search(queryExpression, searchSpec); return new SearchResultsShimImpl(searchResults, mExecutor); } diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java index 6595d8d4abba..69a4c18c4028 100644 --- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java +++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/GlobalSearchSessionShimImpl.java @@ -75,8 +75,7 @@ public class GlobalSearchSessionShimImpl implements GlobalSearchSessionShim { @Override public SearchResultsShim search( @NonNull String queryExpression, @NonNull SearchSpec searchSpec) { - SearchResults searchResults = - mGlobalSearchSession.search(queryExpression, searchSpec, mExecutor); + SearchResults searchResults = mGlobalSearchSession.search(queryExpression, searchSpec); return new SearchResultsShimImpl(searchResults, mExecutor); } diff --git a/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java b/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java index 75add81c8d64..5f26e8cba585 100644 --- a/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java +++ b/apex/appsearch/testing/java/com/android/server/appsearch/testing/SearchResultsShimImpl.java @@ -47,7 +47,7 @@ public class SearchResultsShimImpl implements SearchResultsShim { @NonNull public ListenableFuture<List<SearchResult>> getNextPage() { SettableFuture<AppSearchResult<List<SearchResult>>> future = SettableFuture.create(); - mSearchResults.getNextPage(future::set); + mSearchResults.getNextPage(mExecutor, future::set); return Futures.transform(future, AppSearchResult::getResultValue, mExecutor); } diff --git a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl index 5693abe4d4e1..43d4873a3540 100644 --- a/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl +++ b/apex/jobscheduler/framework/java/android/os/IDeviceIdleController.aidl @@ -43,10 +43,10 @@ interface IDeviceIdleController { boolean isPowerSaveWhitelistApp(String name); @UnsupportedAppUsage(maxTargetSdk = 30, publicAlternatives = "Use SystemApi {@code PowerWhitelistManager#whitelistAppTemporarily(String, int, String)}.") - void addPowerSaveTempWhitelistApp(String name, long duration, int userId, String reason); - long addPowerSaveTempWhitelistAppForMms(String name, int userId, String reason); - long addPowerSaveTempWhitelistAppForSms(String name, int userId, String reason); - long whitelistAppTemporarily(String name, int userId, String reason); + void addPowerSaveTempWhitelistApp(String name, long duration, int userId, int reasonCode, String reason); + long addPowerSaveTempWhitelistAppForMms(String name, int userId, int reasonCode, String reason); + long addPowerSaveTempWhitelistAppForSms(String name, int userId, int reasonCode, String reason); + long whitelistAppTemporarily(String name, int userId, int reasonCode, String reason); void exitIdle(String reason); int setPreIdleTimeoutMode(int Mode); void resetPreIdleTimeoutMode(); diff --git a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java index df0e157abc6a..df690d00a322 100644 --- a/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java +++ b/apex/jobscheduler/framework/java/android/os/PowerWhitelistManager.java @@ -16,8 +16,16 @@ package android.os; +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_FOREGROUND_SERVICE; +import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT; +import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI; +import static android.app.ActivityManager.PROCESS_STATE_TOP; + import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; @@ -94,6 +102,239 @@ public class PowerWhitelistManager { @Retention(RetentionPolicy.SOURCE) public @interface TempAllowListType {} + /* Reason code for BG-FGS-launch. */ + /** + * BG-FGS-launch is denied. + * @hide + */ + public static final int REASON_DENIED = -1; + /** + * The default reason code if reason is unknown. + */ + public static final int REASON_UNKNOWN = 0; + /** + * Use REASON_OTHER if there is no better choice. + */ + public static final int REASON_OTHER = 1; + /** @hide */ + public static final int REASON_PROC_STATE_PERSISTENT = 10; + /** @hide */ + public static final int REASON_PROC_STATE_PERSISTENT_UI = 11; + /** @hide */ + public static final int REASON_PROC_STATE_TOP = 12; + /** @hide */ + public static final int REASON_PROC_STATE_BTOP = 13; + /** @hide */ + public static final int REASON_PROC_STATE_FGS = 14; + /** @hide */ + public static final int REASON_PROC_STATE_BFGS = 15; + /** @hide */ + public static final int REASON_UID_VISIBLE = 50; + /** @hide */ + public static final int REASON_SYSTEM_UID = 51; + /** @hide */ + public static final int REASON_ACTIVITY_STARTER = 52; + /** @hide */ + public static final int REASON_START_ACTIVITY_FLAG = 53; + /** @hide */ + public static final int REASON_FGS_BINDING = 54; + /** @hide */ + public static final int REASON_DEVICE_OWNER = 55; + /** @hide */ + public static final int REASON_PROFILE_OWNER = 56; + /** @hide */ + public static final int REASON_COMPANION_DEVICE_MANAGER = 57; + /** + * START_ACTIVITIES_FROM_BACKGROUND permission. + * @hide + */ + public static final int REASON_BACKGROUND_ACTIVITY_PERMISSION = 58; + /** + * START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. + * @hide + */ + public static final int REASON_BACKGROUND_FGS_PERMISSION = 59; + /** @hide */ + public static final int REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 60; + /** @hide */ + public static final int REASON_INSTR_BACKGROUND_FGS_PERMISSION = 61; + /** @hide */ + public static final int REASON_SYSTEM_ALERT_WINDOW_PERMISSION = 62; + /** @hide */ + public static final int REASON_DEVICE_DEMO_MODE = 63; + /** @hide */ + public static final int REASON_EXEMPTED_PACKAGE = 64; + /** @hide */ + public static final int REASON_ALLOWLISTED_PACKAGE = 65; + /** + * If it's because of a role, + * @hide + */ + public static final int REASON_APPOP = 66; + + /* BG-FGS-launch is allowed by temp-allowlist or system-allowlist. + Reason code for temp and system allowlist starts here. + */ + public static final int REASON_GEOFENCING = 100; + public static final int REASON_PUSH_MESSAGING = 101; + public static final int REASON_ACTIVITY_RECOGNITION = 102; + + /** + * Broadcast ACTION_BOOT_COMPLETED. + * @hide + */ + public static final int REASON_BOOT_COMPLETED = 103; + /** + * Broadcast ACTION_PRE_BOOT_COMPLETED. + * @hide + */ + public static final int REASON_PRE_BOOT_COMPLETED = 104; + + /** + * Broadcast ACTION_LOCKED_BOOT_COMPLETED. + * @hide + */ + public static final int REASON_LOCKED_BOOT_COMPLETED = 105; + /** + * Device idle system allowlist, including EXCEPT-IDLE + * @hide + */ + public static final int REASON_SYSTEM_ALLOW_LISTED = 106; + /** @hide */ + public static final int REASON_ALARM_MANAGER_ALARM_CLOCK = 107; + /** + * AlarmManagerService. + * @hide + */ + public static final int REASON_ALARM_MANAGER_WHILE_IDLE = 108; + /** + * ActiveServices. + * @hide + */ + public static final int REASON_SERVICE_LAUNCH = 109; + /** + * KeyChainSystemService. + * @hide + */ + public static final int REASON_KEY_CHAIN = 110; + /** + * PackageManagerService. + * @hide + */ + public static final int REASON_PACKAGE_VERIFIER = 111; + /** + * SyncManager. + * @hide + */ + public static final int REASON_SYNC_MANAGER = 112; + /** + * DomainVerificationProxyV1. + * @hide + */ + public static final int REASON_DOMAIN_VERIFICATION_V1 = 113; + /** + * DomainVerificationProxyV2. + * @hide + */ + public static final int REASON_DOMAIN_VERIFICATION_V2 = 114; + /** @hide */ + public static final int REASON_VPN = 115; + /** + * NotificationManagerService. + * @hide + */ + public static final int REASON_NOTIFICATION_SERVICE = 116; + /** + * Broadcast ACTION_MY_PACKAGE_REPLACED. + * @hide + */ + public static final int REASON_PACKAGE_REPLACED = 117; + /** + * LocationProviderManager. + * @hide + */ + public static final int REASON_LOCATION_PROVIDER = 118; + /** + * MediaButtonReceiver. + * @hide + */ + public static final int REASON_MEDIA_BUTTON = 119; + /** + * InboundSmsHandler. + * @hide + */ + public static final int REASON_EVENT_SMS = 120; + /** + * InboundSmsHandler. + * @hide + */ + public static final int REASON_EVENT_MMS = 121; + /** + * Shell app. + * @hide + */ + public static final int REASON_SHELL = 122; + + /** + * The list of BG-FGS-Launch and temp-allowlist reason code. + * @hide + */ + @IntDef(flag = true, prefix = { "REASON_" }, value = { + // BG-FGS-Launch reasons. + REASON_DENIED, + REASON_UNKNOWN, + REASON_OTHER, + REASON_PROC_STATE_PERSISTENT, + REASON_PROC_STATE_PERSISTENT_UI, + REASON_PROC_STATE_TOP, + REASON_PROC_STATE_BTOP, + REASON_PROC_STATE_FGS, + REASON_PROC_STATE_BFGS, + REASON_UID_VISIBLE, + REASON_SYSTEM_UID, + REASON_ACTIVITY_STARTER, + REASON_START_ACTIVITY_FLAG, + REASON_FGS_BINDING, + REASON_DEVICE_OWNER, + REASON_PROFILE_OWNER, + REASON_COMPANION_DEVICE_MANAGER, + REASON_BACKGROUND_ACTIVITY_PERMISSION, + REASON_BACKGROUND_FGS_PERMISSION, + REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION, + REASON_INSTR_BACKGROUND_FGS_PERMISSION, + REASON_SYSTEM_ALERT_WINDOW_PERMISSION, + REASON_DEVICE_DEMO_MODE, + REASON_EXEMPTED_PACKAGE, + REASON_ALLOWLISTED_PACKAGE, + REASON_APPOP, + // temp and system allowlist reasons. + REASON_GEOFENCING, + REASON_PUSH_MESSAGING, + REASON_ACTIVITY_RECOGNITION, + REASON_BOOT_COMPLETED, + REASON_PRE_BOOT_COMPLETED, + REASON_LOCKED_BOOT_COMPLETED, + REASON_SYSTEM_ALLOW_LISTED, + REASON_ALARM_MANAGER_ALARM_CLOCK, + REASON_ALARM_MANAGER_WHILE_IDLE, + REASON_SERVICE_LAUNCH, + REASON_KEY_CHAIN, + REASON_PACKAGE_VERIFIER, + REASON_SYNC_MANAGER, + REASON_DOMAIN_VERIFICATION_V1, + REASON_DOMAIN_VERIFICATION_V2, + REASON_VPN, + REASON_NOTIFICATION_SERVICE, + REASON_PACKAGE_REPLACED, + REASON_LOCATION_PROVIDER, + REASON_MEDIA_BUTTON, + REASON_EVENT_SMS, + REASON_EVENT_MMS, + REASON_SHELL, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ReasonCode {} + /** * @hide */ @@ -184,19 +425,34 @@ public class PowerWhitelistManager { * * @param packageName The package to add to the temp whitelist * @param durationMs How long to keep the app on the temp whitelist for (in milliseconds) + * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure. + * @param reason a optional human readable reason string, could be null or empty string. */ @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) - public void whitelistAppTemporarily(@NonNull String packageName, long durationMs) { - String reason = "from:" + UserHandle.formatUid(Binder.getCallingUid()); + public void whitelistAppTemporarily(@NonNull String packageName, long durationMs, + @ReasonCode int reasonCode, @Nullable String reason) { try { mService.addPowerSaveTempWhitelistApp(packageName, durationMs, mContext.getUserId(), - reason); + reasonCode, reason); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } /** + * Add an app to the temporary whitelist for a short amount of time. + * + * @param packageName The package to add to the temp whitelist + * @param durationMs How long to keep the app on the temp whitelist for (in milliseconds) + * @deprecated Use {@link #whitelistAppTemporarily(String, long, int, String)} instead + */ + @Deprecated + @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) + public void whitelistAppTemporarily(@NonNull String packageName, long durationMs) { + whitelistAppTemporarily(packageName, durationMs, REASON_UNKNOWN, packageName); + } + + /** * Add an app to the temporary whitelist for a short amount of time for a specific reason. The * temporary whitelist is kept separately from the permanent whitelist and apps are * automatically removed from the temporary whitelist after a predetermined amount of time. @@ -204,27 +460,179 @@ public class PowerWhitelistManager { * @param packageName The package to add to the temp whitelist * @param event The reason to add the app to the temp whitelist * @param reason A human-readable reason explaining why the app is temp whitelisted. Only - * used for logging purposes + * used for logging purposes. Could be null or empty string. * @return The duration (in milliseconds) that the app is whitelisted for + * @deprecated Use {@link #whitelistAppTemporarilyForEvent(String, int, int, String)} instead */ + @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long whitelistAppTemporarilyForEvent(@NonNull String packageName, - @WhitelistEvent int event, @NonNull String reason) { + @WhitelistEvent int event, @Nullable String reason) { + return whitelistAppTemporarilyForEvent(packageName, event, REASON_UNKNOWN, reason); + } + + /** + * Add an app to the temporary whitelist for a short amount of time for a specific reason. The + * temporary whitelist is kept separately from the permanent whitelist and apps are + * automatically removed from the temporary whitelist after a predetermined amount of time. + * + * @param packageName The package to add to the temp whitelist + * @param event The reason to add the app to the temp whitelist + * @param reasonCode one of {@link ReasonCode}, use {@link #REASON_UNKNOWN} if not sure. + * @param reason A human-readable reason explaining why the app is temp whitelisted. Only + * used for logging purposes. Could be null or empty string. + * @return The duration (in milliseconds) that the app is whitelisted for + */ + @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) + public long whitelistAppTemporarilyForEvent(@NonNull String packageName, + @WhitelistEvent int event, @ReasonCode int reasonCode, @Nullable String reason) { try { switch (event) { case EVENT_MMS: return mService.addPowerSaveTempWhitelistAppForMms( - packageName, mContext.getUserId(), reason); + packageName, mContext.getUserId(), reasonCode, reason); case EVENT_SMS: return mService.addPowerSaveTempWhitelistAppForSms( - packageName, mContext.getUserId(), reason); + packageName, mContext.getUserId(), reasonCode, reason); case EVENT_UNSPECIFIED: default: return mService.whitelistAppTemporarily( - packageName, mContext.getUserId(), reason); + packageName, mContext.getUserId(), reasonCode, reason); } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } + + /** + * @hide + */ + public static @ReasonCode int getReasonCodeFromProcState(int procState) { + if (procState <= PROCESS_STATE_PERSISTENT) { + return REASON_PROC_STATE_PERSISTENT; + } else if (procState <= PROCESS_STATE_PERSISTENT_UI) { + return REASON_PROC_STATE_PERSISTENT_UI; + } else if (procState <= PROCESS_STATE_TOP) { + return REASON_PROC_STATE_TOP; + } else if (procState <= PROCESS_STATE_BOUND_TOP) { + return REASON_PROC_STATE_BTOP; + } else if (procState <= PROCESS_STATE_FOREGROUND_SERVICE) { + return REASON_PROC_STATE_FGS; + } else if (procState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { + return REASON_PROC_STATE_BFGS; + } else { + return REASON_DENIED; + } + } + + /** + * Return string name of the integer reason code. + * @hide + * @param reasonCode + * @return string name of the reason code. + */ + public static String reasonCodeToString(@ReasonCode int reasonCode) { + switch (reasonCode) { + case REASON_DENIED: + return "DENIED"; + case REASON_UNKNOWN: + return "UNKNOWN"; + case REASON_OTHER: + return "OTHER"; + case REASON_PROC_STATE_PERSISTENT: + return "PROC_STATE_PERSISTENT"; + case REASON_PROC_STATE_PERSISTENT_UI: + return "PROC_STATE_PERSISTENT_UI"; + case REASON_PROC_STATE_TOP: + return "PROC_STATE_TOP"; + case REASON_PROC_STATE_BTOP: + return "PROC_STATE_BTOP"; + case REASON_PROC_STATE_FGS: + return "PROC_STATE_FGS"; + case REASON_PROC_STATE_BFGS: + return "PROC_STATE_BFGS"; + case REASON_UID_VISIBLE: + return "UID_VISIBLE"; + case REASON_SYSTEM_UID: + return "SYSTEM_UID"; + case REASON_ACTIVITY_STARTER: + return "ACTIVITY_STARTER"; + case REASON_START_ACTIVITY_FLAG: + return "START_ACTIVITY_FLAG"; + case REASON_FGS_BINDING: + return "FGS_BINDING"; + case REASON_DEVICE_OWNER: + return "DEVICE_OWNER"; + case REASON_PROFILE_OWNER: + return "PROFILE_OWNER"; + case REASON_COMPANION_DEVICE_MANAGER: + return "COMPANION_DEVICE_MANAGER"; + case REASON_BACKGROUND_ACTIVITY_PERMISSION: + return "BACKGROUND_ACTIVITY_PERMISSION"; + case REASON_BACKGROUND_FGS_PERMISSION: + return "BACKGROUND_FGS_PERMISSION"; + case REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION: + return "INSTR_BACKGROUND_ACTIVITY_PERMISSION"; + case REASON_INSTR_BACKGROUND_FGS_PERMISSION: + return "INSTR_BACKGROUND_FGS_PERMISSION"; + case REASON_SYSTEM_ALERT_WINDOW_PERMISSION: + return "SYSTEM_ALERT_WINDOW_PERMISSION"; + case REASON_DEVICE_DEMO_MODE: + return "DEVICE_DEMO_MODE"; + case REASON_EXEMPTED_PACKAGE: + return "EXEMPTED_PACKAGE"; + case REASON_ALLOWLISTED_PACKAGE: + return "ALLOWLISTED_PACKAGE"; + case REASON_APPOP: + return "APPOP"; + case REASON_GEOFENCING: + return "GEOFENCING"; + case REASON_PUSH_MESSAGING: + return "PUSH_MESSAGING"; + case REASON_ACTIVITY_RECOGNITION: + return "ACTIVITY_RECOGNITION"; + case REASON_BOOT_COMPLETED: + return "BOOT_COMPLETED"; + case REASON_PRE_BOOT_COMPLETED: + return "PRE_BOOT_COMPLETED"; + case REASON_LOCKED_BOOT_COMPLETED: + return "LOCKED_BOOT_COMPLETED"; + case REASON_SYSTEM_ALLOW_LISTED: + return "SYSTEM_ALLOW_LISTED"; + case REASON_ALARM_MANAGER_ALARM_CLOCK: + return "ALARM_MANAGER_ALARM_CLOCK"; + case REASON_ALARM_MANAGER_WHILE_IDLE: + return "ALARM_MANAGER_WHILE_IDLE"; + case REASON_SERVICE_LAUNCH: + return "SERVICE_LAUNCH"; + case REASON_KEY_CHAIN: + return "KEY_CHAIN"; + case REASON_PACKAGE_VERIFIER: + return "PACKAGE_VERIFIER"; + case REASON_SYNC_MANAGER: + return "SYNC_MANAGER"; + case REASON_DOMAIN_VERIFICATION_V1: + return "DOMAIN_VERIFICATION_V1"; + case REASON_DOMAIN_VERIFICATION_V2: + return "DOMAIN_VERIFICATION_V2"; + case REASON_VPN: + return "VPN"; + case REASON_NOTIFICATION_SERVICE: + return "NOTIFICATION_SERVICE"; + case REASON_PACKAGE_REPLACED: + return "PACKAGE_REPLACED"; + case REASON_LOCATION_PROVIDER: + return "LOCATION_PROVIDER"; + case REASON_MEDIA_BUTTON: + return "MEDIA_BUTTON"; + case REASON_EVENT_SMS: + return "EVENT_SMS"; + case REASON_EVENT_MMS: + return "EVENT_MMS"; + case REASON_SHELL: + return "SHELL"; + default: + return "(unknown:" + reasonCode + ")"; + } + } } diff --git a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java index e045b0fa3a6b..5e5717d11432 100644 --- a/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java +++ b/apex/jobscheduler/framework/java/com/android/server/DeviceIdleInternal.java @@ -16,6 +16,8 @@ package com.android.server; +import android.annotation.Nullable; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerWhitelistManager.TempAllowListType; import com.android.server.deviceidle.IDeviceIdleConstraint; @@ -34,6 +36,10 @@ public interface DeviceIdleInternal { void addPowerSaveTempWhitelistApp(int callingUid, String packageName, long duration, int userId, boolean sync, String reason); + void addPowerSaveTempWhitelistApp(int callingUid, String packageName, + long duration, int userId, boolean sync, @ReasonCode int reasonCode, + @Nullable String reason); + /** * Called by ActivityManagerService to directly add UID to DeviceIdleController's temp * allowlist. @@ -41,11 +47,12 @@ public interface DeviceIdleInternal { * @param duration duration in milliseconds * @param type temp allowlist type defined at {@link TempAllowListType} * @param sync + * @param reasonCode one of {@link ReasonCode} * @param reason */ void addPowerSaveTempWhitelistAppDirect(int uid, long duration, - @TempAllowListType int type, boolean sync, - String reason); + @TempAllowListType int type, boolean sync, @ReasonCode int reasonCode, + @Nullable String reason); // duration in milliseconds long getNotificationAllowlistDuration(); diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java index 8f7f705163ba..ac28e828eb2e 100644 --- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java +++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java @@ -16,12 +16,17 @@ package com.android.server; +import static android.os.PowerWhitelistManager.REASON_SHELL; +import static android.os.PowerWhitelistManager.REASON_UNKNOWN; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; +import static android.os.Process.INVALID_UID; + import android.Manifest; import android.annotation.NonNull; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.AlarmManager; -import android.app.BroadcastOptions; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -56,6 +61,7 @@ import android.os.Message; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerWhitelistManager.TempAllowListType; import android.os.Process; import android.os.RemoteException; @@ -1838,31 +1844,34 @@ public class DeviceIdleController extends SystemService } @Override - public long whitelistAppTemporarily(String packageName, int userId, String reason) - throws RemoteException { + public long whitelistAppTemporarily(String packageName, int userId, + @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { // At least 10 seconds. long durationMs = Math.max(10_000L, mConstants.MAX_TEMP_APP_ALLOWLIST_DURATION_MS / 2); - addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reason); + addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reasonCode, + reason); return durationMs; } @Override - public void addPowerSaveTempWhitelistApp(String packageName, long duration, - int userId, String reason) throws RemoteException { - addPowerSaveTempAllowlistAppChecked(packageName, duration, userId, reason); + public void addPowerSaveTempWhitelistApp(String packageName, long duration, int userId, + @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { + addPowerSaveTempAllowlistAppChecked(packageName, duration, userId, reasonCode, reason); } - @Override public long addPowerSaveTempWhitelistAppForMms(String packageName, - int userId, String reason) throws RemoteException { + @Override public long addPowerSaveTempWhitelistAppForMms(String packageName, int userId, + @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { long durationMs = mConstants.MMS_TEMP_APP_ALLOWLIST_DURATION_MS; - addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reason); + addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reasonCode, + reason); return durationMs; } - @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, - int userId, String reason) throws RemoteException { + @Override public long addPowerSaveTempWhitelistAppForSms(String packageName, int userId, + @ReasonCode int reasonCode, @Nullable String reason) throws RemoteException { long durationMs = mConstants.SMS_TEMP_APP_ALLOWLIST_DURATION_MS; - addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reason); + addPowerSaveTempAllowlistAppChecked(packageName, durationMs, userId, reasonCode, + reason); return durationMs; } @@ -1934,18 +1943,29 @@ public class DeviceIdleController extends SystemService } // duration in milliseconds + @Deprecated @Override public void addPowerSaveTempWhitelistApp(int callingUid, String packageName, - long duration, int userId, boolean sync, String reason) { + long duration, int userId, boolean sync, @Nullable String reason) { addPowerSaveTempAllowlistAppInternal(callingUid, packageName, duration, - userId, sync, reason); + userId, sync, REASON_UNKNOWN, reason); + } + + @Override + public void addPowerSaveTempWhitelistApp(int callingUid, String packageName, + long duration, int userId, boolean sync, @ReasonCode int reasonCode, + @Nullable String reason) { + addPowerSaveTempAllowlistAppInternal(callingUid, packageName, duration, + userId, sync, reasonCode, reason); } // duration in milliseconds @Override public void addPowerSaveTempWhitelistAppDirect(int uid, long duration, - @TempAllowListType int type, boolean sync, String reason) { - addPowerSaveTempWhitelistAppDirectInternal(0, uid, duration, type, sync, reason); + @TempAllowListType int type, boolean sync, @ReasonCode int reasonCode, + @Nullable String reason) { + addPowerSaveTempWhitelistAppDirectInternal(0, uid, duration, type, sync, + reasonCode, reason); } // duration in milliseconds @@ -2293,7 +2313,7 @@ public class DeviceIdleController extends SystemService filter.addAction(Intent.ACTION_SCREEN_ON); getContext().registerReceiver(mInteractivityReceiver, filter); - mLocalActivityManager.setDeviceIdleWhitelist( + mLocalActivityManager.setDeviceIdleAllowlist( mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); @@ -2671,7 +2691,8 @@ public class DeviceIdleController extends SystemService } void addPowerSaveTempAllowlistAppChecked(String packageName, long duration, - int userId, String reason) throws RemoteException { + int userId, @ReasonCode int reasonCode, @Nullable String reason) + throws RemoteException { getContext().enforceCallingPermission( Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, "No permission to change device idle whitelist"); @@ -2686,7 +2707,7 @@ public class DeviceIdleController extends SystemService final long token = Binder.clearCallingIdentity(); try { addPowerSaveTempAllowlistAppInternal(callingUid, - packageName, duration, userId, true, reason); + packageName, duration, userId, true, reasonCode, reason); } finally { Binder.restoreCallingIdentity(token); } @@ -2718,12 +2739,12 @@ public class DeviceIdleController extends SystemService * app an exemption to access network and acquire wakelocks. */ void addPowerSaveTempAllowlistAppInternal(int callingUid, String packageName, - long duration, int userId, boolean sync, String reason) { + long duration, int userId, boolean sync, @ReasonCode int reasonCode, + @Nullable String reason) { try { int uid = getContext().getPackageManager().getPackageUidAsUser(packageName, userId); addPowerSaveTempWhitelistAppDirectInternal(callingUid, uid, duration, - BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED, sync, - reason); + TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, sync, reasonCode, reason); } catch (NameNotFoundException e) { } } @@ -2733,7 +2754,8 @@ public class DeviceIdleController extends SystemService * app an exemption to access network and acquire wakelocks. */ void addPowerSaveTempWhitelistAppDirectInternal(int callingUid, int uid, - long duration, @TempAllowListType int type, boolean sync, String reason) { + long duration, @TempAllowListType int type, boolean sync, @ReasonCode int reasonCode, + @Nullable String reason) { final long timeNow = SystemClock.elapsedRealtime(); boolean informWhitelistChanged = false; int appId = UserHandle.getAppId(uid); @@ -2765,7 +2787,8 @@ public class DeviceIdleController extends SystemService } catch (RemoteException e) { } postTempActiveTimeoutMessage(uid, duration); - updateTempWhitelistAppIdsLocked(uid, true, duration, type); + updateTempWhitelistAppIdsLocked(uid, true, duration, type, reasonCode, + reason, callingUid); if (sync) { informWhitelistChanged = true; } else { @@ -2844,12 +2867,13 @@ public class DeviceIdleController extends SystemService } @GuardedBy("this") - private void onAppRemovedFromTempWhitelistLocked(int uid, String reason) { + private void onAppRemovedFromTempWhitelistLocked(int uid, @Nullable String reason) { if (DEBUG) { Slog.d(TAG, "Removing uid " + uid + " from temp whitelist"); } final int appId = UserHandle.getAppId(uid); - updateTempWhitelistAppIdsLocked(uid, false, 0, 0); + updateTempWhitelistAppIdsLocked(uid, false, 0, 0, REASON_UNKNOWN, + reason, INVALID_UID); mHandler.obtainMessage(MSG_REPORT_TEMP_APP_WHITELIST_CHANGED_TO_NPMS, appId, 0) .sendToTarget(); reportTempWhitelistChangedLocked(uid, false); @@ -3860,7 +3884,7 @@ public class DeviceIdleController extends SystemService mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null, mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds); if (mLocalActivityManager != null) { - mLocalActivityManager.setDeviceIdleWhitelist( + mLocalActivityManager.setDeviceIdleAllowlist( mPowerSaveWhitelistAllAppIdArray, mPowerSaveWhitelistExceptIdleAppIdArray); } if (mLocalPowerManager != null) { @@ -3880,9 +3904,14 @@ public class DeviceIdleController extends SystemService * @param durationMs duration in milliseconds to add to temp allowlist, only valid when * param adding is true. * @param type temp allowlist type defined at {@link TempAllowListType} + * @prama reasonCode one of {@Link ReasonCode} + * @param reason A human-readable reason for logging purposes. + * @param callingUid the callingUid that setup this temp-allowlist, only valid when param adding + * is true. */ private void updateTempWhitelistAppIdsLocked(int uid, boolean adding, long durationMs, - @TempAllowListType int type) { + @TempAllowListType int type, @ReasonCode int reasonCode, @Nullable String reason, + int callingUid) { final int size = mTempWhitelistAppIdEndTimes.size(); if (mTempWhitelistAppIdArray.length != size) { mTempWhitelistAppIdArray = new int[size]; @@ -3895,8 +3924,8 @@ public class DeviceIdleController extends SystemService Slog.d(TAG, "Setting activity manager temp whitelist to " + Arrays.toString(mTempWhitelistAppIdArray)); } - mLocalActivityManager.updateDeviceIdleTempWhitelist(mTempWhitelistAppIdArray, uid, - adding, durationMs, type); + mLocalActivityManager.updateDeviceIdleTempAllowlist(mTempWhitelistAppIdArray, uid, + adding, durationMs, type, reasonCode, reason, callingUid); } if (mLocalPowerManager != null) { if (DEBUG) { @@ -4428,7 +4457,8 @@ public class DeviceIdleController extends SystemService if (removePkg) { removePowerSaveTempAllowlistAppChecked(arg, shell.userId); } else { - addPowerSaveTempAllowlistAppChecked(arg, duration, shell.userId, "shell"); + addPowerSaveTempAllowlistAppChecked(arg, duration, shell.userId, + REASON_SHELL, "shell"); } } catch (Exception e) { pw.println("Failed: " + e); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 8d12f3d3da76..c62b808b00b4 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -643,8 +643,9 @@ package android.app { method public static android.app.BroadcastOptions makeBasic(); method @RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND) public void setBackgroundActivityStartsAllowed(boolean); method public void setDontSendToRestrictedApps(boolean); - method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long); - method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(int, long); + method @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppAllowlist(long, int, int, @Nullable String); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long); + method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(int, long); method public android.os.Bundle toBundle(); } @@ -2878,7 +2879,7 @@ package android.graphics.fonts { } public class FontManager { - method @Nullable public android.text.FontConfig getFontConfig(); + method @NonNull public android.text.FontConfig getFontConfig(); method @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFamily(@NonNull android.graphics.fonts.FontFamilyUpdateRequest, @IntRange(from=0) int); method @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFile(@NonNull android.graphics.fonts.FontFileUpdateRequest, @IntRange(from=0) int); method @Deprecated @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFile(@NonNull android.os.ParcelFileDescriptor, @NonNull byte[], @IntRange(from=0) int); @@ -8627,11 +8628,18 @@ package android.os { method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToWhitelist(@NonNull String); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void addToWhitelist(@NonNull java.util.List<java.lang.String>); method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public void removeFromWhitelist(@NonNull String); - method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void whitelistAppTemporarily(@NonNull String, long); - method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long whitelistAppTemporarilyForEvent(@NonNull String, int, @NonNull String); + method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void whitelistAppTemporarily(@NonNull String, long, int, @Nullable String); + method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void whitelistAppTemporarily(@NonNull String, long); + method @Deprecated @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long whitelistAppTemporarilyForEvent(@NonNull String, int, @Nullable String); + method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public long whitelistAppTemporarilyForEvent(@NonNull String, int, int, @Nullable String); field public static final int EVENT_MMS = 2; // 0x2 field public static final int EVENT_SMS = 1; // 0x1 field public static final int EVENT_UNSPECIFIED = 0; // 0x0 + field public static final int REASON_ACTIVITY_RECOGNITION = 102; // 0x66 + field public static final int REASON_GEOFENCING = 100; // 0x64 + field public static final int REASON_OTHER = 1; // 0x1 + field public static final int REASON_PUSH_MESSAGING = 101; // 0x65 + field public static final int REASON_UNKNOWN = 0; // 0x0 field public static final int TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED = 0; // 0x0 field public static final int TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED = 1; // 0x1 } diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 6231b958ae9a..de3406870e08 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -861,7 +861,7 @@ package android.graphics.drawable { package android.graphics.fonts { public class FontManager { - method @Nullable public android.text.FontConfig getFontConfig(); + method @NonNull public android.text.FontConfig getFontConfig(); method @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFamily(@NonNull android.graphics.fonts.FontFamilyUpdateRequest, @IntRange(from=0) int); method @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFile(@NonNull android.graphics.fonts.FontFileUpdateRequest, @IntRange(from=0) int); method @Deprecated @RequiresPermission(android.Manifest.permission.UPDATE_FONTS) public int updateFontFile(@NonNull android.os.ParcelFileDescriptor, @NonNull byte[], @IntRange(from=0) int); diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index c31c22cca329..71f164f49262 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -30,6 +30,7 @@ import android.content.pm.UserInfo; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerWhitelistManager.TempAllowListType; import android.os.TransactionTooLargeException; import android.os.WorkSource; @@ -102,12 +103,19 @@ public abstract class ActivityManagerInternal { * Sets how long a {@link PendingIntent} can be temporarily allowlisted to bypass restrictions * such as Power Save mode. * @param target - * @param whitelistToken + * @param allowlistToken * @param duration temp allowlist duration in milliseconds. * @param type temp allowlist type defined at {@link TempAllowListType} + * @param reasonCode one of {@link ReasonCode} + * @param reason A human-readable reason for logging purposes. */ + public abstract void setPendingIntentAllowlistDuration(IIntentSender target, + IBinder allowlistToken, long duration, @TempAllowListType int type, + @ReasonCode int reasonCode, @Nullable String reason); + + @Deprecated public abstract void setPendingIntentWhitelistDuration(IIntentSender target, - IBinder whitelistToken, long duration, int type); + IBinder allowlistToken, long duration, @TempAllowListType int type); /** * Returns the flags set for a {@link PendingIntent}. @@ -127,20 +135,26 @@ public abstract class ActivityManagerInternal { IBinder allowlistToken); /** - * Allow DeviceIdleController to tell us about what apps are whitelisted. + * Allow DeviceIdleController to tell us about what apps are allowlisted. */ - public abstract void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids); + public abstract void setDeviceIdleAllowlist(int[] allAppids, int[] exceptIdleAppids); /** - * Update information about which app IDs are on the temp whitelist. + * Update information about which app IDs are on the temp allowlist. * @param appids the updated list of appIds in temp allowlist. * @param changingUid uid to add or remove to temp allowlist. * @param adding true to add to temp allowlist, false to remove from temp allowlist. * @param durationMs when adding is true, the duration to be in temp allowlist. * @param type temp allowlist type defined at {@link TempAllowListType}. + * @param reasonCode one of {@link ReasonCode} + * @param reason A human-readable reason for logging purposes. + * @param callingUid the callingUid that setup this temp allowlist, only valid when param adding + * is true. */ - public abstract void updateDeviceIdleTempWhitelist(int[] appids, int changingUid, - boolean adding, long durationMs, @TempAllowListType int type); + public abstract void updateDeviceIdleTempAllowlist(int[] appids, int changingUid, + boolean adding, long durationMs, @TempAllowListType int type, + @ReasonCode int reasonCode, + @Nullable String reason, int callingUid); /** * Get the procstate for the UID. The return value will be between @@ -335,10 +349,11 @@ public abstract class ActivityManagerInternal { * @param targetUid the UID that is been temp allowlisted. * @param duration temp allowlist duration in milliseconds. * @param type temp allowlist type defined at {@link TempAllowListType} - * @param tag + * @param reasonCode one of {@link ReasonCode} + * @param reason */ - public abstract void tempWhitelistForPendingIntent(int callerPid, int callerUid, int targetUid, - long duration, int type, String tag); + public abstract void tempAllowlistForPendingIntent(int callerPid, int callerUid, int targetUid, + long duration, int type, @ReasonCode int reasonCode, String reason); public abstract int broadcastIntentInPackage(String packageName, @Nullable String featureId, int uid, int realCallingUid, int realCallingPid, Intent intent, String resolvedType, @@ -495,9 +510,9 @@ public abstract class ActivityManagerInternal { /** * Sends a broadcast, assuming the caller to be the system and allowing the inclusion of an - * approved whitelist of app Ids >= {@link android.os.Process#FIRST_APPLICATION_UID} that the + * approved allowlist of app Ids >= {@link android.os.Process#FIRST_APPLICATION_UID} that the * broadcast my be sent to; any app Ids < {@link android.os.Process#FIRST_APPLICATION_UID} are - * automatically whitelisted. + * automatically allowlisted. * * @see com.android.server.am.ActivityManagerService#broadcastIntentWithFeature( * IApplicationThread, String, Intent, String, IIntentReceiver, int, String, Bundle, diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 062cab457ebe..a6260d6d9cad 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1797,6 +1797,7 @@ public class ApplicationPackageManager extends PackageManager { } } + @UnsupportedAppUsage protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) { mContext = context; mPM = pm; diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index 445fdd83f34a..2e06e9b80595 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -16,11 +16,13 @@ package android.app; +import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.os.Build; import android.os.Bundle; import android.os.PowerWhitelistManager; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerWhitelistManager.TempAllowListType; /** @@ -31,8 +33,11 @@ import android.os.PowerWhitelistManager.TempAllowListType; */ @SystemApi public class BroadcastOptions { - private long mTemporaryAppWhitelistDuration; - private @TempAllowListType int mTemporaryAppWhitelistType; + private long mTemporaryAppAllowlistDuration; + private @TempAllowListType int mTemporaryAppAllowlistType; + private @ReasonCode int mTemporaryAppAllowlistReasonCode = + PowerWhitelistManager.REASON_UNKNOWN; + private @Nullable String mTemporaryAppAllowlistReason; private int mMinManifestReceiverApiLevel = 0; private int mMaxManifestReceiverApiLevel = Build.VERSION_CODES.CUR_DEVELOPMENT; private boolean mDontSendToRestrictedApps = false; @@ -42,11 +47,17 @@ public class BroadcastOptions { * How long to temporarily put an app on the power allowlist when executing this broadcast * to it. */ - static final String KEY_TEMPORARY_APP_WHITELIST_DURATION - = "android:broadcast.temporaryAppWhitelistDuration"; + static final String KEY_TEMPORARY_APP_ALLOWLIST_DURATION + = "android:broadcast.temporaryAppAllowlistDuration"; - static final String KEY_TEMPORARY_APP_WHITELIST_TYPE - = "android:broadcast.temporaryAppWhitelistType"; + static final String KEY_TEMPORARY_APP_ALLOWLIST_TYPE + = "android:broadcast.temporaryAppAllowlistType"; + + static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE = + "android:broadcast.temporaryAppAllowlistReasonCode"; + + static final String KEY_TEMPORARY_APP_ALLOWLIST_REASON = + "android:broadcast.temporaryAppAllowlistReason"; /** * Corresponds to {@link #setMinManifestReceiverApiLevel}. @@ -80,6 +91,7 @@ public class BroadcastOptions { @Deprecated public static final int TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED = PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; + /** * @hide * @deprecated Use {@link android.os.PowerWhitelistManager# @@ -99,8 +111,11 @@ public class BroadcastOptions { /** @hide */ public BroadcastOptions(Bundle opts) { - mTemporaryAppWhitelistDuration = opts.getLong(KEY_TEMPORARY_APP_WHITELIST_DURATION); - mTemporaryAppWhitelistType = opts.getInt(KEY_TEMPORARY_APP_WHITELIST_TYPE); + mTemporaryAppAllowlistDuration = opts.getLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION); + mTemporaryAppAllowlistType = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE); + mTemporaryAppAllowlistReasonCode = opts.getInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, + PowerWhitelistManager.REASON_UNKNOWN); + mTemporaryAppAllowlistReason = opts.getString(KEY_TEMPORARY_APP_ALLOWLIST_REASON); mMinManifestReceiverApiLevel = opts.getInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, 0); mMaxManifestReceiverApiLevel = opts.getInt(KEY_MAX_MANIFEST_RECEIVER_API_LEVEL, Build.VERSION_CODES.CUR_DEVELOPMENT); @@ -113,14 +128,16 @@ public class BroadcastOptions { * Set a duration for which the system should temporary place an application on the * power allowlist when this broadcast is being delivered to it. * @param duration The duration in milliseconds; 0 means to not place on allowlist. + * @deprecated use {@link #setTemporaryAppAllowlist(long, int, int, String)} instead. */ + @Deprecated @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(long duration) { - mTemporaryAppWhitelistDuration = duration; - mTemporaryAppWhitelistType = - PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; + setTemporaryAppAllowlist(duration, + PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + PowerWhitelistManager.REASON_UNKNOWN, null); } /** @@ -129,29 +146,69 @@ public class BroadcastOptions { * type. * @param type one of {@link TempAllowListType} * @param duration the duration in milliseconds; 0 means to not place on allowlist. + * @deprecated use {@link #setTemporaryAppAllowlist(long, int, int, String)} instead. */ + @Deprecated @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) public void setTemporaryAppWhitelistDuration(@TempAllowListType int type, long duration) { - mTemporaryAppWhitelistDuration = duration; - mTemporaryAppWhitelistType = type; + setTemporaryAppAllowlist(duration, type, + PowerWhitelistManager.REASON_UNKNOWN, null); } /** - * Return {@link #setTemporaryAppWhitelistDuration}. + * Set a duration for which the system should temporary place an application on the + * power allowlist when this broadcast is being delivered to it, specify the temp allowlist + * type. + * @param duration the duration in milliseconds; 0 means to not place on allowlist. + * @param type one of {@link TempAllowListType} + * @param reasonCode one of {@link ReasonCode}, use + * {@link PowerWhitelistManager#REASON_UNKNOWN} if not sure. + * @param reason A human-readable reason explaining why the app is temp allowlisted. Only + * used for logging purposes. Could be null or empty string. + */ + @RequiresPermission(anyOf = {android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, + android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND, + android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND}) + public void setTemporaryAppAllowlist(long duration, @TempAllowListType int type, + @ReasonCode int reasonCode, @Nullable String reason) { + mTemporaryAppAllowlistDuration = duration; + mTemporaryAppAllowlistType = type; + mTemporaryAppAllowlistReasonCode = reasonCode; + mTemporaryAppAllowlistReason = reason; + } + + /** + * Return {@link #setTemporaryAppAllowlist}. + * @hide + */ + public long getTemporaryAppAllowlistDuration() { + return mTemporaryAppAllowlistDuration; + } + + /** + * Return {@link #mTemporaryAppAllowlistType}. * @hide */ - public long getTemporaryAppWhitelistDuration() { - return mTemporaryAppWhitelistDuration; + public @TempAllowListType int getTemporaryAppAllowlistType() { + return mTemporaryAppAllowlistType; } /** - * Return {@link #mTemporaryAppWhitelistType}. + * Return {@link #mTemporaryAppAllowlistReasonCode}. * @hide */ - public @TempAllowListType int getTemporaryAppWhitelistType() { - return mTemporaryAppWhitelistType; + public @ReasonCode int getTemporaryAppAllowlistReasonCode() { + return mTemporaryAppAllowlistReasonCode; + } + + /** + * Return {@link #mTemporaryAppAllowlistReason}. + * @hide + */ + public @Nullable String getTemporaryAppAllowlistReason() { + return mTemporaryAppAllowlistReason; } /** @@ -236,11 +293,17 @@ public class BroadcastOptions { */ public Bundle toBundle() { Bundle b = new Bundle(); - if (mTemporaryAppWhitelistDuration > 0) { - b.putLong(KEY_TEMPORARY_APP_WHITELIST_DURATION, mTemporaryAppWhitelistDuration); + if (mTemporaryAppAllowlistDuration > 0) { + b.putLong(KEY_TEMPORARY_APP_ALLOWLIST_DURATION, mTemporaryAppAllowlistDuration); + } + if (mTemporaryAppAllowlistType != 0) { + b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_TYPE, mTemporaryAppAllowlistType); + } + if (mTemporaryAppAllowlistReasonCode != PowerWhitelistManager.REASON_UNKNOWN) { + b.putInt(KEY_TEMPORARY_APP_ALLOWLIST_REASON_CODE, mTemporaryAppAllowlistReasonCode); } - if (mTemporaryAppWhitelistType != 0) { - b.putInt(KEY_TEMPORARY_APP_WHITELIST_TYPE, mTemporaryAppWhitelistType); + if (mTemporaryAppAllowlistReason != null) { + b.putString(KEY_TEMPORARY_APP_ALLOWLIST_REASON, mTemporaryAppAllowlistReason); } if (mMinManifestReceiverApiLevel != 0) { b.putInt(KEY_MIN_MANIFEST_RECEIVER_API_LEVEL, mMinManifestReceiverApiLevel); diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 2e684b1d3ef7..3a8172ea98b8 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -549,7 +549,7 @@ interface IActivityManager { /** * Add a bare uid to the background restrictions whitelist. Only the system uid may call this. */ - void backgroundWhitelistUid(int uid); + void backgroundAllowlistUid(int uid); // Start of P transactions /** diff --git a/core/java/android/content/pm/DataLoaderParamsParcel.aidl b/core/java/android/content/pm/DataLoaderParamsParcel.aidl index d40012fd5718..29d472e6e927 100644 --- a/core/java/android/content/pm/DataLoaderParamsParcel.aidl +++ b/core/java/android/content/pm/DataLoaderParamsParcel.aidl @@ -23,7 +23,7 @@ import android.content.pm.DataLoaderType; * @hide */ parcelable DataLoaderParamsParcel { - DataLoaderType type; + DataLoaderType type = DataLoaderType.NONE; @utf8InCpp String packageName; @utf8InCpp String className; @utf8InCpp String arguments; diff --git a/core/java/android/content/pm/InstallationFileParcel.aidl b/core/java/android/content/pm/InstallationFileParcel.aidl index b7efc1947cc3..09d1a3291b69 100644 --- a/core/java/android/content/pm/InstallationFileParcel.aidl +++ b/core/java/android/content/pm/InstallationFileParcel.aidl @@ -24,7 +24,7 @@ import android.content.pm.InstallationFileLocation; */ parcelable InstallationFileParcel { String name; - InstallationFileLocation location; + InstallationFileLocation location = InstallationFileLocation.UNKNOWN; long size; byte[] metadata; byte[] signature; diff --git a/core/java/android/graphics/fonts/FontManager.java b/core/java/android/graphics/fonts/FontManager.java index e512cf1bbb1f..429eef95f952 100644 --- a/core/java/android/graphics/fonts/FontManager.java +++ b/core/java/android/graphics/fonts/FontManager.java @@ -20,7 +20,6 @@ import android.Manifest; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; @@ -29,7 +28,6 @@ import android.content.Context; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.text.FontConfig; -import android.util.Log; import com.android.internal.graphics.fonts.IFontManager; @@ -198,12 +196,11 @@ public class FontManager { * @return The current font configuration. null if failed to fetch information from the system * service. */ - public @Nullable FontConfig getFontConfig() { + public @NonNull FontConfig getFontConfig() { try { return mIFontManager.getFontConfig(); } catch (RemoteException e) { - Log.e(TAG, "Failed to call getFontConfig", e); - return null; + throw e.rethrowAsRuntimeException(); } } diff --git a/core/proto/android/server/activitymanagerservice.proto b/core/proto/android/server/activitymanagerservice.proto index d3c2d31779db..ec41a47a8798 100644 --- a/core/proto/android/server/activitymanagerservice.proto +++ b/core/proto/android/server/activitymanagerservice.proto @@ -627,6 +627,7 @@ message ActivityManagerServiceDumpProcessesProto { optional int64 duration_ms = 2; optional string tag = 3; optional int32 type = 4; + optional int32 reason_code = 5; } repeated PendingTempWhitelist pending_temp_whitelist = 26; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java index 19c3cf9c462a..7d5c9f07f86c 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java @@ -227,24 +227,29 @@ public class BubbleFlyoutView extends FrameLayout { /* * Fade animation for consecutive flyouts. */ - void animateUpdate(Bubble.FlyoutMessage flyoutMessage, float parentWidth, float stackY) { + void animateUpdate(Bubble.FlyoutMessage flyoutMessage, float parentWidth, PointF stackPos) { final Runnable afterFadeOut = () -> { updateFlyoutMessage(flyoutMessage, parentWidth); // Wait for TextViews to layout with updated height. post(() -> { - mFlyoutY = stackY + (mBubbleSize - mFlyoutTextContainer.getHeight()) / 2f; - fade(true /* in */, () -> {} /* after */); + fade(true /* in */, stackPos, () -> {} /* after */); } /* after */ ); }; - fade(false /* in */, afterFadeOut); + fade(false /* in */, stackPos, afterFadeOut); } /* * Fade-out above or fade-in from below. */ - private void fade(boolean in, Runnable afterFade) { + private void fade(boolean in, PointF stackPos, Runnable afterFade) { + mFlyoutY = stackPos.y + (mBubbleSize - mFlyoutTextContainer.getHeight()) / 2f; + setAlpha(in ? 0f : 1f); setTranslationY(in ? mFlyoutY + FLYOUT_FADE_Y : mFlyoutY); + mRestingTranslationX = mArrowPointingLeft + ? stackPos.x + mBubbleSize + mFlyoutSpaceFromBubble + : stackPos.x - getWidth() - mFlyoutSpaceFromBubble; + setTranslationX(mRestingTranslationX); animate() .alpha(in ? 1f : 0f) .setDuration(in ? FLYOUT_FADE_IN_DURATION : FLYOUT_FADE_OUT_DURATION) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java index a8ab4064455c..e99669f5b5e0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java @@ -2431,7 +2431,7 @@ public class BubbleStackView extends FrameLayout if (mFlyout.getVisibility() == View.VISIBLE) { mFlyout.animateUpdate(bubble.getFlyoutMessage(), getWidth(), - mStackAnimationController.getStackPosition().y); + mStackAnimationController.getStackPosition()); } else { mFlyout.setVisibility(INVISIBLE); mFlyout.setupFlyoutStartingAsDot(bubble.getFlyoutMessage(), diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java index 28072ca4f113..f1a98adc0ab2 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java @@ -143,7 +143,7 @@ public class CompanionDeviceActivity extends Activity { } static void notifyDevicesChanged() { - if (sInstance != null && !sInstance.isFinishing()) { + if (sInstance != null && sInstance.mDevicesAdapter != null && !sInstance.isFinishing()) { sInstance.mDevicesAdapter.notifyDataSetChanged(); } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 2efc83c4af06..e5ef9353135d 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -20,10 +20,35 @@ import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.SYSTEM_ALERT_WINDOW; import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; +import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT; import static android.app.ActivityManager.PROCESS_STATE_RECEIVER; import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST; +import static android.os.PowerWhitelistManager.REASON_ACTIVITY_STARTER; +import static android.os.PowerWhitelistManager.REASON_ALLOWLISTED_PACKAGE; +import static android.os.PowerWhitelistManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_BACKGROUND_FGS_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_COMPANION_DEVICE_MANAGER; +import static android.os.PowerWhitelistManager.REASON_DENIED; +import static android.os.PowerWhitelistManager.REASON_DEVICE_DEMO_MODE; +import static android.os.PowerWhitelistManager.REASON_DEVICE_OWNER; +import static android.os.PowerWhitelistManager.REASON_EXEMPTED_PACKAGE; +import static android.os.PowerWhitelistManager.REASON_FGS_BINDING; +import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_INSTR_BACKGROUND_FGS_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_PROC_STATE_PERSISTENT; +import static android.os.PowerWhitelistManager.REASON_PROC_STATE_PERSISTENT_UI; +import static android.os.PowerWhitelistManager.REASON_PROC_STATE_TOP; +import static android.os.PowerWhitelistManager.REASON_PROFILE_OWNER; +import static android.os.PowerWhitelistManager.REASON_START_ACTIVITY_FLAG; +import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALLOW_LISTED; +import static android.os.PowerWhitelistManager.REASON_SYSTEM_UID; +import static android.os.PowerWhitelistManager.REASON_UID_VISIBLE; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; +import static android.os.PowerWhitelistManager.getReasonCodeFromProcState; +import static android.os.PowerWhitelistManager.reasonCodeToString; import static android.os.Process.NFC_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; @@ -43,7 +68,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE_E import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -86,6 +110,8 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.PowerWhitelistManager; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.Process; import android.os.RemoteCallback; import android.os.RemoteException; @@ -130,8 +156,6 @@ import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Comparator; @@ -152,58 +176,6 @@ public final class ActiveServices { private static final boolean SHOW_DUNGEON_NOTIFICATION = false; - public static final int FGS_FEATURE_DENIED = 0; - public static final int FGS_FEATURE_ALLOWED_BY_UID_STATE = 1; - public static final int FGS_FEATURE_ALLOWED_BY_PROC_STATE = 2; - public static final int FGS_FEATURE_ALLOWED_BY_UID_VISIBLE = 3; - public static final int FGS_FEATURE_ALLOWED_BY_FLAG = 4; - public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_UID = 5; - public static final int FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION = 6; - public static final int FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION = 7; - public static final int FGS_FEATURE_ALLOWED_BY_ACTIVITY_TOKEN = 8; - public static final int FGS_FEATURE_ALLOWED_BY_FGS_TOKEN = 9; - public static final int FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION = 10; - public static final int FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION = 12; - public static final int FGS_FEATURE_ALLOWED_BY_ALLOWLIST = 13; - public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER = 14; - public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST = 15; - public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION = 16; - public static final int FGS_FEATURE_ALLOWED_BY_FGS_BINDING = 17; - public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE = 18; - public static final int FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD = 19; - public static final int FGS_FEATURE_ALLOWED_BY_EXEMPTED_PACKAGES = 20; - public static final int FGS_FEATURE_ALLOWED_BY_ACTIVITY_STARTER = 21; - public static final int FGS_FEATURE_ALLOWED_BY_COMPANION_APP = 22; - public static final int FGS_FEATURE_ALLOWED_BY_PROFILE_OWNER = 23; - - @IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = { - FGS_FEATURE_DENIED, - FGS_FEATURE_ALLOWED_BY_UID_STATE, - FGS_FEATURE_ALLOWED_BY_PROC_STATE, - FGS_FEATURE_ALLOWED_BY_UID_VISIBLE, - FGS_FEATURE_ALLOWED_BY_FLAG, - FGS_FEATURE_ALLOWED_BY_SYSTEM_UID, - FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION, - FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION, - FGS_FEATURE_ALLOWED_BY_ACTIVITY_TOKEN, - FGS_FEATURE_ALLOWED_BY_FGS_TOKEN, - FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION, - FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION, - FGS_FEATURE_ALLOWED_BY_ALLOWLIST, - FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER, - FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST, - FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION, - FGS_FEATURE_ALLOWED_BY_FGS_BINDING, - FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE, - FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD, - FGS_FEATURE_ALLOWED_BY_EXEMPTED_PACKAGES, - FGS_FEATURE_ALLOWED_BY_ACTIVITY_STARTER, - FGS_FEATURE_ALLOWED_BY_COMPANION_APP, - FGS_FEATURE_ALLOWED_BY_PROFILE_OWNER - }) - @Retention(RetentionPolicy.SOURCE) - public @interface FgsFeatureRetCode {} - // How long we wait for a service to finish executing. static final int SERVICE_TIMEOUT = 20*1000; @@ -275,7 +247,7 @@ public final class ActiveServices { AppWidgetManagerInternal mAppWidgetManagerInternal; - // white listed packageName. + // allowlisted packageName. ArraySet<String> mAllowListWhileInUsePermissionInFgs = new ArraySet<>(); // TODO: remove this after feature development is done @@ -675,7 +647,7 @@ public final class ActiveServices { if (fgRequired) { logFgsBackgroundStart(r); - if (r.mAllowStartForeground == FGS_FEATURE_DENIED && isBgFgsRestrictionEnabled(r)) { + if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) { String msg = "startForegroundService() not allowed due to " + "mAllowStartForeground false: service " + r.shortInstanceName; @@ -1768,8 +1740,7 @@ public final class ActiveServices { if (!ignoreForeground) { logFgsBackgroundStart(r); - if (r.mAllowStartForeground == FGS_FEATURE_DENIED - && isBgFgsRestrictionEnabled(r)) { + if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) { final String msg = "Service.startForeground() not allowed due to " + "mAllowStartForeground false: service " + r.shortInstanceName; @@ -2250,7 +2221,7 @@ public final class ActiveServices { psr.mAllowlistManager = false; for (int i = psr.numberOfRunningServices() - 1; i >= 0; i--) { ServiceRecord sr = psr.getRunningServiceAt(i); - if (sr.whitelistManager) { + if (sr.allowlistManager) { psr.mAllowlistManager = true; break; } @@ -2261,7 +2232,7 @@ public final class ActiveServices { final ProcessServiceRecord psr = service.app.mServices; psr.stopService(service); psr.updateBoundClientUids(); - if (service.whitelistManager) { + if (service.allowlistManager) { updateAllowlistManagerLocked(psr); } } @@ -2483,7 +2454,7 @@ public final class ActiveServices { clientPsr.setHasAboveClient(true); } if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { - s.whitelistManager = true; + s.allowlistManager = true; } if ((flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) { s.setAllowedBgActivityStartsByBinding(true); @@ -2520,7 +2491,7 @@ public final class ActiveServices { if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { servicePsr.setTreatLikeActivity(true); } - if (s.whitelistManager) { + if (s.allowlistManager) { servicePsr.mAllowlistManager = true; } // This could have made the service more important. @@ -2949,7 +2920,6 @@ public final class ActiveServices { final ServiceRestarter res = new ServiceRestarter(); r = new ServiceRecord(mAm, className, name, definingPackageName, definingUid, filter, sInfo, callingFromFg, res); - r.mRecentCallingPackage = callingPackage; res.setService(r); smap.mServicesByInstanceName.put(name, r); smap.mServicesByIntent.put(filter, r); @@ -2978,6 +2948,8 @@ public final class ActiveServices { } } if (r != null) { + r.mRecentCallingPackage = callingPackage; + r.mRecentCallingUid = callingUid; if (!mAm.validateAssociationAllowedLocked(callingPackage, callingUid, r.packageName, r.appInfo.uid)) { String msg = "association not allowed between packages " @@ -3440,12 +3412,13 @@ public final class ActiveServices { if (r.fgRequired) { if (DEBUG_FOREGROUND_SERVICE) { - Slog.v(TAG, "Whitelisting " + UserHandle.formatUid(r.appInfo.uid) + Slog.v(TAG, "Allowlisting " + UserHandle.formatUid(r.appInfo.uid) + " for fg-service launch"); } mAm.tempAllowlistUidLocked(r.appInfo.uid, - SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch", - BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED); + SERVICE_START_FOREGROUND_TIMEOUT, PowerWhitelistManager.REASON_SERVICE_LAUNCH, + "fg-service-launch", TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, + r.mRecentCallingUid); } if (!mPendingServices.contains(r)) { @@ -3551,7 +3524,7 @@ public final class ActiveServices { } } - if (r.whitelistManager) { + if (r.allowlistManager) { psr.mAllowlistManager = true; } @@ -3941,11 +3914,11 @@ public final class ActiveServices { if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) { psr.updateHasAboveClientLocked(); } - // If this connection requested whitelist management, see if we should + // If this connection requested allowlist management, see if we should // now clear that state. if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { - s.updateWhitelistManager(); - if (!s.whitelistManager && s.app != null) { + s.updateAllowlistManager(); + if (!s.allowlistManager && s.app != null) { updateAllowlistManagerLocked(s.app.mServices); } } @@ -5400,13 +5373,13 @@ public final class ActiveServices { } if (!r.mAllowWhileInUsePermissionInFgs - || (r.mAllowStartForeground == FGS_FEATURE_DENIED)) { - final @FgsFeatureRetCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked( + || (r.mAllowStartForeground == REASON_DENIED)) { + final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked( callingPackage, callingPid, callingUid, r, allowBackgroundActivityStarts); if (!r.mAllowWhileInUsePermissionInFgs) { - r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != FGS_FEATURE_DENIED); + r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED); } - if (r.mAllowStartForeground == FGS_FEATURE_DENIED) { + if (r.mAllowStartForeground == REASON_DENIED) { r.mAllowStartForeground = shouldAllowFgsStartForegroundLocked(allowWhileInUse, callingPackage, callingPid, callingUid, intent, r, allowBackgroundActivityStarts); @@ -5420,37 +5393,37 @@ public final class ActiveServices { * @param callingPackage caller app's package name. * @param callingUid caller app's uid. * @param r the service to start. - * @return {@link FgsFeatureRetCode} + * @return {@link ReasonCode} */ - private @FgsFeatureRetCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage, + private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage, int callingPid, int callingUid, ServiceRecord r, boolean allowBackgroundActivityStarts) { - int ret = FGS_FEATURE_DENIED; + int ret = REASON_DENIED; final int uidState = mAm.getUidStateLocked(callingUid); - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { // Is the calling UID at PROCESS_STATE_TOP or above? if (uidState <= PROCESS_STATE_TOP) { - ret = FGS_FEATURE_ALLOWED_BY_UID_STATE; + ret = getReasonCodeFromProcState(uidState); } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { // Does the calling UID have any visible activity? final boolean isCallingUidVisible = mAm.mAtmInternal.isUidForeground(callingUid); if (isCallingUidVisible) { - ret = FGS_FEATURE_ALLOWED_BY_UID_VISIBLE; + ret = REASON_UID_VISIBLE; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { // Is the allow activity background start flag on? if (allowBackgroundActivityStarts) { - ret = FGS_FEATURE_ALLOWED_BY_FLAG; + ret = REASON_START_ACTIVITY_FLAG; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { boolean isCallerSystem = false; final int callingAppId = UserHandle.getAppId(callingUid); switch (callingAppId) { @@ -5466,15 +5439,15 @@ public final class ActiveServices { } if (isCallerSystem) { - ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_UID; + ret = REASON_SYSTEM_UID; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, pr -> { if (pr.uid == callingUid) { if (pr.getWindowProcessController().areBackgroundFgsStartsAllowed()) { - return FGS_FEATURE_ALLOWED_BY_ACTIVITY_STARTER; + return REASON_ACTIVITY_STARTER; } } return null; @@ -5484,35 +5457,35 @@ public final class ActiveServices { } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { if (r.app != null) { ActiveInstrumentation instr = r.app.getActiveInstrumentation(); if (instr != null && instr.mHasBackgroundActivityStartsPermission) { - ret = FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION; + ret = REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION; } } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { if (mAm.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid) == PERMISSION_GRANTED) { - ret = FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION; + ret = REASON_BACKGROUND_ACTIVITY_PERMISSION; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { final boolean isAllowedPackage = mAllowListWhileInUsePermissionInFgs.contains(callingPackage); if (isAllowedPackage) { - ret = FGS_FEATURE_ALLOWED_BY_ALLOWLIST; + ret = REASON_ALLOWLISTED_PACKAGE; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { // Is the calling UID a device owner app? final boolean isDeviceOwner = mAm.mInternal.isDeviceOwner(callingUid); if (isDeviceOwner) { - ret = FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER; + ret = REASON_DEVICE_OWNER; } } return ret; @@ -5527,38 +5500,40 @@ public final class ActiveServices { * @param callingUid caller app's uid. * @param intent intent to start/bind service. * @param r the service to start. - * @return {@link FgsFeatureRetCode} + * @return {@link ReasonCode} */ - private @FgsFeatureRetCode int shouldAllowFgsStartForegroundLocked( - @FgsFeatureRetCode int allowWhileInUse, String callingPackage, int callingPid, + private @ReasonCode int shouldAllowFgsStartForegroundLocked( + @ReasonCode int allowWhileInUse, String callingPackage, int callingPid, int callingUid, Intent intent, ServiceRecord r, boolean allowBackgroundActivityStarts) { int ret = allowWhileInUse; + FgsStartTempAllowList.TempFgsAllowListEntry tempAllowListReason = + r.mInfoTempFgsAllowListReason = mAm.isAllowlistedForFgsStartLOSP(callingUid); final StringBuilder sb = new StringBuilder(64); final int uidState = mAm.getUidStateLocked(callingUid); - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { // Is the calling UID at PROCESS_STATE_TOP or above? if (uidState <= PROCESS_STATE_TOP) { sb.append("uidState=").append(uidState); - ret = FGS_FEATURE_ALLOWED_BY_UID_STATE; + ret = getReasonCodeFromProcState(uidState); } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { final Integer allowedType = mAm.mProcessList.searchEachLruProcessesLOSP(false, app -> { if (app.uid == callingUid) { final ProcessStateRecord state = app.mState; - if (state.getAllowedStartFgs() != FGS_FEATURE_DENIED) { + if (state.getAllowedStartFgs() != REASON_DENIED) { return state.getAllowedStartFgs(); } else if (state.isAllowedStartFgsState()) { - return FGS_FEATURE_ALLOWED_BY_PROC_STATE; + return getReasonCodeFromProcState(state.getAllowStartFgsState()); } else if (state.areBackgroundFgsStartsAllowedByToken()) { - return FGS_FEATURE_ALLOWED_BY_FGS_BINDING; + return REASON_FGS_BINDING; } else { final ActiveInstrumentation instr = app.getActiveInstrumentation(); if (instr != null && instr.mHasBackgroundForegroundServiceStartsPermission) { - return FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION; + return REASON_INSTR_BACKGROUND_FGS_PERMISSION; } } } @@ -5569,55 +5544,59 @@ public final class ActiveServices { } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { if (mAm.checkPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND, callingPid, callingUid) == PERMISSION_GRANTED) { - ret = FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION; + ret = REASON_BACKGROUND_FGS_PERMISSION; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { if (mAm.checkPermission(SYSTEM_ALERT_WINDOW, callingPid, callingUid) == PERMISSION_GRANTED) { - ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION; + ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION; } } - if (ret == FGS_FEATURE_DENIED) { - if (mAm.isAllowlistedForFgsStartLOSP(callingUid)) { - // uid is on DeviceIdleController's user/system allowlist - // or AMS's FgsStartTempAllowList. - ret = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST; + if (ret == REASON_DENIED) { + FgsStartTempAllowList.TempFgsAllowListEntry entry = + mAm.isAllowlistedForFgsStartLOSP(callingUid); + if (entry != null) { + if (entry == ActivityManagerService.FAKE_TEMP_ALLOWLIST_ENTRY) { + ret = REASON_SYSTEM_ALLOW_LISTED; + } else { + ret = entry.mReasonCode; + } } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { if (UserManager.isDeviceInDemoMode(mAm.mContext)) { - ret = FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE; + ret = REASON_DEVICE_DEMO_MODE; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { // Is the calling UID a profile owner app? final boolean isProfileOwner = mAm.mInternal.isProfileOwner(callingUid); if (isProfileOwner) { - ret = FGS_FEATURE_ALLOWED_BY_PROFILE_OWNER; + ret = REASON_PROFILE_OWNER; } } // NOTE this should always be the last check. - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { if (isPackageExemptedFromFgsRestriction(r.appInfo.packageName, r.appInfo.uid) || isPackageExemptedFromFgsRestriction(callingPackage, callingUid)) { - ret = FGS_FEATURE_ALLOWED_BY_EXEMPTED_PACKAGES; + ret = REASON_EXEMPTED_PACKAGE; } } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { final boolean isCompanionApp = mAm.mInternal.isAssociatedCompanionApp( UserHandle.getUserId(callingUid), callingUid); if (isCompanionApp) { - ret = FGS_FEATURE_ALLOWED_BY_COMPANION_APP; + ret = REASON_COMPANION_DEVICE_MANAGER; } } @@ -5626,7 +5605,15 @@ public final class ActiveServices { + "; callingUid: " + callingUid + "; uidState: " + ProcessList.makeProcStateString(uidState) + "; intent: " + intent - + "; code:" + fgsCodeToString(ret) + + "; code:" + reasonCodeToString(ret) + + "; tempAllowListReason:<" + + (tempAllowListReason == null ? null : + (tempAllowListReason.mReason + + ",reasonCode:" + + reasonCodeToString(tempAllowListReason.mReasonCode) + + ",duration:" + tempAllowListReason.mDuration + + ",callingUid:" + tempAllowListReason.mCallingUid)) + + ">" + "; extra:" + sb.toString() + "; targetSdkVersion:" + r.appInfo.targetSdkVersion + "]"; @@ -5660,62 +5647,11 @@ public final class ActiveServices { return CompatChanges.isChangeEnabled(FGS_BG_START_USE_EXEMPTION_LIST_CHANGE_ID, uid); } - static String fgsCodeToString(@FgsFeatureRetCode int code) { - switch (code) { - case FGS_FEATURE_DENIED: - return "DENIED"; - case FGS_FEATURE_ALLOWED_BY_UID_STATE: - return "ALLOWED_BY_UID_STATE"; - case FGS_FEATURE_ALLOWED_BY_PROC_STATE: - return "ALLOWED_BY_PROC_STATE"; - case FGS_FEATURE_ALLOWED_BY_UID_VISIBLE: - return "ALLOWED_BY_UID_VISIBLE"; - case FGS_FEATURE_ALLOWED_BY_FLAG: - return "ALLOWED_BY_FLAG"; - case FGS_FEATURE_ALLOWED_BY_SYSTEM_UID: - return "ALLOWED_BY_SYSTEM_UID"; - case FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION: - return "ALLOWED_BY_INSTR_BACKGROUND_ACTIVITY_PERMISSION"; - case FGS_FEATURE_ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION: - return "ALLOWED_BY_INSTR_BACKGROUND_FGS_PERMISSION"; - case FGS_FEATURE_ALLOWED_BY_ACTIVITY_TOKEN: - return "ALLOWED_BY_ACTIVITY_TOKEN"; - case FGS_FEATURE_ALLOWED_BY_FGS_TOKEN: - return "ALLOWED_BY_FGS_TOKEN"; - case FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION: - return "ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION"; - case FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION: - return "ALLOWED_BY_BACKGROUND_FGS_PERMISSION"; - case FGS_FEATURE_ALLOWED_BY_ALLOWLIST: - return "ALLOWED_BY_ALLOWLIST"; - case FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER: - return "ALLOWED_BY_DEVICE_OWNER"; - case FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST: - return "ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST"; - case FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION: - return "ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION"; - case FGS_FEATURE_ALLOWED_BY_FGS_BINDING: - return "ALLOWED_BY_FGS_BINDING"; - case FGS_FEATURE_ALLOWED_BY_DEVICE_DEMO_MODE: - return "ALLOWED_BY_DEVICE_DEMO_MODE"; - case FGS_FEATURE_ALLOWED_BY_PROCESS_RECORD: - return "ALLOWED_BY_PROCESS_RECORD"; - case FGS_FEATURE_ALLOWED_BY_EXEMPTED_PACKAGES: - return "FGS_FEATURE_ALLOWED_BY_EXEMPTED_PACKAGES"; - case FGS_FEATURE_ALLOWED_BY_ACTIVITY_STARTER: - return "ALLOWED_BY_ACTIVITY_STARTER"; - case FGS_FEATURE_ALLOWED_BY_COMPANION_APP: - return "ALLOWED_BY_COMPANION_APP"; - case FGS_FEATURE_ALLOWED_BY_PROFILE_OWNER: - return "ALLOWED_BY_PROFILE_OWNER"; - default: - return ""; - } - } - - private static boolean isFgsBgStart(@FgsFeatureRetCode int code) { - return code != FGS_FEATURE_ALLOWED_BY_UID_STATE - && code != FGS_FEATURE_ALLOWED_BY_UID_VISIBLE; + private static boolean isFgsBgStart(@ReasonCode int code) { + return code != REASON_PROC_STATE_PERSISTENT + && code != REASON_PROC_STATE_PERSISTENT_UI + && code != REASON_PROC_STATE_TOP + && code != REASON_UID_VISIBLE; } // TODO: remove this notification after feature development is done @@ -5754,10 +5690,10 @@ public final class ActiveServices { } if (!r.mLoggedInfoAllowStartForeground) { final String msg = "Background started FGS: " - + ((r.mAllowStartForeground != FGS_FEATURE_DENIED) ? "Allowed " : "Disallowed ") + + ((r.mAllowStartForeground != REASON_DENIED) ? "Allowed " : "Disallowed ") + r.mInfoAllowStartForeground; Slog.wtfQuiet(TAG, msg); - if (r.mAllowStartForeground != FGS_FEATURE_DENIED) { + if (r.mAllowStartForeground != REASON_DENIED) { Slog.i(TAG, msg); } else { Slog.w(TAG, msg); diff --git a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java index 171b20c03689..9d1c83894d46 100644 --- a/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java +++ b/services/core/java/com/android/server/am/ActivityManagerDebugConfig.java @@ -68,7 +68,7 @@ class ActivityManagerDebugConfig { static final boolean DEBUG_UID_OBSERVERS = DEBUG_ALL || false; static final boolean DEBUG_USAGE_STATS = DEBUG_ALL || false; static final boolean DEBUG_PERMISSIONS_REVIEW = DEBUG_ALL || false; - static final boolean DEBUG_WHITELISTS = DEBUG_ALL || false; + static final boolean DEBUG_ALLOWLISTS = DEBUG_ALL || false; static final String POSTFIX_BACKUP = (APPEND_CATEGORY_NAME) ? "_Backup" : ""; static final String POSTFIX_BROADCAST = (APPEND_CATEGORY_NAME) ? "_Broadcast" : ""; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a36d913ee669..5e61f94826c1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -33,7 +33,6 @@ import static android.app.ActivityManager.PROCESS_STATE_TOP; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.AppOpsManager.OP_NONE; -import static android.app.BroadcastOptions.TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT; import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES; import static android.content.pm.PackageManager.MATCH_ALL; @@ -50,8 +49,12 @@ import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH; import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL; import static android.os.IServiceManager.DUMP_FLAG_PROTO; +import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALLOW_LISTED; +import static android.os.PowerWhitelistManager.REASON_UNKNOWN; +import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED; import static android.os.Process.BLUETOOTH_UID; import static android.os.Process.FIRST_APPLICATION_UID; +import static android.os.Process.INVALID_UID; import static android.os.Process.NETWORK_STACK_UID; import static android.os.Process.NFC_UID; import static android.os.Process.PHONE_UID; @@ -101,7 +104,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE; -import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALLOWLISTS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP; @@ -253,6 +256,7 @@ import android.os.ParcelFileDescriptor; import android.os.PowerManager; import android.os.PowerManager.ServiceType; import android.os.PowerManagerInternal; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.PowerWhitelistManager.TempAllowListType; import android.os.Process; import android.os.RemoteCallback; @@ -625,7 +629,7 @@ public class ActivityManagerService extends IActivityManager.Stub */ private volatile String mDeviceOwnerName; - private volatile int mDeviceOwnerUid = Process.INVALID_UID; + private volatile int mDeviceOwnerUid = INVALID_UID; /** * Map userId to its companion app uids. @@ -1151,13 +1155,13 @@ public class ActivityManagerService extends IActivityManager.Stub DeviceIdleInternal mLocalDeviceIdleController; /** - * Power-save whitelisted app-ids (not including except-idle-whitelisted ones). + * Power-save allowlisted app-ids (not including except-idle-allowlisted ones). */ @CompositeRWLock({"this", "mProcLock"}) int[] mDeviceIdleAllowlist = new int[0]; /** - * Power-save whitelisted app-ids (including except-idle-whitelisted ones). + * Power-save allowlisted app-ids (including except-idle-allowlisted ones). */ @CompositeRWLock({"this", "mProcLock"}) int[] mDeviceIdleExceptIdleAllowlist = new int[0]; @@ -1173,20 +1177,27 @@ public class ActivityManagerService extends IActivityManager.Stub final long duration; final String tag; final int type; + final @ReasonCode int reasonCode; - PendingTempAllowlist(int targetUid, long duration, String tag, int type) { + PendingTempAllowlist(int targetUid, long duration, @ReasonCode int reasonCode, String tag, + int type) { this.targetUid = targetUid; this.duration = duration; this.tag = tag; this.type = type; + this.reasonCode = reasonCode; } void dumpDebug(ProtoOutputStream proto, long fieldId) { final long token = proto.start(fieldId); - proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, targetUid); - proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, duration); + proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TARGET_UID, + targetUid); + proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.DURATION_MS, + duration); proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TAG, tag); proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.TYPE, type); + proto.write(ActivityManagerServiceDumpProcessesProto.PendingTempWhitelist.REASON_CODE, + reasonCode); proto.end(token); } } @@ -1200,6 +1211,9 @@ public class ActivityManagerService extends IActivityManager.Stub @CompositeRWLock({"this", "mProcLock"}) final FgsStartTempAllowList mFgsStartTempAllowList = new FgsStartTempAllowList(); + static final FgsStartTempAllowList.TempFgsAllowListEntry FAKE_TEMP_ALLOWLIST_ENTRY = new + FgsStartTempAllowList.TempFgsAllowListEntry(Long.MAX_VALUE, Long.MAX_VALUE, + REASON_SYSTEM_ALLOW_LISTED, "", INVALID_UID); /** * Information about and control over application operations */ @@ -4829,12 +4843,12 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code, + public int sendIntentSender(IIntentSender target, IBinder allowlistToken, int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { if (target instanceof PendingIntentRecord) { return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType, - whitelistToken, finishedReceiver, requiredPermission, options); + allowlistToken, finishedReceiver, requiredPermission, options); } else { if (intent == null) { // Weird case: someone has given us their own custom IIntentSender, and now @@ -4846,7 +4860,7 @@ public class ActivityManagerService extends IActivityManager.Stub intent = new Intent(Intent.ACTION_MAIN); } try { - target.send(code, intent, resolvedType, whitelistToken, null, + target.send(code, intent, resolvedType, allowlistToken, null, requiredPermission, options); } catch (RemoteException e) { } @@ -5414,7 +5428,7 @@ public class ActivityManagerService extends IActivityManager.Stub } switch (appop) { case AppOpsManager.MODE_ALLOWED: - // If force-background-check is enabled, restrict all apps that aren't whitelisted. + // If force-background-check is enabled, restrict all apps that aren't allowlisted. if (mForceBackgroundCheck && !UserHandle.isCore(uid) && !isOnDeviceIdleAllowlistLOSP(uid, /*allowExceptIdleToo=*/ true)) { @@ -5450,7 +5464,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (uidOnBackgroundAllowlistLOSP(uid)) { if (DEBUG_BACKGROUND_CHECK) { Slog.i(TAG, "App " + uid + "/" + packageName - + " on background whitelist; not restricted in background"); + + " on background allowlist; not restricted in background"); } return ActivityManager.APP_START_MODE_NORMAL; } @@ -5459,7 +5473,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (isOnDeviceIdleAllowlistLOSP(uid, /*allowExceptIdleToo=*/ false)) { if (DEBUG_BACKGROUND_CHECK) { Slog.i(TAG, "App " + uid + "/" + packageName - + " on idle whitelist; not restricted in background"); + + " on idle allowlist; not restricted in background"); } return ActivityManager.APP_START_MODE_NORMAL; } @@ -5547,10 +5561,19 @@ public class ActivityManagerService extends IActivityManager.Stub || mPendingTempAllowlist.indexOfKey(uid) >= 0; } + /** + * Is the uid allowlisted to start FGS? + * @param uid + * @return a TempAllowListEntry if the uid is allowed. + * null if the uid is not allowed. + */ + @Nullable @GuardedBy(anyOf = {"this", "mProcLock"}) - boolean isAllowlistedForFgsStartLOSP(int uid) { - return Arrays.binarySearch(mDeviceIdleExceptIdleAllowlist, UserHandle.getAppId(uid)) >= 0 - || mFgsStartTempAllowList.isAllowed(uid); + FgsStartTempAllowList.TempFgsAllowListEntry isAllowlistedForFgsStartLOSP(int uid) { + if (Arrays.binarySearch(mDeviceIdleExceptIdleAllowlist, UserHandle.getAppId(uid)) >= 0) { + return FAKE_TEMP_ALLOWLIST_ENTRY; + } + return mFgsStartTempAllowList.getAllowedDurationAndReason(uid); } /** @@ -6022,13 +6045,13 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void backgroundWhitelistUid(final int uid) { + public void backgroundAllowlistUid(final int uid) { if (Binder.getCallingUid() != Process.SYSTEM_UID) { - throw new SecurityException("Only the OS may call backgroundWhitelistUid()"); + throw new SecurityException("Only the OS may call backgroundAllowlistUid()"); } if (DEBUG_BACKGROUND_CHECK) { - Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist"); + Slog.i(TAG, "Adding uid " + uid + " to bg uid allowlist"); } synchronized (this) { synchronized (mProcLock) { @@ -8271,7 +8294,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (!TextUtils.isEmpty(packageName)) { final int uid = enforceDumpPermissionForPackage(packageName, userId, callingUid, "getHistoricalProcessExitReasons"); - if (uid != Process.INVALID_UID) { + if (uid != INVALID_UID) { mProcessList.mAppExitInfoTracker.getExitInfo( packageName, uid, pid, maxNum, results); tombstoneService.collectTombstones(results, uid, pid, maxNum); @@ -8305,7 +8328,7 @@ public class ActivityManagerService extends IActivityManager.Stub int enforceDumpPermissionForPackage(String packageName, int userId, int callingUid, String function) { final long identity = Binder.clearCallingIdentity(); - int uid = Process.INVALID_UID; + int uid = INVALID_UID; try { uid = mPackageManagerInt.getPackageUid(packageName, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId); @@ -9197,6 +9220,8 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(ptw.tag); pw.print(" "); pw.print(ptw.type); + pw.print(" "); + pw.print(ptw.reasonCode); } } } @@ -10382,6 +10407,8 @@ public class ActivityManagerService extends IActivityManager.Stub } endTime = SystemClock.currentThreadTimeMillis(); hasSwapPss = mi.hasSwappedOutPss; + memtrackGraphics = mi.getOtherPrivate(Debug.MemoryInfo.OTHER_GRAPHICS); + memtrackGl = mi.getOtherPrivate(Debug.MemoryInfo.OTHER_GL); } else { reportType = ProcessStats.ADD_PSS_EXTERNAL; startTime = SystemClock.currentThreadTimeMillis(); @@ -10533,6 +10560,8 @@ public class ActivityManagerService extends IActivityManager.Stub if (!Debug.getMemoryInfo(st.pid, info)) { return; } + memtrackGraphics = info.getOtherPrivate(Debug.MemoryInfo.OTHER_GRAPHICS); + memtrackGl = info.getOtherPrivate(Debug.MemoryInfo.OTHER_GL); } else { long pss = Debug.getPss(st.pid, tmpLong, memtrackTmp); if (pss == 0) { @@ -12550,7 +12579,7 @@ public class ActivityManagerService extends IActivityManager.Stub BroadcastOptions brOptions = null; if (bOptions != null) { brOptions = new BroadcastOptions(bOptions); - if (brOptions.getTemporaryAppWhitelistDuration() > 0) { + if (brOptions.getTemporaryAppAllowlistDuration() > 0) { // See if the caller is allowed to do this. Note we are checking against // the actual real caller (not whoever provided the operation as say a // PendingIntent), because that who is actually supplied the arguments. @@ -14432,8 +14461,8 @@ public class ActivityManagerService extends IActivityManager.Stub */ @GuardedBy("this") void tempAllowlistForPendingIntentLocked(int callerPid, int callerUid, int targetUid, - long duration, int type, String tag) { - if (DEBUG_WHITELISTS) { + long duration, int type, @ReasonCode int reasonCode, String reason) { + if (DEBUG_ALLOWLISTS) { Slog.d(TAG, "tempAllowlistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", " + targetUid + ", " + duration + ", " + type + ")"); } @@ -14452,7 +14481,7 @@ public class ActivityManagerService extends IActivityManager.Stub != PackageManager.PERMISSION_GRANTED && checkPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND, callerPid, callerUid) != PackageManager.PERMISSION_GRANTED) { - if (DEBUG_WHITELISTS) { + if (DEBUG_ALLOWLISTS) { Slog.d(TAG, "tempAllowlistForPendingIntentLocked() for target " + targetUid + ": pid " + callerPid + " is not allowed"); } @@ -14461,22 +14490,23 @@ public class ActivityManagerService extends IActivityManager.Stub } } - tempAllowlistUidLocked(targetUid, duration, tag, type); + tempAllowlistUidLocked(targetUid, duration, reasonCode, reason, type, callerUid); } /** * Allowlists {@code targetUid} to temporarily bypass Power Save mode. */ @GuardedBy("this") - void tempAllowlistUidLocked(int targetUid, long duration, String tag, int type) { + void tempAllowlistUidLocked(int targetUid, long duration, @ReasonCode int reasonCode, + String reason, int type, int callingUid) { synchronized (mProcLock) { mPendingTempAllowlist.put(targetUid, - new PendingTempAllowlist(targetUid, duration, tag, type)); + new PendingTempAllowlist(targetUid, duration, reasonCode, reason, type)); setUidTempAllowlistStateLSP(targetUid, true); mUiHandler.obtainMessage(PUSH_TEMP_ALLOWLIST_UI_MSG).sendToTarget(); - if (type == TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED) { - mFgsStartTempAllowList.add(targetUid, duration); + if (type == TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED) { + mFgsStartTempAllowList.add(targetUid, duration, reasonCode, reason, callingUid); } } } @@ -14502,7 +14532,7 @@ public class ActivityManagerService extends IActivityManager.Stub for (int i = 0; i < N; i++) { PendingTempAllowlist ptw = list[i]; mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid, - ptw.duration, ptw.type, true, ptw.tag); + ptw.duration, ptw.type, true, ptw.reasonCode, ptw.tag); } } @@ -15090,10 +15120,17 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken, + public void setPendingIntentAllowlistDuration(IIntentSender target, IBinder allowlistToken, + long duration, int type, @ReasonCode int reasonCode, @Nullable String reason) { + mPendingIntentController.setPendingIntentAllowlistDuration(target, allowlistToken, + duration, type, reasonCode, reason); + } + + @Override + public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder allowlistToken, long duration, int type) { - mPendingIntentController.setPendingIntentWhitelistDuration(target, whitelistToken, - duration, type); + mPendingIntentController.setPendingIntentAllowlistDuration(target, allowlistToken, + duration, type, REASON_UNKNOWN, ""); } @Override @@ -15103,32 +15140,32 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setPendingIntentAllowBgActivityStarts(IIntentSender target, - IBinder whitelistToken, int flags) { + IBinder allowlistToken, int flags) { if (!(target instanceof PendingIntentRecord)) { Slog.w(TAG, "setPendingIntentAllowBgActivityStarts():" + " not a PendingIntentRecord: " + target); return; } synchronized (ActivityManagerService.this) { - ((PendingIntentRecord) target).setAllowBgActivityStarts(whitelistToken, flags); + ((PendingIntentRecord) target).setAllowBgActivityStarts(allowlistToken, flags); } } @Override public void clearPendingIntentAllowBgActivityStarts(IIntentSender target, - IBinder whitelistToken) { + IBinder allowlistToken) { if (!(target instanceof PendingIntentRecord)) { Slog.w(TAG, "clearPendingIntentAllowBgActivityStarts():" + " not a PendingIntentRecord: " + target); return; } synchronized (ActivityManagerService.this) { - ((PendingIntentRecord) target).clearAllowBgActivityStarts(whitelistToken); + ((PendingIntentRecord) target).clearAllowBgActivityStarts(allowlistToken); } } @Override - public void setDeviceIdleWhitelist(int[] allAppids, int[] exceptIdleAppids) { + public void setDeviceIdleAllowlist(int[] allAppids, int[] exceptIdleAppids) { synchronized (ActivityManagerService.this) { synchronized (mProcLock) { mDeviceIdleAllowlist = allAppids; @@ -15138,17 +15175,19 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void updateDeviceIdleTempWhitelist(int[] appids, int changingUid, boolean adding, - long durationMs, @TempAllowListType int type) { + public void updateDeviceIdleTempAllowlist(int[] appids, int changingUid, boolean adding, + long durationMs, @TempAllowListType int type, @ReasonCode int reasonCode, + @Nullable String reason, int callingUid) { synchronized (ActivityManagerService.this) { synchronized (mProcLock) { mDeviceIdleTempAllowlist = appids; if (adding) { - if (type == TEMPORARY_WHITELIST_TYPE_FOREGROUND_SERVICE_ALLOWED) { - mFgsStartTempAllowList.add(changingUid, durationMs); + if (type == TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED) { + mFgsStartTempAllowList.add(changingUid, durationMs, reasonCode, reason, + callingUid); } + setAppIdTempAllowlistStateLSP(changingUid, adding); } - setAppIdTempAllowlistStateLSP(changingUid, adding); } } } @@ -15509,11 +15548,11 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void tempWhitelistForPendingIntent(int callerPid, int callerUid, int targetUid, - long duration, int type, String tag) { + public void tempAllowlistForPendingIntent(int callerPid, int callerUid, int targetUid, + long duration, int type, @ReasonCode int reasonCode, String reason) { synchronized (ActivityManagerService.this) { ActivityManagerService.this.tempAllowlistForPendingIntentLocked( - callerPid, callerUid, targetUid, duration, type, tag); + callerPid, callerUid, targetUid, duration, type, reasonCode, reason); } } diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index c8630fa52973..f8494d8a7c04 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -1327,6 +1327,8 @@ public class AppProfiler { // Get a list of Stats that have vsize > 0 final List<ProcessCpuTracker.Stats> stats = getCpuStats(st -> st.vsize > 0); final int statsCount = stats.size(); + long totalMemtrackGraphics = 0; + long totalMemtrackGl = 0; for (int i = 0; i < statsCount; i++) { ProcessCpuTracker.Stats st = stats.get(i); long pss = Debug.getPss(st.pid, swaptrackTmp, memtrackTmp); @@ -1337,6 +1339,8 @@ public class AppProfiler { mi.pss = pss; mi.swapPss = swaptrackTmp[1]; mi.memtrack = memtrackTmp[0]; + totalMemtrackGraphics += memtrackTmp[1]; + totalMemtrackGl += memtrackTmp[2]; memInfos.add(mi); } } @@ -1345,20 +1349,18 @@ public class AppProfiler { long totalPss = 0; long totalSwapPss = 0; long totalMemtrack = 0; - long totalMemtrackGraphics = 0; - long totalMemtrackGl = 0; for (int i = 0, size = memInfos.size(); i < size; i++) { ProcessMemInfo mi = memInfos.get(i); if (mi.pss == 0) { mi.pss = Debug.getPss(mi.pid, swaptrackTmp, memtrackTmp); mi.swapPss = swaptrackTmp[1]; mi.memtrack = memtrackTmp[0]; + totalMemtrackGraphics += memtrackTmp[1]; + totalMemtrackGl += memtrackTmp[2]; } totalPss += mi.pss; totalSwapPss += mi.swapPss; totalMemtrack += mi.memtrack; - totalMemtrackGraphics += memtrackTmp[1]; - totalMemtrackGl += memtrackTmp[2]; } Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 34ff77494f94..29061930cd84 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -22,6 +22,7 @@ import static android.text.TextUtils.formatSimple; import static com.android.server.am.ActivityManagerDebugConfig.*; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.AppGlobals; import android.app.AppOpsManager; @@ -43,6 +44,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.PowerWhitelistManager; import android.os.PowerWhitelistManager.TempAllowListType; import android.os.Process; import android.os.RemoteException; @@ -903,8 +905,9 @@ public final class BroadcastQueue { return false; } - final void scheduleTempWhitelistLocked(int uid, long duration, BroadcastRecord r, - @TempAllowListType int type) { + final void scheduleTempAllowlistLocked(int uid, long duration, BroadcastRecord r, + @TempAllowListType int type, @PowerWhitelistManager.ReasonCode int reasonCode, + @Nullable String reason) { if (duration > Integer.MAX_VALUE) { duration = Integer.MAX_VALUE; } @@ -926,10 +929,11 @@ public final class BroadcastQueue { b.append(r.intent.getData()); } if (DEBUG_BROADCAST) { - Slog.v(TAG, "Broadcast temp whitelist uid=" + uid + " duration=" + duration + Slog.v(TAG, "Broadcast temp allowlist uid=" + uid + " duration=" + duration + " type=" + type + " : " + b.toString()); } - mService.tempAllowlistUidLocked(uid, duration, b.toString(), type); + mService.tempAllowlistUidLocked(uid, duration, reasonCode, b.toString(), type, + r.callingUid); } /** @@ -1332,10 +1336,12 @@ public final class BroadcastQueue { // r is guaranteed ordered at this point, so we know finishReceiverLocked() // will get a callback and handle the activity start token lifecycle. } - if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) { - scheduleTempWhitelistLocked(filter.owningUid, - brOptions.getTemporaryAppWhitelistDuration(), r, - brOptions.getTemporaryAppWhitelistType()); + if (brOptions != null && brOptions.getTemporaryAppAllowlistDuration() > 0) { + scheduleTempAllowlistLocked(filter.owningUid, + brOptions.getTemporaryAppAllowlistDuration(), r, + brOptions.getTemporaryAppAllowlistType(), + brOptions.getTemporaryAppAllowlistReasonCode(), + brOptions.getTemporaryAppAllowlistReason()); } } return; @@ -1619,11 +1625,13 @@ public final class BroadcastQueue { } final boolean isActivityCapable = - (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0); + (brOptions != null && brOptions.getTemporaryAppAllowlistDuration() > 0); if (isActivityCapable) { - scheduleTempWhitelistLocked(receiverUid, - brOptions.getTemporaryAppWhitelistDuration(), r, - brOptions.getTemporaryAppWhitelistType()); + scheduleTempAllowlistLocked(receiverUid, + brOptions.getTemporaryAppAllowlistDuration(), r, + brOptions.getTemporaryAppAllowlistType(), + brOptions.getTemporaryAppAllowlistReasonCode(), + brOptions.getTemporaryAppAllowlistReason()); } // Broadcast is being executed, its package can't be stopped. diff --git a/services/core/java/com/android/server/am/FgsStartTempAllowList.java b/services/core/java/com/android/server/am/FgsStartTempAllowList.java index 4d8749c05294..1f897b5928ce 100644 --- a/services/core/java/com/android/server/am/FgsStartTempAllowList.java +++ b/services/core/java/com/android/server/am/FgsStartTempAllowList.java @@ -18,24 +18,53 @@ package com.android.server.am; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; +import android.annotation.Nullable; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.SystemClock; import android.util.Slog; -import android.util.SparseLongArray; +import android.util.SparseArray; /** * List of uids that are temporarily allowed to start FGS from background. */ final class FgsStartTempAllowList { private static final int MAX_SIZE = 100; + + public static final class TempFgsAllowListEntry { + final long mExpirationTime; + final long mDuration; + final @ReasonCode int mReasonCode; + final String mReason; + final int mCallingUid; + + TempFgsAllowListEntry(long expirationTime, long duration, @ReasonCode int reasonCode, + String reason, int callingUid) { + mExpirationTime = expirationTime; + mDuration = duration; + mReasonCode = reasonCode; + mReason = reason; + mCallingUid = callingUid; + } + } + /** - * The key is the uid, the value is expiration elapse time in ms of this temp-allowed uid. + * The key is the uid, the value is a TempAllowListEntry. */ - private final SparseLongArray mTempAllowListFgs = new SparseLongArray(); + private final SparseArray<TempFgsAllowListEntry> mTempAllowListFgs = new SparseArray<>(); FgsStartTempAllowList() { } - void add(int uid, long duration) { + /** + * Add a uid and its duration with reason into the FGS temp-allowlist. + * @param uid + * @param duration temp-allowlisted duration in milliseconds. + * @param reason A human-readable reason for logging purposes. + * @param callingUid the callingUid that setup this temp allowlist, only valid when param adding + * is true. + */ + void add(int uid, long duration, @ReasonCode int reasonCode, @Nullable String reason, + int callingUid) { if (duration <= 0) { Slog.e(TAG_AM, "FgsStartTempAllowList bad duration:" + duration + " uid: " + uid); @@ -48,26 +77,36 @@ final class FgsStartTempAllowList { } final long now = SystemClock.elapsedRealtime(); for (int index = mTempAllowListFgs.size() - 1; index >= 0; index--) { - if (mTempAllowListFgs.valueAt(index) < now) { + if (mTempAllowListFgs.valueAt(index).mExpirationTime < now) { mTempAllowListFgs.removeAt(index); } } - final long existingExpirationTime = mTempAllowListFgs.get(uid, -1); + final TempFgsAllowListEntry existing = mTempAllowListFgs.get(uid); final long expirationTime = now + duration; - if (existingExpirationTime == -1 || existingExpirationTime < expirationTime) { - mTempAllowListFgs.put(uid, expirationTime); + if (existing == null || existing.mExpirationTime < expirationTime) { + mTempAllowListFgs.put(uid, + new TempFgsAllowListEntry(expirationTime, duration, reasonCode, + reason == null ? "" : reason, callingUid)); } } - boolean isAllowed(int uid) { + /** + * Is this uid temp-allowlisted to start FGS. + * @param uid + * @return If uid is in the temp-allowlist, return the {@link TempFgsAllowListEntry}; If not in + * temp-allowlist, return null. + */ + @Nullable + TempFgsAllowListEntry getAllowedDurationAndReason(int uid) { final int index = mTempAllowListFgs.indexOfKey(uid); if (index < 0) { - return false; - } else if (mTempAllowListFgs.valueAt(index) < SystemClock.elapsedRealtime()) { + return null; + } else if (mTempAllowListFgs.valueAt(index).mExpirationTime + < SystemClock.elapsedRealtime()) { mTempAllowListFgs.removeAt(index); - return false; + return null; } else { - return true; + return mTempAllowListFgs.valueAt(index); } } diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index b956e306dc3f..24953fc9c5d6 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -42,6 +42,7 @@ import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; +import static android.os.PowerWhitelistManager.REASON_DENIED; import static android.os.Process.SCHED_OTHER; import static android.os.Process.THREAD_GROUP_BACKGROUND; import static android.os.Process.THREAD_GROUP_DEFAULT; @@ -52,7 +53,6 @@ import static android.os.Process.setProcessGroup; import static android.os.Process.setThreadPriority; import static android.os.Process.setThreadScheduler; -import static com.android.server.am.ActiveServices.FGS_FEATURE_DENIED; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; @@ -1968,7 +1968,7 @@ public final class OomAdjuster { int clientProcState = cstate.getCurRawProcState(); // pass client's mAllowStartFgs to the app if client is not persistent process. - if (cstate.getAllowedStartFgs() != FGS_FEATURE_DENIED + if (cstate.getAllowedStartFgs() != REASON_DENIED && cstate.getMaxAdj() >= ProcessList.FOREGROUND_APP_ADJ) { state.setAllowStartFgs(cstate.getAllowedStartFgs()); } diff --git a/services/core/java/com/android/server/am/PendingIntentController.java b/services/core/java/com/android/server/am/PendingIntentController.java index 42172bf7e1df..534bd84a91a3 100644 --- a/services/core/java/com/android/server/am/PendingIntentController.java +++ b/services/core/java/com/android/server/am/PendingIntentController.java @@ -36,6 +36,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.PowerWhitelistManager; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; @@ -300,15 +301,16 @@ public class PendingIntentController { } } - void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken, - long duration, int type) { + void setPendingIntentAllowlistDuration(IIntentSender target, IBinder allowlistToken, + long duration, int type, @PowerWhitelistManager.ReasonCode int reasonCode, + @Nullable String reason) { if (!(target instanceof PendingIntentRecord)) { Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target); return; } synchronized (mLock) { - ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration, - type); + ((PendingIntentRecord) target).setAllowlistDurationLocked(allowlistToken, duration, + type, reasonCode, reason); } } diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 0eb48f6da60d..51666acb8134 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -31,13 +31,14 @@ import android.content.Intent; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; +import android.os.PowerWhitelistManager; +import android.os.PowerWhitelistManager.ReasonCode; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.TransactionTooLargeException; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; -import android.util.Pair; import android.util.Slog; import android.util.TimeUtils; @@ -67,7 +68,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub { * milliseconds, Integer is allowlist type defined at * {@link android.os.PowerWhitelistManager.TempAllowListType} */ - private ArrayMap<IBinder, Pair<Long, Integer>> mWhitelistDuration; + private ArrayMap<IBinder, TempAllowListDuration> mAllowlistDuration; private RemoteCallbackList<IResultReceiver> mCancelCallbacks; private ArraySet<IBinder> mAllowBgActivityStartsForActivitySender = new ArraySet<>(); private ArraySet<IBinder> mAllowBgActivityStartsForBroadcastSender = new ArraySet<>(); @@ -214,6 +215,21 @@ public final class PendingIntentRecord extends IIntentSender.Stub { } } + static final class TempAllowListDuration { + long duration; + int type; + @ReasonCode int reasonCode; + @Nullable String reason; + + TempAllowListDuration(long _duration, int _type, @ReasonCode int _reasonCode, + String _reason) { + duration = _duration; + type = _type; + reasonCode = _reasonCode; + reason = _reason; + } + } + PendingIntentRecord(PendingIntentController _controller, Key _k, int _u) { controller = _controller; key = _k; @@ -221,18 +237,19 @@ public final class PendingIntentRecord extends IIntentSender.Stub { ref = new WeakReference<>(this); } - void setWhitelistDurationLocked(IBinder whitelistToken, long duration, int type) { + void setAllowlistDurationLocked(IBinder allowlistToken, long duration, int type, + @ReasonCode int reasonCode, @Nullable String reason) { if (duration > 0) { - if (mWhitelistDuration == null) { - mWhitelistDuration = new ArrayMap<>(); + if (mAllowlistDuration == null) { + mAllowlistDuration = new ArrayMap<>(); } - mWhitelistDuration.put(whitelistToken, new Pair(duration, type)); - } else if (mWhitelistDuration != null) { - mWhitelistDuration.remove(whitelistToken); - if (mWhitelistDuration.size() <= 0) { - mWhitelistDuration = null; + mAllowlistDuration.put(allowlistToken, + new TempAllowListDuration(duration, type, reasonCode, reason)); + } else if (mAllowlistDuration != null) { + mAllowlistDuration.remove(allowlistToken); + if (mAllowlistDuration.size() <= 0) { + mAllowlistDuration = null; } - } this.stringName = null; } @@ -280,25 +297,25 @@ public final class PendingIntentRecord extends IIntentSender.Stub { return listeners; } - public void send(int code, Intent intent, String resolvedType, IBinder whitelistToken, + public void send(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { - sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver, + sendInner(code, intent, resolvedType, allowlistToken, finishedReceiver, requiredPermission, null, null, 0, 0, 0, options); } - public int sendWithResult(int code, Intent intent, String resolvedType, IBinder whitelistToken, + public int sendWithResult(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { - return sendInner(code, intent, resolvedType, whitelistToken, finishedReceiver, + return sendInner(code, intent, resolvedType, allowlistToken, finishedReceiver, requiredPermission, null, null, 0, 0, 0, options); } - public int sendInner(int code, Intent intent, String resolvedType, IBinder whitelistToken, + public int sendInner(int code, Intent intent, String resolvedType, IBinder allowlistToken, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle options) { if (intent != null) intent.setDefusable(true); if (options != null) options.setDefusable(true); - Pair<Long, Integer> duration = null; + TempAllowListDuration duration = null; Intent finalIntent = null; Intent[] allIntents = null; String[] allResolvedTypes = null; @@ -347,8 +364,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { mergedOptions.setCallerOptions(opts); } - if (mWhitelistDuration != null) { - duration = mWhitelistDuration.get(whitelistToken); + if (mAllowlistDuration != null) { + duration = mAllowlistDuration.get(allowlistToken); } if (key.type == ActivityManager.INTENT_SENDER_ACTIVITY @@ -377,7 +394,9 @@ public final class PendingIntentRecord extends IIntentSender.Stub { try { if (duration != null) { StringBuilder tag = new StringBuilder(64); - tag.append("pendingintent:"); + tag.append("setPendingIntentAllowlistDuration,reason:"); + tag.append(duration.reason == null ? "" : duration.reason); + tag.append(",pendingintent:"); UserHandle.formatUid(tag, callingUid); tag.append(":"); if (finalIntent.getAction() != null) { @@ -387,8 +406,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { } else if (finalIntent.getData() != null) { tag.append(finalIntent.getData().toSafeString()); } - controller.mAmInternal.tempWhitelistForPendingIntent(callingPid, callingUid, - uid, duration.first, duration.second, tag.toString()); + controller.mAmInternal.tempAllowlistForPendingIntent(callingPid, callingUid, + uid, duration.duration, duration.type, duration.reasonCode, tag.toString()); } boolean sendFinish = finishedReceiver != null; @@ -417,7 +436,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { allIntents, allResolvedTypes, resultTo, mergedOptions, userId, false /* validateIncomingUser */, this /* originatingPendingIntent */, - mAllowBgActivityStartsForActivitySender.contains(whitelistToken)); + mAllowBgActivityStartsForActivitySender.contains( + allowlistToken)); } else { res = controller.mAtmInternal.startActivityInPackage(uid, callingPid, callingUid, key.packageName, key.featureId, finalIntent, @@ -426,7 +446,7 @@ public final class PendingIntentRecord extends IIntentSender.Stub { false /* validateIncomingUser */, this /* originatingPendingIntent */, mAllowBgActivityStartsForActivitySender.contains( - whitelistToken)); + allowlistToken)); } } catch (RuntimeException e) { Slog.w(TAG, "Unable to send startActivity intent", e); @@ -439,8 +459,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { case ActivityManager.INTENT_SENDER_BROADCAST: try { final boolean allowedByToken = - mAllowBgActivityStartsForBroadcastSender.contains(whitelistToken); - final IBinder bgStartsToken = (allowedByToken) ? whitelistToken : null; + mAllowBgActivityStartsForBroadcastSender.contains(allowlistToken); + final IBinder bgStartsToken = (allowedByToken) ? allowlistToken : null; // If a completion callback has been requested, require // that the broadcast be delivered synchronously @@ -460,8 +480,8 @@ public final class PendingIntentRecord extends IIntentSender.Stub { case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE: try { final boolean allowedByToken = - mAllowBgActivityStartsForServiceSender.contains(whitelistToken); - final IBinder bgStartsToken = (allowedByToken) ? whitelistToken : null; + mAllowBgActivityStartsForServiceSender.contains(allowlistToken); + final IBinder bgStartsToken = (allowedByToken) ? allowlistToken : null; controller.mAmInternal.startServiceInPackage(uid, finalIntent, resolvedType, key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE, @@ -533,18 +553,23 @@ public final class PendingIntentRecord extends IIntentSender.Stub { pw.print(prefix); pw.print("sent="); pw.print(sent); pw.print(" canceled="); pw.println(canceled); } - if (mWhitelistDuration != null) { + if (mAllowlistDuration != null) { pw.print(prefix); - pw.print("whitelistDuration="); - for (int i = 0; i < mWhitelistDuration.size(); i++) { + pw.print("allowlistDuration="); + for (int i = 0; i < mAllowlistDuration.size(); i++) { if (i != 0) { pw.print(", "); } - pw.print(Integer.toHexString(System.identityHashCode(mWhitelistDuration.keyAt(i)))); + TempAllowListDuration entry = mAllowlistDuration.valueAt(i); + pw.print(Integer.toHexString(System.identityHashCode(mAllowlistDuration.keyAt(i)))); pw.print(":"); - TimeUtils.formatDuration(mWhitelistDuration.valueAt(i).first, pw); + TimeUtils.formatDuration(entry.duration, pw); pw.print("/"); - pw.print(mWhitelistDuration.valueAt(i).second); + pw.print(entry.type); + pw.print("/"); + pw.print(PowerWhitelistManager.reasonCodeToString(entry.reasonCode)); + pw.print("/"); + pw.print(entry.reason); } pw.println(); } @@ -572,18 +597,23 @@ public final class PendingIntentRecord extends IIntentSender.Stub { } sb.append(' '); sb.append(key.typeName()); - if (mWhitelistDuration != null) { - sb.append( " (whitelist: "); - for (int i = 0; i < mWhitelistDuration.size(); i++) { + if (mAllowlistDuration != null) { + sb.append(" (allowlist: "); + for (int i = 0; i < mAllowlistDuration.size(); i++) { if (i != 0) { sb.append(","); } + TempAllowListDuration entry = mAllowlistDuration.valueAt(i); sb.append(Integer.toHexString(System.identityHashCode( - mWhitelistDuration.keyAt(i)))); + mAllowlistDuration.keyAt(i)))); sb.append(":"); - TimeUtils.formatDuration(mWhitelistDuration.valueAt(i).first, sb); + TimeUtils.formatDuration(entry.duration, sb); + sb.append("/"); + sb.append(entry.type); + sb.append("/"); + sb.append(PowerWhitelistManager.reasonCodeToString(entry.reasonCode)); sb.append("/"); - sb.append(mWhitelistDuration.valueAt(i).second); + sb.append(entry.reason); } sb.append(")"); } diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java index 499fbcb0642d..6d783fc63901 100644 --- a/services/core/java/com/android/server/am/ProcessStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessStateRecord.java @@ -23,22 +23,23 @@ 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_NONEXISTENT; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.os.PowerWhitelistManager.REASON_BACKGROUND_ACTIVITY_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_BACKGROUND_FGS_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_COMPANION_DEVICE_MANAGER; +import static android.os.PowerWhitelistManager.REASON_DENIED; +import static android.os.PowerWhitelistManager.REASON_DEVICE_OWNER; +import static android.os.PowerWhitelistManager.REASON_PROFILE_OWNER; +import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION; +import static android.os.PowerWhitelistManager.REASON_SYSTEM_ALLOW_LISTED; +import static android.os.PowerWhitelistManager.REASON_SYSTEM_UID; +import static android.os.PowerWhitelistManager.ReasonCode; +import static android.os.PowerWhitelistManager.getReasonCodeFromProcState; +import static android.os.PowerWhitelistManager.reasonCodeToString; import static android.os.Process.NFC_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_COMPANION_APP; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_PROC_STATE; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_PROFILE_OWNER; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION; -import static com.android.server.am.ActiveServices.FGS_FEATURE_ALLOWED_BY_SYSTEM_UID; -import static com.android.server.am.ActiveServices.FGS_FEATURE_DENIED; -import static com.android.server.am.ActiveServices.fgsCodeToString; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; import static com.android.server.am.ProcessRecord.TAG; @@ -329,7 +330,7 @@ final class ProcessStateRecord { * Does the process has permission to start FGS from background. */ @GuardedBy("mService") - private @ActiveServices.FgsFeatureRetCode int mAllowStartFgsByPermission; + private @ReasonCode int mAllowStartFgsByPermission = REASON_DENIED; /** * Can this process start FGS from background? @@ -337,7 +338,7 @@ final class ProcessStateRecord { * another process through service binding. */ @GuardedBy("mService") - private @ActiveServices.FgsFeatureRetCode int mAllowStartFgs; + private @ReasonCode int mAllowStartFgs = REASON_DENIED; /** * Debugging: primary thing impacting oom_adj. @@ -1152,44 +1153,47 @@ final class ProcessStateRecord { } @GuardedBy("mService") + int getAllowStartFgsState() { + return mAllowStartFgsState; + } + + @GuardedBy("mService") boolean isAllowedStartFgsState() { return mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE; } @GuardedBy("mService") void setAllowStartFgsByPermission() { - int ret = FGS_FEATURE_DENIED; - if (ret == FGS_FEATURE_DENIED) { - boolean isSystem = false; - final int uid = UserHandle.getAppId(mApp.info.uid); - switch (uid) { - case ROOT_UID: - case SYSTEM_UID: - case NFC_UID: - case SHELL_UID: - isSystem = true; - break; - default: - isSystem = false; - break; - } + int ret = REASON_DENIED; + boolean isSystem = false; + final int uid = UserHandle.getAppId(mApp.info.uid); + switch (uid) { + case ROOT_UID: + case SYSTEM_UID: + case NFC_UID: + case SHELL_UID: + isSystem = true; + break; + default: + isSystem = false; + break; + } - if (isSystem) { - ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_UID; - } + if (isSystem) { + ret = REASON_SYSTEM_UID; } - if (ret == FGS_FEATURE_DENIED) { + if (ret == REASON_DENIED) { if (ActivityManager.checkComponentPermission(START_ACTIVITIES_FROM_BACKGROUND, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { - ret = FGS_FEATURE_ALLOWED_BY_BACKGROUND_ACTIVITY_PERMISSION; + ret = REASON_BACKGROUND_ACTIVITY_PERMISSION; } else if (ActivityManager.checkComponentPermission( START_FOREGROUND_SERVICES_FROM_BACKGROUND, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { - ret = FGS_FEATURE_ALLOWED_BY_BACKGROUND_FGS_PERMISSION; + ret = REASON_BACKGROUND_FGS_PERMISSION; } else if (ActivityManager.checkComponentPermission(SYSTEM_ALERT_WINDOW, mApp.info.uid, -1, true) == PERMISSION_GRANTED) { - ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_ALERT_WINDOW_PERMISSION; + ret = REASON_SYSTEM_ALERT_WINDOW_PERMISSION; } } mAllowStartFgs = mAllowStartFgsByPermission = ret; @@ -1197,59 +1201,65 @@ final class ProcessStateRecord { @GuardedBy("mService") void setAllowStartFgs() { - if (mAllowStartFgs != FGS_FEATURE_DENIED) { + if (mAllowStartFgs != REASON_DENIED) { return; } - if (mAllowStartFgs == FGS_FEATURE_DENIED) { + if (mAllowStartFgs == REASON_DENIED) { if (isAllowedStartFgsState()) { - mAllowStartFgs = FGS_FEATURE_ALLOWED_BY_PROC_STATE; + mAllowStartFgs = getReasonCodeFromProcState(mAllowStartFgsState); } } - if (mAllowStartFgs == FGS_FEATURE_DENIED) { + if (mAllowStartFgs == REASON_DENIED) { // Is the calling UID a device owner app? if (mService.mInternal != null) { if (mService.mInternal.isDeviceOwner(mApp.info.uid)) { - mAllowStartFgs = FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER; + mAllowStartFgs = REASON_DEVICE_OWNER; } } } - if (mAllowStartFgs == FGS_FEATURE_DENIED) { + if (mAllowStartFgs == REASON_DENIED) { if (mService.mInternal != null) { final boolean isCompanionApp = mService.mInternal.isAssociatedCompanionApp( UserHandle.getUserId(mApp.info.uid), mApp.info.uid); if (isCompanionApp) { - mAllowStartFgs = FGS_FEATURE_ALLOWED_BY_COMPANION_APP; + mAllowStartFgs = REASON_COMPANION_DEVICE_MANAGER; } } } - if (mAllowStartFgs == FGS_FEATURE_DENIED) { + if (mAllowStartFgs == REASON_DENIED) { // Is the calling UID a profile owner app? if (mService.mInternal != null) { if (mService.mInternal.isProfileOwner(mApp.info.uid)) { - mAllowStartFgs = FGS_FEATURE_ALLOWED_BY_PROFILE_OWNER; + mAllowStartFgs = REASON_PROFILE_OWNER; } } } - if (mAllowStartFgs == FGS_FEATURE_DENIED) { + if (mAllowStartFgs == REASON_DENIED) { // uid is on DeviceIdleController's user/system allowlist // or AMS's FgsStartTempAllowList. - if (mService.isAllowlistedForFgsStartLOSP(mApp.info.uid)) { - mAllowStartFgs = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST; + FgsStartTempAllowList.TempFgsAllowListEntry entry = + mService.isAllowlistedForFgsStartLOSP(mApp.info.uid); + if (entry != null) { + if (entry == ActivityManagerService.FAKE_TEMP_ALLOWLIST_ENTRY) { + mAllowStartFgs = REASON_SYSTEM_ALLOW_LISTED; + } else { + mAllowStartFgs = entry.mReasonCode; + } } } } @GuardedBy("mService") - void setAllowStartFgs(@ActiveServices.FgsFeatureRetCode int allowStartFgs) { + void setAllowStartFgs(@ReasonCode int allowStartFgs) { mAllowStartFgs = allowStartFgs; } @GuardedBy("mService") - @ActiveServices.FgsFeatureRetCode int getAllowedStartFgs() { + @ReasonCode int getAllowedStartFgs() { return mAllowStartFgs; } @@ -1291,9 +1301,9 @@ final class ProcessStateRecord { pw.println(); pw.print(prefix); pw.print("allowStartFgsState="); pw.println(mAllowStartFgsState); - if (mAllowStartFgs != FGS_FEATURE_DENIED) { + if (mAllowStartFgs != REASON_DENIED) { pw.print(prefix); pw.print("allowStartFgs="); - pw.println(fgsCodeToString(mAllowStartFgs)); + pw.println(reasonCodeToString(mAllowStartFgs)); } if (mHasShownUi || mApp.mProfile.hasPendingUiClean()) { pw.print(prefix); pw.print("hasShownUi="); pw.print(mHasShownUi); diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 485087d29422..3ab95d131fad 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -18,6 +18,7 @@ package com.android.server.am; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; +import static android.os.PowerWhitelistManager.REASON_DENIED; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -36,6 +37,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.IBinder; +import android.os.PowerWhitelistManager; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; @@ -101,7 +103,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN ProcessRecord isolatedProc; // keep track of isolated process, if requested ServiceState tracker; // tracking service execution, may be null ServiceState restartTracker; // tracking service restart - boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? + boolean allowlistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? boolean delayed; // are we waiting to start this service in the background? boolean fgRequired; // is the service required to go foreground after starting? boolean fgWaiting; // is a timeout for going foreground already scheduled? @@ -156,11 +158,14 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN // the most recent package that start/bind this service. String mRecentCallingPackage; + // the most recent uid that start/bind this service. + int mRecentCallingUid; // allow the service becomes foreground service? Service started from background may not be // allowed to become a foreground service. - @ActiveServices.FgsFeatureRetCode int mAllowStartForeground; + @PowerWhitelistManager.ReasonCode int mAllowStartForeground = REASON_DENIED; String mInfoAllowStartForeground; + FgsStartTempAllowList.TempFgsAllowListEntry mInfoTempFgsAllowListReason; boolean mLoggedInfoAllowStartForeground; String stringName; // caching of toString @@ -309,7 +314,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN if (isolatedProc != null) { isolatedProc.dumpDebug(proto, ServiceRecordProto.ISOLATED_PROC); } - proto.write(ServiceRecordProto.WHITELIST_MANAGER, whitelistManager); + proto.write(ServiceRecordProto.WHITELIST_MANAGER, allowlistManager); proto.write(ServiceRecordProto.DELAYED, delayed); if (isForeground || foregroundId != 0) { long fgToken = proto.start(ServiceRecordProto.FOREGROUND); @@ -410,8 +415,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN if (isolatedProc != null) { pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc); } - if (whitelistManager) { - pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager); + if (allowlistManager) { + pw.print(prefix); pw.print("allowlistManager="); pw.println(allowlistManager); } if (mIsAllowedBgActivityStartsByBinding) { pw.print(prefix); pw.print("mIsAllowedBgActivityStartsByBinding="); @@ -429,6 +434,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN pw.println(mAllowWhileInUsePermissionInFgs); pw.print(prefix); pw.print("recentCallingPackage="); pw.println(mRecentCallingPackage); + pw.print(prefix); pw.print("recentCallingUid="); + pw.println(mRecentCallingUid); pw.print(prefix); pw.print("allowStartForeground="); pw.println(mAllowStartForeground); pw.print(prefix); pw.print("infoAllowStartForeground="); @@ -894,13 +901,13 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN return false; } - public void updateWhitelistManager() { - whitelistManager = false; + public void updateAllowlistManager() { + allowlistManager = false; for (int conni=connections.size()-1; conni>=0; conni--) { ArrayList<ConnectionRecord> cr = connections.valueAt(conni); for (int i=0; i<cr.size(); i++) { if ((cr.get(i).flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { - whitelistManager = true; + allowlistManager = true; return; } } diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java index 6aefe41891f9..557fa8944445 100644 --- a/services/core/java/com/android/server/net/NetworkStatsCollection.java +++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java @@ -54,6 +54,8 @@ import android.util.proto.ProtoOutputStream; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; +import com.android.internal.util.FastDataInput; +import com.android.internal.util.FastDataOutput; import com.android.internal.util.FileRotator; import com.android.internal.util.IndentingPrintWriter; @@ -89,6 +91,9 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W /** File header magic number: "ANET" */ private static final int FILE_MAGIC = 0x414E4554; + /** Default buffer size from BufferedInputStream */ + private static final int BUFFER_SIZE = 8192; + private static final int VERSION_NETWORK_INIT = 1; private static final int VERSION_UID_INIT = 1; @@ -434,7 +439,8 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W @Override public void read(InputStream in) throws IOException { - read((DataInput) new DataInputStream(in)); + final FastDataInput dataIn = new FastDataInput(in, BUFFER_SIZE); + read(dataIn); } private void read(DataInput in) throws IOException { @@ -473,8 +479,9 @@ public class NetworkStatsCollection implements FileRotator.Reader, FileRotator.W @Override public void write(OutputStream out) throws IOException { - write((DataOutput) new DataOutputStream(out)); - out.flush(); + final FastDataOutput dataOut = new FastDataOutput(out, BUFFER_SIZE); + write(dataOut); + dataOut.flush(); } private void write(DataOutput out) throws IOException { diff --git a/services/core/java/com/android/server/pm/DumpState.java b/services/core/java/com/android/server/pm/DumpState.java index 380cdb10569b..6875b8a5abeb 100644 --- a/services/core/java/com/android/server/pm/DumpState.java +++ b/services/core/java/com/android/server/pm/DumpState.java @@ -56,6 +56,7 @@ public final class DumpState { private boolean mTitlePrinted; private boolean mFullPreferred; + private boolean mCheckIn; private String mTargetPackageName; @@ -118,4 +119,12 @@ public final class DumpState { public void setFullPreferred(boolean fullPreferred) { mFullPreferred = fullPreferred; } + + public boolean isCheckIn() { + return mCheckIn; + } + + public void setCheckIn(boolean checkIn) { + mCheckIn = checkIn; + } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 16966d4de4e6..ff5ce95811f8 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -4403,6 +4403,7 @@ public class PackageManagerService extends IPackageManager.Stub public void dump(int type, FileDescriptor fd, PrintWriter pw, DumpState dumpState) { final String packageName = dumpState.getTargetPackageName(); + final boolean checkin = dumpState.isCheckIn(); switch (type) { case DumpState.DUMP_VERSION: @@ -4415,6 +4416,56 @@ public class PackageManagerService extends IPackageManager.Stub break; } + case DumpState.DUMP_LIBS: + { + boolean printedHeader = false; + final int numSharedLibraries = mSharedLibraries.size(); + for (int index = 0; index < numSharedLibraries; index++) { + final String libName = mSharedLibraries.keyAt(index); + final WatchedLongSparseArray<SharedLibraryInfo> versionedLib = + mSharedLibraries.get(libName); + if (versionedLib == null) { + continue; + } + final int versionCount = versionedLib.size(); + for (int i = 0; i < versionCount; i++) { + SharedLibraryInfo libraryInfo = versionedLib.valueAt(i); + if (!checkin) { + if (!printedHeader) { + if (dumpState.onTitlePrinted()) { + pw.println(); + } + pw.println("Libraries:"); + printedHeader = true; + } + pw.print(" "); + } else { + pw.print("lib,"); + } + pw.print(libraryInfo.getName()); + if (libraryInfo.isStatic()) { + pw.print(" version=" + libraryInfo.getLongVersion()); + } + if (!checkin) { + pw.print(" -> "); + } + if (libraryInfo.getPath() != null) { + if (libraryInfo.isNative()) { + pw.print(" (so) "); + } else { + pw.print(" (jar) "); + } + pw.print(libraryInfo.getPath()); + } else { + pw.print(" (apk) "); + pw.print(libraryInfo.getPackageName()); + } + pw.println(); + } + } + break; + } + case DumpState.DUMP_PREFERRED_XML: { pw.flush(); @@ -9167,6 +9218,11 @@ public class PackageManagerService extends IPackageManager.Stub */ @Override public String[] getPackagesForUid(int uid) { + final int callingUid = Binder.getCallingUid(); + final int userId = UserHandle.getUserId(uid); + enforceCrossUserOrProfilePermission(callingUid, userId, + /* requireFullPermission */ false, + /* checkShell */ false, "getPackagesForUid"); return snapshotComputer().getPackagesForUid(uid); } @@ -23699,8 +23755,6 @@ public class PackageManagerService extends IPackageManager.Stub if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; DumpState dumpState = new DumpState(); - boolean checkin = false; - ArraySet<String> permissionNames = null; int opti = 0; @@ -23750,7 +23804,7 @@ public class PackageManagerService extends IPackageManager.Stub pw.println(" <package.name>: info about given package"); return; } else if ("--checkin".equals(opt)) { - checkin = true; + dumpState.setCheckIn(true); } else if ("--all-components".equals(opt)) { dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS); } else if ("-f".equals(opt)) { @@ -23904,6 +23958,7 @@ public class PackageManagerService extends IPackageManager.Stub } final String packageName = dumpState.getTargetPackageName(); + final boolean checkin = dumpState.isCheckIn(); if (checkin) { pw.println("vers,1"); } @@ -23992,11 +24047,7 @@ public class PackageManagerService extends IPackageManager.Stub } if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) { - // TODO: Move it to ComputerEngine once LongSparseArray<SharedLibraryInfo> is copied - // in snapshot. - synchronized (mLock) { - dumpSharedLibrariesLPr(pw, dumpState, checkin); - } + dump(DumpState.DUMP_LIBS, fd, pw, dumpState); } if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) { @@ -24337,53 +24388,6 @@ public class PackageManagerService extends IPackageManager.Stub } } - private void dumpSharedLibrariesLPr(PrintWriter pw, DumpState dumpState, boolean checkin) { - boolean printedHeader = false; - final int numSharedLibraries = mSharedLibraries.size(); - for (int index = 0; index < numSharedLibraries; index++) { - final String libName = mSharedLibraries.keyAt(index); - WatchedLongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName); - if (versionedLib == null) { - continue; - } - final int versionCount = versionedLib.size(); - for (int i = 0; i < versionCount; i++) { - SharedLibraryInfo libraryInfo = versionedLib.valueAt(i); - if (!checkin) { - if (!printedHeader) { - if (dumpState.onTitlePrinted()) { - pw.println(); - } - pw.println("Libraries:"); - printedHeader = true; - } - pw.print(" "); - } else { - pw.print("lib,"); - } - pw.print(libraryInfo.getName()); - if (libraryInfo.isStatic()) { - pw.print(" version=" + libraryInfo.getLongVersion()); - } - if (!checkin) { - pw.print(" -> "); - } - if (libraryInfo.getPath() != null) { - if (libraryInfo.isNative()) { - pw.print(" (so) "); - } else { - pw.print(" (jar) "); - } - pw.print(libraryInfo.getPath()); - } else { - pw.print(" (apk) "); - pw.print(libraryInfo.getPackageName()); - } - pw.println(); - } - } - } - // ------- apps on sdcard specific code ------- static final boolean DEBUG_SD_INSTALL = false; diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 60ca725b118e..6ce9048d79e2 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1708,7 +1708,7 @@ class ActivityStarter { // If the activity being launched is the same as the one currently at the top, then // we need to check if it should only be launched once. - final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask(); + final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask(); if (topRootTask != null) { startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants); if (startResult != START_SUCCESS) { |