Elaborate on the reason of FGS background start.
shouldAllowFgsFeatureLocked used to return boolean, now return an integer that specify the reason of denial/allowance. If FGS startForeground() is allowed in bg proc state because the list of exemptions, still generate the Slog.wtf() log messages so we have a complete list of bg started FGS. Bug: 157473819 Test: adb logcat | grep "Background started FGS" atest cts/tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java Change-Id: I21cbaa1d6c44e7c252b8cc91fe258065d0b2ccaf
This commit is contained in:
@@ -37,6 +37,7 @@ 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;
|
||||
@@ -116,6 +117,8 @@ 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.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -135,9 +138,31 @@ public final class ActiveServices {
|
||||
|
||||
private static final boolean SHOW_DUNGEON_NOTIFICATION = false;
|
||||
|
||||
//TODO: remove this when development is done.
|
||||
private static final int DEBUG_FGS_ALLOW_WHILE_IN_USE = 0;
|
||||
private static final int DEBUG_FGS_ENFORCE_TYPE = 1;
|
||||
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_VISIBLE = 2;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_FLAG = 3;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_SYSTEM_UID = 4;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION = 5;
|
||||
public static final int FGS_FEATURE_ALLOWED_BY_TOKEN = 6;
|
||||
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;
|
||||
|
||||
@IntDef(flag = true, prefix = { "FGS_FEATURE_" }, value = {
|
||||
FGS_FEATURE_DENIED,
|
||||
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_PERMISSION,
|
||||
FGS_FEATURE_ALLOWED_BY_TOKEN,
|
||||
FGS_FEATURE_ALLOWED_BY_PERMISSION,
|
||||
FGS_FEATURE_ALLOWED_BY_WHITELIST,
|
||||
FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface FgsFeatureRetCode {}
|
||||
|
||||
// How long we wait for a service to finish executing.
|
||||
static final int SERVICE_TIMEOUT = 20*1000;
|
||||
@@ -519,12 +544,13 @@ public final class ActiveServices {
|
||||
}
|
||||
|
||||
if (fgRequired) {
|
||||
if (!r.mAllowStartForeground) {
|
||||
if (isFgsBgStart(r.mAllowStartForeground)) {
|
||||
if (!r.mLoggedInfoAllowStartForeground) {
|
||||
Slog.wtf(TAG, "Background started FGS " + r.mInfoAllowStartForeground);
|
||||
r.mLoggedInfoAllowStartForeground = true;
|
||||
}
|
||||
if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
|
||||
if (r.mAllowStartForeground == FGS_FEATURE_DENIED
|
||||
&& mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
|
||||
Slog.w(TAG, "startForegroundService() not allowed due to "
|
||||
+ " mAllowStartForeground false: service "
|
||||
+ r.shortInstanceName);
|
||||
@@ -1421,13 +1447,14 @@ public final class ActiveServices {
|
||||
}
|
||||
|
||||
if (!ignoreForeground) {
|
||||
if (!r.mAllowStartForeground) {
|
||||
if (isFgsBgStart(r.mAllowStartForeground)) {
|
||||
if (!r.mLoggedInfoAllowStartForeground) {
|
||||
Slog.wtf(TAG, "Background started FGS "
|
||||
+ r.mInfoAllowStartForeground);
|
||||
r.mLoggedInfoAllowStartForeground = true;
|
||||
}
|
||||
if (mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
|
||||
if (r.mAllowStartForeground == FGS_FEATURE_DENIED
|
||||
&& mAm.mConstants.mFlagFgsStartRestrictionEnabled) {
|
||||
Slog.w(TAG,
|
||||
"Service.startForeground() not allowed due to "
|
||||
+ "mAllowStartForeground false: service "
|
||||
@@ -4874,13 +4901,13 @@ public final class ActiveServices {
|
||||
r.mAllowWhileInUsePermissionInFgs = true;
|
||||
}
|
||||
|
||||
if (!r.mAllowWhileInUsePermissionInFgs || !r.mAllowStartForeground) {
|
||||
final boolean temp = shouldAllowFgsFeatureLocked(callingPackage, callingPid,
|
||||
callingUid, intent, r, allowBackgroundActivityStarts);
|
||||
if (!r.mAllowWhileInUsePermissionInFgs || (r.mAllowStartForeground == FGS_FEATURE_DENIED)) {
|
||||
final @FgsFeatureRetCode int temp = shouldAllowFgsFeatureLocked(callingPackage,
|
||||
callingPid, callingUid, intent, r, allowBackgroundActivityStarts);
|
||||
if (!r.mAllowWhileInUsePermissionInFgs) {
|
||||
r.mAllowWhileInUsePermissionInFgs = temp;
|
||||
r.mAllowWhileInUsePermissionInFgs = (temp != FGS_FEATURE_DENIED);
|
||||
}
|
||||
if (!r.mAllowStartForeground) {
|
||||
if (r.mAllowStartForeground == FGS_FEATURE_DENIED) {
|
||||
r.mAllowStartForeground = temp;
|
||||
}
|
||||
}
|
||||
@@ -4892,85 +4919,141 @@ public final class ActiveServices {
|
||||
* @param callingUid caller app's uid.
|
||||
* @param intent intent to start/bind service.
|
||||
* @param r the service to start.
|
||||
* @return true if allow, false otherwise.
|
||||
* @return {@link FgsFeatureRetCode}
|
||||
*/
|
||||
private boolean shouldAllowFgsFeatureLocked(String callingPackage,
|
||||
private @FgsFeatureRetCode int shouldAllowFgsFeatureLocked(String callingPackage,
|
||||
int callingPid, int callingUid, Intent intent, ServiceRecord r,
|
||||
boolean allowBackgroundActivityStarts) {
|
||||
// Is the allow activity background start flag on?
|
||||
if (allowBackgroundActivityStarts) {
|
||||
return true;
|
||||
}
|
||||
int ret = FGS_FEATURE_DENIED;
|
||||
|
||||
boolean isCallerSystem = false;
|
||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||
switch (callingAppId) {
|
||||
case ROOT_UID:
|
||||
case SYSTEM_UID:
|
||||
case NFC_UID:
|
||||
case SHELL_UID:
|
||||
isCallerSystem = true;
|
||||
break;
|
||||
default:
|
||||
isCallerSystem = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isCallerSystem) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (r.app != null) {
|
||||
ActiveInstrumentation instr = r.app.getActiveInstrumentation();
|
||||
if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
|
||||
return true;
|
||||
}
|
||||
if (r.app.areBackgroundActivityStartsAllowedByToken()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mAm.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
|
||||
== PERMISSION_GRANTED) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Is the calling UID at PROCESS_STATE_TOP or above?
|
||||
final StringBuilder sb = new StringBuilder(64);
|
||||
final int uidState = mAm.getUidState(callingUid);
|
||||
if (uidState <= ActivityManager.PROCESS_STATE_TOP) {
|
||||
return true;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// Does the calling UID have any visible activity?
|
||||
final boolean isCallingUidVisible = mAm.mAtmInternal.isUidForeground(callingUid);
|
||||
if (isCallingUidVisible) {
|
||||
return true;
|
||||
if (ret == FGS_FEATURE_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;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean isWhiteListedPackage =
|
||||
mWhiteListAllowWhileInUsePermissionInFgs.contains(callingPackage);
|
||||
if (isWhiteListedPackage) {
|
||||
return true;
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
// Is the allow activity background start flag on?
|
||||
if (allowBackgroundActivityStarts) {
|
||||
ret = FGS_FEATURE_ALLOWED_BY_FLAG;
|
||||
}
|
||||
}
|
||||
|
||||
// Is the calling UID a device owner app?
|
||||
final boolean isDeviceOwner = mAm.mInternal.isDeviceOwner(callingUid);
|
||||
if (isDeviceOwner) {
|
||||
return true;
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
boolean isCallerSystem = false;
|
||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||
switch (callingAppId) {
|
||||
case ROOT_UID:
|
||||
case SYSTEM_UID:
|
||||
case NFC_UID:
|
||||
case SHELL_UID:
|
||||
isCallerSystem = true;
|
||||
break;
|
||||
default:
|
||||
isCallerSystem = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (isCallerSystem) {
|
||||
sb.append("callingUid=").append(callingAppId);
|
||||
ret = FGS_FEATURE_ALLOWED_BY_SYSTEM_UID;
|
||||
}
|
||||
}
|
||||
|
||||
final String info =
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
if (r.app != null) {
|
||||
ActiveInstrumentation instr = r.app.getActiveInstrumentation();
|
||||
if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
|
||||
ret = FGS_FEATURE_ALLOWED_BY_INSTR_PERMISSION;
|
||||
}
|
||||
if (r.app.areBackgroundActivityStartsAllowedByToken()) {
|
||||
ret = FGS_FEATURE_ALLOWED_BY_TOKEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
if (mAm.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
|
||||
== PERMISSION_GRANTED) {
|
||||
ret = FGS_FEATURE_ALLOWED_BY_PERMISSION;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == FGS_FEATURE_DENIED) {
|
||||
final boolean isWhiteListedPackage =
|
||||
mWhiteListAllowWhileInUsePermissionInFgs.contains(callingPackage);
|
||||
if (isWhiteListedPackage) {
|
||||
ret = FGS_FEATURE_ALLOWED_BY_WHITELIST;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == FGS_FEATURE_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;
|
||||
}
|
||||
}
|
||||
|
||||
final String debugInfo =
|
||||
"[callingPackage: " + callingPackage
|
||||
+ "; callingUid: " + callingUid
|
||||
+ "; uidState: " + ProcessList.makeProcStateString(uidState)
|
||||
+ "; intent: " + intent
|
||||
+ "; code:" + fgsCodeToString(ret)
|
||||
+ "; extra:" + sb.toString()
|
||||
+ "; targetSdkVersion:" + r.appInfo.targetSdkVersion
|
||||
+ "]";
|
||||
if (!info.equals(r.mInfoAllowStartForeground)) {
|
||||
if (!debugInfo.equals(r.mInfoAllowStartForeground)) {
|
||||
r.mLoggedInfoAllowStartForeground = false;
|
||||
r.mInfoAllowStartForeground = info;
|
||||
r.mInfoAllowStartForeground = debugInfo;
|
||||
}
|
||||
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String fgsCodeToString(@FgsFeatureRetCode int code) {
|
||||
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_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_PERMISSION:
|
||||
return "ALLOWED_BY_INSTR_PERMISSION";
|
||||
case FGS_FEATURE_ALLOWED_BY_TOKEN:
|
||||
return "ALLOWED_BY_TOKEN";
|
||||
case FGS_FEATURE_ALLOWED_BY_PERMISSION:
|
||||
return "ALLOWED_BY_PERMISSION";
|
||||
case FGS_FEATURE_ALLOWED_BY_WHITELIST:
|
||||
return "ALLOWED_BY_WHITELIST";
|
||||
case FGS_FEATURE_ALLOWED_BY_DEVICE_OWNER:
|
||||
return "ALLOWED_BY_DEVICE_OWNER";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isFgsBgStart(@FgsFeatureRetCode int code) {
|
||||
return code != FGS_FEATURE_ALLOWED_BY_PROC_STATE
|
||||
&& code != FGS_FEATURE_ALLOWED_BY_UID_VISIBLE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
||||
|
||||
// allow the service becomes foreground service? Service started from background may not be
|
||||
// allowed to become a foreground service.
|
||||
boolean mAllowStartForeground;
|
||||
@ActiveServices.FgsFeatureRetCode int mAllowStartForeground;
|
||||
String mInfoAllowStartForeground;
|
||||
boolean mLoggedInfoAllowStartForeground;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user