Merge "Clean up BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
c8d8b7cd9c
@@ -68,7 +68,7 @@ message RootWindowContainerProto {
|
|||||||
// Whether or not the home activity is the recents activity. This is needed for the CTS tests to
|
// Whether or not the home activity is the recents activity. This is needed for the CTS tests to
|
||||||
// know what activity types to check for when invoking splitscreen multi-window.
|
// know what activity types to check for when invoking splitscreen multi-window.
|
||||||
optional bool is_home_recents_component = 6;
|
optional bool is_home_recents_component = 6;
|
||||||
repeated IdentifierProto pending_activities = 7;
|
repeated IdentifierProto pending_activities = 7 [deprecated=true];
|
||||||
}
|
}
|
||||||
|
|
||||||
message BarControllerProto {
|
message BarControllerProto {
|
||||||
|
|||||||
@@ -37,15 +37,11 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.proto.ProtoOutputStream;
|
|
||||||
import android.view.RemoteAnimationAdapter;
|
import android.view.RemoteAnimationAdapter;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
@@ -55,10 +51,8 @@ import com.android.server.am.PendingIntentRecord;
|
|||||||
import com.android.server.uri.NeededUriGrants;
|
import com.android.server.uri.NeededUriGrants;
|
||||||
import com.android.server.wm.ActivityStarter.DefaultFactory;
|
import com.android.server.wm.ActivityStarter.DefaultFactory;
|
||||||
import com.android.server.wm.ActivityStarter.Factory;
|
import com.android.server.wm.ActivityStarter.Factory;
|
||||||
import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,35 +81,12 @@ public class ActivityStartController {
|
|||||||
/** The result of the last home activity we attempted to start. */
|
/** The result of the last home activity we attempted to start. */
|
||||||
private int mLastHomeActivityStartResult;
|
private int mLastHomeActivityStartResult;
|
||||||
|
|
||||||
/** A list of activities that are waiting to launch. */
|
|
||||||
private final ArrayList<ActivityTaskSupervisor.PendingActivityLaunch>
|
|
||||||
mPendingActivityLaunches = new ArrayList<>();
|
|
||||||
|
|
||||||
private final Factory mFactory;
|
private final Factory mFactory;
|
||||||
|
|
||||||
private final Handler mHandler;
|
|
||||||
|
|
||||||
private final PendingRemoteAnimationRegistry mPendingRemoteAnimationRegistry;
|
private final PendingRemoteAnimationRegistry mPendingRemoteAnimationRegistry;
|
||||||
|
|
||||||
boolean mCheckedForSetup = false;
|
boolean mCheckedForSetup = false;
|
||||||
|
|
||||||
private final class StartHandler extends Handler {
|
|
||||||
public StartHandler(Looper looper) {
|
|
||||||
super(looper, null, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleMessage(Message msg) {
|
|
||||||
switch(msg.what) {
|
|
||||||
case DO_PENDING_ACTIVITY_LAUNCHES_MSG:
|
|
||||||
synchronized (mService.mGlobalLock) {
|
|
||||||
doPendingActivityLaunches(true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
@@ -134,7 +105,6 @@ public class ActivityStartController {
|
|||||||
Factory factory) {
|
Factory factory) {
|
||||||
mService = service;
|
mService = service;
|
||||||
mSupervisor = supervisor;
|
mSupervisor = supervisor;
|
||||||
mHandler = new StartHandler(mService.mH.getLooper());
|
|
||||||
mFactory = factory;
|
mFactory = factory;
|
||||||
mFactory.setController(this);
|
mFactory.setController(this);
|
||||||
mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
|
mPendingRemoteAnimationRegistry = new PendingRemoteAnimationRegistry(service.mGlobalLock,
|
||||||
@@ -514,45 +484,6 @@ public class ActivityStartController {
|
|||||||
return START_SUCCESS;
|
return START_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void schedulePendingActivityLaunches(long delayMs) {
|
|
||||||
mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
|
|
||||||
Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
|
|
||||||
mHandler.sendMessageDelayed(msg, delayMs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void doPendingActivityLaunches(boolean doResume) {
|
|
||||||
while (!mPendingActivityLaunches.isEmpty()) {
|
|
||||||
final PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
|
|
||||||
final boolean resume = doResume && mPendingActivityLaunches.isEmpty();
|
|
||||||
final ActivityStarter starter = obtainStarter(null /* intent */,
|
|
||||||
"pendingActivityLaunch");
|
|
||||||
try {
|
|
||||||
starter.startResolvedActivity(pal.r, pal.sourceRecord, null, null, pal.startFlags,
|
|
||||||
resume, pal.r.getOptions(), null, pal.intentGrants);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
|
|
||||||
pal.sendErrorResult(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addPendingActivityLaunch(PendingActivityLaunch launch) {
|
|
||||||
mPendingActivityLaunches.add(launch);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean clearPendingActivityLaunches(String packageName) {
|
|
||||||
final int pendingLaunches = mPendingActivityLaunches.size();
|
|
||||||
|
|
||||||
for (int palNdx = pendingLaunches - 1; palNdx >= 0; --palNdx) {
|
|
||||||
final PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
|
|
||||||
final ActivityRecord r = pal.r;
|
|
||||||
if (r != null && r.packageName.equals(packageName)) {
|
|
||||||
mPendingActivityLaunches.remove(palNdx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mPendingActivityLaunches.size() < pendingLaunches;
|
|
||||||
}
|
|
||||||
|
|
||||||
void registerRemoteAnimationForNextActivityStart(String packageName,
|
void registerRemoteAnimationForNextActivityStart(String packageName,
|
||||||
RemoteAnimationAdapter adapter) {
|
RemoteAnimationAdapter adapter) {
|
||||||
mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter);
|
mPendingRemoteAnimationRegistry.addPendingAnimation(packageName, adapter);
|
||||||
@@ -609,10 +540,4 @@ public class ActivityStartController {
|
|||||||
pw.println("(nothing)");
|
pw.println("(nothing)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dumpDebug(ProtoOutputStream proto, long fieldId) {
|
|
||||||
for (PendingActivityLaunch activity: mPendingActivityLaunches) {
|
|
||||||
activity.r.writeIdentifierToProto(proto, fieldId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ import com.android.server.power.ShutdownCheckPoints;
|
|||||||
import com.android.server.statusbar.StatusBarManagerInternal;
|
import com.android.server.statusbar.StatusBarManagerInternal;
|
||||||
import com.android.server.uri.NeededUriGrants;
|
import com.android.server.uri.NeededUriGrants;
|
||||||
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
|
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
|
||||||
import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch;
|
|
||||||
import com.android.server.wm.LaunchParamsController.LaunchParams;
|
import com.android.server.wm.LaunchParamsController.LaunchParams;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -1171,42 +1170,19 @@ class ActivityStarter {
|
|||||||
r.appTimeTracker = sourceRecord.appTimeTracker;
|
r.appTimeTracker = sourceRecord.appTimeTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
|
// Only allow app switching to be resumed if activity is not a restricted background
|
||||||
|
// activity and target app is not home process, otherwise any background activity
|
||||||
// If we are starting an activity that is not from the same uid as the currently resumed
|
// started in background task can stop home button protection mode.
|
||||||
// one, check whether app switches are allowed.
|
// As the targeted app is not a home process and we don't need to wait for the 2nd
|
||||||
if (voiceSession == null && rootTask != null && (rootTask.getResumedActivity() == null
|
// activity to be started to resume app switching, we can just enable app switching
|
||||||
|| rootTask.getResumedActivity().info.applicationInfo.uid != realCallingUid)) {
|
// directly.
|
||||||
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
|
WindowProcessController homeProcess = mService.mHomeProcess;
|
||||||
realCallingPid, realCallingUid, "Activity start")) {
|
boolean isHomeProcess = homeProcess != null
|
||||||
if (!(restrictedBgActivity && handleBackgroundActivityAbort(r))) {
|
&& aInfo.applicationInfo.uid == homeProcess.mUid;
|
||||||
mController.addPendingActivityLaunch(new PendingActivityLaunch(r,
|
if (!restrictedBgActivity && !isHomeProcess) {
|
||||||
sourceRecord, startFlags, rootTask, callerApp, intentGrants));
|
mService.resumeAppSwitches();
|
||||||
}
|
|
||||||
ActivityOptions.abort(checkedOptions);
|
|
||||||
return ActivityManager.START_SWITCHES_CANCELED;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mService.getBalAppSwitchesProtectionEnabled()) {
|
|
||||||
// Only allow app switching to be resumed if activity is not a restricted background
|
|
||||||
// activity and target app is not home process, otherwise any background activity
|
|
||||||
// started in background task can stop home button protection mode.
|
|
||||||
// As the targeted app is not a home process and we don't need to wait for the 2nd
|
|
||||||
// activity to be started to resume app switching, we can just enable app switching
|
|
||||||
// directly.
|
|
||||||
WindowProcessController homeProcess = mService.mHomeProcess;
|
|
||||||
boolean isHomeProcess = homeProcess != null
|
|
||||||
&& aInfo.applicationInfo.uid == homeProcess.mUid;
|
|
||||||
if (!restrictedBgActivity && !isHomeProcess) {
|
|
||||||
mService.resumeAppSwitches();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mService.onStartActivitySetDidAppSwitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
mController.doPendingActivityLaunches(false);
|
|
||||||
|
|
||||||
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
|
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
|
||||||
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
|
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
|
||||||
restrictedBgActivity, intentGrants);
|
restrictedBgActivity, intentGrants);
|
||||||
@@ -1286,8 +1262,6 @@ class ActivityStarter {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// App switching will be allowed if BAL app switching flag is not enabled, or if
|
|
||||||
// its app switching rule allows it.
|
|
||||||
// This is used to block background activity launch even if the app is still
|
// This is used to block background activity launch even if the app is still
|
||||||
// visible to user after user clicking home button.
|
// visible to user after user clicking home button.
|
||||||
final boolean appSwitchAllowed = mService.getBalAppSwitchesAllowed();
|
final boolean appSwitchAllowed = mService.getBalAppSwitchesAllowed();
|
||||||
@@ -1438,7 +1412,6 @@ class ActivityStarter {
|
|||||||
Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
|
Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
|
||||||
+ "; callingUid: " + callingUid
|
+ "; callingUid: " + callingUid
|
||||||
+ "; appSwitchAllowed: " + appSwitchAllowed
|
+ "; appSwitchAllowed: " + appSwitchAllowed
|
||||||
+ "; balAppSwitchEnabled: " + mService.getBalAppSwitchesProtectionEnabled()
|
|
||||||
+ "; isCallingUidForeground: " + isCallingUidForeground
|
+ "; isCallingUidForeground: " + isCallingUidForeground
|
||||||
+ "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow
|
+ "; callingUidHasAnyVisibleWindow: " + callingUidHasAnyVisibleWindow
|
||||||
+ "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
|
+ "; callingUidProcState: " + DebugUtils.valueToString(ActivityManager.class,
|
||||||
|
|||||||
@@ -202,7 +202,6 @@ import android.os.UserManager;
|
|||||||
import android.os.WorkSource;
|
import android.os.WorkSource;
|
||||||
import android.os.storage.IStorageManager;
|
import android.os.storage.IStorageManager;
|
||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.provider.DeviceConfig;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.service.dreams.DreamActivity;
|
import android.service.dreams.DreamActivity;
|
||||||
import android.service.voice.IVoiceInteractionSession;
|
import android.service.voice.IVoiceInteractionSession;
|
||||||
@@ -324,12 +323,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
/** This activity is being relaunched due to a free-resize operation. */
|
/** This activity is being relaunched due to a free-resize operation. */
|
||||||
public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
|
public static final int RELAUNCH_REASON_FREE_RESIZE = 2;
|
||||||
|
|
||||||
/**
|
|
||||||
* Apps are blocked from starting activities in the foreground after the user presses home.
|
|
||||||
*/
|
|
||||||
public static final String BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG =
|
|
||||||
"am_block_activity_starts_after_home";
|
|
||||||
|
|
||||||
Context mContext;
|
Context mContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -386,7 +379,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
volatile WindowProcessController mHeavyWeightProcess;
|
volatile WindowProcessController mHeavyWeightProcess;
|
||||||
boolean mHasHeavyWeightFeature;
|
boolean mHasHeavyWeightFeature;
|
||||||
boolean mHasLeanbackFeature;
|
boolean mHasLeanbackFeature;
|
||||||
boolean mBlockActivityAfterHomeEnabled;
|
|
||||||
/** The process of the top most activity. */
|
/** The process of the top most activity. */
|
||||||
volatile WindowProcessController mTopApp;
|
volatile WindowProcessController mTopApp;
|
||||||
/**
|
/**
|
||||||
@@ -490,20 +482,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
/** Temporary to avoid allocations. */
|
/** Temporary to avoid allocations. */
|
||||||
final StringBuilder mStringBuilder = new StringBuilder(256);
|
final StringBuilder mStringBuilder = new StringBuilder(256);
|
||||||
|
|
||||||
// Amount of time after a call to stopAppSwitches() during which we will
|
|
||||||
// prevent further untrusted switches from happening.
|
|
||||||
private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time at which we will allow normal application switches again,
|
* Whether normal application switches are allowed; a call to {@link #stopAppSwitches()
|
||||||
* after a call to {@link #stopAppSwitches()}.
|
* disables this.
|
||||||
*/
|
*/
|
||||||
private long mAppSwitchesAllowedTime;
|
private boolean mAppSwitchesAllowed = true;
|
||||||
/**
|
|
||||||
* This is set to true after the first switch after mAppSwitchesAllowedTime
|
|
||||||
* is set; any switches after that will clear the time.
|
|
||||||
*/
|
|
||||||
private boolean mDidAppSwitch;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Last stop app switches time, apps finished before this time cannot start background activity
|
* Last stop app switches time, apps finished before this time cannot start background activity
|
||||||
@@ -749,9 +732,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
mRecentTasks.onSystemReadyLocked();
|
mRecentTasks.onSystemReadyLocked();
|
||||||
mTaskSupervisor.onSystemReady();
|
mTaskSupervisor.onSystemReady();
|
||||||
mActivityClientController.onSystemReady();
|
mActivityClientController.onSystemReady();
|
||||||
mBlockActivityAfterHomeEnabled = DeviceConfig.getBoolean(
|
|
||||||
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
|
|
||||||
BLOCK_ACTIVITY_STARTS_AFTER_HOME_FLAG, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1146,7 +1126,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
if (topFocusedRootTask != null && topFocusedRootTask.getResumedActivity() != null
|
if (topFocusedRootTask != null && topFocusedRootTask.getResumedActivity() != null
|
||||||
&& topFocusedRootTask.getResumedActivity().info.applicationInfo.uid
|
&& topFocusedRootTask.getResumedActivity().info.applicationInfo.uid
|
||||||
== Binder.getCallingUid()) {
|
== Binder.getCallingUid()) {
|
||||||
mAppSwitchesAllowedTime = 0;
|
mAppSwitchesAllowed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pir.sendInner(0, fillInIntent, resolvedType, allowlistToken, null, null,
|
return pir.sendInner(0, fillInIntent, resolvedType, allowlistToken, null, null,
|
||||||
@@ -2002,10 +1982,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
final int callingPid = Binder.getCallingPid();
|
final int callingPid = Binder.getCallingPid();
|
||||||
final int callingUid = Binder.getCallingUid();
|
final int callingUid = Binder.getCallingUid();
|
||||||
assertPackageMatchesCallingUid(callingPackage);
|
assertPackageMatchesCallingUid(callingPackage);
|
||||||
if (!checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1, "Task to front")) {
|
|
||||||
SafeActivityOptions.abort(options);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final long origId = Binder.clearCallingIdentity();
|
final long origId = Binder.clearCallingIdentity();
|
||||||
WindowProcessController callerApp = null;
|
WindowProcessController callerApp = null;
|
||||||
if (appThread != null) {
|
if (appThread != null) {
|
||||||
@@ -2085,77 +2062,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
throw new SecurityException(msg);
|
throw new SecurityException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if app switch protection will be handled by background activity launch logic.
|
|
||||||
*/
|
|
||||||
boolean getBalAppSwitchesProtectionEnabled() {
|
|
||||||
return mBlockActivityAfterHomeEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if app switching is allowed.
|
* Return true if app switching is allowed.
|
||||||
*/
|
*/
|
||||||
boolean getBalAppSwitchesAllowed() {
|
boolean getBalAppSwitchesAllowed() {
|
||||||
if (getBalAppSwitchesProtectionEnabled()) {
|
return mAppSwitchesAllowed;
|
||||||
// Apps no longer able to start BAL again until app switching is resumed.
|
|
||||||
return mAppSwitchesAllowedTime == 0;
|
|
||||||
} else {
|
|
||||||
// Legacy behavior, BAL logic won't block app switching.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
|
|
||||||
int callingPid, int callingUid, String name) {
|
|
||||||
|
|
||||||
// Background activity launch logic replaces app switching protection, so allow
|
|
||||||
// apps to start activity here now.
|
|
||||||
if (getBalAppSwitchesProtectionEnabled()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getRecentTasks().isCallerRecents(sourceUid)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int perm = checkComponentPermission(STOP_APP_SWITCHES, sourcePid, sourceUid, -1, true);
|
|
||||||
if (perm == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (checkAllowAppSwitchUid(sourceUid)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the actual IPC caller is different from the logical source, then
|
|
||||||
// also see if they are allowed to control app switches.
|
|
||||||
if (callingUid != -1 && callingUid != sourceUid) {
|
|
||||||
perm = checkComponentPermission(STOP_APP_SWITCHES, callingPid, callingUid, -1, true);
|
|
||||||
if (perm == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (checkAllowAppSwitchUid(callingUid)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Slog.w(TAG, name + " request from " + sourceUid + " stopped");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean checkAllowAppSwitchUid(int uid) {
|
|
||||||
ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(UserHandle.getUserId(uid));
|
|
||||||
if (types != null) {
|
|
||||||
for (int i = types.size() - 1; i >= 0; i--) {
|
|
||||||
if (types.valueAt(i).intValue() == uid) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -3663,13 +3574,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
public void stopAppSwitches() {
|
public void stopAppSwitches() {
|
||||||
enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
|
enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches");
|
||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME;
|
mAppSwitchesAllowed = false;
|
||||||
mLastStopAppSwitchesTime = SystemClock.uptimeMillis();
|
mLastStopAppSwitchesTime = SystemClock.uptimeMillis();
|
||||||
mDidAppSwitch = false;
|
|
||||||
// If BAL app switching enabled, app switches are blocked not delayed.
|
|
||||||
if (!getBalAppSwitchesProtectionEnabled()) {
|
|
||||||
getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3677,10 +3583,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
public void resumeAppSwitches() {
|
public void resumeAppSwitches() {
|
||||||
enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
|
enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches");
|
||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
// Note that we don't execute any pending app switches... we will
|
mAppSwitchesAllowed = true;
|
||||||
// let those wait until either the timeout, or the next start
|
|
||||||
// activity request.
|
|
||||||
mAppSwitchesAllowedTime = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3688,19 +3591,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
return mLastStopAppSwitchesTime;
|
return mLastStopAppSwitchesTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onStartActivitySetDidAppSwitch() {
|
|
||||||
if (mDidAppSwitch) {
|
|
||||||
// This is the second allowed switch since we stopped switches, so now just generally
|
|
||||||
// allow switches. Use case:
|
|
||||||
// - user presses home (switches disabled, switch to home, mDidAppSwitch now true);
|
|
||||||
// - user taps a home icon (coming from home so allowed, we hit here and now allow
|
|
||||||
// anyone to switch again).
|
|
||||||
mAppSwitchesAllowedTime = 0;
|
|
||||||
} else {
|
|
||||||
mDidAppSwitch = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return whether the system should disable UI modes incompatible with VR mode. */
|
/** @return whether the system should disable UI modes incompatible with VR mode. */
|
||||||
boolean shouldDisableNonVrUiLocked() {
|
boolean shouldDisableNonVrUiLocked() {
|
||||||
return mVrController.shouldDisableNonVrUiLocked();
|
return mVrController.shouldDisableNonVrUiLocked();
|
||||||
@@ -5822,15 +5712,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
|||||||
int userId) {
|
int userId) {
|
||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
|
|
||||||
boolean didSomething =
|
return mRootWindowContainer.finishDisabledPackageActivities(packageName,
|
||||||
getActivityStartController().clearPendingActivityLaunches(packageName);
|
|
||||||
didSomething |= mRootWindowContainer.finishDisabledPackageActivities(packageName,
|
|
||||||
null /* filterByClasses */, doit, evenPersistent, userId,
|
null /* filterByClasses */, doit, evenPersistent, userId,
|
||||||
// Only remove the activities without process because the activities with
|
// Only remove the activities without process because the activities with
|
||||||
// attached process will be removed when handling process died with
|
// attached process will be removed when handling process died with
|
||||||
// WindowProcessController#isRemoved == true.
|
// WindowProcessController#isRemoved == true.
|
||||||
true /* onlyRemoveNoProcess */);
|
true /* onlyRemoveNoProcess */);
|
||||||
return didSomething;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -142,7 +142,6 @@ import com.android.internal.util.function.pooled.PooledConsumer;
|
|||||||
import com.android.internal.util.function.pooled.PooledLambda;
|
import com.android.internal.util.function.pooled.PooledLambda;
|
||||||
import com.android.server.am.ActivityManagerService;
|
import com.android.server.am.ActivityManagerService;
|
||||||
import com.android.server.am.UserState;
|
import com.android.server.am.UserState;
|
||||||
import com.android.server.uri.NeededUriGrants;
|
|
||||||
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
|
import com.android.server.wm.ActivityMetricsLogger.LaunchingState;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
@@ -376,41 +375,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
|
|||||||
|
|
||||||
private boolean mInitialized;
|
private boolean mInitialized;
|
||||||
|
|
||||||
/**
|
|
||||||
* Description of a request to start a new activity, which has been held
|
|
||||||
* due to app switches being disabled.
|
|
||||||
*/
|
|
||||||
static class PendingActivityLaunch {
|
|
||||||
final ActivityRecord r;
|
|
||||||
final ActivityRecord sourceRecord;
|
|
||||||
final int startFlags;
|
|
||||||
final Task rootTask;
|
|
||||||
final WindowProcessController callerApp;
|
|
||||||
final NeededUriGrants intentGrants;
|
|
||||||
|
|
||||||
PendingActivityLaunch(ActivityRecord r, ActivityRecord sourceRecord,
|
|
||||||
int startFlags, Task rootTask, WindowProcessController callerApp,
|
|
||||||
NeededUriGrants intentGrants) {
|
|
||||||
this.r = r;
|
|
||||||
this.sourceRecord = sourceRecord;
|
|
||||||
this.startFlags = startFlags;
|
|
||||||
this.rootTask = rootTask;
|
|
||||||
this.callerApp = callerApp;
|
|
||||||
this.intentGrants = intentGrants;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendErrorResult(String message) {
|
|
||||||
try {
|
|
||||||
if (callerApp != null && callerApp.hasThread()) {
|
|
||||||
callerApp.getThread().scheduleCrash(message);
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Slog.e(TAG, "Exception scheduling crash of failed "
|
|
||||||
+ "activity launcher sourceRecord=" + sourceRecord, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper) {
|
public ActivityTaskSupervisor(ActivityTaskManagerService service, Looper looper) {
|
||||||
mService = service;
|
mService = service;
|
||||||
mLooper = looper;
|
mLooper = looper;
|
||||||
|
|||||||
@@ -101,10 +101,6 @@ class AppTaskImpl extends IAppTask.Stub {
|
|||||||
final long origId = Binder.clearCallingIdentity();
|
final long origId = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
synchronized (mService.mGlobalLock) {
|
synchronized (mService.mGlobalLock) {
|
||||||
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1,
|
|
||||||
"Move to front")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
WindowProcessController callerApp = null;
|
WindowProcessController callerApp = null;
|
||||||
if (appThread != null) {
|
if (appThread != null) {
|
||||||
callerApp = mService.getProcessController(appThread);
|
callerApp = mService.getProcessController(appThread);
|
||||||
|
|||||||
@@ -68,7 +68,6 @@ import static com.android.server.wm.ActivityTaskSupervisor.printThisActivity;
|
|||||||
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
|
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
|
||||||
import static com.android.server.wm.RootWindowContainerProto.IS_HOME_RECENTS_COMPONENT;
|
import static com.android.server.wm.RootWindowContainerProto.IS_HOME_RECENTS_COMPONENT;
|
||||||
import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER;
|
import static com.android.server.wm.RootWindowContainerProto.KEYGUARD_CONTROLLER;
|
||||||
import static com.android.server.wm.RootWindowContainerProto.PENDING_ACTIVITIES;
|
|
||||||
import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
|
import static com.android.server.wm.RootWindowContainerProto.WINDOW_CONTAINER;
|
||||||
import static com.android.server.wm.Task.ActivityState.FINISHING;
|
import static com.android.server.wm.Task.ActivityState.FINISHING;
|
||||||
import static com.android.server.wm.Task.ActivityState.PAUSED;
|
import static com.android.server.wm.Task.ActivityState.PAUSED;
|
||||||
@@ -1289,7 +1288,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
|
|||||||
mTaskSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
|
mTaskSupervisor.getKeyguardController().dumpDebug(proto, KEYGUARD_CONTROLLER);
|
||||||
proto.write(IS_HOME_RECENTS_COMPONENT,
|
proto.write(IS_HOME_RECENTS_COMPONENT,
|
||||||
mTaskSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
|
mTaskSupervisor.mRecentTasks.isRecentsComponentHomeActivity(mCurrentUser));
|
||||||
mService.getActivityStartController().dumpDebug(proto, PENDING_ACTIVITIES);
|
|
||||||
|
|
||||||
proto.end(token);
|
proto.end(token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
|
||||||
|
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
|
||||||
@@ -26,22 +23,17 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy;
|
|||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
|
||||||
|
|
||||||
import android.app.IApplicationThread;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.UserHandle;
|
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.server.wm.ActivityStarter.Factory;
|
import com.android.server.wm.ActivityStarter.Factory;
|
||||||
import com.android.server.wm.ActivityTaskSupervisor.PendingActivityLaunch;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests for the {@link ActivityStartController} class.
|
* Tests for the {@link ActivityStartController} class.
|
||||||
*
|
*
|
||||||
@@ -65,36 +57,6 @@ public class ActivityStartControllerTests extends WindowTestsBase {
|
|||||||
doReturn(mStarter).when(mFactory).obtain();
|
doReturn(mStarter).when(mFactory).obtain();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that pending launches are processed.
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testPendingActivityLaunches() {
|
|
||||||
final Random random = new Random();
|
|
||||||
|
|
||||||
final ActivityRecord activity = new ActivityBuilder(mAtm).build();
|
|
||||||
final ActivityRecord source = new ActivityBuilder(mAtm)
|
|
||||||
.setCreateTask(true)
|
|
||||||
.build();
|
|
||||||
final int startFlags = random.nextInt();
|
|
||||||
final Task rootTask = mAtm.mRootWindowContainer.getDefaultTaskDisplayArea().createRootTask(
|
|
||||||
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
|
|
||||||
final WindowProcessController wpc = new WindowProcessController(mAtm,
|
|
||||||
mAtm.mContext.getApplicationInfo(), "name", 12345,
|
|
||||||
UserHandle.getUserId(12345), mock(Object.class),
|
|
||||||
mock(WindowProcessListener.class));
|
|
||||||
wpc.setThread(mock(IApplicationThread.class));
|
|
||||||
|
|
||||||
mController.addPendingActivityLaunch(
|
|
||||||
new PendingActivityLaunch(activity, source, startFlags, rootTask, wpc, null));
|
|
||||||
final boolean resume = random.nextBoolean();
|
|
||||||
mController.doPendingActivityLaunches(resume);
|
|
||||||
|
|
||||||
verify(mStarter, times(1)).startResolvedActivity(eq(activity), eq(source), eq(null),
|
|
||||||
eq(null), eq(startFlags), eq(resume), eq(null), eq(null), eq(null));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures instances are recycled after execution.
|
* Ensures instances are recycled after execution.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import static android.app.ActivityManager.START_NOT_VOICE_COMPATIBLE;
|
|||||||
import static android.app.ActivityManager.START_PERMISSION_DENIED;
|
import static android.app.ActivityManager.START_PERMISSION_DENIED;
|
||||||
import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
|
import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
|
||||||
import static android.app.ActivityManager.START_SUCCESS;
|
import static android.app.ActivityManager.START_SUCCESS;
|
||||||
import static android.app.ActivityManager.START_SWITCHES_CANCELED;
|
|
||||||
import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
import static android.app.ActivityManager.START_TASK_TO_FRONT;
|
||||||
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
|
||||||
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||||
@@ -119,7 +118,6 @@ public class ActivityStarterTests extends WindowTestsBase {
|
|||||||
private static final int PRECONDITION_DIFFERENT_UID = 1 << 7;
|
private static final int PRECONDITION_DIFFERENT_UID = 1 << 7;
|
||||||
private static final int PRECONDITION_ACTIVITY_SUPPORTS_INTENT_EXCEPTION = 1 << 8;
|
private static final int PRECONDITION_ACTIVITY_SUPPORTS_INTENT_EXCEPTION = 1 << 8;
|
||||||
private static final int PRECONDITION_CANNOT_START_ANY_ACTIVITY = 1 << 9;
|
private static final int PRECONDITION_CANNOT_START_ANY_ACTIVITY = 1 << 9;
|
||||||
private static final int PRECONDITION_DISALLOW_APP_SWITCHING = 1 << 10;
|
|
||||||
|
|
||||||
private static final int FAKE_CALLING_UID = 666;
|
private static final int FAKE_CALLING_UID = 666;
|
||||||
private static final int FAKE_REAL_CALLING_UID = 667;
|
private static final int FAKE_REAL_CALLING_UID = 667;
|
||||||
@@ -153,8 +151,6 @@ public class ActivityStarterTests extends WindowTestsBase {
|
|||||||
| PRECONDITION_ACTIVITY_SUPPORTS_INTENT_EXCEPTION,
|
| PRECONDITION_ACTIVITY_SUPPORTS_INTENT_EXCEPTION,
|
||||||
START_NOT_VOICE_COMPATIBLE);
|
START_NOT_VOICE_COMPATIBLE);
|
||||||
verifyStartActivityPreconditions(PRECONDITION_CANNOT_START_ANY_ACTIVITY, START_ABORTED);
|
verifyStartActivityPreconditions(PRECONDITION_CANNOT_START_ANY_ACTIVITY, START_ABORTED);
|
||||||
verifyStartActivityPreconditions(PRECONDITION_DISALLOW_APP_SWITCHING,
|
|
||||||
START_SWITCHES_CANCELED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean containsConditions(int preconditions, int mask) {
|
private static boolean containsConditions(int preconditions, int mask) {
|
||||||
@@ -244,11 +240,6 @@ public class ActivityStarterTests extends WindowTestsBase {
|
|||||||
intent.setComponent(source.mActivityComponent);
|
intent.setComponent(source.mActivityComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (containsConditions(preconditions, PRECONDITION_DISALLOW_APP_SWITCHING)) {
|
|
||||||
doReturn(false).when(service).checkAppSwitchAllowedLocked(
|
|
||||||
anyInt(), anyInt(), anyInt(), anyInt(), any());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (containsConditions(preconditions, PRECONDITION_CANNOT_START_ANY_ACTIVITY)) {
|
if (containsConditions(preconditions, PRECONDITION_CANNOT_START_ANY_ACTIVITY)) {
|
||||||
doReturn(false).when(service.mTaskSupervisor).checkStartAnyActivityPermission(
|
doReturn(false).when(service.mTaskSupervisor).checkStartAnyActivityPermission(
|
||||||
any(), any(), any(), anyInt(), anyInt(), anyInt(), any(), any(),
|
any(), any(), any(), anyInt(), anyInt(), anyInt(), any(), any(),
|
||||||
|
|||||||
Reference in New Issue
Block a user