diff --git a/core/api/current.txt b/core/api/current.txt index 324ad33166a10..4a053073997c1 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -141,6 +141,7 @@ package android { field public static final String REORDER_TASKS = "android.permission.REORDER_TASKS"; field public static final String REQUEST_COMPANION_PROFILE_WATCH = "android.permission.REQUEST_COMPANION_PROFILE_WATCH"; field public static final String REQUEST_COMPANION_RUN_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND"; + field public static final String REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND"; field public static final String REQUEST_COMPANION_USE_DATA_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND"; field public static final String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES"; field public static final String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index ffb8d1daac906..bcecd7442e9c4 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -2900,6 +2900,12 @@ android:description="@string/permdesc_runInBackground" android:protectionLevel="normal" /> + + + diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index aadb25c7ef7ff..f480cbc26ff44 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -16,6 +16,8 @@ package com.android.server.am; +import static android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND; +import static android.Manifest.permission.REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.app.ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; @@ -5831,6 +5833,26 @@ public final class ActiveServices { } } + // Check for CDM apps with either REQUEST_COMPANION_RUN_IN_BACKGROUND or + // REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND. + // Note: When a CDM app has REQUEST_COMPANION_RUN_IN_BACKGROUND, the app is also put + // in the user-allowlist. However, in this case, we want to use the reason code + // REASON_COMPANION_DEVICE_MANAGER, so this check needs to be before the + // isAllowlistedForFgsStartLOSP check. + if (ret == REASON_DENIED) { + final boolean isCompanionApp = mAm.mInternal.isAssociatedCompanionApp( + UserHandle.getUserId(callingUid), callingUid); + if (isCompanionApp) { + if (isPermissionGranted( + REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND, + callingPid, callingUid) + || isPermissionGranted(REQUEST_COMPANION_RUN_IN_BACKGROUND, + callingPid, callingUid)) { + ret = REASON_COMPANION_DEVICE_MANAGER; + } + } + } + if (ret == REASON_DENIED) { ActivityManagerService.FgsTempAllowListItem item = mAm.isAllowlistedForFgsStartLOSP(callingUid); @@ -5857,14 +5879,6 @@ public final class ActiveServices { } } - if (ret == REASON_DENIED) { - final boolean isCompanionApp = mAm.mInternal.isAssociatedCompanionApp( - UserHandle.getUserId(callingUid), callingUid); - if (isCompanionApp) { - ret = REASON_COMPANION_DEVICE_MANAGER; - } - } - if (ret == REASON_DENIED) { final AppOpsManager appOpsManager = mAm.getAppOpsManager(); if (appOpsManager.checkOpNoThrow(AppOpsManager.OP_ACTIVATE_VPN, callingUid, @@ -5884,6 +5898,10 @@ public final class ActiveServices { return ret; } + private boolean isPermissionGranted(String permission, int callingPid, int callingUid) { + return mAm.checkPermission(permission, callingPid, callingUid) == PERMISSION_GRANTED; + } + private static boolean isFgsBgStart(@ReasonCode int code) { return code != REASON_PROC_STATE_PERSISTENT && code != REASON_PROC_STATE_PERSISTENT_UI @@ -5957,7 +5975,7 @@ public final class ActiveServices { } FrameworkStatsLog.write(FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED, r.appInfo.uid, - r.shortInstanceName, + null, state, r.mAllowWhileInUsePermissionInFgs, r.mAllowStartForeground, diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java index 6429b79f61114..801e3824d7b02 100644 --- a/services/core/java/com/android/server/am/ProcessStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessStateRecord.java @@ -25,7 +25,6 @@ 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; @@ -1217,6 +1216,7 @@ final class ProcessStateRecord { mAllowStartFgs = mAllowStartFgsByPermission = ret; } + // TODO(b/188063200) Clean up this method. Why do we need to duplicate only some of the checks? @GuardedBy("mService") void setAllowStartFgs() { if (mAllowStartFgs != REASON_DENIED) { @@ -1237,16 +1237,6 @@ final class ProcessStateRecord { } } - 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 = REASON_COMPANION_DEVICE_MANAGER; - } - } - } - if (mAllowStartFgs == REASON_DENIED) { // Is the calling UID a profile owner app? if (mService.mInternal != null) {