Merge "Allow FGS start for proc state BOUND_FOREGROUND_SERVICE and above."
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package com.android.server.am;
|
||||
|
||||
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
|
||||
import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MANIFEST;
|
||||
import static android.os.Process.NFC_UID;
|
||||
@@ -145,7 +146,7 @@ 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_PROC_STATE = 1;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_UID_STATE = 1;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_UID_VISIBLE = 2;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_FLAG = 3;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_UID = 4;
|
||||
@@ -154,10 +155,12 @@ public final class ActiveServices {
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_PERMISSION = 7;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_WHITELIST = 8;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER = 9;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_PROC_STATE = 10;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST = 11;
|
||||
|
||||
@IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = {
|
||||
FGS_FEATURE_DENIED,
|
||||
FGS_FEATURE_ALLOWED_BY_PROC_STATE,
|
||||
FGS_FEATURE_ALLOWED_BY_UID_STATE,
|
||||
FGS_FEATURE_ALLOWED_BY_UID_VISIBLE,
|
||||
FGS_FEATURE_ALLOWED_BY_FLAG,
|
||||
FGS_FEATURE_ALLOWED_BY_SYSTEM_UID,
|
||||
@@ -165,7 +168,9 @@ public final class ActiveServices {
|
||||
FGS_FEATURE_ALLOWED_BY_TOKEN,
|
||||
FGS_FEATURE_ALLOWED_BY_PERMISSION,
|
||||
FGS_FEATURE_ALLOWED_BY_WHITELIST,
|
||||
FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER
|
||||
FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER,
|
||||
FGS_FEATURE_ALLOWED_BY_PROC_STATE,
|
||||
FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface FgsFeatureRetCode {}
|
||||
@@ -576,18 +581,11 @@ public final class ActiveServices {
|
||||
if (r.mAllowStartForeground == FGS_FEATURE_DENIED
|
||||
&& (mAm.mConstants.mFlagFgsStartRestrictionEnabled
|
||||
|| isChangeEnabled(FGS_BG_START_RESTRICTION_CHANGE_ID, r))) {
|
||||
if (mAm.mConstants.mFlagFgsStartTempAllowListEnabled
|
||||
&& mAm.isOnDeviceIdleWhitelistLocked(r.appInfo.uid, false)) {
|
||||
// uid is on DeviceIdleController's allowlist.
|
||||
Slog.d(TAG, "startForegroundService() mAllowStartForeground false "
|
||||
+ "but allowlist true: service " + r.shortInstanceName);
|
||||
} else {
|
||||
Slog.w(TAG, "startForegroundService() not allowed due to "
|
||||
+ "mAllowStartForeground false: service "
|
||||
+ r.shortInstanceName);
|
||||
showFgsBgRestrictedNotificationLocked(r);
|
||||
return null;
|
||||
}
|
||||
Slog.w(TAG, "startForegroundService() not allowed due to "
|
||||
+ "mAllowStartForeground false: service "
|
||||
+ r.shortInstanceName);
|
||||
showFgsBgRestrictedNotificationLocked(r);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1488,20 +1486,12 @@ public final class ActiveServices {
|
||||
if (r.mAllowStartForeground == FGS_FEATURE_DENIED
|
||||
&& (mAm.mConstants.mFlagFgsStartRestrictionEnabled
|
||||
|| isChangeEnabled(FGS_BG_START_RESTRICTION_CHANGE_ID, r))) {
|
||||
if (mAm.mConstants.mFlagFgsStartTempAllowListEnabled
|
||||
&& mAm.isOnDeviceIdleWhitelistLocked(r.appInfo.uid, false)) {
|
||||
// uid is on DeviceIdleController's allowlist.
|
||||
Slog.d(TAG, "Service.startForeground() "
|
||||
+ "mAllowStartForeground false but allowlist true: service "
|
||||
+ r.shortInstanceName);
|
||||
} else {
|
||||
Slog.w(TAG, "Service.startForeground() not allowed due to "
|
||||
+ "mAllowStartForeground false: service "
|
||||
+ r.shortInstanceName);
|
||||
showFgsBgRestrictedNotificationLocked(r);
|
||||
updateServiceForegroundLocked(r.app, true);
|
||||
ignoreForeground = true;
|
||||
}
|
||||
Slog.w(TAG, "Service.startForeground() not allowed due to "
|
||||
+ "mAllowStartForeground false: service "
|
||||
+ r.shortInstanceName);
|
||||
showFgsBgRestrictedNotificationLocked(r);
|
||||
updateServiceForegroundLocked(r.app, true);
|
||||
ignoreForeground = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4944,38 +4934,39 @@ public final class ActiveServices {
|
||||
r.mAllowWhileInUsePermissionInFgs = true;
|
||||
}
|
||||
|
||||
if (!r.mAllowWhileInUsePermissionInFgs || (r.mAllowStartForeground == FGS_FEATURE_DENIED)) {
|
||||
final @FgsFeatureRetCode int temp = shouldAllowFgsFeatureLocked(callingPackage,
|
||||
callingPid, callingUid, intent, r, allowBackgroundActivityStarts);
|
||||
if (!r.mAllowWhileInUsePermissionInFgs
|
||||
|| (r.mAllowStartForeground == FGS_FEATURE_DENIED)) {
|
||||
final @FgsFeatureRetCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
|
||||
callingPackage, callingPid, callingUid, r, allowBackgroundActivityStarts);
|
||||
if (!r.mAllowWhileInUsePermissionInFgs) {
|
||||
r.mAllowWhileInUsePermissionInFgs = (temp != FGS_FEATURE_DENIED);
|
||||
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != FGS_FEATURE_DENIED);
|
||||
}
|
||||
if (r.mAllowStartForeground == FGS_FEATURE_DENIED) {
|
||||
r.mAllowStartForeground = temp;
|
||||
r.mAllowStartForeground = shouldAllowFgsStartForegroundLocked(allowWhileInUse,
|
||||
callingPackage, callingPid, callingUid, intent, r,
|
||||
allowBackgroundActivityStarts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should allow FGS feature or not.
|
||||
* Should allow while-in-use permissions in FGS or not.
|
||||
* A typical BG started FGS is not allowed to have while-in-use permissions.
|
||||
* @param callingPackage caller app's package name.
|
||||
* @param callingUid caller app's uid.
|
||||
* @param intent intent to start/bind service.
|
||||
* @param r the service to start.
|
||||
* @return {@link FgsFeatureRetCode}
|
||||
*/
|
||||
private @FgsFeatureRetCode int shouldAllowFgsFeatureLocked(String callingPackage,
|
||||
int callingPid, int callingUid, Intent intent, ServiceRecord r,
|
||||
private @FgsFeatureRetCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
|
||||
int callingPid, int callingUid, ServiceRecord r,
|
||||
boolean allowBackgroundActivityStarts) {
|
||||
int ret = FGS_FEATURE_DENIED;
|
||||
|
||||
final StringBuilder sb = new StringBuilder(64);
|
||||
final int uidState = mAm.getUidState(callingUid);
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
// Is the calling UID at PROCESS_STATE_TOP or above?
|
||||
if (uidState <= ActivityManager.PROCESS_STATE_TOP) {
|
||||
sb.append("uidState=").append(uidState);
|
||||
ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE;
|
||||
ret = FGS_FEATURE_ALLOWED_BY_UID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5010,7 +5001,6 @@ public final class ActiveServices {
|
||||
}
|
||||
|
||||
if (isCallerSystem) {
|
||||
sb.append("callingUid=").append(callingAppId);
|
||||
ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_UID;
|
||||
}
|
||||
}
|
||||
@@ -5049,6 +5039,53 @@ public final class ActiveServices {
|
||||
ret = FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should allow the FGS to start (AKA startForeground()) or not.
|
||||
* The check in this method is in addition to check in
|
||||
* {@link #shouldAllowFgsWhileInUsePermissionLocked}
|
||||
* @param allowWhileInUse the return code from {@link #shouldAllowFgsWhileInUsePermissionLocked}
|
||||
* @param callingPackage caller app's package name.
|
||||
* @param callingUid caller app's uid.
|
||||
* @param intent intent to start/bind service.
|
||||
* @param r the service to start.
|
||||
* @return {@link FgsFeatureRetCode}
|
||||
*/
|
||||
private @FgsFeatureRetCode int shouldAllowFgsStartForegroundLocked(
|
||||
@FgsFeatureRetCode int allowWhileInUse, String callingPackage, int callingPid,
|
||||
int callingUid, Intent intent, ServiceRecord r, boolean allowBackgroundActivityStarts) {
|
||||
int ret = allowWhileInUse;
|
||||
|
||||
final StringBuilder sb = new StringBuilder(64);
|
||||
final int uidState = mAm.getUidState(callingUid);
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
// Is the calling UID at PROCESS_STATE_TOP or above?
|
||||
if (uidState <= ActivityManager.PROCESS_STATE_TOP) {
|
||||
sb.append("uidState=").append(uidState);
|
||||
ret = FGS_FEATURE_ALLOWED_BY_UID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
for (int i = mAm.mProcessList.mLruProcesses.size() - 1; i >= 0; i--) {
|
||||
final ProcessRecord pr = mAm.mProcessList.mLruProcesses.get(i);
|
||||
if (pr.uid == callingUid
|
||||
&& pr.mAllowStartFgsState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
|
||||
ret = FGS_FEATURE_ALLOWED_BY_PROC_STATE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
if (mAm.mConstants.mFlagFgsStartTempAllowListEnabled
|
||||
&& mAm.isOnDeviceIdleWhitelistLocked(r.appInfo.uid, false)) {
|
||||
// uid is on DeviceIdleController's allowlist.
|
||||
ret = FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST;
|
||||
}
|
||||
}
|
||||
|
||||
final String debugInfo =
|
||||
"[callingPackage: " + callingPackage
|
||||
@@ -5071,8 +5108,8 @@ public final class ActiveServices {
|
||||
switch (code) {
|
||||
case FGS_FEATURE_DENIED:
|
||||
return "DENIED";
|
||||
case FGS_FEATURE_ALLOWED_BY_PROC_STATE:
|
||||
return "ALLOWED_BY_PROC_STATE";
|
||||
case FGS_FEATURE_ALLOWED_BY_UID_STATE:
|
||||
return "ALLOWED_BY_UID_STATE";
|
||||
case FGS_FEATURE_ALLOWED_BY_UID_VISIBLE:
|
||||
return "ALLOWED_BY_UID_VISIBLE";
|
||||
case FGS_FEATURE_ALLOWED_BY_FLAG:
|
||||
@@ -5089,13 +5126,17 @@ public final class ActiveServices {
|
||||
return "ALLOWED_BY_WHITELIST";
|
||||
case FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER:
|
||||
return "ALLOWED_BY_DEVICE_OWNER";
|
||||
case FGS_FEATURE_ALLOWED_BY_PROC_STATE:
|
||||
return "ALLOWED_BY_PROC_STATE";
|
||||
case FGS_FEATURE_ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST:
|
||||
return "ALLOWED_BY_DEVICE_IDLE_ALLOW_LIST";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isFgsBgStart(@FgsFeatureRetCode int code) {
|
||||
return code != FGS_FEATURE_ALLOWED_BY_PROC_STATE
|
||||
return code != FGS_FEATURE_ALLOWED_BY_UID_STATE
|
||||
&& code != FGS_FEATURE_ALLOWED_BY_UID_VISIBLE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1329,6 +1329,8 @@ public final class OomAdjuster {
|
||||
app.setCached(false);
|
||||
app.shouldNotFreeze = false;
|
||||
|
||||
app.mAllowStartFgsState = PROCESS_STATE_NONEXISTENT;
|
||||
|
||||
final int appUid = app.info.uid;
|
||||
final int logUid = mService.mCurOomAdjUid;
|
||||
|
||||
@@ -1349,6 +1351,7 @@ public final class OomAdjuster {
|
||||
app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT);
|
||||
app.curCapability = PROCESS_CAPABILITY_ALL;
|
||||
app.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT);
|
||||
app.bumpAllowStartFgsState(PROCESS_STATE_PERSISTENT);
|
||||
// System processes can do UI, and when they do we want to have
|
||||
// them trim their memory after the user leaves the UI. To
|
||||
// facilitate this, here we need to determine whether or not it
|
||||
@@ -1403,6 +1406,7 @@ public final class OomAdjuster {
|
||||
app.adjType = "top-activity";
|
||||
foregroundActivities = true;
|
||||
procState = PROCESS_STATE_CUR_TOP;
|
||||
app.bumpAllowStartFgsState(PROCESS_STATE_TOP);
|
||||
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
|
||||
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
|
||||
}
|
||||
@@ -1500,6 +1504,7 @@ public final class OomAdjuster {
|
||||
// The user is aware of this app, so make it visible.
|
||||
adj = ProcessList.PERCEPTIBLE_APP_ADJ;
|
||||
procState = PROCESS_STATE_FOREGROUND_SERVICE;
|
||||
app.bumpAllowStartFgsState(PROCESS_STATE_FOREGROUND_SERVICE);
|
||||
app.adjType = "fg-service";
|
||||
app.setCached(false);
|
||||
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
|
||||
@@ -1887,7 +1892,9 @@ public final class OomAdjuster {
|
||||
// into the top state, since they are not on top. Instead
|
||||
// give them the best bound state after that.
|
||||
if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) {
|
||||
clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; ;
|
||||
clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
|
||||
app.bumpAllowStartFgsState(
|
||||
PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
|
||||
} else if (mService.mWakefulness
|
||||
== PowerManagerInternal.WAKEFULNESS_AWAKE
|
||||
&& (cr.flags & Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
|
||||
@@ -1901,6 +1908,7 @@ public final class OomAdjuster {
|
||||
// Go at most to BOUND_TOP, unless requested to elevate
|
||||
// to client's state.
|
||||
clientProcState = PROCESS_STATE_BOUND_TOP;
|
||||
app.bumpAllowStartFgsState(PROCESS_STATE_BOUND_TOP);
|
||||
boolean enabled = false;
|
||||
try {
|
||||
enabled = mPlatformCompatCache.isChangeEnabled(
|
||||
|
||||
@@ -353,6 +353,10 @@ class ProcessRecord implements WindowProcessListener {
|
||||
|
||||
long mKillTime; // The timestamp in uptime when this process was killed.
|
||||
|
||||
// If the proc state is PROCESS_STATE_BOUND_FOREGROUND_SERVICE or above, it can start FGS.
|
||||
// It must obtain the proc state from a persistent/top process or FGS, not transitive.
|
||||
int mAllowStartFgsState = PROCESS_STATE_NONEXISTENT;
|
||||
|
||||
void setStartParams(int startUid, HostingRecord hostingRecord, String seInfo,
|
||||
long startTime) {
|
||||
this.startUid = startUid;
|
||||
@@ -466,6 +470,8 @@ class ProcessRecord implements WindowProcessListener {
|
||||
pw.print(" setCapability=");
|
||||
ActivityManager.printCapabilitiesFull(pw, setCapability);
|
||||
pw.println();
|
||||
pw.print(prefix); pw.print("allowStartFgsState=");
|
||||
pw.println(mAllowStartFgsState);
|
||||
if (hasShownUi || mPendingUiClean || hasAboveClient || treatLikeActivity) {
|
||||
pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
|
||||
pw.print(" pendingUiClean="); pw.print(mPendingUiClean);
|
||||
@@ -1942,6 +1948,12 @@ class ProcessRecord implements WindowProcessListener {
|
||||
return mDialogController;
|
||||
}
|
||||
|
||||
void bumpAllowStartFgsState(int newProcState) {
|
||||
if (newProcState < mAllowStartFgsState) {
|
||||
mAllowStartFgsState = newProcState;
|
||||
}
|
||||
}
|
||||
|
||||
/** A controller to generate error dialogs in {@link ProcessRecord} */
|
||||
class ErrorDialogController {
|
||||
/** dialogs being displayed due to crash */
|
||||
|
||||
Reference in New Issue
Block a user