Merge "BG-FGS-start while-in-use permission restriction improvement." into rvc-dev
This commit is contained in:
@@ -734,11 +734,8 @@ public final class ActiveServices {
|
|||||||
}
|
}
|
||||||
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
|
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
|
||||||
|
|
||||||
if (!r.mAllowWhileInUsePermissionInFgs) {
|
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, r,
|
||||||
r.mAllowWhileInUsePermissionInFgs =
|
allowBackgroundActivityStarts);
|
||||||
shouldAllowWhileInUsePermissionInFgsLocked(callingPackage, callingPid,
|
|
||||||
callingUid, service, r, allowBackgroundActivityStarts);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
@@ -1400,14 +1397,6 @@ public final class ActiveServices {
|
|||||||
+ String.format("0x%08X", manifestType)
|
+ String.format("0x%08X", manifestType)
|
||||||
+ " in service element of manifest file");
|
+ " in service element of manifest file");
|
||||||
}
|
}
|
||||||
// If the foreground service is not started from TOP process, do not allow it to
|
|
||||||
// have while-in-use location/camera/microphone access.
|
|
||||||
if (!r.mAllowWhileInUsePermissionInFgs) {
|
|
||||||
Slog.w(TAG,
|
|
||||||
"Foreground service started from background can not have "
|
|
||||||
+ "location/camera/microphone access: service "
|
|
||||||
+ r.shortInstanceName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
boolean alreadyStartedOp = false;
|
boolean alreadyStartedOp = false;
|
||||||
boolean stopProcStatsOp = false;
|
boolean stopProcStatsOp = false;
|
||||||
@@ -1455,6 +1444,57 @@ public final class ActiveServices {
|
|||||||
ignoreForeground = true;
|
ignoreForeground = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ignoreForeground) {
|
||||||
|
if (r.mStartForegroundCount == 0) {
|
||||||
|
/*
|
||||||
|
If the service was started with startService(), not
|
||||||
|
startForegroundService(), and if startForeground() isn't called within
|
||||||
|
mFgsStartForegroundTimeoutMs, then we check the state of the app
|
||||||
|
(who owns the service, which is the app that called startForeground())
|
||||||
|
again. If the app is in the foreground, or in any other cases where
|
||||||
|
FGS-starts are allowed, then we still allow the FGS to be started.
|
||||||
|
Otherwise, startForeground() would fail.
|
||||||
|
|
||||||
|
If the service was started with startForegroundService(), then the service
|
||||||
|
must call startForeground() within a timeout anyway, so we don't need this
|
||||||
|
check.
|
||||||
|
*/
|
||||||
|
if (!r.fgRequired) {
|
||||||
|
final long delayMs = SystemClock.elapsedRealtime() - r.createRealTime;
|
||||||
|
if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
|
||||||
|
resetFgsRestrictionLocked(r);
|
||||||
|
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.pid,
|
||||||
|
r.appInfo.uid, r, false);
|
||||||
|
EventLog.writeEvent(0x534e4554, "183147114",
|
||||||
|
r.appInfo.uid,
|
||||||
|
"call setFgsRestrictionLocked again due to "
|
||||||
|
+ "startForegroundTimeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (r.mStartForegroundCount >= 1) {
|
||||||
|
// The second or later time startForeground() is called after service is
|
||||||
|
// started. Check for app state again.
|
||||||
|
final long delayMs = SystemClock.elapsedRealtime() -
|
||||||
|
r.mLastSetFgsRestrictionTime;
|
||||||
|
if (delayMs > mAm.mConstants.mFgsStartForegroundTimeoutMs) {
|
||||||
|
resetFgsRestrictionLocked(r);
|
||||||
|
setFgsRestrictionLocked(r.serviceInfo.packageName, r.app.pid,
|
||||||
|
r.appInfo.uid, r, false);
|
||||||
|
EventLog.writeEvent(0x534e4554, "183147114", r.appInfo.uid,
|
||||||
|
"call setFgsRestrictionLocked for "
|
||||||
|
+ (r.mStartForegroundCount + 1) + "th startForeground");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the foreground service is not started from TOP process, do not allow it to
|
||||||
|
// have while-in-use location/camera/microphone access.
|
||||||
|
if (!r.mAllowWhileInUsePermissionInFgs) {
|
||||||
|
Slog.w(TAG,
|
||||||
|
"Foreground service started from background can not have "
|
||||||
|
+ "location/camera/microphone access: service "
|
||||||
|
+ r.shortInstanceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Apps under strict background restrictions simply don't get to have foreground
|
// Apps under strict background restrictions simply don't get to have foreground
|
||||||
// services, so now that we've enforced the startForegroundService() contract
|
// services, so now that we've enforced the startForegroundService() contract
|
||||||
// we only do the machinery of making the service foreground when the app
|
// we only do the machinery of making the service foreground when the app
|
||||||
@@ -1490,6 +1530,7 @@ public final class ActiveServices {
|
|||||||
active.mNumActive++;
|
active.mNumActive++;
|
||||||
}
|
}
|
||||||
r.isForeground = true;
|
r.isForeground = true;
|
||||||
|
r.mStartForegroundCount++;
|
||||||
if (!stopProcStatsOp) {
|
if (!stopProcStatsOp) {
|
||||||
ServiceState stracker = r.getTracker();
|
ServiceState stracker = r.getTracker();
|
||||||
if (stracker != null) {
|
if (stracker != null) {
|
||||||
@@ -1548,6 +1589,7 @@ public final class ActiveServices {
|
|||||||
decActiveForegroundAppLocked(smap, r);
|
decActiveForegroundAppLocked(smap, r);
|
||||||
}
|
}
|
||||||
r.isForeground = false;
|
r.isForeground = false;
|
||||||
|
resetFgsRestrictionLocked(r);
|
||||||
ServiceState stracker = r.getTracker();
|
ServiceState stracker = r.getTracker();
|
||||||
if (stracker != null) {
|
if (stracker != null) {
|
||||||
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
|
stracker.setForeground(false, mAm.mProcessStats.getMemFactorLocked(),
|
||||||
@@ -2107,12 +2149,7 @@ public final class ActiveServices {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!s.mAllowWhileInUsePermissionInFgs) {
|
setFgsRestrictionLocked(callingPackage, callingPid, callingUid, s, false);
|
||||||
s.mAllowWhileInUsePermissionInFgs =
|
|
||||||
shouldAllowWhileInUsePermissionInFgsLocked(callingPackage,
|
|
||||||
callingPid, callingUid,
|
|
||||||
service, s, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.app != null) {
|
if (s.app != null) {
|
||||||
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
|
if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
|
||||||
@@ -3408,7 +3445,7 @@ public final class ActiveServices {
|
|||||||
r.isForeground = false;
|
r.isForeground = false;
|
||||||
r.foregroundId = 0;
|
r.foregroundId = 0;
|
||||||
r.foregroundNoti = null;
|
r.foregroundNoti = null;
|
||||||
r.mAllowWhileInUsePermissionInFgs = false;
|
resetFgsRestrictionLocked(r);
|
||||||
|
|
||||||
// Clear start entries.
|
// Clear start entries.
|
||||||
r.clearDeliveredStartsLocked();
|
r.clearDeliveredStartsLocked();
|
||||||
@@ -4889,7 +4926,7 @@ public final class ActiveServices {
|
|||||||
* @return true if allow, false otherwise.
|
* @return true if allow, false otherwise.
|
||||||
*/
|
*/
|
||||||
private boolean shouldAllowWhileInUsePermissionInFgsLocked(String callingPackage,
|
private boolean shouldAllowWhileInUsePermissionInFgsLocked(String callingPackage,
|
||||||
int callingPid, int callingUid, Intent intent, ServiceRecord r,
|
int callingPid, int callingUid, ServiceRecord r,
|
||||||
boolean allowBackgroundActivityStarts) {
|
boolean allowBackgroundActivityStarts) {
|
||||||
// Is the background FGS start restriction turned on?
|
// Is the background FGS start restriction turned on?
|
||||||
if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
|
if (!mAm.mConstants.mFlagBackgroundFgsStartRestrictionEnabled) {
|
||||||
@@ -4960,4 +4997,32 @@ public final class ActiveServices {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid,
|
||||||
|
String callingPackage) {
|
||||||
|
return shouldAllowWhileInUsePermissionInFgsLocked(
|
||||||
|
callingPackage, callingPid, callingUid, null, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In R, mAllowWhileInUsePermissionInFgs is to allow while-in-use permissions in foreground
|
||||||
|
* service or not. while-in-use permissions in FGS started from background might be restricted.
|
||||||
|
* @param callingPackage caller app's package name.
|
||||||
|
* @param callingUid caller app's uid.
|
||||||
|
* @param r the service to start.
|
||||||
|
* @return true if allow, false otherwise.
|
||||||
|
*/
|
||||||
|
private void setFgsRestrictionLocked(String callingPackage,
|
||||||
|
int callingPid, int callingUid, ServiceRecord r,
|
||||||
|
boolean allowBackgroundActivityStarts) {
|
||||||
|
r.mLastSetFgsRestrictionTime = SystemClock.elapsedRealtime();
|
||||||
|
if (!r.mAllowWhileInUsePermissionInFgs) {
|
||||||
|
r.mAllowWhileInUsePermissionInFgs = shouldAllowWhileInUsePermissionInFgsLocked(
|
||||||
|
callingPackage, callingPid, callingUid, r, allowBackgroundActivityStarts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetFgsRestrictionLocked(ServiceRecord r) {
|
||||||
|
r.mAllowWhileInUsePermissionInFgs = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ final class ActivityManagerConstants extends ContentObserver {
|
|||||||
static final String KEY_PROCESS_START_ASYNC = "process_start_async";
|
static final String KEY_PROCESS_START_ASYNC = "process_start_async";
|
||||||
static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time";
|
static final String KEY_MEMORY_INFO_THROTTLE_TIME = "memory_info_throttle_time";
|
||||||
static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration";
|
static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration";
|
||||||
|
static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout";
|
||||||
static final String KEY_PENDINGINTENT_WARNING_THRESHOLD = "pendingintent_warning_threshold";
|
static final String KEY_PENDINGINTENT_WARNING_THRESHOLD = "pendingintent_warning_threshold";
|
||||||
|
|
||||||
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
|
private static final int DEFAULT_MAX_CACHED_PROCESSES = 32;
|
||||||
@@ -120,6 +121,7 @@ final class ActivityManagerConstants extends ContentObserver {
|
|||||||
private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
|
private static final boolean DEFAULT_PROCESS_START_ASYNC = true;
|
||||||
private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000;
|
private static final long DEFAULT_MEMORY_INFO_THROTTLE_TIME = 5*60*1000;
|
||||||
private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000;
|
private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000;
|
||||||
|
private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000;
|
||||||
private static final int DEFAULT_PENDINGINTENT_WARNING_THRESHOLD = 2000;
|
private static final int DEFAULT_PENDINGINTENT_WARNING_THRESHOLD = 2000;
|
||||||
|
|
||||||
// Flag stored in the DeviceConfig API.
|
// Flag stored in the DeviceConfig API.
|
||||||
@@ -272,6 +274,12 @@ final class ActivityManagerConstants extends ContentObserver {
|
|||||||
// this long.
|
// this long.
|
||||||
public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION;
|
public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When service started from background, before the timeout it can be promoted to FGS by calling
|
||||||
|
* Service.startForeground().
|
||||||
|
*/
|
||||||
|
volatile long mFgsStartForegroundTimeoutMs = DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS;
|
||||||
|
|
||||||
// Indicates whether the activity starts logging is enabled.
|
// Indicates whether the activity starts logging is enabled.
|
||||||
// Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
|
// Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED
|
||||||
volatile boolean mFlagActivityStartsLoggingEnabled;
|
volatile boolean mFlagActivityStartsLoggingEnabled;
|
||||||
@@ -415,6 +423,9 @@ final class ActivityManagerConstants extends ContentObserver {
|
|||||||
case KEY_MIN_ASSOC_LOG_DURATION:
|
case KEY_MIN_ASSOC_LOG_DURATION:
|
||||||
updateMinAssocLogDuration();
|
updateMinAssocLogDuration();
|
||||||
break;
|
break;
|
||||||
|
case KEY_FGS_START_FOREGROUND_TIMEOUT:
|
||||||
|
updateFgsStartForegroundTimeout();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -687,6 +698,13 @@ final class ActivityManagerConstants extends ContentObserver {
|
|||||||
/* defaultValue */ DEFAULT_MIN_ASSOC_LOG_DURATION);
|
/* defaultValue */ DEFAULT_MIN_ASSOC_LOG_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateFgsStartForegroundTimeout() {
|
||||||
|
mFgsStartForegroundTimeoutMs = DeviceConfig.getLong(
|
||||||
|
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
||||||
|
KEY_FGS_START_FOREGROUND_TIMEOUT,
|
||||||
|
DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS);
|
||||||
|
}
|
||||||
|
|
||||||
void dump(PrintWriter pw) {
|
void dump(PrintWriter pw) {
|
||||||
pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
|
pw.println("ACTIVITY MANAGER SETTINGS (dumpsys activity settings) "
|
||||||
+ Settings.Global.ACTIVITY_MANAGER_CONSTANTS + ":");
|
+ Settings.Global.ACTIVITY_MANAGER_CONSTANTS + ":");
|
||||||
@@ -759,6 +777,8 @@ final class ActivityManagerConstants extends ContentObserver {
|
|||||||
pw.println(Arrays.toString(IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.toArray()));
|
pw.println(Arrays.toString(IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.toArray()));
|
||||||
pw.print(" "); pw.print(KEY_MIN_ASSOC_LOG_DURATION); pw.print("=");
|
pw.print(" "); pw.print(KEY_MIN_ASSOC_LOG_DURATION); pw.print("=");
|
||||||
pw.println(MIN_ASSOC_LOG_DURATION);
|
pw.println(MIN_ASSOC_LOG_DURATION);
|
||||||
|
pw.print(" "); pw.print(KEY_FGS_START_FOREGROUND_TIMEOUT); pw.print("=");
|
||||||
|
pw.println(mFgsStartForegroundTimeoutMs);
|
||||||
|
|
||||||
pw.println();
|
pw.println();
|
||||||
if (mOverrideMaxCachedProcesses >= 0) {
|
if (mOverrideMaxCachedProcesses >= 0) {
|
||||||
|
|||||||
@@ -138,6 +138,10 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
|||||||
// allow while-in-use permissions in foreground service or not.
|
// allow while-in-use permissions in foreground service or not.
|
||||||
// while-in-use permissions in FGS started from background might be restricted.
|
// while-in-use permissions in FGS started from background might be restricted.
|
||||||
boolean mAllowWhileInUsePermissionInFgs;
|
boolean mAllowWhileInUsePermissionInFgs;
|
||||||
|
// The number of times Service.startForeground() is called;
|
||||||
|
int mStartForegroundCount;
|
||||||
|
// Last time mAllowWhileInUsePermissionInFgs is set.
|
||||||
|
long mLastSetFgsRestrictionTime;
|
||||||
|
|
||||||
// the most recent package that start/bind this service.
|
// the most recent package that start/bind this service.
|
||||||
String mRecentCallingPackage;
|
String mRecentCallingPackage;
|
||||||
@@ -400,6 +404,8 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
|
|||||||
}
|
}
|
||||||
pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs=");
|
pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs=");
|
||||||
pw.println(mAllowWhileInUsePermissionInFgs);
|
pw.println(mAllowWhileInUsePermissionInFgs);
|
||||||
|
pw.print(prefix); pw.print("startForegroundCount=");
|
||||||
|
pw.println(mStartForegroundCount);
|
||||||
pw.print(prefix); pw.print("recentCallingPackage=");
|
pw.print(prefix); pw.print("recentCallingPackage=");
|
||||||
pw.println(mRecentCallingPackage);
|
pw.println(mRecentCallingPackage);
|
||||||
if (delayed) {
|
if (delayed) {
|
||||||
|
|||||||
Reference in New Issue
Block a user