Add ownership for BackgroundActivityStartController.
BackgroundActivityStartController is a new class to contain the logic to permit activity launches from the background. The logic itself has just been moved from ActivityStarter without any changes. Bug: 236234252 Test: atest ActivityStarterTests Ignore-AOSP-First: Internal merge conflict, AOSP change in aosp/2169485 Change-Id: I6ee0e839a4000c9e27630c2e654d945bf45b21e6
This commit is contained in:
@@ -97,6 +97,8 @@ public class ActivityStartController {
|
|||||||
/** Whether an {@link ActivityStarter} is currently executing (starting an Activity). */
|
/** Whether an {@link ActivityStarter} is currently executing (starting an Activity). */
|
||||||
private boolean mInExecution = false;
|
private boolean mInExecution = false;
|
||||||
|
|
||||||
|
private final BackgroundActivityStartController mBalController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO(b/64750076): Capture information necessary for dump and
|
* TODO(b/64750076): Capture information necessary for dump and
|
||||||
* {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object
|
* {@link #postStartActivityProcessingForLastStarter} rather than keeping the entire object
|
||||||
@@ -119,6 +121,7 @@ public class ActivityStartController {
|
|||||||
mFactory.setController(this);
|
mFactory.setController(this);
|
||||||
mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
|
mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
|
||||||
service.mH);
|
service.mH);
|
||||||
|
mBalController = new BackgroundActivityStartController(mService, mSupervisor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -632,4 +635,8 @@ public class ActivityStartController {
|
|||||||
pw.println("(nothing)");
|
pw.println("(nothing)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BackgroundActivityStartController getBackgroundActivityLaunchController() {
|
||||||
|
return mBalController;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
|
|
||||||
import static android.app.Activity.RESULT_CANCELED;
|
import static android.app.Activity.RESULT_CANCELED;
|
||||||
import static android.app.ActivityManager.START_ABORTED;
|
import static android.app.ActivityManager.START_ABORTED;
|
||||||
import static android.app.ActivityManager.START_CANCELED;
|
import static android.app.ActivityManager.START_CANCELED;
|
||||||
@@ -52,7 +51,6 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE_PER_TASK;
|
|||||||
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
|
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
|
||||||
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
|
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
|
||||||
import static android.content.pm.ActivityInfo.launchModeToString;
|
import static android.content.pm.ActivityInfo.launchModeToString;
|
||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
|
||||||
import static android.os.Process.INVALID_UID;
|
import static android.os.Process.INVALID_UID;
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
import static android.view.WindowManager.TRANSIT_OPEN;
|
import static android.view.WindowManager.TRANSIT_OPEN;
|
||||||
@@ -61,7 +59,6 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP
|
|||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
|
||||||
import static com.android.server.wm.ActivityRecord.State.RESUMED;
|
import static com.android.server.wm.ActivityRecord.State.RESUMED;
|
||||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
|
|
||||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
|
||||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_RESULTS;
|
||||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_USER_LEAVING;
|
||||||
@@ -72,8 +69,6 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_USER_
|
|||||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
|
||||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||||
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
|
import static com.android.server.wm.ActivityTaskManagerService.ANIMATE;
|
||||||
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
|
|
||||||
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY;
|
|
||||||
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
|
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
|
||||||
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
|
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
|
||||||
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
|
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
|
||||||
@@ -98,7 +93,6 @@ import android.app.WaitResult;
|
|||||||
import android.app.WindowConfiguration;
|
import android.app.WindowConfiguration;
|
||||||
import android.compat.annotation.ChangeId;
|
import android.compat.annotation.ChangeId;
|
||||||
import android.compat.annotation.EnabledSince;
|
import android.compat.annotation.EnabledSince;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.IIntentSender;
|
import android.content.IIntentSender;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
@@ -114,15 +108,12 @@ import android.os.Binder;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Process;
|
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.service.voice.IVoiceInteractionSession;
|
import android.service.voice.IVoiceInteractionSession;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.ArraySet;
|
|
||||||
import android.util.DebugUtils;
|
|
||||||
import android.util.Pools.SynchronizedPool;
|
import android.util.Pools.SynchronizedPool;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.window.RemoteTransition;
|
import android.window.RemoteTransition;
|
||||||
@@ -261,8 +252,6 @@ class ActivityStarter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an {@link ActivityStarter} that is ready to handle a new start request.
|
* Generates an {@link ActivityStarter} that is ready to handle a new start request.
|
||||||
* @param controller The {@link ActivityStartController} which the starter who will own
|
|
||||||
* this instance.
|
|
||||||
* @return an {@link ActivityStarter}
|
* @return an {@link ActivityStarter}
|
||||||
*/
|
*/
|
||||||
ActivityStarter obtain();
|
ActivityStarter obtain();
|
||||||
@@ -1035,10 +1024,20 @@ class ActivityStarter {
|
|||||||
try {
|
try {
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
|
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
|
||||||
"shouldAbortBackgroundActivityStart");
|
"shouldAbortBackgroundActivityStart");
|
||||||
restrictedBgActivity = shouldAbortBackgroundActivityStart(callingUid,
|
BackgroundActivityStartController balController =
|
||||||
callingPid, callingPackage, realCallingUid, realCallingPid, callerApp,
|
mController.getBackgroundActivityLaunchController();
|
||||||
request.originatingPendingIntent, request.allowBackgroundActivityStart,
|
restrictedBgActivity =
|
||||||
intent, checkedOptions);
|
balController.shouldAbortBackgroundActivityStart(
|
||||||
|
callingUid,
|
||||||
|
callingPid,
|
||||||
|
callingPackage,
|
||||||
|
realCallingUid,
|
||||||
|
realCallingPid,
|
||||||
|
callerApp,
|
||||||
|
request.originatingPendingIntent,
|
||||||
|
request.allowBackgroundActivityStart,
|
||||||
|
intent,
|
||||||
|
checkedOptions);
|
||||||
} finally {
|
} finally {
|
||||||
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
|
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
|
||||||
}
|
}
|
||||||
@@ -1272,282 +1271,6 @@ class ActivityStarter {
|
|||||||
mController.onExecutionStarted();
|
mController.onExecutionStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHomeApp(int uid, @Nullable String packageName) {
|
|
||||||
if (mService.mHomeProcess != null) {
|
|
||||||
// Fast check
|
|
||||||
return uid == mService.mHomeProcess.mUid;
|
|
||||||
}
|
|
||||||
if (packageName == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ComponentName activity =
|
|
||||||
mService.getPackageManagerInternalLocked().getDefaultHomeActivity(
|
|
||||||
UserHandle.getUserId(uid));
|
|
||||||
return activity != null && packageName.equals(activity.getPackageName());
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
|
|
||||||
final String callingPackage, int realCallingUid, int realCallingPid,
|
|
||||||
WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
|
|
||||||
boolean allowBackgroundActivityStart, Intent intent, ActivityOptions checkedOptions) {
|
|
||||||
// don't abort for the most important UIDs
|
|
||||||
final int callingAppId = UserHandle.getAppId(callingUid);
|
|
||||||
final boolean useCallingUidState =
|
|
||||||
originatingPendingIntent == null || checkedOptions == null
|
|
||||||
|| !checkedOptions.getIgnorePendingIntentCreatorForegroundState();
|
|
||||||
if (useCallingUidState) {
|
|
||||||
if (callingUid == Process.ROOT_UID || callingAppId == Process.SYSTEM_UID
|
|
||||||
|| callingAppId == Process.NFC_UID) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG,
|
|
||||||
"Activity start allowed for important callingUid (" + callingUid + ")");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always allow home application to start activities.
|
|
||||||
if (isHomeApp(callingUid, callingPackage)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG,
|
|
||||||
"Activity start allowed for home app callingUid (" + callingUid + ")");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// IME should always be allowed to start activity, like IME settings.
|
|
||||||
final WindowState imeWindow = mRootWindowContainer.getCurrentInputMethodWindow();
|
|
||||||
if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is used to block background activity launch even if the app is still
|
|
||||||
// visible to user after user clicking home button.
|
|
||||||
final int appSwitchState = mService.getBalAppSwitchesState();
|
|
||||||
|
|
||||||
// don't abort if the callingUid has a visible window or is a persistent system process
|
|
||||||
final int callingUidProcState = mService.mActiveUids.getUidState(callingUid);
|
|
||||||
final boolean callingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid);
|
|
||||||
final boolean isCallingUidForeground = callingUidHasAnyVisibleWindow
|
|
||||||
|| callingUidProcState == ActivityManager.PROCESS_STATE_TOP
|
|
||||||
|| callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
|
|
||||||
final boolean isCallingUidPersistentSystemProcess =
|
|
||||||
callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
|
|
||||||
|
|
||||||
// Normal apps with visible app window will be allowed to start activity if app switching
|
|
||||||
// is allowed, or apps like live wallpaper with non app visible window will be allowed.
|
|
||||||
final boolean appSwitchAllowedOrFg =
|
|
||||||
appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY;
|
|
||||||
final boolean allowCallingUidStartActivity =
|
|
||||||
((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
|
|
||||||
&& callingUidHasAnyVisibleWindow)
|
|
||||||
|| isCallingUidPersistentSystemProcess;
|
|
||||||
if (useCallingUidState && allowCallingUidStartActivity) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Activity start allowed: callingUidHasAnyVisibleWindow = " + callingUid
|
|
||||||
+ ", isCallingUidPersistentSystemProcess = "
|
|
||||||
+ isCallingUidPersistentSystemProcess);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// take realCallingUid into consideration
|
|
||||||
final int realCallingUidProcState = (callingUid == realCallingUid)
|
|
||||||
? callingUidProcState
|
|
||||||
: mService.mActiveUids.getUidState(realCallingUid);
|
|
||||||
final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid)
|
|
||||||
? callingUidHasAnyVisibleWindow
|
|
||||||
: mService.hasActiveVisibleWindow(realCallingUid);
|
|
||||||
final boolean isRealCallingUidForeground = (callingUid == realCallingUid)
|
|
||||||
? isCallingUidForeground
|
|
||||||
: realCallingUidHasAnyVisibleWindow
|
|
||||||
|| realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
|
|
||||||
final int realCallingAppId = UserHandle.getAppId(realCallingUid);
|
|
||||||
final boolean isRealCallingUidPersistentSystemProcess = (callingUid == realCallingUid)
|
|
||||||
? isCallingUidPersistentSystemProcess
|
|
||||||
: (realCallingAppId == Process.SYSTEM_UID)
|
|
||||||
|| realCallingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
|
|
||||||
|
|
||||||
// In the case of an SDK sandbox calling uid, check if the corresponding app uid has a
|
|
||||||
// visible window.
|
|
||||||
if (Process.isSdkSandboxUid(realCallingUid)) {
|
|
||||||
int realCallingSdkSandboxUidToAppUid = Process.getAppUidForSdkSandboxUid(
|
|
||||||
UserHandle.getAppId(realCallingUid));
|
|
||||||
|
|
||||||
if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Activity start allowed: uid in SDK sandbox ("
|
|
||||||
+ realCallingUid + ") has visible (non-toast) window.");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy behavior allows to use caller foreground state to bypass BAL restriction.
|
|
||||||
final boolean balAllowedByPiSender =
|
|
||||||
PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions);
|
|
||||||
|
|
||||||
if (balAllowedByPiSender && realCallingUid != callingUid) {
|
|
||||||
final boolean useCallerPermission =
|
|
||||||
PendingIntentRecord.isPendingIntentBalAllowedByPermission(checkedOptions);
|
|
||||||
if (useCallerPermission && ActivityManager.checkComponentPermission(
|
|
||||||
android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
|
|
||||||
realCallingUid, -1, true)
|
|
||||||
== PackageManager.PERMISSION_GRANTED) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
|
|
||||||
+ ") has BAL permission.");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't abort if the realCallingUid has a visible window
|
|
||||||
// TODO(b/171459802): We should check appSwitchAllowed also
|
|
||||||
if (realCallingUidHasAnyVisibleWindow) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
|
|
||||||
+ ") has visible (non-toast) window");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// if the realCallingUid is a persistent system process, abort if the IntentSender
|
|
||||||
// wasn't allowed to start an activity
|
|
||||||
if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
|
|
||||||
+ ") is persistent system process AND intent sender allowed "
|
|
||||||
+ "(allowBackgroundActivityStart = true)");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// don't abort if the realCallingUid is an associated companion app
|
|
||||||
if (mService.isAssociatedCompanionApp(UserHandle.getUserId(realCallingUid),
|
|
||||||
realCallingUid)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Activity start allowed: realCallingUid (" + realCallingUid
|
|
||||||
+ ") is companion app");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (useCallingUidState) {
|
|
||||||
// don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
|
|
||||||
if (mService.checkPermission(
|
|
||||||
START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
|
|
||||||
== PERMISSION_GRANTED) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG,
|
|
||||||
"Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
|
|
||||||
+ "permission granted for uid "
|
|
||||||
+ callingUid);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// don't abort if the caller has the same uid as the recents component
|
|
||||||
if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
|
|
||||||
+ ") is recents");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// don't abort if the callingUid is the device owner
|
|
||||||
if (mService.isDeviceOwner(callingUid)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
|
|
||||||
+ ") is device owner");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// don't abort if the callingUid has companion device
|
|
||||||
final int callingUserId = UserHandle.getUserId(callingUid);
|
|
||||||
if (mService.isAssociatedCompanionApp(callingUserId,
|
|
||||||
callingUid)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Background activity start allowed: callingUid (" + callingUid
|
|
||||||
+ ") is companion app");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
|
|
||||||
if (mService.hasSystemAlertWindowPermission(callingUid,
|
|
||||||
callingPid, callingPackage)) {
|
|
||||||
Slog.w(TAG, "Background activity start for " + callingPackage
|
|
||||||
+ " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If we don't have callerApp at this point, no caller was provided to startActivity().
|
|
||||||
// That's the case for PendingIntent-based starts, since the creator's process might not be
|
|
||||||
// up and alive. If that's the case, we retrieve the WindowProcessController for the send()
|
|
||||||
// caller if caller allows, so that we can make the decision based on its state.
|
|
||||||
int callerAppUid = callingUid;
|
|
||||||
if (callerApp == null && balAllowedByPiSender) {
|
|
||||||
callerApp = mService.getProcessController(realCallingPid, realCallingUid);
|
|
||||||
callerAppUid = realCallingUid;
|
|
||||||
}
|
|
||||||
// don't abort if the callerApp or other processes of that uid are allowed in any way
|
|
||||||
if (callerApp != null && useCallingUidState) {
|
|
||||||
// first check the original calling process
|
|
||||||
if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG, "Background activity start allowed: callerApp process (pid = "
|
|
||||||
+ callerApp.getPid() + ", uid = " + callerAppUid + ") is allowed");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// only if that one wasn't allowed, check the other ones
|
|
||||||
final ArraySet<WindowProcessController> uidProcesses =
|
|
||||||
mService.mProcessMap.getProcesses(callerAppUid);
|
|
||||||
if (uidProcesses != null) {
|
|
||||||
for (int i = uidProcesses.size() - 1; i >= 0; i--) {
|
|
||||||
final WindowProcessController proc = uidProcesses.valueAt(i);
|
|
||||||
if (proc != callerApp
|
|
||||||
&& proc.areBackgroundActivityStartsAllowed(appSwitchState)) {
|
|
||||||
if (DEBUG_ACTIVITY_STARTS) {
|
|
||||||
Slog.d(TAG,
|
|
||||||
"Background activity start allowed: process " + proc.getPid()
|
|
||||||
+ " from uid " + callerAppUid + " is allowed");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// anything that has fallen through would currently be aborted
|
|
||||||
Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
|
|
||||||
+ "; callingUid: " + callingUid
|
|
||||||
+ "; appSwitchState: " + appSwitchState
|
|
||||||
+ "; isCallingUidForeground: " + isCallingUidForeground
|
|
||||||
+ "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow
|
|
||||||
+ "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
|
|
||||||
"PROCESS_STATE_", callingUidProcState)
|
|
||||||
+ "; isCallingUidPersistentSystemProcess: " + isCallingUidPersistentSystemProcess
|
|
||||||
+ "; realCallingUid: " + realCallingUid
|
|
||||||
+ "; isRealCallingUidForeground: " + isRealCallingUidForeground
|
|
||||||
+ "; realCallingUidHasAnyVisibleWindow: " + realCallingUidHasAnyVisibleWindow
|
|
||||||
+ "; realCallingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
|
|
||||||
"PROCESS_STATE_", realCallingUidProcState)
|
|
||||||
+ "; isRealCallingUidPersistentSystemProcess: "
|
|
||||||
+ isRealCallingUidPersistentSystemProcess
|
|
||||||
+ "; originatingPendingIntent: " + originatingPendingIntent
|
|
||||||
+ "; allowBackgroundActivityStart: " + allowBackgroundActivityStart
|
|
||||||
+ "; intent: " + intent
|
|
||||||
+ "; callerApp: " + callerApp
|
|
||||||
+ "; inVisibleTask: " + (callerApp != null && callerApp.hasActivityInVisibleTask())
|
|
||||||
+ "]");
|
|
||||||
// log aborted activity start to TRON
|
|
||||||
if (mService.isActivityStartsLoggingEnabled()) {
|
|
||||||
mSupervisor.getActivityMetricsLogger().logAbortedBgActivityStart(intent, callerApp,
|
|
||||||
callingUid, callingPackage, callingUidProcState, callingUidHasAnyVisibleWindow,
|
|
||||||
realCallingUid, realCallingUidProcState, realCallingUidHasAnyVisibleWindow,
|
|
||||||
(originatingPendingIntent != null));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a launch intent for the given auxiliary resolution data.
|
* Creates a launch intent for the given auxiliary resolution data.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2181,10 +2181,19 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
if (appThread != null) {
|
if (appThread != null) {
|
||||||
callerApp = getProcessController(appThread);
|
callerApp = getProcessController(appThread);
|
||||||
}
|
}
|
||||||
final ActivityStarter starter = getActivityStartController().obtainStarter(
|
final BackgroundActivityStartController balController =
|
||||||
null /* intent */, "moveTaskToFront");
|
getActivityStartController().getBackgroundActivityLaunchController();
|
||||||
if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid, callingPackage, -1,
|
if (balController.shouldAbortBackgroundActivityStart(
|
||||||
-1, callerApp, null, false, null, null)) {
|
callingUid,
|
||||||
|
callingPid,
|
||||||
|
callingPackage,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
callerApp,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
null)) {
|
||||||
if (!isBackgroundActivityStartsEnabled()) {
|
if (!isBackgroundActivityStartsEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,10 +119,20 @@ class AppTaskImpl extends IAppTask.Stub {
|
|||||||
if (appThread != null) {
|
if (appThread != null) {
|
||||||
callerApp = mService.getProcessController(appThread);
|
callerApp = mService.getProcessController(appThread);
|
||||||
}
|
}
|
||||||
final ActivityStarter starter = mService.getActivityStartController().obtainStarter(
|
final BackgroundActivityStartController balController =
|
||||||
null /* intent */, "moveToFront");
|
mService.getActivityStartController()
|
||||||
if (starter.shouldAbortBackgroundActivityStart(callingUid, callingPid,
|
.getBackgroundActivityLaunchController();
|
||||||
callingPackage, -1, -1, callerApp, null, false, null, null)) {
|
if (balController.shouldAbortBackgroundActivityStart(
|
||||||
|
callingUid,
|
||||||
|
callingPid,
|
||||||
|
callingPackage,
|
||||||
|
-1,
|
||||||
|
-1,
|
||||||
|
callerApp,
|
||||||
|
null,
|
||||||
|
false,
|
||||||
|
null,
|
||||||
|
null)) {
|
||||||
if (!mService.isBackgroundActivityStartsEnabled()) {
|
if (!mService.isBackgroundActivityStartsEnabled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,421 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.server.wm;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
|
|
||||||
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ACTIVITY_STARTS;
|
||||||
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
|
||||||
|
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||||
|
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_ALLOW;
|
||||||
|
import static com.android.server.wm.ActivityTaskManagerService.APP_SWITCH_FG_ONLY;
|
||||||
|
|
||||||
|
import android.annotation.Nullable;
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.app.ActivityOptions;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.os.Process;
|
||||||
|
import android.os.UserHandle;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import android.util.DebugUtils;
|
||||||
|
import android.util.Slog;
|
||||||
|
|
||||||
|
import com.android.server.am.PendingIntentRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to check permissions for starting Activities.
|
||||||
|
*
|
||||||
|
* <p>This class collects all the logic to prevent malicious attempts to start activities.
|
||||||
|
*/
|
||||||
|
public class BackgroundActivityStartController {
|
||||||
|
|
||||||
|
private static final String TAG =
|
||||||
|
TAG_WITH_CLASS_NAME ? "BackgroundActivityStartController" : TAG_ATM;
|
||||||
|
|
||||||
|
private final ActivityTaskManagerService mService;
|
||||||
|
private final ActivityTaskSupervisor mSupervisor;
|
||||||
|
|
||||||
|
BackgroundActivityStartController(
|
||||||
|
final ActivityTaskManagerService service, final ActivityTaskSupervisor supervisor) {
|
||||||
|
mService = service;
|
||||||
|
mSupervisor = supervisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHomeApp(int uid, @Nullable String packageName) {
|
||||||
|
if (mService.mHomeProcess != null) {
|
||||||
|
// Fast check
|
||||||
|
return uid == mService.mHomeProcess.mUid;
|
||||||
|
}
|
||||||
|
if (packageName == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ComponentName activity =
|
||||||
|
mService.getPackageManagerInternalLocked()
|
||||||
|
.getDefaultHomeActivity(UserHandle.getUserId(uid));
|
||||||
|
return activity != null && packageName.equals(activity.getPackageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean shouldAbortBackgroundActivityStart(
|
||||||
|
int callingUid,
|
||||||
|
int callingPid,
|
||||||
|
final String callingPackage,
|
||||||
|
int realCallingUid,
|
||||||
|
int realCallingPid,
|
||||||
|
WindowProcessController callerApp,
|
||||||
|
PendingIntentRecord originatingPendingIntent,
|
||||||
|
boolean allowBackgroundActivityStart,
|
||||||
|
Intent intent,
|
||||||
|
ActivityOptions checkedOptions) {
|
||||||
|
// don't abort for the most important UIDs
|
||||||
|
final int callingAppId = UserHandle.getAppId(callingUid);
|
||||||
|
final boolean useCallingUidState =
|
||||||
|
originatingPendingIntent == null
|
||||||
|
|| checkedOptions == null
|
||||||
|
|| !checkedOptions.getIgnorePendingIntentCreatorForegroundState();
|
||||||
|
if (useCallingUidState) {
|
||||||
|
if (callingUid == Process.ROOT_UID
|
||||||
|
|| callingAppId == Process.SYSTEM_UID
|
||||||
|
|| callingAppId == Process.NFC_UID) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed for important callingUid (" + callingUid + ")");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always allow home application to start activities.
|
||||||
|
if (isHomeApp(callingUid, callingPackage)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed for home app callingUid (" + callingUid + ")");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// IME should always be allowed to start activity, like IME settings.
|
||||||
|
final WindowState imeWindow =
|
||||||
|
mService.mRootWindowContainer.getCurrentInputMethodWindow();
|
||||||
|
if (imeWindow != null && callingAppId == imeWindow.mOwnerUid) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(TAG, "Activity start allowed for active ime (" + callingUid + ")");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is used to block background activity launch even if the app is still
|
||||||
|
// visible to user after user clicking home button.
|
||||||
|
final int appSwitchState = mService.getBalAppSwitchesState();
|
||||||
|
|
||||||
|
// don't abort if the callingUid has a visible window or is a persistent system process
|
||||||
|
final int callingUidProcState = mService.mActiveUids.getUidState(callingUid);
|
||||||
|
final boolean callingUidHasAnyVisibleWindow = mService.hasActiveVisibleWindow(callingUid);
|
||||||
|
final boolean isCallingUidForeground =
|
||||||
|
callingUidHasAnyVisibleWindow
|
||||||
|
|| callingUidProcState == ActivityManager.PROCESS_STATE_TOP
|
||||||
|
|| callingUidProcState == ActivityManager.PROCESS_STATE_BOUND_TOP;
|
||||||
|
final boolean isCallingUidPersistentSystemProcess =
|
||||||
|
callingUidProcState <= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
|
||||||
|
|
||||||
|
// Normal apps with visible app window will be allowed to start activity if app switching
|
||||||
|
// is allowed, or apps like live wallpaper with non app visible window will be allowed.
|
||||||
|
final boolean appSwitchAllowedOrFg =
|
||||||
|
appSwitchState == APP_SWITCH_ALLOW || appSwitchState == APP_SWITCH_FG_ONLY;
|
||||||
|
final boolean allowCallingUidStartActivity =
|
||||||
|
((appSwitchAllowedOrFg || mService.mActiveUids.hasNonAppVisibleWindow(callingUid))
|
||||||
|
&& callingUidHasAnyVisibleWindow)
|
||||||
|
|| isCallingUidPersistentSystemProcess;
|
||||||
|
if (useCallingUidState && allowCallingUidStartActivity) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed: callingUidHasAnyVisibleWindow = "
|
||||||
|
+ callingUid
|
||||||
|
+ ", isCallingUidPersistentSystemProcess = "
|
||||||
|
+ isCallingUidPersistentSystemProcess);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// take realCallingUid into consideration
|
||||||
|
final int realCallingUidProcState =
|
||||||
|
(callingUid == realCallingUid)
|
||||||
|
? callingUidProcState
|
||||||
|
: mService.mActiveUids.getUidState(realCallingUid);
|
||||||
|
final boolean realCallingUidHasAnyVisibleWindow =
|
||||||
|
(callingUid == realCallingUid)
|
||||||
|
? callingUidHasAnyVisibleWindow
|
||||||
|
: mService.hasActiveVisibleWindow(realCallingUid);
|
||||||
|
final boolean isRealCallingUidForeground =
|
||||||
|
(callingUid == realCallingUid)
|
||||||
|
? isCallingUidForeground
|
||||||
|
: realCallingUidHasAnyVisibleWindow
|
||||||
|
|| realCallingUidProcState == ActivityManager.PROCESS_STATE_TOP;
|
||||||
|
final int realCallingAppId = UserHandle.getAppId(realCallingUid);
|
||||||
|
final boolean isRealCallingUidPersistentSystemProcess =
|
||||||
|
(callingUid == realCallingUid)
|
||||||
|
? isCallingUidPersistentSystemProcess
|
||||||
|
: (realCallingAppId == Process.SYSTEM_UID)
|
||||||
|
|| realCallingUidProcState
|
||||||
|
<= ActivityManager.PROCESS_STATE_PERSISTENT_UI;
|
||||||
|
|
||||||
|
// In the case of an SDK sandbox calling uid, check if the corresponding app uid has a
|
||||||
|
// visible window.
|
||||||
|
if (Process.isSdkSandboxUid(realCallingUid)) {
|
||||||
|
int realCallingSdkSandboxUidToAppUid =
|
||||||
|
Process.getAppUidForSdkSandboxUid(UserHandle.getAppId(realCallingUid));
|
||||||
|
|
||||||
|
if (mService.hasActiveVisibleWindow(realCallingSdkSandboxUidToAppUid)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed: uid in SDK sandbox ("
|
||||||
|
+ realCallingUid
|
||||||
|
+ ") has visible (non-toast) window.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Legacy behavior allows to use caller foreground state to bypass BAL restriction.
|
||||||
|
final boolean balAllowedByPiSender =
|
||||||
|
PendingIntentRecord.isPendingIntentBalAllowedByCaller(checkedOptions);
|
||||||
|
|
||||||
|
if (balAllowedByPiSender && realCallingUid != callingUid) {
|
||||||
|
final boolean useCallerPermission =
|
||||||
|
PendingIntentRecord.isPendingIntentBalAllowedByPermission(checkedOptions);
|
||||||
|
if (useCallerPermission
|
||||||
|
&& ActivityManager.checkComponentPermission(
|
||||||
|
android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
|
||||||
|
realCallingUid,
|
||||||
|
-1,
|
||||||
|
true)
|
||||||
|
== PackageManager.PERMISSION_GRANTED) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed: realCallingUid ("
|
||||||
|
+ realCallingUid
|
||||||
|
+ ") has BAL permission.");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't abort if the realCallingUid has a visible window
|
||||||
|
// TODO(b/171459802): We should check appSwitchAllowed also
|
||||||
|
if (realCallingUidHasAnyVisibleWindow) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed: realCallingUid ("
|
||||||
|
+ realCallingUid
|
||||||
|
+ ") has visible (non-toast) window");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// if the realCallingUid is a persistent system process, abort if the IntentSender
|
||||||
|
// wasn't allowed to start an activity
|
||||||
|
if (isRealCallingUidPersistentSystemProcess && allowBackgroundActivityStart) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed: realCallingUid ("
|
||||||
|
+ realCallingUid
|
||||||
|
+ ") is persistent system process AND intent sender allowed "
|
||||||
|
+ "(allowBackgroundActivityStart = true)");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// don't abort if the realCallingUid is an associated companion app
|
||||||
|
if (mService.isAssociatedCompanionApp(
|
||||||
|
UserHandle.getUserId(realCallingUid), realCallingUid)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Activity start allowed: realCallingUid ("
|
||||||
|
+ realCallingUid
|
||||||
|
+ ") is companion app");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (useCallingUidState) {
|
||||||
|
// don't abort if the callingUid has START_ACTIVITIES_FROM_BACKGROUND permission
|
||||||
|
if (mService.checkPermission(START_ACTIVITIES_FROM_BACKGROUND, callingPid, callingUid)
|
||||||
|
== PERMISSION_GRANTED) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Background activity start allowed: START_ACTIVITIES_FROM_BACKGROUND "
|
||||||
|
+ "permission granted for uid "
|
||||||
|
+ callingUid);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// don't abort if the caller has the same uid as the recents component
|
||||||
|
if (mSupervisor.mRecentTasks.isCallerRecents(callingUid)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Background activity start allowed: callingUid ("
|
||||||
|
+ callingUid
|
||||||
|
+ ") is recents");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// don't abort if the callingUid is the device owner
|
||||||
|
if (mService.isDeviceOwner(callingUid)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Background activity start allowed: callingUid ("
|
||||||
|
+ callingUid
|
||||||
|
+ ") is device owner");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// don't abort if the callingUid has companion device
|
||||||
|
final int callingUserId = UserHandle.getUserId(callingUid);
|
||||||
|
if (mService.isAssociatedCompanionApp(callingUserId, callingUid)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Background activity start allowed: callingUid ("
|
||||||
|
+ callingUid
|
||||||
|
+ ") is companion app");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
|
||||||
|
if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
|
||||||
|
Slog.w(
|
||||||
|
TAG,
|
||||||
|
"Background activity start for "
|
||||||
|
+ callingPackage
|
||||||
|
+ " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If we don't have callerApp at this point, no caller was provided to startActivity().
|
||||||
|
// That's the case for PendingIntent-based starts, since the creator's process might not be
|
||||||
|
// up and alive. If that's the case, we retrieve the WindowProcessController for the send()
|
||||||
|
// caller if caller allows, so that we can make the decision based on its state.
|
||||||
|
int callerAppUid = callingUid;
|
||||||
|
if (callerApp == null && balAllowedByPiSender) {
|
||||||
|
callerApp = mService.getProcessController(realCallingPid, realCallingUid);
|
||||||
|
callerAppUid = realCallingUid;
|
||||||
|
}
|
||||||
|
// don't abort if the callerApp or other processes of that uid are allowed in any way
|
||||||
|
if (callerApp != null && useCallingUidState) {
|
||||||
|
// first check the original calling process
|
||||||
|
if (callerApp.areBackgroundActivityStartsAllowed(appSwitchState)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Background activity start allowed: callerApp process (pid = "
|
||||||
|
+ callerApp.getPid()
|
||||||
|
+ ", uid = "
|
||||||
|
+ callerAppUid
|
||||||
|
+ ") is allowed");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// only if that one wasn't allowed, check the other ones
|
||||||
|
final ArraySet<WindowProcessController> uidProcesses =
|
||||||
|
mService.mProcessMap.getProcesses(callerAppUid);
|
||||||
|
if (uidProcesses != null) {
|
||||||
|
for (int i = uidProcesses.size() - 1; i >= 0; i--) {
|
||||||
|
final WindowProcessController proc = uidProcesses.valueAt(i);
|
||||||
|
if (proc != callerApp
|
||||||
|
&& proc.areBackgroundActivityStartsAllowed(appSwitchState)) {
|
||||||
|
if (DEBUG_ACTIVITY_STARTS) {
|
||||||
|
Slog.d(
|
||||||
|
TAG,
|
||||||
|
"Background activity start allowed: process "
|
||||||
|
+ proc.getPid()
|
||||||
|
+ " from uid "
|
||||||
|
+ callerAppUid
|
||||||
|
+ " is allowed");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// anything that has fallen through would currently be aborted
|
||||||
|
Slog.w(
|
||||||
|
TAG,
|
||||||
|
"Background activity start [callingPackage: "
|
||||||
|
+ callingPackage
|
||||||
|
+ "; callingUid: "
|
||||||
|
+ callingUid
|
||||||
|
+ "; appSwitchState: "
|
||||||
|
+ appSwitchState
|
||||||
|
+ "; isCallingUidForeground: "
|
||||||
|
+ isCallingUidForeground
|
||||||
|
+ "; callingUidHasAnyVisibleWindow: "
|
||||||
|
+ callingUidHasAnyVisibleWindow
|
||||||
|
+ "; callingUidProcState: "
|
||||||
|
+ DebugUtils.valueToString(
|
||||||
|
ActivityManager.class, "PROCESS_STATE_", callingUidProcState)
|
||||||
|
+ "; isCallingUidPersistentSystemProcess: "
|
||||||
|
+ isCallingUidPersistentSystemProcess
|
||||||
|
+ "; realCallingUid: "
|
||||||
|
+ realCallingUid
|
||||||
|
+ "; isRealCallingUidForeground: "
|
||||||
|
+ isRealCallingUidForeground
|
||||||
|
+ "; realCallingUidHasAnyVisibleWindow: "
|
||||||
|
+ realCallingUidHasAnyVisibleWindow
|
||||||
|
+ "; realCallingUidProcState: "
|
||||||
|
+ DebugUtils.valueToString(
|
||||||
|
ActivityManager.class, "PROCESS_STATE_", realCallingUidProcState)
|
||||||
|
+ "; isRealCallingUidPersistentSystemProcess: "
|
||||||
|
+ isRealCallingUidPersistentSystemProcess
|
||||||
|
+ "; originatingPendingIntent: "
|
||||||
|
+ originatingPendingIntent
|
||||||
|
+ "; allowBackgroundActivityStart: "
|
||||||
|
+ allowBackgroundActivityStart
|
||||||
|
+ "; intent: "
|
||||||
|
+ intent
|
||||||
|
+ "; callerApp: "
|
||||||
|
+ callerApp
|
||||||
|
+ "; inVisibleTask: "
|
||||||
|
+ (callerApp != null && callerApp.hasActivityInVisibleTask())
|
||||||
|
+ "]");
|
||||||
|
// log aborted activity start to TRON
|
||||||
|
if (mService.isActivityStartsLoggingEnabled()) {
|
||||||
|
mSupervisor
|
||||||
|
.getActivityMetricsLogger()
|
||||||
|
.logAbortedBgActivityStart(
|
||||||
|
intent,
|
||||||
|
callerApp,
|
||||||
|
callingUid,
|
||||||
|
callingPackage,
|
||||||
|
callingUidProcState,
|
||||||
|
callingUidHasAnyVisibleWindow,
|
||||||
|
realCallingUid,
|
||||||
|
realCallingUidProcState,
|
||||||
|
realCallingUidHasAnyVisibleWindow,
|
||||||
|
(originatingPendingIntent != null));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,3 +14,6 @@ winsonc@google.com
|
|||||||
tigerhuang@google.com
|
tigerhuang@google.com
|
||||||
lihongyu@google.com
|
lihongyu@google.com
|
||||||
mariiasand@google.com
|
mariiasand@google.com
|
||||||
|
|
||||||
|
per-file BackgroundActivityStartController.java = set noparent
|
||||||
|
per-file BackgroundActivityStartController.java = brufino@google.com, ogunwale@google.com, louischang@google.com, lus@google.com, rickywai@google.com
|
||||||
|
|||||||
@@ -147,6 +147,9 @@ public class ActivityStarterTests extends WindowTestsBase {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
mController = mock(ActivityStartController.class);
|
mController = mock(ActivityStartController.class);
|
||||||
|
BackgroundActivityStartController balController =
|
||||||
|
new BackgroundActivityStartController(mAtm, mSupervisor);
|
||||||
|
doReturn(balController).when(mController).getBackgroundActivityLaunchController();
|
||||||
mActivityMetricsLogger = mock(ActivityMetricsLogger.class);
|
mActivityMetricsLogger = mock(ActivityMetricsLogger.class);
|
||||||
clearInvocations(mActivityMetricsLogger);
|
clearInvocations(mActivityMetricsLogger);
|
||||||
}
|
}
|
||||||
@@ -208,10 +211,13 @@ public class ActivityStarterTests extends WindowTestsBase {
|
|||||||
int expectedResult) {
|
int expectedResult) {
|
||||||
final ActivityTaskManagerService service = mAtm;
|
final ActivityTaskManagerService service = mAtm;
|
||||||
final IPackageManager packageManager = mock(IPackageManager.class);
|
final IPackageManager packageManager = mock(IPackageManager.class);
|
||||||
final ActivityStartController controller = mock(ActivityStartController.class);
|
|
||||||
|
|
||||||
final ActivityStarter starter = new ActivityStarter(controller, service,
|
final ActivityStarter starter =
|
||||||
service.mTaskSupervisor, mock(ActivityStartInterceptor.class));
|
new ActivityStarter(
|
||||||
|
mController,
|
||||||
|
service,
|
||||||
|
service.mTaskSupervisor,
|
||||||
|
mock(ActivityStartInterceptor.class));
|
||||||
prepareStarter(launchFlags);
|
prepareStarter(launchFlags);
|
||||||
final IApplicationThread caller = mock(IApplicationThread.class);
|
final IApplicationThread caller = mock(IApplicationThread.class);
|
||||||
final WindowProcessListener listener = mock(WindowProcessListener.class);
|
final WindowProcessListener listener = mock(WindowProcessListener.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user