diff options
| author | 2018-06-21 23:36:52 +0000 | |
|---|---|---|
| committer | 2018-06-21 23:36:52 +0000 | |
| commit | dff7a680ab4276921b58b160debeebc49751a109 (patch) | |
| tree | 446bd5065a97f629643f3bdf16e1cf740325a6b0 | |
| parent | bb29a80c6b8970d9c9ffcde78e011126f539450a (diff) | |
| parent | a6191b4fa1255f334afbfad15faf00423934a463 (diff) | |
Merge "Moved more stuff from ActivityManagerService to ActivityTaskManagerService (9/n)"
34 files changed, 1255 insertions, 1134 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 4e6cc7ebdf25..2fdb715087de 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.content.ComponentName; import android.content.IIntentSender; import android.content.Intent; +import android.content.pm.ApplicationInfo; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; @@ -41,6 +42,11 @@ import java.util.List; public abstract class ActivityManagerInternal { + // Access modes for handleIncomingUser. + public static final int ALLOW_NON_FULL = 0; + public static final int ALLOW_NON_FULL_IN_PROFILE = 1; + public static final int ALLOW_FULL_ONLY = 2; + /** * Grant Uri permissions from one app to another. This method only extends * permission grants if {@code callingUid} has permission to them. @@ -63,15 +69,6 @@ public abstract class ActivityManagerInternal { String processName, String abiOverride, int uid, Runnable crashHandler); /** - * Called when a user has been deleted. This can happen during normal device usage - * or just at startup, when partially removed users are purged. Any state persisted by the - * ActivityManager should be purged now. - * - * @param userId The user being cleaned up. - */ - public abstract void onUserRemoved(int userId); - - /** * Kill foreground apps from the specified user. */ public abstract void killForegroundAppsForUser(int userHandle); @@ -95,15 +92,6 @@ public abstract class ActivityManagerInternal { boolean adding); /** - * Updates and persists the {@link Configuration} for a given user. - * - * @param values the configuration to update - * @param userId the user to update the configuration for - */ - public abstract void updatePersistentConfigurationForUser(@NonNull Configuration values, - int userId); - - /** * Get the procstate for the UID. The return value will be between * {@link ActivityManager#MIN_PROCESS_STATE} and {@link ActivityManager#MAX_PROCESS_STATE}. * Note if the UID doesn't exist, it'll return {@link ActivityManager#PROCESS_STATE_NONEXISTENT} @@ -155,17 +143,6 @@ public abstract class ActivityManagerInternal { public abstract void clearSavedANRState(); /** - * Set a uid that is allowed to bypass stopped app switches, launching an app - * whenever it wants. - * - * @param type Type of the caller -- unique string the caller supplies to identify itself - * and disambiguate with other calles. - * @param uid The uid of the app to be allowed, or -1 to clear the uid for this type. - * @param userId The user it is allowed for. - */ - public abstract void setAllowAppSwitches(@NonNull String type, int uid, int userId); - - /** * @return true if runtime was restarted, false if it's normal boot */ public abstract boolean isRuntimeRestarted(); @@ -199,4 +176,32 @@ public abstract class ActivityManagerInternal { * Returns a list that contains the memory stats for currently running processes. */ public abstract List<ProcessMemoryState> getMemoryStateForProcesses(); + + /** + * Checks to see if the calling pid is allowed to handle the user. Returns adjusted user id as + * needed. + */ + public abstract int handleIncomingUser(int callingPid, int callingUid, int userId, + boolean allowAll, int allowMode, String name, String callerPackage); + + /** Checks if the calling binder pid as the permission. */ + public abstract void enforceCallingPermission(String permission, String func); + + /** Returns the current user id. */ + public abstract int getCurrentUserId(); + + /** Returns true if the user is running. */ + public abstract boolean isUserRunning(int userId, int flags); + + /** Trims memory usage in the system by removing/stopping unused application processes. */ + public abstract void trimApplications(); + + /** Returns the screen compatibility mode for the given application. */ + public abstract int getPackageScreenCompatMode(ApplicationInfo ai); + + /** Sets the screen compatibility mode for the given application. */ + public abstract void setPackageScreenCompatMode(ApplicationInfo ai, int mode); + + /** Closes all system dialogs. */ + public abstract void closeSystemDialogs(String reason); } diff --git a/core/java/android/app/ActivityTaskManagerInternal.java b/core/java/android/app/ActivityTaskManagerInternal.java index 170cb52e41f4..fa78db5c3d6d 100644 --- a/core/java/android/app/ActivityTaskManagerInternal.java +++ b/core/java/android/app/ActivityTaskManagerInternal.java @@ -243,4 +243,24 @@ public abstract class ActivityTaskManagerInternal { */ public abstract void notifyActiveVoiceInteractionServiceChanged(ComponentName component); + /** + * Set a uid that is allowed to bypass stopped app switches, launching an app + * whenever it wants. + * + * @param type Type of the caller -- unique string the caller supplies to identify itself + * and disambiguate with other calles. + * @param uid The uid of the app to be allowed, or -1 to clear the uid for this type. + * @param userId The user it is allowed for. + */ + public abstract void setAllowAppSwitches(@NonNull String type, int uid, int userId); + + /** + * Called when a user has been deleted. This can happen during normal device usage + * or just at startup, when partially removed users are purged. Any state persisted by the + * ActivityManager should be purged now. + * + * @param userId The user being cleaned up. + */ + public abstract void onUserStopped(int userId); + public abstract boolean isGetTasksAllowed(String caller, int callingPid, int callingUid); } diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl index a5082899f64e..1eb187e445b4 100644 --- a/core/java/android/app/IActivityTaskManager.aidl +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -418,4 +418,7 @@ interface IActivityTaskManager { void setVrThread(int tid); void setPersistentVrThread(int tid); + void stopAppSwitches(); + void resumeAppSwitches(); + void setActivityController(in IActivityController watcher, boolean imAMonkey); } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index ca715b51a328..652bc6a7b0fe 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; -import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; @@ -32,6 +31,7 @@ import java.util.List; import java.util.Set; import java.util.function.Predicate; +import android.app.ActivityManagerInternal; import android.app.ActivityThread; import android.app.AppOpsManager; import android.app.NotificationManager; @@ -59,7 +59,6 @@ import com.android.internal.messages.nano.SystemMessageProto; import com.android.internal.notification.SystemNotificationChannels; import com.android.internal.os.BatteryStatsImpl; import com.android.internal.os.TransferPipe; -import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastPrintWriter; import com.android.server.AppStateTracker; @@ -1869,7 +1868,7 @@ public final class ActiveServices { + " type=" + resolvedType + " callingUid=" + callingUid); userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false, - ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null); + ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE, "service", null); ServiceMap smap = getServiceMapLocked(userId); final ComponentName comp = service.getComponent(); diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java index ee93fc8db06e..5608f97aa3e5 100644 --- a/services/core/java/com/android/server/am/ActivityDisplay.java +++ b/services/core/java/com/android/server/am/ActivityDisplay.java @@ -300,7 +300,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } } - final ActivityManagerService service = mSupervisor.mService.mAm; + final ActivityTaskManagerService service = mSupervisor.mService; if (!isWindowingModeSupported(windowingMode, service.mSupportsMultiWindow, service.mSupportsSplitScreenMultiWindow, service.mSupportsFreeformWindowManagement, service.mSupportsPictureInPicture, activityType)) { @@ -536,7 +536,7 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack> } // Make sure the windowing mode we are trying to use makes sense for what is supported. - final ActivityManagerService service = mSupervisor.mService.mAm; + final ActivityTaskManagerService service = mSupervisor.mService; boolean supportsMultiWindow = service.mSupportsMultiWindow; boolean supportsSplitScreen = service.mSupportsSplitScreenMultiWindow; boolean supportsFreeform = service.mSupportsFreeformWindowManagement; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 37253ecbf608..1c61f300e2eb 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -22,11 +22,10 @@ import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.REMOVE_TASKS; -import static android.Manifest.permission.STOP_APP_SWITCHES; +import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; +import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; import static android.app.ActivityThread.PROC_START_SEQ_IDENT; import static android.app.AppOpsManager.OP_NONE; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME; @@ -120,7 +119,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_B import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; -import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; @@ -134,9 +132,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBS import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE; -import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; -import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS; @@ -169,10 +165,6 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NA import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import static com.android.server.am.MemoryStatUtil.hasMemcg; -import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN; -import static android.view.WindowManager.TRANSIT_NONE; -import static android.view.WindowManager.TRANSIT_TASK_OPEN; -import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -187,6 +179,7 @@ import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackInfo; import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityManagerInternal; +import android.app.ActivityTaskManagerInternal; import android.app.ActivityTaskManagerInternal.ScreenObserver; import android.app.ActivityTaskManagerInternal.SleepToken; import android.app.ActivityManagerProto; @@ -307,7 +300,6 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.TransactionTooLargeException; -import android.os.UpdateLock; import android.os.UserHandle; import android.os.UserManager; import android.os.WorkSource; @@ -471,8 +463,6 @@ public class ActivityManagerService extends IActivityManager.Stub private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST; private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP; private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; - private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; - private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE; private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; private static final String TAG_LRU = TAG + POSTFIX_LRU; private static final String TAG_MU = TAG + POSTFIX_MU; @@ -483,13 +473,10 @@ public class ActivityManagerService extends IActivityManager.Stub private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES; private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER; private static final String TAG_PSS = TAG + POSTFIX_PSS; - private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS; private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE; - private static final String TAG_STACK = TAG + POSTFIX_STACK; private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH; private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS; private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION; - private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; // Mock "pretend we're idle now" broadcast action to the job scheduler; declared // here so that while the job scheduler can depend on AMS, the other way around @@ -514,10 +501,6 @@ public class ActivityManagerService extends IActivityManager.Stub // Maximum number of receivers an app can register. private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000; - // Amount of time after a call to stopAppSwitches() during which we will - // prevent further untrusted switches from happening. - static final long APP_SWITCH_DELAY_TIME = 5*1000; - // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real. static final int PROC_START_TIMEOUT = 10*1000; @@ -561,11 +544,6 @@ public class ActivityManagerService extends IActivityManager.Stub /** If a UID observer takes more than this long, send a WTF. */ private static final int SLOW_UID_OBSERVER_THRESHOLD_MS = 20; - // Access modes for handleIncomingUser. - static final int ALLOW_NON_FULL = 0; - static final int ALLOW_NON_FULL_IN_PROFILE = 1; - static final int ALLOW_FULL_ONLY = 2; - // Necessary ApplicationInfo flags to mark an app as persistent private static final int PERSISTENT_MASK = ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT; @@ -577,9 +555,6 @@ public class ActivityManagerService extends IActivityManager.Stub // Used to indicate that an app transition should be animated. static final boolean ANIMATE = true; - // Determines whether to take full screen screenshots - static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true; - /** * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}. */ @@ -628,9 +603,6 @@ public class ActivityManagerService extends IActivityManager.Stub // devices. private boolean mShowDialogs = true; - // VR Vr2d Display Id. - int mVr2dDisplayId = INVALID_DISPLAY; - // Whether we should use SCHED_FIFO for UI and RenderThreads. private boolean mUseFifoUiScheduling = false; @@ -679,12 +651,6 @@ public class ActivityManagerService extends IActivityManager.Stub final UserController mUserController; - /** - * Packages that are being allowed to perform unrestricted app switches. Mapping is - * User -> Type -> uid. - */ - final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>(); - final AppErrors mAppErrors; final AppWarnings mAppWarnings; @@ -1329,18 +1295,6 @@ public class ActivityManagerService extends IActivityManager.Stub final Context mUiContext; /** - * The time at which we will allow normal application switches again, - * after a call to {@link #stopAppSwitches()}. - */ - long mAppSwitchesAllowedTime; - - /** - * This is set to true after the first switch after mAppSwitchesAllowedTime - * is set; any switches after that will clear the time. - */ - boolean mDidAppSwitch; - - /** * Last time (in uptime) at which we checked for power usage. */ long mLastPowerCheckUptime; @@ -1491,29 +1445,7 @@ public class ActivityManagerService extends IActivityManager.Stub String mOrigDebugApp = null; boolean mOrigWaitForDebugger = false; boolean mAlwaysFinishActivities = false; - boolean mForceResizableActivities; - /** - * Flag that indicates if multi-window is enabled. - * - * For any particular form of multi-window to be enabled, generic multi-window must be enabled - * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or - * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set. - * At least one of the forms of multi-window must be enabled in order for this flag to be - * initialized to 'true'. - * - * @see #mSupportsSplitScreenMultiWindow - * @see #mSupportsFreeformWindowManagement - * @see #mSupportsPictureInPicture - * @see #mSupportsMultiDisplay - */ - boolean mSupportsMultiWindow; - boolean mSupportsSplitScreenMultiWindow; - boolean mSupportsFreeformWindowManagement; - boolean mSupportsPictureInPicture; - boolean mSupportsMultiDisplay; - boolean mSupportsLeanbackOnly; - IActivityController mController = null; - boolean mControllerIsAMonkey = false; + String mProfileApp = null; ProcessRecord mProfileProc = null; ProfilerInfo mProfilerInfo = null; @@ -1637,8 +1569,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - final List<ScreenObserver> mScreenObservers = new ArrayList<>(); - final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>(); ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; @@ -1680,12 +1610,6 @@ public class ActivityManagerService extends IActivityManager.Stub long mLastWriteTime = 0; /** - * Used to retain an update lock when the foreground activity is in - * immersive mode. - */ - final UpdateLock mUpdateLock = new UpdateLock("immersive"); - - /** * Set to true after the system has finished booting. */ boolean mBooted = false; @@ -1697,6 +1621,7 @@ public class ActivityManagerService extends IActivityManager.Stub WindowManagerService mWindowManager; ActivityTaskManagerService mActivityTaskManager; + ActivityTaskManagerInternal mAtmInternal; final ActivityThread mSystemThread; private final class AppDeathRecipient implements IBinder.DeathRecipient { @@ -1748,7 +1673,6 @@ public class ActivityManagerService extends IActivityManager.Stub static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31; static final int DISPATCH_PROCESS_DIED_UI_MSG = 32; static final int REPORT_MEM_USAGE_MSG = 33; - static final int IMMERSIVE_MODE_LOCK_MSG = 37; static final int PERSIST_URI_GRANTS_MSG = 38; static final int UPDATE_TIME_PREFERENCE_MSG = 41; static final int FINISH_BOOTING_MSG = 45; @@ -1763,8 +1687,6 @@ public class ActivityManagerService extends IActivityManager.Stub static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57; static final int IDLE_UIDS_MSG = 58; static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63; - static final int DISPATCH_SCREEN_AWAKE_MSG = 64; - static final int DISPATCH_SCREEN_KEYGUARD_MSG = 65; static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66; static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67; static final int PUSH_TEMP_WHITELIST_UI_MSG = 68; @@ -1790,11 +1712,6 @@ public class ActivityManagerService extends IActivityManager.Stub */ private boolean mUserIsMonkey; - /** The dimensions of the thumbnails in the Recents UI. */ - int mThumbnailWidth; - int mThumbnailHeight; - float mFullscreenThumbnailScale; - final ServiceThread mHandlerThread; final MainHandler mHandler; final Handler mUiHandler; @@ -2201,20 +2118,6 @@ public class ActivityManagerService extends IActivityManager.Stub thread.start(); break; } - case IMMERSIVE_MODE_LOCK_MSG: { - final boolean nextState = (msg.arg1 != 0); - if (mUpdateLock.isHeld() != nextState) { - if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, - "Applying new update lock state '" + nextState - + "' for " + (ActivityRecord)msg.obj); - if (nextState) { - mUpdateLock.acquire(); - } else { - mUpdateLock.release(); - } - } - break; - } case PERSIST_URI_GRANTS_MSG: { writeGrantedUriPermissions(); break; @@ -2382,18 +2285,6 @@ public class ActivityManagerService extends IActivityManager.Stub case IDLE_UIDS_MSG: { idleUids(); } break; - case DISPATCH_SCREEN_AWAKE_MSG: { - final boolean isAwake = msg.arg1 != 0; - for (int i = mScreenObservers.size() - 1; i >= 0; i--) { - mScreenObservers.get(i).onAwakeStateChanged(isAwake); - } - } break; - case DISPATCH_SCREEN_KEYGUARD_MSG: { - final boolean isShowing = msg.arg1 != 0; - for (int i = mScreenObservers.size() - 1; i >= 0; i--) { - mScreenObservers.get(i).onKeyguardStateChanged(isShowing); - } - } break; case HANDLE_TRUST_STORAGE_UPDATE_MSG: { synchronized (ActivityManagerService.this) { for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { @@ -2588,6 +2479,7 @@ public class ActivityManagerService extends IActivityManager.Stub synchronized (this) { mActivityTaskManager = atm; mActivityTaskManager.setActivityManagerService(this); + mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); mStackSupervisor = mActivityTaskManager.mStackSupervisor; } } @@ -3011,11 +2903,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - void onUserStoppedLocked(int userId) { - mActivityTaskManager.getRecentTasks().unloadUserDataFromMemoryLocked(userId); - mAllowAppSwitchUids.remove(userId); - } - public void initPowerManagement() { mStackSupervisor.initPowerManagement(); mBatteryStatsService.initPowerManagement(); @@ -3338,7 +3225,7 @@ public class ActivityManagerService extends IActivityManager.Stub mWindowManager.setFocusedApp(r.appToken, true); - applyUpdateLockStateLocked(r); + mActivityTaskManager.applyUpdateLockStateLocked(r); mActivityTaskManager.applyUpdateVrModeLocked(r); EventLogTags.writeAmSetResumedActivity( @@ -3382,16 +3269,6 @@ public class ActivityManagerService extends IActivityManager.Stub mActivityTaskManager.unregisterTaskStackListener(listener); } - final void applyUpdateLockStateLocked(ActivityRecord r) { - // Modifications to the UpdateLock state are done on our handler, outside - // the activity manager's locks. The new state is determined based on the - // state *now* of the relevant activity record. The object is passed to - // the handler solely for logging detail, not to be consulted/modified. - final boolean nextState = r != null && r.immersive; - mHandler.sendMessage( - mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); - } - final void showAskCompatModeDialogLocked(ActivityRecord r) { Message msg = Message.obtain(); msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG; @@ -4416,7 +4293,7 @@ public class ActivityManagerService extends IActivityManager.Stub return mCompatModePackages.compatibilityInfoForPackageLocked(ai); } - void enforceNotIsolatedCaller(String caller) { + private void enforceNotIsolatedCaller(String caller) { if (UserHandle.isIsolated(Binder.getCallingUid())) { throw new SecurityException("Isolated process not allowed to call " + caller); } @@ -5651,7 +5528,7 @@ public class ActivityManagerService extends IActivityManager.Stub * @param maxProcState the process state at or below which to preserve * processes, or {@code -1} to ignore the process state */ - private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { + void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) { if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) != PackageManager.PERMISSION_GRANTED) { final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid=" @@ -7612,7 +7489,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } - int checkComponentPermission(String permission, int pid, int uid, + static int checkComponentPermission(String permission, int pid, int uid, int owningUid, boolean exported) { if (pid == MY_PID) { return PackageManager.PERMISSION_GRANTED; @@ -7700,15 +7577,6 @@ public class ActivityManagerService extends IActivityManager.Stub } /** - * This can be called with or without the global lock held. - */ - void enforceCallerIsRecentsOrHasPermission(String permission, String func) { - if (!mActivityTaskManager.getRecentTasks().isCallerRecents(Binder.getCallingUid())) { - enforceCallingPermission(permission, func); - } - } - - /** * Determine if UID is holding permissions required to access {@link Uri} in * the given {@link ProviderInfo}. Final permission checking is always done * in {@link ContentProvider}. @@ -9165,38 +9033,6 @@ public class ActivityManagerService extends IActivityManager.Stub mActivityTaskManager.cancelTaskWindowTransition(taskId); } - boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { - if (mActivityTaskManager.getRecentTasks().isCallerRecents(callingUid)) { - // Always allow the recents component to get tasks - return true; - } - - boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS, - callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; - if (!allowed) { - if (checkPermission(android.Manifest.permission.GET_TASKS, - callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { - // Temporary compatibility: some existing apps on the system image may - // still be requesting the old permission and not switched to the new - // one; if so, we'll still allow them full access. This means we need - // to see if they are holding the old permission and are a system app. - try { - if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { - allowed = true; - if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid - + " is using old GET_TASKS but privileged; allowing"); - } - } catch (RemoteException e) { - } - } - } - if (!allowed) { - if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid - + " does not hold REAL_GET_TASKS; limiting output"); - } - return allowed; - } - @Override public void setTaskResizeable(int taskId, int resizeableMode) { mActivityTaskManager.setTaskResizeable(taskId, resizeableMode); @@ -10813,8 +10649,7 @@ public class ActivityManagerService extends IActivityManager.Stub // Also update state in a special way for running foreground services UI. mServices.updateScreenStateLocked(isAwake); reportCurWakefulnessUsageEventLocked(); - mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0) - .sendToTarget(); + mActivityTaskManager.onScreenAwakeChanged(isAwake); } updateOomAdjLocked(); } @@ -10978,69 +10813,12 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void stopAppSwitches() { - enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches"); - synchronized(this) { - mAppSwitchesAllowedTime = SystemClock.uptimeMillis() - + APP_SWITCH_DELAY_TIME; - mDidAppSwitch = false; - mActivityTaskManager.getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME); - } + mActivityTaskManager.stopAppSwitches(); } + @Override public void resumeAppSwitches() { - enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches"); - synchronized(this) { - // Note that we don't execute any pending app switches... we will - // let those wait until either the timeout, or the next start - // activity request. - mAppSwitchesAllowedTime = 0; - } - } - - 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; - } - - boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, - int callingPid, int callingUid, String name) { - if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { - return true; - } - - if (mActivityTaskManager.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; + mActivityTaskManager.resumeAppSwitches(); } public void setDebugApp(String packageName, boolean waitForDebugger, @@ -11194,13 +10972,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setActivityController(IActivityController controller, boolean imAMonkey) { - enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, - "setActivityController()"); - synchronized (this) { - mController = controller; - mControllerIsAMonkey = imAMonkey; - Watchdog.getInstance().setActivityController(controller); - } + mActivityTaskManager.setActivityController(controller, imAMonkey); } @Override @@ -11225,7 +10997,7 @@ public class ActivityManagerService extends IActivityManager.Stub public boolean isUserAMonkey() { synchronized (this) { // If there is a controller also implies the user is a monkey. - return (mUserIsMonkey || (mController != null && mControllerIsAMonkey)); + return mUserIsMonkey || mActivityTaskManager.isControllerAMonkey(); } } @@ -11532,17 +11304,6 @@ public class ActivityManagerService extends IActivityManager.Stub return false; } - /** - * Check that we have the features required for VR-related API calls, and throw an exception if - * not. - */ - void enforceSystemHasVrFeature() { - if (!mContext.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) { - throw new UnsupportedOperationException("VR mode not supported on this device!"); - } - } - @Override public void setRenderThread(int tid) { synchronized (this) { @@ -11597,7 +11358,7 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean isVrModePackageEnabled(ComponentName packageName) { - enforceSystemHasVrFeature(); + mActivityTaskManager.enforceSystemHasVrFeature(); final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); @@ -12070,78 +11831,22 @@ public class ActivityManagerService extends IActivityManager.Stub private void retrieveSettings() { final ContentResolver resolver = mContext.getContentResolver(); - final boolean freeformWindowManagement = - mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT) - || Settings.Global.getInt( - resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; - - final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext); - final boolean supportsPictureInPicture = supportsMultiWindow && - mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); - final boolean supportsSplitScreenMultiWindow = - ActivityTaskManager.supportsSplitScreenMultiWindow(mContext); - final boolean supportsMultiDisplay = mContext.getPackageManager() - .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS); + mActivityTaskManager.retrieveSettings(resolver); + final String debugApp = Settings.Global.getString(resolver, DEBUG_APP); final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0; final boolean alwaysFinishActivities = Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0; - final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0; - final boolean forceResizable = Settings.Global.getInt( - resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0; final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver, NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS); - final boolean supportsLeanbackOnly = - mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY); mHiddenApiBlacklist.registerObserver(); - // Transfer any global setting for forcing RTL layout, into a System Property - SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); - - final Configuration configuration = new Configuration(); - Settings.System.getConfiguration(resolver, configuration); - if (forceRtl) { - // This will take care of setting the correct layout direction flags - configuration.setLayoutDirection(configuration.locale); - } - synchronized (this) { mDebugApp = mOrigDebugApp = debugApp; mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; mAlwaysFinishActivities = alwaysFinishActivities; - mSupportsLeanbackOnly = supportsLeanbackOnly; - mForceResizableActivities = forceResizable; - final boolean multiWindowFormEnabled = freeformWindowManagement - || supportsSplitScreenMultiWindow - || supportsPictureInPicture - || supportsMultiDisplay; - if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) { - mSupportsMultiWindow = true; - mSupportsFreeformWindowManagement = freeformWindowManagement; - mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow; - mSupportsPictureInPicture = supportsPictureInPicture; - mSupportsMultiDisplay = supportsMultiDisplay; - } else { - mSupportsMultiWindow = false; - mSupportsFreeformWindowManagement = false; - mSupportsSplitScreenMultiWindow = false; - mSupportsPictureInPicture = false; - mSupportsMultiDisplay = false; - } - mWindowManager.setForceResizableTasks(mForceResizableActivities); - mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture); - // This happens before any activities are started, so we can change global configuration - // in-place. - updateConfigurationLocked(configuration, null, true); - final Configuration globalConfig = getGlobalConfiguration(); - if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig); - // Load resources only after the current configuration has been set. final Resources res = mContext.getResources(); - mThumbnailWidth = res.getDimensionPixelSize( - com.android.internal.R.dimen.thumbnail_width); - mThumbnailHeight = res.getDimensionPixelSize( - com.android.internal.R.dimen.thumbnail_height); mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString( com.android.internal.R.string.config_appsNotReportingCrashes)); mUserController.mUserSwitchUiEnabled = !res.getBoolean( @@ -12149,14 +11854,6 @@ public class ActivityManagerService extends IActivityManager.Stub mUserController.mMaxRunningUsers = res.getInteger( com.android.internal.R.integer.config_multiuserMaxRunningUsers); - if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) { - mFullscreenThumbnailScale = (float) res - .getInteger(com.android.internal.R.integer.thumbnail_width_tv) / - (float) globalConfig.screenWidthDp; - } else { - mFullscreenThumbnailScale = res.getFraction( - com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1); - } mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs; } } @@ -12937,7 +12634,7 @@ public class ActivityManagerService extends IActivityManager.Stub final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid) == PackageManager.PERMISSION_GRANTED; final int userId = UserHandle.getUserId(callingUid); - final boolean allUids = isGetTasksAllowed( + final boolean allUids = mAtmInternal.isGetTasksAllowed( "getRunningAppProcesses", Binder.getCallingPid(), callingUid); synchronized (this) { @@ -13965,7 +13662,7 @@ public class ActivityManagerService extends IActivityManager.Stub } if (dumpAll) { if (dumpPackage == null) { - pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); + pw.println(" mConfigWillChange: " + mActivityTaskManager.getFocusedStack().mConfigWillChange); } if (mCompatModePackages.getPackages().size() > 0) { boolean printed = false; @@ -14130,10 +13827,10 @@ public class ActivityManagerService extends IActivityManager.Stub pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp); } } - if (mAllowAppSwitchUids.size() > 0) { + if (mActivityTaskManager.mAllowAppSwitchUids.size() > 0) { boolean printed = false; - for (int i = 0; i < mAllowAppSwitchUids.size(); i++) { - ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i); + for (int i = 0; i < mActivityTaskManager.mAllowAppSwitchUids.size(); i++) { + ArrayMap<String, Integer> types = mActivityTaskManager.mAllowAppSwitchUids.valueAt(i); for (int j = 0; j < types.size(); j++) { if (dumpPackage == null || UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) { @@ -14146,7 +13843,7 @@ public class ActivityManagerService extends IActivityManager.Stub printed = true; } pw.print(" User "); - pw.print(mAllowAppSwitchUids.keyAt(i)); + pw.print(mActivityTaskManager.mAllowAppSwitchUids.keyAt(i)); pw.print(": Type "); pw.print(types.keyAt(j)); pw.print(" = "); @@ -14160,9 +13857,9 @@ public class ActivityManagerService extends IActivityManager.Stub if (mAlwaysFinishActivities) { pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities); } - if (mController != null) { - pw.println(" mController=" + mController - + " mControllerIsAMonkey=" + mControllerIsAMonkey); + if (mActivityTaskManager.mController != null) { + pw.println(" mController=" + mActivityTaskManager.mController + + " mControllerIsAMonkey=" + mActivityTaskManager.mControllerIsAMonkey); } if (dumpAll) { pw.println(" Total persistent processes: " + numPers); @@ -14343,7 +14040,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpPackage == null) { mUserController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.USER_CONTROLLER); getGlobalConfiguration().writeToProto(proto, ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION); - proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, getFocusedStack().mConfigWillChange); + proto.write(ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE, mActivityTaskManager.getFocusedStack().mConfigWillChange); } if (mHomeProcess != null && (dumpPackage == null @@ -14493,10 +14190,10 @@ public class ActivityManagerService extends IActivityManager.Stub if (dumpPackage == null) { proto.write(ActivityManagerServiceDumpProcessesProto.ALWAYS_FINISH_ACTIVITIES, mAlwaysFinishActivities); - if (mController != null) { + if (mActivityTaskManager.mController != null) { final long token = proto.start(ActivityManagerServiceDumpProcessesProto.CONTROLLER); - proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mController.toString()); - proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mControllerIsAMonkey); + proto.write(ActivityManagerServiceDumpProcessesProto.Controller.CONTROLLER, mActivityTaskManager.mController.toString()); + proto.write(ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY, mActivityTaskManager.mControllerIsAMonkey); proto.end(token); } proto.write(ActivityManagerServiceDumpProcessesProto.TOTAL_PERSISTENT_PROCS, numPers); @@ -17363,8 +17060,8 @@ public class ActivityManagerService extends IActivityManager.Stub final int callingUid = Binder.getCallingUid(); final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission( INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED); - final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(), - callingUid); + final boolean allowed = mAtmInternal.isGetTasksAllowed("getServices", + Binder.getCallingPid(), callingUid); synchronized (this) { return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid, allowed, canInteractAcrossUsers); @@ -19336,10 +19033,6 @@ public class ActivityManagerService extends IActivityManager.Stub return config; } - ActivityStack getFocusedStack() { - return mStackSupervisor.getFocusedStack(); - } - @Override public StackInfo getFocusedStackInfo() throws RemoteException { return mActivityTaskManager.getFocusedStackInfo(); @@ -19369,18 +19062,7 @@ public class ActivityManagerService extends IActivityManager.Stub int userId = UserHandle.getCallingUserId(); - synchronized(this) { - updatePersistentConfigurationLocked(values, userId); - } - } - - private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) { - final long origId = Binder.clearCallingIdentity(); - try { - updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */); - } finally { - Binder.restoreCallingIdentity(origId); - } + mActivityTaskManager.updatePersistentConfiguration(values, userId); } private void updateFontScaleIfNeeded(@UserIdInt int userId) { @@ -19395,7 +19077,7 @@ public class ActivityManagerService extends IActivityManager.Stub final Configuration configuration = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); configuration.fontScale = scaleFactor; - updatePersistentConfigurationLocked(configuration, userId); + mActivityTaskManager.updatePersistentConfiguration(configuration, userId); } } @@ -19423,356 +19105,6 @@ public class ActivityManagerService extends IActivityManager.Stub return mActivityTaskManager.updateConfiguration(values); } - void updateUserConfigurationLocked() { - final Configuration configuration = new Configuration(getGlobalConfiguration()); - final int currentUserId = mUserController.getCurrentUserId(); - Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration, - currentUserId, Settings.System.canWrite(mContext)); - updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */, - false /* persistent */, currentUserId, false /* deferResume */); - } - - boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, - boolean initLocale) { - return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */); - } - - boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, - boolean initLocale, boolean deferResume) { - // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user - return updateConfigurationLocked(values, starting, initLocale, false /* persistent */, - UserHandle.USER_NULL, deferResume); - } - - // To cache the list of supported system locales - private String[] mSupportedSystemLocales = null; - - private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, - boolean initLocale, boolean persistent, int userId, boolean deferResume) { - return updateConfigurationLocked(values, starting, initLocale, persistent, userId, - deferResume, null /* result */); - } - - /** - * Do either or both things: (1) change the current configuration, and (2) - * make sure the given activity is running with the (now) current - * configuration. Returns true if the activity has been left running, or - * false if <var>starting</var> is being destroyed to match the new - * configuration. - * - * @param userId is only used when persistent parameter is set to true to persist configuration - * for that particular user - */ - boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, - boolean initLocale, boolean persistent, int userId, boolean deferResume, - ActivityTaskManagerService.UpdateConfigurationResult result) { - int changes = 0; - boolean kept = true; - - if (mWindowManager != null) { - mWindowManager.deferSurfaceLayout(); - } - try { - if (values != null) { - changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId, - deferResume); - } - - kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); - } finally { - if (mWindowManager != null) { - mWindowManager.continueSurfaceLayout(); - } - } - - if (result != null) { - result.changes = changes; - result.activityRelaunched = !kept; - } - return kept; - } - - /** - * Returns true if this configuration change is interesting enough to send an - * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast. - */ - private static boolean isSplitConfigurationChange(int configDiff) { - return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0; - } - - /** Update default (global) configuration and notify listeners about changes. */ - private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale, - boolean persistent, int userId, boolean deferResume) { - mActivityTaskManager.mTempConfig.setTo(getGlobalConfiguration()); - final int changes = mActivityTaskManager.mTempConfig.updateFrom(values); - if (changes == 0) { - // Since calling to Activity.setRequestedOrientation leads to freezing the window with - // setting WindowManagerService.mWaitingForConfig to true, it is important that we call - // performDisplayOverrideConfigUpdate in order to send the new display configuration - // (even if there are no actual changes) to unfreeze the window. - performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY); - return 0; - } - - if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION, - "Updating global configuration to: " + values); - - EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); - StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED, - values.colorMode, - values.densityDpi, - values.fontScale, - values.hardKeyboardHidden, - values.keyboard, - values.keyboardHidden, - values.mcc, - values.mnc, - values.navigation, - values.navigationHidden, - values.orientation, - values.screenHeightDp, - values.screenLayout, - values.screenWidthDp, - values.smallestScreenWidthDp, - values.touchscreen, - values.uiMode); - - - if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { - final LocaleList locales = values.getLocales(); - int bestLocaleIndex = 0; - if (locales.size() > 1) { - if (mSupportedSystemLocales == null) { - mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales(); - } - bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales)); - } - SystemProperties.set("persist.sys.locale", - locales.get(bestLocaleIndex).toLanguageTag()); - LocaleList.setDefault(locales, bestLocaleIndex); - mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, - locales.get(bestLocaleIndex))); - } - - mActivityTaskManager.mConfigurationSeq = Math.max(++mActivityTaskManager.mConfigurationSeq, 1); - mActivityTaskManager.mTempConfig.seq = mActivityTaskManager.mConfigurationSeq; - - // Update stored global config and notify everyone about the change. - mStackSupervisor.onConfigurationChanged(mActivityTaskManager.mTempConfig); - - Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mActivityTaskManager.mTempConfig); - // TODO(multi-display): Update UsageEvents#Event to include displayId. - mUsageStatsService.reportConfigurationChange(mActivityTaskManager.mTempConfig, - mUserController.getCurrentUserId()); - - // TODO: If our config changes, should we auto dismiss any currently showing dialogs? - updateShouldShowDialogsLocked(mActivityTaskManager.mTempConfig); - - AttributeCache ac = AttributeCache.instance(); - if (ac != null) { - ac.updateConfiguration(mActivityTaskManager.mTempConfig); - } - - // Make sure all resources in our process are updated right now, so that anyone who is going - // to retrieve resource values after we return will be sure to get the new ones. This is - // especially important during boot, where the first config change needs to guarantee all - // resources have that config before following boot code is executed. - mSystemThread.applyConfigurationToResources(mActivityTaskManager.mTempConfig); - - // We need another copy of global config because we're scheduling some calls instead of - // running them in place. We need to be sure that object we send will be handled unchanged. - final Configuration configCopy = new Configuration(mActivityTaskManager.mTempConfig); - if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { - Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); - msg.obj = configCopy; - msg.arg1 = userId; - mHandler.sendMessage(msg); - } - - for (int i = mLruProcesses.size() - 1; i >= 0; i--) { - ProcessRecord app = mLruProcesses.get(i); - try { - if (app.thread != null) { - if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc " - + app.processName + " new config " + configCopy); - mActivityTaskManager.getLifecycleManager().scheduleTransaction(app.thread, - ConfigurationChangeItem.obtain(configCopy)); - } - } catch (Exception e) { - Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e); - } - } - - Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING - | Intent.FLAG_RECEIVER_FOREGROUND - | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); - broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - UserHandle.USER_ALL); - if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { - intent = new Intent(Intent.ACTION_LOCALE_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND - | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); - if (initLocale || !mProcessesReady) { - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); - } - broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, - OP_NONE, null, false, false, MY_PID, SYSTEM_UID, - UserHandle.USER_ALL); - } - - // Send a broadcast to PackageInstallers if the configuration change is interesting - // for the purposes of installing additional splits. - if (!initLocale && isSplitConfigurationChange(changes)) { - intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED); - intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING - | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); - - // Typically only app stores will have this permission. - String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES }; - broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions, - OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); - } - - // Override configuration of the default display duplicates global config, so we need to - // update it also. This will also notify WindowManager about changes. - performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume, - DEFAULT_DISPLAY); - - return changes; - } - - boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting, - boolean deferResume, int displayId) { - return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */, - displayId, null /* result */); - } - - /** - * Updates override configuration specific for the selected display. If no config is provided, - * new one will be computed in WM based on current display info. - */ - boolean updateDisplayOverrideConfigurationLocked(Configuration values, - ActivityRecord starting, boolean deferResume, int displayId, - ActivityTaskManagerService.UpdateConfigurationResult result) { - int changes = 0; - boolean kept = true; - - if (mWindowManager != null) { - mWindowManager.deferSurfaceLayout(); - } - try { - if (values != null) { - if (displayId == DEFAULT_DISPLAY) { - // Override configuration of the default display duplicates global config, so - // we're calling global config update instead for default display. It will also - // apply the correct override config. - changes = updateGlobalConfigurationLocked(values, false /* initLocale */, - false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume); - } else { - changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId); - } - } - - kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); - } finally { - if (mWindowManager != null) { - mWindowManager.continueSurfaceLayout(); - } - } - - if (result != null) { - result.changes = changes; - result.activityRelaunched = !kept; - } - return kept; - } - - private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume, - int displayId) { - mActivityTaskManager.mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); - final int changes = mActivityTaskManager.mTempConfig.updateFrom(values); - if (changes != 0) { - Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " - + mActivityTaskManager.mTempConfig + " for displayId=" + displayId); - mStackSupervisor.setDisplayOverrideConfiguration(mActivityTaskManager.mTempConfig, displayId); - - final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; - if (isDensityChange && displayId == DEFAULT_DISPLAY) { - mAppWarnings.onDensityChanged(); - - killAllBackgroundProcessesExcept(N, - ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); - } - } - - // Update the configuration with WM first and check if any of the stacks need to be resized - // due to the configuration change. If so, resize the stacks now and do any relaunches if - // necessary. This way we don't need to relaunch again afterwards in - // ensureActivityConfiguration(). - if (mWindowManager != null) { - final int[] resizedStacks = - mWindowManager.setNewDisplayOverrideConfiguration(mActivityTaskManager.mTempConfig, displayId); - if (resizedStacks != null) { - for (int stackId : resizedStacks) { - resizeStackWithBoundsFromWindowManager(stackId, deferResume); - } - } - } - - return changes; - } - - /** Applies latest configuration and/or visibility updates if needed. */ - private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) { - boolean kept = true; - final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); - // mainStack is null during startup. - if (mainStack != null) { - if (changes != 0 && starting == null) { - // If the configuration changed, and the caller is not already - // in the process of starting an activity, then find the top - // activity to check if its configuration needs to change. - starting = mainStack.topRunningActivityLocked(); - } - - if (starting != null) { - kept = starting.ensureActivityConfiguration(changes, - false /* preserveWindow */); - // And we need to make sure at this point that all other activities - // are made visible with the correct configuration. - mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes, - !PRESERVE_WINDOWS); - } - } - - return kept; - } - - /** Helper method that requests bounds from WM and applies them to stack. */ - private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) { - final Rect newStackBounds = new Rect(); - final ActivityStack stack = mStackSupervisor.getStack(stackId); - - // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found. - if (stack == null) { - final StringWriter writer = new StringWriter(); - final PrintWriter printWriter = new PrintWriter(writer); - mStackSupervisor.dumpDisplays(printWriter); - printWriter.flush(); - - Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer); - } - - stack.getBoundsForNewConfiguration(newStackBounds); - mStackSupervisor.resizeStackLocked( - stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */, - null /* tempTaskBounds */, null /* tempTaskInsetBounds */, - false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume); - } - /** * Decide based on the configuration whether we should show the ANR, * crash, etc dialogs. The idea is that if there is no affordance to @@ -19782,7 +19114,7 @@ public class ActivityManagerService extends IActivityManager.Stub * A thought: SystemUI might also want to get told about this, the Power * dialog / global actions also might want different behaviors. */ - private void updateShouldShowDialogsLocked(Configuration config) { + void updateShouldShowDialogsLocked(Configuration config) { final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH && config.navigation == Configuration.NAVIGATION_NONAV); @@ -23233,15 +22565,6 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void onUserRemoved(int userId) { - synchronized (ActivityManagerService.this) { - ActivityManagerService.this.onUserStoppedLocked(userId); - } - mBatteryStatsService.onUserRemoved(userId); - mUserController.onUserRemoved(userId); - } - - @Override public void killForegroundAppsForUser(int userHandle) { synchronized (ActivityManagerService.this) { final ArrayList<ProcessRecord> procs = new ArrayList<>(); @@ -23300,17 +22623,6 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void updatePersistentConfigurationForUser(@NonNull Configuration values, - int userId) { - Preconditions.checkNotNull(values, "Configuration must not be null"); - Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported"); - synchronized (ActivityManagerService.this) { - updateConfigurationLocked(values, null, false, true, userId, - false /* deferResume */); - } - } - - @Override public int getUidProcessState(int uid) { return getUidState(uid); } @@ -23428,27 +22740,6 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void setAllowAppSwitches(@NonNull String type, int uid, int userId) { - synchronized (ActivityManagerService.this) { - if (mUserController.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) { - ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId); - if (types == null) { - if (uid < 0) { - return; - } - types = new ArrayMap<>(); - mAllowAppSwitchUids.put(userId, types); - } - if (uid < 0) { - types.remove(type); - } else { - types.put(type, uid); - } - } - } - } - - @Override public boolean isRuntimeRestarted() { return mSystemServiceManager.isRuntimeRestarted(); } @@ -23511,6 +22802,51 @@ public class ActivityManagerService extends IActivityManager.Stub } return processMemoryStates; } + + @Override + public int handleIncomingUser(int callingPid, int callingUid, int userId, + boolean allowAll, int allowMode, String name, String callerPackage) { + return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll, + allowMode, name, callerPackage); + } + + @Override + public void enforceCallingPermission(String permission, String func) { + ActivityManagerService.this.enforceCallingPermission(permission, func); + } + + @Override + public int getCurrentUserId() { + return mUserController.getCurrentUserIdLU(); + } + + @Override + public boolean isUserRunning(int userId, int flags) { + synchronized (ActivityManagerService.this) { + return mUserController.isUserRunning(userId, flags); + } + } + + @Override + public void trimApplications() { + ActivityManagerService.this.trimApplications(); + } + + public int getPackageScreenCompatMode(ApplicationInfo ai) { + synchronized (ActivityManagerService.this) { + return mCompatModePackages.computeCompatModeLocked(ai); + } + } + + public void setPackageScreenCompatMode(ApplicationInfo ai, int mode) { + synchronized (ActivityManagerService.this) { + mCompatModePackages.setPackageScreenCompatModeLocked(ai, mode); + } + } + + public void closeSystemDialogs(String reason) { + ActivityManagerService.this.closeSystemDialogs(reason); + } } /** diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 0e427d667af4..7f3f8f34ce71 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -1220,7 +1220,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo * @return whether this activity supports PiP multi-window and can be put in the pinned stack. */ boolean supportsPictureInPicture() { - return service.mAm.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined() + return service.mSupportsPictureInPicture && isActivityTypeStandardOrUndefined() && info.supportsPictureInPicture(); } @@ -1233,7 +1233,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // An activity can not be docked even if it is considered resizeable because it only // supports picture-in-picture mode but has a non-resizeable resizeMode return super.supportsSplitScreenWindowingMode() - && service.mAm.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow(); + && service.mSupportsSplitScreenMultiWindow && supportsResizeableMultiWindow(); } /** @@ -1241,16 +1241,16 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo * stack. */ boolean supportsFreeform() { - return service.mAm.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow(); + return service.mSupportsFreeformWindowManagement && supportsResizeableMultiWindow(); } /** * @return whether this activity supports non-PiP multi-window. */ private boolean supportsResizeableMultiWindow() { - return service.mAm.mSupportsMultiWindow && !isActivityTypeHome() + return service.mSupportsMultiWindow && !isActivityTypeHome() && (ActivityInfo.isResizeableMode(info.resizeMode) - || service.mAm.mForceResizableActivities); + || service.mForceResizableActivities); } /** @@ -2347,7 +2347,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo displayId, displayConfig, mayFreezeScreenLocked(app)); if (config != null) { frozenBeforeDestroy = true; - if (!service.mAm.updateDisplayOverrideConfigurationLocked(config, this, + if (!service.updateDisplayOverrideConfigurationLocked(config, this, false /* deferResume */, displayId)) { mStackSupervisor.resumeFocusedStackTopActivityLocked(); } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 6118131cd2b2..d177702c49d3 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -3956,7 +3956,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai } } - IActivityController controller = mService.mAm.mController; + // TODO: There is a dup. of this block of code in ActivityTaskManagerService.finishActivity + // We should consolidate. + IActivityController controller = mService.mController; if (controller != null) { ActivityRecord next = topRunningActivityLocked(srec.appToken, 0); if (next != null) { @@ -3965,7 +3967,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai try { resumeOK = controller.activityResuming(next.packageName); } catch (RemoteException e) { - mService.mAm.mController = null; + mService.mController = null; Watchdog.getInstance().setActivityController(null); } @@ -4662,7 +4664,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // If we have a watcher, preflight the move before committing to it. First check // for *other* available tasks, but if none are available, then try again allowing the // current task to be selected. - if (isTopStackOnDisplay() && mService.mAm.mController != null) { + if (isTopStackOnDisplay() && mService.mController != null) { ActivityRecord next = topRunningActivityLocked(null, taskId); if (next == null) { next = topRunningActivityLocked(null, 0); @@ -4671,9 +4673,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // ask watcher if this is allowed boolean moveOK = true; try { - moveOK = mService.mAm.mController.activityResuming(next.packageName); + moveOK = mService.mController.activityResuming(next.packageName); } catch (RemoteException e) { - mService.mAm.mController = null; + mService.mController = null; Watchdog.getInstance().setActivityController(null); } if (!moveOK) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index a77d7348620e..10b721e2d690 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -488,7 +488,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // No restrictions for the default display. return true; } - if (!mService.mAm.mSupportsMultiDisplay) { + if (!mService.mSupportsMultiDisplay) { // Can't launch on secondary displays if feature is not supported. return false; } @@ -624,7 +624,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, mHandler.getLooper()); mKeyguardController = new KeyguardController(mService.mAm, this); - mLaunchParamsController = new LaunchParamsController(mService.mAm); + mLaunchParamsController = new LaunchParamsController(mService); mLaunchParamsController.registerDefaultModifiers(this); } @@ -1661,7 +1661,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } // Update the configuration of the activities on the display. - return mService.mAm.updateDisplayOverrideConfigurationLocked(config, starting, deferResume, + return mService.updateDisplayOverrideConfigurationLocked(config, starting, deferResume, displayId); } @@ -2347,9 +2347,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D if (options == null || options.getLaunchBounds() == null) { return false; } - return (mService.mAm.mSupportsPictureInPicture + return (mService.mSupportsPictureInPicture && options.getLaunchWindowingMode() == WINDOWING_MODE_PINNED) - || mService.mAm.mSupportsFreeformWindowManagement; + || mService.mSupportsFreeformWindowManagement; } LaunchParamsController getLaunchParamsController() { @@ -3258,21 +3258,21 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D // Ensure that we aren't trying to move into a multi-window stack without multi-window // support - if (inMultiWindowMode && !mService.mAm.mSupportsMultiWindow) { + if (inMultiWindowMode && !mService.mSupportsMultiWindow) { throw new IllegalArgumentException("Device doesn't support multi-window, can not" + " reparent task=" + task + " to stack=" + stack); } // Ensure that we're not moving a task to a dynamic stack if device doesn't support // multi-display. - if (stack.mDisplayId != DEFAULT_DISPLAY && !mService.mAm.mSupportsMultiDisplay) { + if (stack.mDisplayId != DEFAULT_DISPLAY && !mService.mSupportsMultiDisplay) { throw new IllegalArgumentException("Device doesn't support multi-display, can not" + " reparent task=" + task + " to stackId=" + stackId); } // Ensure that we aren't trying to move into a freeform stack without freeform support if (stack.getWindowingMode() == WINDOWING_MODE_FREEFORM - && !mService.mAm.mSupportsFreeformWindowManagement) { + && !mService.mSupportsFreeformWindowManagement) { throw new IllegalArgumentException("Device doesn't support freeform, can not reparent" + " task=" + task); } @@ -3305,7 +3305,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return false; } - if (!mService.mAm.mForceResizableActivities && !r.supportsPictureInPicture()) { + if (!mService.mForceResizableActivities && !r.supportsPictureInPicture()) { Slog.w(TAG, "moveTopStackActivityToPinnedStackLocked: Picture-In-Picture not supported for " + " r=" + r); diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java index fa001dfadefa..f7ea4b228e52 100644 --- a/services/core/java/com/android/server/am/ActivityStartController.java +++ b/services/core/java/com/android/server/am/ActivityStartController.java @@ -21,7 +21,7 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY; +import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import android.app.IApplicationThread; import android.content.ComponentName; @@ -237,8 +237,8 @@ public class ActivityStartController { int checkTargetUser(int targetUserId, boolean validateIncomingUser, int realCallingPid, int realCallingUid, String reason) { if (validateIncomingUser) { - return mService.mAm.mUserController.handleIncomingUser(realCallingPid, realCallingUid, - targetUserId, false, ALLOW_FULL_ONLY, reason, null); + return mService.handleIncomingUser( + realCallingPid, realCallingUid, targetUserId, reason); } else { mService.mAm.mUserController.ensureNotSpecialUser(targetUserId); return targetUserId; diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index f50bb3789b96..6f58aeab0cab 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -729,15 +729,15 @@ class ActivityStarter { .getPendingRemoteAnimationRegistry() .overrideOptionsIfNeeded(callingPackage, checkedOptions); } - if (mService.mAm.mController != null) { + if (mService.mController != null) { try { // The Intent we give to the watcher has the extra data // stripped off, since it can contain private information. Intent watchIntent = intent.cloneFilter(); - abort |= !mService.mAm.mController.activityStarting(watchIntent, + abort |= !mService.mController.activityStarting(watchIntent, aInfo.applicationInfo.packageName); } catch (RemoteException e) { - mService.mAm.mController = null; + mService.mController = null; } } @@ -844,7 +844,7 @@ class ActivityStarter { // one, check whether app switches are allowed. if (voiceSession == null && (stack.getResumedActivity() == null || stack.getResumedActivity().info.applicationInfo.uid != realCallingUid)) { - if (!mService.mAm.checkAppSwitchAllowedLocked(callingPid, callingUid, + if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, realCallingPid, realCallingUid, "Activity start")) { mController.addPendingActivityLaunch(new PendingActivityLaunch(r, sourceRecord, startFlags, stack, callerApp)); @@ -853,17 +853,7 @@ class ActivityStarter { } } - if (mService.mAm.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). - mService.mAm.mAppSwitchesAllowedTime = 0; - } else { - mService.mAm.mDidAppSwitch = true; - } - + mService.onStartActivitySetDidAppSwitch(); mController.doPendingActivityLaunches(false); return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, @@ -1110,12 +1100,12 @@ class ActivityStarter { // do so now. This allows a clean switch, as we are waiting // for the current activity to pause (so we will not destroy // it), and have not yet started the next activity. - mService.mAm.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, + mService.mAmInternal.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, "updateConfiguration()"); stack.mConfigWillChange = false; if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Updating to new configuration after starting activity."); - mService.mAm.updateConfigurationLocked(globalConfig, null, false); + mService.updateConfigurationLocked(globalConfig, null, false); } if (outResult != null) { @@ -1821,7 +1811,7 @@ class ActivityStarter { } // Get the virtual display id from ActivityManagerService. - int displayId = mService.mAm.mVr2dDisplayId; + int displayId = mService.mVr2dDisplayId; if (displayId != INVALID_DISPLAY) { if (DEBUG_STACK) { Slog.d(TAG, "getSourceDisplayId :" + displayId); diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java index 90097fd976e2..d554e0f3c713 100644 --- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java +++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java @@ -24,6 +24,7 @@ import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; +import static android.Manifest.permission.STOP_APP_SWITCHES; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT; import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_DATA; @@ -32,6 +33,7 @@ import static android.app.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE; import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW; import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.AppOpsManager.OP_NONE; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; @@ -42,8 +44,19 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMAR import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS; +import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT; +import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY; +import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION; +import static android.os.Build.VERSION_CODES.N; import static android.os.Process.SYSTEM_UID; +import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES; +import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT; +import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES; +import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL; +import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS; import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; @@ -60,7 +73,9 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK; @@ -69,10 +84,13 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH; import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY; +import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static com.android.server.am.ActivityManagerService.ANIMATE; -import static com.android.server.am.ActivityManagerService.DISPATCH_SCREEN_KEYGUARD_MSG; +import static com.android.server.am.ActivityManagerService.MY_PID; +import static com.android.server.am.ActivityManagerService.SEND_LOCALE_TO_MOUNT_DAEMON_MSG; import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS; +import static com.android.server.am.ActivityManagerService.UPDATE_CONFIGURATION_MSG; +import static com.android.server.am.ActivityManagerService.checkComponentPermission; import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_DESTROYING; import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME; import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS_ONLY; @@ -88,14 +106,17 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_P import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION; import android.Manifest; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.ActivityTaskManager; import android.app.ActivityTaskManagerInternal; import android.app.AppGlobals; +import android.app.IActivityController; import android.app.IActivityTaskManager; import android.app.IApplicationThread; import android.app.IAssistDataReceiver; @@ -108,17 +129,21 @@ import android.app.WindowConfiguration; import android.app.admin.DevicePolicyCache; import android.app.assist.AssistContent; import android.app.assist.AssistStructure; +import android.app.servertransaction.ConfigurationChangeItem; import android.app.usage.UsageEvents; import android.content.ActivityNotFoundException; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.res.Configuration; +import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; @@ -134,21 +159,29 @@ import android.os.Message; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; -import android.os.TransactionTooLargeException; +import android.os.SystemClock; +import android.os.SystemProperties; +import android.os.UpdateLock; import android.os.UserHandle; import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.service.voice.VoiceInteractionManagerInternal; import android.telecom.TelecomManager; import android.text.TextUtils; +import android.util.ArrayMap; +import android.util.EventLog; +import android.util.Log; import android.util.Slog; +import android.util.SparseArray; import android.util.SparseIntArray; +import android.util.StatsLog; import android.util.proto.ProtoOutputStream; import android.view.IRecentsAnimationRunner; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.AssistUtils; import com.android.internal.app.IVoiceInteractor; import com.android.internal.logging.MetricsLogger; @@ -157,6 +190,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.policy.KeyguardDismissCallback; import com.android.internal.util.Preconditions; +import com.android.server.AttributeCache; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.Watchdog; @@ -166,6 +200,7 @@ import com.android.server.wm.WindowManagerService; import java.io.File; import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.List; @@ -182,10 +217,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS; private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY; private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK; + private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION; Context mContext; H mH; + UiHandler mUiHandler; ActivityManagerService mAm; + ActivityManagerInternal mAmInternal; /* Global service lock used by the package the owns this service. */ Object mGlobalLock; ActivityStackSupervisor mStackSupervisor; @@ -245,14 +283,77 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } /** Current sequencing integer of the configuration, for skipping old configurations. */ - int mConfigurationSeq; + private int mConfigurationSeq; + // To cache the list of supported system locales + private String[] mSupportedSystemLocales = null; /** * Temp object used when global and/or display override configuration is updated. It is also * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust * anyone... */ - Configuration mTempConfig = new Configuration(); + private Configuration mTempConfig = new Configuration(); + + // 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, + * after a call to {@link #stopAppSwitches()}. + */ + long mAppSwitchesAllowedTime; + /** + * This is set to true after the first switch after mAppSwitchesAllowedTime + * is set; any switches after that will clear the time. + */ + boolean mDidAppSwitch; + + IActivityController mController = null; + boolean mControllerIsAMonkey = false; + + /** + * Used to retain an update lock when the foreground activity is in + * immersive mode. + */ + final UpdateLock mUpdateLock = new UpdateLock("immersive"); + + /** + * Packages that are being allowed to perform unrestricted app switches. Mapping is + * User -> Type -> uid. + */ + final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>(); + + /** The dimensions of the thumbnails in the Recents UI. */ + int mThumbnailWidth; + int mThumbnailHeight; + float mFullscreenThumbnailScale; + + /** + * Flag that indicates if multi-window is enabled. + * + * For any particular form of multi-window to be enabled, generic multi-window must be enabled + * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or + * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set. + * At least one of the forms of multi-window must be enabled in order for this flag to be + * initialized to 'true'. + * + * @see #mSupportsSplitScreenMultiWindow + * @see #mSupportsFreeformWindowManagement + * @see #mSupportsPictureInPicture + * @see #mSupportsMultiDisplay + */ + boolean mSupportsMultiWindow; + boolean mSupportsSplitScreenMultiWindow; + boolean mSupportsFreeformWindowManagement; + boolean mSupportsPictureInPicture; + boolean mSupportsMultiDisplay; + boolean mForceResizableActivities; + + final List<ActivityTaskManagerInternal.ScreenObserver> mScreenObservers = new ArrayList<>(); + + // VR Vr2d Display Id. + int mVr2dDisplayId = INVALID_DISPLAY; ActivityTaskManagerService(Context context) { mContext = context; @@ -265,11 +366,87 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mRecentTasks.onSystemReadyLocked(); } + void retrieveSettings(ContentResolver resolver) { + final boolean freeformWindowManagement = + mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT) + || Settings.Global.getInt( + resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; + + final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext); + final boolean supportsPictureInPicture = supportsMultiWindow && + mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); + final boolean supportsSplitScreenMultiWindow = + ActivityTaskManager.supportsSplitScreenMultiWindow(mContext); + final boolean supportsMultiDisplay = mContext.getPackageManager() + .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS); + final boolean alwaysFinishActivities = + Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0; + final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0; + final boolean forceResizable = Settings.Global.getInt( + resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0; + + // Transfer any global setting for forcing RTL layout, into a System Property + SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); + + final Configuration configuration = new Configuration(); + Settings.System.getConfiguration(resolver, configuration); + if (forceRtl) { + // This will take care of setting the correct layout direction flags + configuration.setLayoutDirection(configuration.locale); + } + + synchronized (mGlobalLock) { + mForceResizableActivities = forceResizable; + final boolean multiWindowFormEnabled = freeformWindowManagement + || supportsSplitScreenMultiWindow + || supportsPictureInPicture + || supportsMultiDisplay; + if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) { + mSupportsMultiWindow = true; + mSupportsFreeformWindowManagement = freeformWindowManagement; + mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow; + mSupportsPictureInPicture = supportsPictureInPicture; + mSupportsMultiDisplay = supportsMultiDisplay; + } else { + mSupportsMultiWindow = false; + mSupportsFreeformWindowManagement = false; + mSupportsSplitScreenMultiWindow = false; + mSupportsPictureInPicture = false; + mSupportsMultiDisplay = false; + } + mWindowManager.setForceResizableTasks(mForceResizableActivities); + mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture); + // This happens before any activities are started, so we can change global configuration + // in-place. + updateConfigurationLocked(configuration, null, true); + final Configuration globalConfig = getGlobalConfiguration(); + if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig); + + // Load resources only after the current configuration has been set. + final Resources res = mContext.getResources(); + mThumbnailWidth = res.getDimensionPixelSize( + com.android.internal.R.dimen.thumbnail_width); + mThumbnailHeight = res.getDimensionPixelSize( + com.android.internal.R.dimen.thumbnail_height); + + if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) { + mFullscreenThumbnailScale = (float) res + .getInteger(com.android.internal.R.integer.thumbnail_width_tv) / + (float) globalConfig.screenWidthDp; + } else { + mFullscreenThumbnailScale = res.getFraction( + com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1); + } + } + } + // TODO: Will be converted to WM lock once transition is complete. void setActivityManagerService(ActivityManagerService am) { mAm = am; + mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mGlobalLock = mAm; mH = new H(mAm.mHandlerThread.getLooper()); + mUiHandler = new UiHandler(); mTempConfig.setToDefaults(); mTempConfig.setLocales(LocaleList.getDefault()); @@ -278,12 +455,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mStackSupervisor.onConfigurationChanged(mTempConfig); mTaskChangeNotificationController = - new TaskChangeNotificationController(mAm, mStackSupervisor, mH); + new TaskChangeNotificationController(mGlobalLock, mStackSupervisor, mH); mLockTaskController = new LockTaskController(mContext, mStackSupervisor, mH); mActivityStartController = new ActivityStartController(this); mRecentTasks = createRecentTasks(); mStackSupervisor.setRecentTasks(mRecentTasks); - mVrController = new VrController(mAm); + mVrController = new VrController(mGlobalLock); mKeyguardController = mStackSupervisor.getKeyguardController(); } @@ -359,9 +536,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions, int userId) { final String reason = "startActivities"; - mAm.enforceNotIsolatedCaller(reason); - userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, reason, null); + enforceNotIsolatedCaller(reason); + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason); // TODO: Switch to user app stacks here. return getActivityStartController().startActivities(caller, -1, callingPackage, intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, reason); @@ -380,7 +556,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { - mAm.enforceNotIsolatedCaller("startActivityAsUser"); + enforceNotIsolatedCaller("startActivityAsUser"); userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); @@ -404,9 +580,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public int startActivityIntentSender(IApplicationThread caller, IIntentSender target, IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo, - String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) - throws TransactionTooLargeException { - mAm.enforceNotIsolatedCaller("startActivityIntentSender"); + String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions) { + enforceNotIsolatedCaller("startActivityIntentSender"); // Refuse possible leaked file descriptors if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); @@ -421,15 +596,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { // If this is coming from the currently resumed activity, it is // effectively saying that app switches are allowed at this point. - final ActivityStack stack = mAm.getFocusedStack(); + final ActivityStack stack = getFocusedStack(); if (stack.mResumedActivity != null && stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { - mAm.mAppSwitchesAllowedTime = 0; + mAppSwitchesAllowedTime = 0; } } - int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null, + return pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null, resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions); - return ret; } @Override @@ -556,10 +730,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { final WaitResult res = new WaitResult(); synchronized (mGlobalLock) { - mAm.enforceNotIsolatedCaller("startActivityAndWait"); - userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, - "startActivityAndWait", null); + enforceNotIsolatedCaller("startActivityAndWait"); + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, "startActivityAndWait"); // TODO: Switch to user app stacks here. getActivityStartController().obtainStarter(intent, "startActivityAndWait") .setCaller(caller) @@ -583,10 +756,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration config, Bundle bOptions, int userId) { synchronized (mGlobalLock) { - mAm.enforceNotIsolatedCaller("startActivityWithConfig"); - userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, - "startActivityWithConfig", null); + enforceNotIsolatedCaller("startActivityWithConfig"); + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, + "startActivityWithConfig"); // TODO: Switch to user app stacks here. return getActivityStartController().obtainStarter(intent, "startActivityWithConfig") .setCaller(caller) @@ -692,17 +864,21 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + int handleIncomingUser(int callingPid, int callingUid, int userId, String name) { + return mAmInternal.handleIncomingUser(callingPid, callingUid, userId, false /* allowAll */, + ALLOW_FULL_ONLY, name, null /* callerPackage */); + } + @Override public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, Intent intent, String resolvedType, IVoiceInteractionSession session, IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { - mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()"); + mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()"); if (session == null || interactor == null) { throw new NullPointerException("null session or interactor"); } - userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false, - ALLOW_FULL_ONLY, "startVoiceActivity", null); + userId = handleIncomingUser(callingPid, callingUid, userId, "startVoiceActivity"); // TODO: Switch to user app stacks here. return getActivityStartController().obtainStarter(intent, "startVoiceActivity") .setCallingUid(callingUid) @@ -720,9 +896,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public int startAssistantActivity(String callingPackage, int callingPid, int callingUid, Intent intent, String resolvedType, Bundle bOptions, int userId) { - mAm.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()"); - userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false, - ALLOW_FULL_ONLY, "startAssistantActivity", null); + mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()"); + userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity"); return getActivityStartController().obtainStarter(intent, "startAssistantActivity") .setCallingUid(callingUid) @@ -736,7 +911,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver, IRecentsAnimationRunner recentsAnimationRunner) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()"); final int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); try { @@ -745,9 +920,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final int recentsUid = mRecentTasks.getRecentsComponentUid(); // Start a new recents animation - final RecentsAnimation anim = new RecentsAnimation(mAm, mStackSupervisor, - getActivityStartController(), mAm.mWindowManager, mAm.mUserController, - callingPid); + final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor, + getActivityStartController(), mWindowManager, callingPid); anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent, recentsUid, assistDataReceiver); } @@ -758,7 +932,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public final int startActivityFromRecents(int taskId, Bundle bOptions) { - mAm.enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS, + enforceCallerIsRecentsOrHasPermission(START_TASKS_FROM_RECENTS, "startActivityFromRecents()"); final int callingPid = Binder.getCallingPid(); @@ -810,16 +984,18 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return false; } - if (mAm.mController != null) { + // TODO: There is a dup. of this block of code in ActivityStack.navigateUpToLocked + // We should consolidate. + if (mController != null) { // Find the first activity that is not finishing. ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0); if (next != null) { // ask watcher if this is allowed boolean resumeOK = true; try { - resumeOK = mAm.mController.activityResuming(next.packageName); + resumeOK = mController.activityResuming(next.packageName); } catch (RemoteException e) { - mAm.mController = null; + mController = null; Watchdog.getInstance().setActivityController(null); } @@ -907,7 +1083,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { final long origId = Binder.clearCallingIdentity(); synchronized (mGlobalLock) { ActivityRecord.activityResumedLocked(token); - mAm.mWindowManager.notifyAppResumedFinished(token); + mWindowManager.notifyAppResumedFinished(token); } Binder.restoreCallingIdentity(origId); } @@ -943,7 +1119,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - mAm.trimApplications(); + mAmInternal.trimApplications(); Binder.restoreCallingIdentity(origId); } @@ -1022,11 +1198,30 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // update associated state if we're frontmost if (r == mStackSupervisor.getResumedActivityLocked()) { if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r); - mAm.applyUpdateLockStateLocked(r); + applyUpdateLockStateLocked(r); } } } + void applyUpdateLockStateLocked(ActivityRecord r) { + // Modifications to the UpdateLock state are done on our handler, outside + // the activity manager's locks. The new state is determined based on the + // state *now* of the relevant activity record. The object is passed to + // the handler solely for logging detail, not to be consulted/modified. + final boolean nextState = r != null && r.immersive; + mH.post(() -> { + if (mUpdateLock.isHeld() != nextState) { + if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, + "Applying new update lock state '" + nextState + "' for " + r); + if (nextState) { + mUpdateLock.acquire(); + } else { + mUpdateLock.release(); + } + } + }); + } + @Override public boolean isImmersive(IBinder token) { synchronized (mGlobalLock) { @@ -1040,9 +1235,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean isTopActivityImmersive() { - mAm.enforceNotIsolatedCaller("isTopActivityImmersive"); + enforceNotIsolatedCaller("isTopActivityImmersive"); synchronized (mGlobalLock) { - final ActivityRecord r = mAm.getFocusedStack().topRunningActivityLocked(); + final ActivityRecord r = getFocusedStack().topRunningActivityLocked(); return (r != null) ? r.immersive : false; } } @@ -1060,7 +1255,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (self.isState( ActivityStack.ActivityState.RESUMED, ActivityStack.ActivityState.PAUSING)) { - mAm.mWindowManager.overridePendingAppTransition(packageName, + mWindowManager.overridePendingAppTransition(packageName, enterAnim, exitAnim, null); } @@ -1070,19 +1265,34 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public int getFrontActivityScreenCompatMode() { - mAm.enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); + enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); + ApplicationInfo ai; synchronized (mGlobalLock) { - return mAm.mCompatModePackages.getFrontActivityScreenCompatModeLocked(); + final ActivityRecord r = getFocusedStack().topRunningActivityLocked(); + if (r == null) { + return ActivityManager.COMPAT_MODE_UNKNOWN; + } + ai = r.info.applicationInfo; } + + return mAmInternal.getPackageScreenCompatMode(ai); } @Override public void setFrontActivityScreenCompatMode(int mode) { - mAm.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, + mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, "setFrontActivityScreenCompatMode"); + ApplicationInfo ai; synchronized (mGlobalLock) { - mAm.mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); + final ActivityRecord r = getFocusedStack().topRunningActivityLocked(); + if (r == null) { + Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity"); + return; + } + ai = r.info.applicationInfo; } + + mAmInternal.setPackageScreenCompatMode(ai, mode); } @Override @@ -1122,7 +1332,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (translucentChanged) { mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); } - mAm.mWindowManager.setAppFullscreen(token, true); + mWindowManager.setAppFullscreen(token, true); return translucentChanged; } } finally { @@ -1151,7 +1361,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { r.getStack().convertActivityToTranslucent(r); } mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); - mAm.mWindowManager.setAppFullscreen(token, false); + mWindowManager.setAppFullscreen(token, false); return translucentChanged; } } finally { @@ -1194,11 +1404,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public ActivityManager.StackInfo getFocusedStackInfo() throws RemoteException { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { - ActivityStack focusedStack = mAm.getFocusedStack(); + ActivityStack focusedStack = getFocusedStack(); if (focusedStack != null) { return mStackSupervisor.getStackInfo(focusedStack.mStackId); } @@ -1211,7 +1421,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setFocusedStack(int stackId) { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()"); if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId); final long callingId = Binder.clearCallingIdentity(); try { @@ -1234,7 +1444,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setFocusedTask(int taskId) { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()"); if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId); final long callingId = Binder.clearCallingIdentity(); try { @@ -1255,7 +1465,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean removeTask(int taskId) { - mAm.enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()"); + enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { @@ -1312,7 +1522,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { - mAm.enforceNotIsolatedCaller("moveActivityTaskToBack"); + enforceNotIsolatedCaller("moveActivityTaskToBack"); synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); try { @@ -1330,7 +1540,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public Rect getTaskBounds(int taskId) { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()"); long ident = Binder.clearCallingIdentity(); Rect rect = new Rect(); try { @@ -1364,7 +1574,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public ActivityManager.TaskDescription getTaskDescription(int id) { synchronized (mGlobalLock) { - mAm.enforceCallerIsRecentsOrHasPermission( + enforceCallerIsRecentsOrHasPermission( MANAGE_ACTIVITY_STACKS, "getTaskDescription()"); final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS); @@ -1382,7 +1592,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { toTop, ANIMATE, null /* initialBounds */, true /* showRecents */); return; } - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { @@ -1414,7 +1624,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public String getCallingPackage(IBinder token) { - synchronized (this) { + synchronized (mGlobalLock) { ActivityRecord r = getCallingRecordLocked(token); return r != null ? r.info.packageName : null; } @@ -1422,7 +1632,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public ComponentName getCallingActivity(IBinder token) { - synchronized (this) { + synchronized (mGlobalLock) { ActivityRecord r = getCallingRecordLocked(token); return r != null ? r.intent.getComponent() : null; } @@ -1438,12 +1648,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void unhandledBack() { - mAm.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()"); + mAmInternal.enforceCallingPermission(android.Manifest.permission.FORCE_BACK, "unhandledBack()"); synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); try { - mAm.getFocusedStack().unhandledBackLocked(); + getFocusedStack().unhandledBackLocked(); } finally { Binder.restoreCallingIdentity(origId); } @@ -1455,7 +1665,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void moveTaskToFront(int taskId, int flags, Bundle bOptions) { - mAm.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()"); + mAmInternal.enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()"); if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId); synchronized (mGlobalLock) { @@ -1467,7 +1677,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { void moveTaskToFrontLocked(int taskId, int flags, SafeActivityOptions options, boolean fromRecents) { - if (!mAm.checkAppSwitchAllowedLocked(Binder.getCallingPid(), + if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), Binder.getCallingUid(), -1, -1, "Task to front")) { SafeActivityOptions.abort(options); return; @@ -1503,6 +1713,69 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { SafeActivityOptions.abort(options); } + boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, + int callingPid, int callingUid, String name) { + 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 + public void setActivityController(IActivityController controller, boolean imAMonkey) { + mAmInternal.enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, + "setActivityController()"); + synchronized (mGlobalLock) { + mController = controller; + mControllerIsAMonkey = imAMonkey; + Watchdog.getInstance().setActivityController(controller); + } + } + + boolean isControllerAMonkey() { + synchronized (mGlobalLock) { + return mController != null && mControllerIsAMonkey; + } + } + @Override public int getTaskForActivity(IBinder token, boolean onlyRoot) { synchronized (mGlobalLock) { @@ -1525,7 +1798,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum); - final boolean allowed = mAm.isGetTasksAllowed("getTasks", Binder.getCallingPid(), + final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), callingUid); mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, callingUid, allowed); @@ -1548,7 +1821,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean willActivityBeVisible(IBinder token) { - synchronized(this) { + synchronized (mGlobalLock) { ActivityStack stack = ActivityRecord.getStackLocked(token); if (stack != null) { return stack.willActivityBeVisibleLocked(token); @@ -1559,7 +1832,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void moveTaskToStack(int taskId, int stackId, boolean toTop) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { @@ -1582,7 +1855,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + taskId + " to stack " + stackId); } if (stack.inSplitScreenPrimaryWindowingMode()) { - mAm.mWindowManager.setDockedStackCreateState( + mWindowManager.setDockedStackCreateState( SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */); } task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, @@ -1596,7 +1869,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode, boolean preserveWindows, boolean animate, int animationDuration) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); final long ident = Binder.clearCallingIdentity(); try { @@ -1648,7 +1921,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingModeSplitScreenPrimary()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); @@ -1666,7 +1939,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + " non-standard task " + taskId + " to split-screen windowing mode"); } - mAm.mWindowManager.setDockedStackCreateState(createMode, initialBounds); + mWindowManager.setDockedStackCreateState(createMode, initialBounds); final int windowingMode = task.getWindowingMode(); final ActivityStack stack = task.getStack(); if (toTop) { @@ -1687,7 +1960,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void removeStacksInWindowingModes(int[] windowingModes) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStacksInWindowingModes()"); synchronized (mGlobalLock) { @@ -1702,7 +1975,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void removeStacksWithActivityTypes(int[] activityTypes) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStacksWithActivityTypes()"); synchronized (mGlobalLock) { @@ -1719,12 +1992,12 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { final int callingUid = Binder.getCallingUid(); - userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, - false, ALLOW_FULL_ONLY, "getRecentTasks", null); - final boolean allowed = mAm.isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), + userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, "getRecentTasks"); + final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(), callingUid); - final boolean detailed = mAm.checkCallingPermission( - android.Manifest.permission.GET_DETAILED_TASKS) + final boolean detailed = checkGetTasksPermission( + android.Manifest.permission.GET_DETAILED_TASKS, Binder.getCallingPid(), + UserHandle.getAppId(callingUid)) == PackageManager.PERMISSION_GRANTED; synchronized (mGlobalLock) { @@ -1735,7 +2008,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public List<ActivityManager.StackInfo> getAllStackInfos() { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -1748,7 +2021,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -1761,13 +2034,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void cancelRecentsAnimation(boolean restoreHomeStackPosition) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelRecentsAnimation()"); final long callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { // Cancel the recents animation synchronously (do not hold the WM lock) - mAm.mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition + mWindowManager.cancelRecentsAnimationSynchronously(restoreHomeStackPosition ? REORDER_MOVE_TO_ORIGINAL_POSITION : REORDER_KEEP_IN_PLACE, "cancelRecentsAnimation/uid=" + callingUid); } @@ -1789,7 +2062,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void startSystemLockTaskMode(int taskId) throws RemoteException { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode"); // This makes inner call to look as if it was initiated by system. long ident = Binder.clearCallingIdentity(); try { @@ -1822,7 +2095,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void stopSystemLockTaskMode() throws RemoteException { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopSystemLockTaskMode"); stopLockTaskModeInternal(null, true /* isSystemCaller */); } @@ -1979,7 +2252,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, AssistContent content, Uri referrer) { - PendingAssistExtras pae = (PendingAssistExtras)token; + PendingAssistExtras pae = (PendingAssistExtras) token; synchronized (pae) { pae.result = extras; pae.structure = structure; @@ -2003,13 +2276,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { buildAssistBundleLocked(pae, extras); boolean exists = mPendingAssistExtras.remove(pae); - mAm.mUiHandler.removeCallbacks(pae); + mUiHandler.removeCallbacks(pae); if (!exists) { // Timed out. return; } - if ((sendReceiver=pae.receiver) != null) { + if ((sendReceiver = pae.receiver) != null) { // Caller wants result sent back to them. sendBundle = new Bundle(); sendBundle.putBundle(ASSIST_KEY_DATA, pae.extras); @@ -2037,7 +2310,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); - mAm.closeSystemDialogs("assist"); + mAmInternal.closeSystemDialogs("assist"); try { mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle)); @@ -2068,11 +2341,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { throw new IllegalArgumentException("Intent " + intent + " must specify explicit component"); } - if (thumbnail.getWidth() != mAm.mThumbnailWidth - || thumbnail.getHeight() != mAm.mThumbnailHeight) { + if (thumbnail.getWidth() != mThumbnailWidth + || thumbnail.getHeight() != mThumbnailHeight) { throw new IllegalArgumentException("Bad thumbnail size: got " + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " - + mAm.mThumbnailWidth + "x" + mAm.mThumbnailHeight); + + mThumbnailWidth + "x" + mThumbnailHeight); } if (intent.getSelector() != null) { intent.setSelector(null); @@ -2118,7 +2391,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public Point getAppTaskThumbnailSize() { synchronized (mGlobalLock) { - return new Point(mAm.mThumbnailWidth, mAm.mThumbnailHeight); + return new Point(mThumbnailWidth, mThumbnailHeight); } } @@ -2137,7 +2410,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void resizeTask(int taskId, Rect bounds, int resizeMode) { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2215,7 +2488,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing, int secondaryDisplayShowing) { - if (mAm.checkCallingPermission(android.Manifest.permission.DEVICE_POWER) + if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires permission " + android.Manifest.permission.DEVICE_POWER); @@ -2235,14 +2508,25 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - mAm.mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0) - .sendToTarget(); + mH.post(() -> { + for (int i = mScreenObservers.size() - 1; i >= 0; i--) { + mScreenObservers.get(i).onKeyguardStateChanged(keyguardShowing); + } + }); + } + + void onScreenAwakeChanged(boolean isAwake) { + mH.post(() -> { + for (int i = mScreenObservers.size() - 1; i >= 0; i--) { + mScreenObservers.get(i).onAwakeStateChanged(isAwake); + } + }); } @Override public Bitmap getTaskDescriptionIcon(String filePath, int userId) { - userId = mAm.mUserController.handleIncomingUser(Binder.getCallingPid(), - Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null); + userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, "getTaskDescriptionIcon"); final File passedIconFile = new File(filePath); final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), @@ -2256,8 +2540,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } @Override - public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) - throws RemoteException { + public void startInPlaceAnimationOnFrontMostApplication(Bundle opts) { final SafeActivityOptions safeOptions = SafeActivityOptions.fromBundle(opts); final ActivityOptions activityOptions = safeOptions != null ? safeOptions.getOptions(mStackSupervisor) @@ -2268,15 +2551,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { throw new IllegalArgumentException("Expected in-place ActivityOption " + "with valid animation"); } - mAm.mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false); - mAm.mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(), + mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false); + mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(), activityOptions.getCustomInPlaceResId()); - mAm.mWindowManager.executeAppTransition(); + mWindowManager.executeAppTransition(); } @Override public void removeStack(int stackId) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "removeStack()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); try { @@ -2298,7 +2581,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void moveStackToDisplay(int stackId, int displayId) { - mAm.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()"); + mAmInternal.enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()"); synchronized (mGlobalLock) { final long ident = Binder.clearCallingIdentity(); @@ -2314,7 +2597,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public int createStackOnDisplay(int displayId) { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()"); synchronized (mGlobalLock) { final ActivityDisplay display = mStackSupervisor.getActivityDisplayOrCreateLocked(displayId); @@ -2356,7 +2639,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** Sets the task stack listener that gets callbacks when a task stack changes. */ @Override public void registerTaskStackListener(ITaskStackListener listener) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()"); mTaskChangeNotificationController.registerTaskStackListener(listener); } @@ -2364,7 +2647,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { /** Unregister a task stack listener so that it stops receiving callbacks. */ @Override public void unregisterTaskStackListener(ITaskStackListener listener) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()"); mTaskChangeNotificationController.unregisterTaskStackListener(listener); } @@ -2418,20 +2701,78 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { synchronized (mGlobalLock) { buildAssistBundleLocked(pae, pae.result); mPendingAssistExtras.remove(pae); - mAm.mUiHandler.removeCallbacks(pae); + mUiHandler.removeCallbacks(pae); } return pae.extras; } + /** + * Binder IPC calls go through the public entry point. + * This can be called with or without the global lock held. + */ + private static int checkCallingPermission(String permission) { + return checkPermission( + permission, Binder.getCallingPid(), UserHandle.getAppId(Binder.getCallingUid())); + } + + /** This can be called with or without the global lock held. */ + void enforceCallerIsRecentsOrHasPermission(String permission, String func) { + if (!getRecentTasks().isCallerRecents(Binder.getCallingUid())) { + mAmInternal.enforceCallingPermission(permission, func); + } + } + + @VisibleForTesting + int checkGetTasksPermission(String permission, int pid, int uid) { + return checkPermission(permission, pid, uid); + } + + static int checkPermission(String permission, int pid, int uid) { + if (permission == null) { + return PackageManager.PERMISSION_DENIED; + } + return checkComponentPermission(permission, pid, uid, -1, true); + } + + boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { + if (getRecentTasks().isCallerRecents(callingUid)) { + // Always allow the recents component to get tasks + return true; + } + + boolean allowed = checkGetTasksPermission(android.Manifest.permission.REAL_GET_TASKS, + callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; + if (!allowed) { + if (checkGetTasksPermission(android.Manifest.permission.GET_TASKS, + callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { + // Temporary compatibility: some existing apps on the system image may + // still be requesting the old permission and not switched to the new + // one; if so, we'll still allow them full access. This means we need + // to see if they are holding the old permission and are a system app. + try { + if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) { + allowed = true; + if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid + + " is using old GET_TASKS but privileged; allowing"); + } + } catch (RemoteException e) { + } + } + if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid + + " does not hold REAL_GET_TASKS; limiting output"); + } + return allowed; + } + private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint, IAssistDataReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout, int flags) { - mAm.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, + mAmInternal.enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, "enqueueAssistContext()"); synchronized (mGlobalLock) { - ActivityRecord activity = mAm.getFocusedStack().getTopActivity(); + ActivityRecord activity = getFocusedStack().getTopActivity(); if (activity == null) { Slog.w(TAG, "getAssistContextExtras failed: no top activity"); return null; @@ -2482,7 +2823,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType, mViSessionId, flags); mPendingAssistExtras.add(pae); - mAm.mUiHandler.postDelayed(pae, timeout); + mUiHandler.postDelayed(pae, timeout); } catch (RemoteException e) { Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); return null; @@ -2559,7 +2900,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public boolean isAssistDataAllowedOnCurrentActivity() { int userId; synchronized (mGlobalLock) { - final ActivityStack focusedStack = mAm.getFocusedStack(); + final ActivityStack focusedStack = getFocusedStack(); if (focusedStack == null || focusedStack.isActivityTypeAssistant()) { return false; } @@ -2579,7 +2920,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { try { synchronized (mGlobalLock) { ActivityRecord caller = ActivityRecord.forTokenLocked(token); - ActivityRecord top = mAm.getFocusedStack().getTopActivity(); + ActivityRecord top = getFocusedStack().getTopActivity(); if (top != caller) { Slog.w(TAG, "showAssistFromActivity failed: caller " + caller + " is not current top " + top); @@ -2644,7 +2985,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void keyguardGoingAway(int flags) { - mAm.enforceNotIsolatedCaller("keyguardGoingAway"); + enforceNotIsolatedCaller("keyguardGoingAway"); final long token = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2662,7 +3003,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void positionTaskInStack(int taskId, int stackId, int position) { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()"); synchronized (mGlobalLock) { long ident = Binder.clearCallingIdentity(); try { @@ -2723,7 +3064,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void dismissSplitScreenMode(boolean toTop) { - mAm.enforceCallerIsRecentsOrHasPermission( + enforceCallerIsRecentsOrHasPermission( MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()"); final long ident = Binder.clearCallingIdentity(); try { @@ -2765,7 +3106,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public void dismissPip(boolean animate, int animationDuration) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -2793,7 +3134,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void suppressResizeConfigChanges(boolean suppress) throws RemoteException { - mAm.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); + mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()"); synchronized (mGlobalLock) { mSuppressResizeConfigChanges = suppress; } @@ -2807,7 +3148,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override // TODO: API should just be about changing windowing modes... public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()"); synchronized (mGlobalLock) { final long origId = Binder.clearCallingIdentity(); @@ -2837,10 +3178,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ @Override public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()"); synchronized (mGlobalLock) { - if (!mAm.mSupportsPictureInPicture) { + if (!mSupportsPictureInPicture) { throw new IllegalStateException("moveTopActivityToPinnedStack:" + "Device doesn't support picture-in-picture mode"); } @@ -2942,8 +3283,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // device is currently locked). dismissKeyguard(token, new KeyguardDismissCallback() { @Override - public void onDismissSucceeded() throws RemoteException { - mAm.mHandler.post(enterPipRunnable); + public void onDismissSucceeded() { + mH.post(enterPipRunnable); } }, null /* message */); } else { @@ -3012,7 +3353,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { */ private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller, IBinder token, PictureInPictureParams params) { - if (!mAm.mSupportsPictureInPicture) { + if (!mSupportsPictureInPicture) { throw new IllegalStateException(caller + ": Device doesn't support picture-in-picture mode."); } @@ -3029,7 +3370,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } if (params.hasSetAspectRatio() - && !mAm.mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId, + && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId, params.getAspectRatio())) { final float minAspectRatio = mContext.getResources().getFloat( com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio); @@ -3048,7 +3389,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) { - mAm.enforceNotIsolatedCaller("getUriPermissionOwnerForActivity"); + enforceNotIsolatedCaller("getUriPermissionOwnerForActivity"); synchronized (mGlobalLock) { ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); if (r == null) { @@ -3063,7 +3404,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeDockedStack()"); long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -3078,7 +3419,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setSplitScreenResizing(boolean resizing) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setSplitScreenResizing()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -3089,9 +3430,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } + /** + * Check that we have the features required for VR-related API calls, and throw an exception if + * not. + */ + void enforceSystemHasVrFeature() { + if (!mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE)) { + throw new UnsupportedOperationException("VR mode not supported on this device!"); + } + } + @Override public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) { - mAm.enforceSystemHasVrFeature(); + enforceSystemHasVrFeature(); final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class); @@ -3131,7 +3483,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options) { Slog.i(TAG, "Activity tried to startLocalVoiceInteraction"); synchronized (mGlobalLock) { - ActivityRecord activity = mAm.getFocusedStack().getTopActivity(); + ActivityRecord activity = getFocusedStack().getTopActivity(); if (ActivityRecord.forTokenLocked(callingActivity) != activity) { throw new SecurityException("Only focused activity can call startVoiceInteraction"); } @@ -3176,7 +3528,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()"); + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizePinnedStack()"); final long ident = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { @@ -3189,7 +3541,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) { - mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()"); + mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()"); synchronized (mGlobalLock) { // Check if display is initialized in AM. @@ -3202,14 +3554,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { return false; } - if (values == null && mAm.mWindowManager != null) { + if (values == null && mWindowManager != null) { // sentinel: fetch the current configuration from the window manager - values = mAm.mWindowManager.computeNewConfiguration(displayId); + values = mWindowManager.computeNewConfiguration(displayId); } - if (mAm.mWindowManager != null) { + if (mWindowManager != null) { // Update OOM levels based on display size. - mAm.mProcessList.applyDisplaySize(mAm.mWindowManager); + mAm.mProcessList.applyDisplaySize(mWindowManager); } final long origId = Binder.clearCallingIdentity(); @@ -3217,7 +3569,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (values != null) { Settings.System.clearConfiguration(values); } - mAm.updateDisplayOverrideConfigurationLocked(values, null /* starting */, + updateDisplayOverrideConfigurationLocked(values, null /* starting */, false /* deferResume */, displayId, mTmpUpdateConfigurationResult); return mTmpUpdateConfigurationResult.changes != 0; } finally { @@ -3228,17 +3580,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public boolean updateConfiguration(Configuration values) { - mAm.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()"); + mAmInternal.enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()"); synchronized (mGlobalLock) { - if (values == null && mAm.mWindowManager != null) { + if (values == null && mWindowManager != null) { // sentinel: fetch the current configuration from the window manager - values = mAm.mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); + values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY); } - if (mAm.mWindowManager != null) { + if (mWindowManager != null) { // Update OOM levels based on display size. - mAm.mProcessList.applyDisplaySize(mAm.mWindowManager); + mAm.mProcessList.applyDisplaySize(mWindowManager); } final long origId = Binder.clearCallingIdentity(); @@ -3246,7 +3598,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { if (values != null) { Settings.System.clearConfiguration(values); } - mAm.updateConfigurationLocked(values, null, false, false /* persistent */, + updateConfigurationLocked(values, null, false, false /* persistent */, UserHandle.USER_NULL, false /* deferResume */, mTmpUpdateConfigurationResult); return mTmpUpdateConfigurationResult.changes != 0; @@ -3260,7 +3612,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback, CharSequence message) { if (message != null) { - mAm.enforceCallingPermission( + mAmInternal.enforceCallingPermission( Manifest.permission.SHOW_KEYGUARD_MESSAGE, "dismissKeyguard()"); } final long callingId = Binder.clearCallingIdentity(); @@ -3275,7 +3627,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void cancelTaskWindowTransition(int taskId) { - mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()"); final long ident = Binder.clearCallingIdentity(); try { @@ -3295,7 +3647,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) { - mAm.enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); + enforceCallerIsRecentsOrHasPermission(READ_FRAME_BUFFER, "getTaskSnapshot()"); final long ident = Binder.clearCallingIdentity(); try { final TaskRecord task; @@ -3336,11 +3688,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public @UserIdInt int getLastResumedActivityUserId() { - mAm.enforceCallingPermission( + mAmInternal.enforceCallingPermission( Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()"); synchronized (mGlobalLock) { if (mAm.mLastResumedActivity == null) { - return mAm.mUserController.getCurrentUserId(); + return getCurrentUserId(); } return mAm.mLastResumedActivity.userId; } @@ -3350,7 +3702,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void updateLockTaskFeatures(int userId, int flags) { final int callingUid = Binder.getCallingUid(); if (callingUid != 0 && callingUid != SYSTEM_UID) { - mAm.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, + mAmInternal.enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES, "updateLockTaskFeatures()"); } synchronized (mGlobalLock) { @@ -3394,7 +3746,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void registerRemoteAnimations(IBinder token, RemoteAnimationDefinition definition) { - mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, + mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, "registerRemoteAnimations"); definition.setCallingPid(Binder.getCallingPid()); synchronized (mGlobalLock) { @@ -3414,7 +3766,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void registerRemoteAnimationForNextActivityStart(String packageName, RemoteAnimationAdapter adapter) { - mAm.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, + mAmInternal.enforceCallingPermission(CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, "registerRemoteAnimationForNextActivityStart"); adapter.setCallingPid(Binder.getCallingPid()); synchronized (mGlobalLock) { @@ -3443,7 +3795,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setVrThread(int tid) { - mAm.enforceSystemHasVrFeature(); + enforceSystemHasVrFeature(); synchronized (mGlobalLock) { synchronized (mAm.mPidsSelfLocked) { final int pid = Binder.getCallingPid(); @@ -3455,7 +3807,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void setPersistentVrThread(int tid) { - if (mAm.checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS) + if (checkCallingPermission(Manifest.permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) { final String msg = "Permission Denial: setPersistentVrThread() from pid=" + Binder.getCallingPid() @@ -3464,7 +3816,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { Slog.w(TAG, msg); throw new SecurityException(msg); } - mAm.enforceSystemHasVrFeature(); + enforceSystemHasVrFeature(); synchronized (mGlobalLock) { synchronized (mAm.mPidsSelfLocked) { final int pid = Binder.getCallingPid(); @@ -3474,9 +3826,41 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { } } - /** - * @return whether the system should disable UI modes incompatible with VR mode. - */ + @Override + public void stopAppSwitches() { + enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "stopAppSwitches"); + synchronized (mGlobalLock) { + mAppSwitchesAllowedTime = SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME; + mDidAppSwitch = false; + getActivityStartController().schedulePendingActivityLaunches(APP_SWITCH_DELAY_TIME); + } + } + + @Override + public void resumeAppSwitches() { + enforceCallerIsRecentsOrHasPermission(STOP_APP_SWITCHES, "resumeAppSwitches"); + synchronized (mGlobalLock) { + // Note that we don't execute any pending app switches... we will + // let those wait until either the timeout, or the next start + // activity request. + mAppSwitchesAllowedTime = 0; + } + } + + 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. */ boolean shouldDisableNonVrUiLocked() { return mVrController.shouldDisableNonVrUiLocked(); } @@ -3512,6 +3896,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { }); } + ActivityStack getFocusedStack() { + return mStackSupervisor.getFocusedStack(); + } + /** Pokes the task persister. */ void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { mRecentTasks.notifyTaskPersisterLocked(task, flush); @@ -3540,12 +3928,398 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mVrController.writeToProto(proto, fieldId); } + int getCurrentUserId() { + return mAmInternal.getCurrentUserId(); + } + + private void enforceNotIsolatedCaller(String caller) { + if (UserHandle.isIsolated(Binder.getCallingUid())) { + throw new SecurityException("Isolated process not allowed to call " + caller); + } + } + + /** + * Current global configuration information. Contains general settings for the entire system, + * also corresponds to the merged configuration of the default display. + */ + Configuration getGlobalConfiguration() { + return mStackSupervisor.getConfiguration(); + } + + boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, + boolean initLocale) { + return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */); + } + + boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, + boolean initLocale, boolean deferResume) { + // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user + return updateConfigurationLocked(values, starting, initLocale, false /* persistent */, + UserHandle.USER_NULL, deferResume); + } + + void updatePersistentConfiguration(Configuration values, @UserIdInt int userId) { + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + updateConfigurationLocked(values, null, false, true, userId, + false /* deferResume */); + } + } finally { + Binder.restoreCallingIdentity(origId); + } + } + + void updateUserConfiguration() { + synchronized (mGlobalLock) { + final Configuration configuration = new Configuration(getGlobalConfiguration()); + final int currentUserId = mAmInternal.getCurrentUserId(); + Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration, + currentUserId, Settings.System.canWrite(mContext)); + updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */, + false /* persistent */, currentUserId, false /* deferResume */); + } + } + + private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, + boolean initLocale, boolean persistent, int userId, boolean deferResume) { + return updateConfigurationLocked(values, starting, initLocale, persistent, userId, + deferResume, null /* result */); + } + + /** + * Do either or both things: (1) change the current configuration, and (2) + * make sure the given activity is running with the (now) current + * configuration. Returns true if the activity has been left running, or + * false if <var>starting</var> is being destroyed to match the new + * configuration. + * + * @param userId is only used when persistent parameter is set to true to persist configuration + * for that particular user + */ + boolean updateConfigurationLocked(Configuration values, ActivityRecord starting, + boolean initLocale, boolean persistent, int userId, boolean deferResume, + ActivityTaskManagerService.UpdateConfigurationResult result) { + int changes = 0; + boolean kept = true; + + if (mWindowManager != null) { + mWindowManager.deferSurfaceLayout(); + } + try { + if (values != null) { + changes = updateGlobalConfigurationLocked(values, initLocale, persistent, userId, + deferResume); + } + + kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); + } finally { + if (mWindowManager != null) { + mWindowManager.continueSurfaceLayout(); + } + } + + if (result != null) { + result.changes = changes; + result.activityRelaunched = !kept; + } + return kept; + } + + /** + * Returns true if this configuration change is interesting enough to send an + * {@link Intent#ACTION_SPLIT_CONFIGURATION_CHANGED} broadcast. + */ + private static boolean isSplitConfigurationChange(int configDiff) { + return (configDiff & (ActivityInfo.CONFIG_LOCALE | ActivityInfo.CONFIG_DENSITY)) != 0; + } + + /** Update default (global) configuration and notify listeners about changes. */ + private int updateGlobalConfigurationLocked(@NonNull Configuration values, boolean initLocale, + boolean persistent, int userId, boolean deferResume) { + mTempConfig.setTo(getGlobalConfiguration()); + final int changes = mTempConfig.updateFrom(values); + if (changes == 0) { + // Since calling to Activity.setRequestedOrientation leads to freezing the window with + // setting WindowManagerService.mWaitingForConfig to true, it is important that we call + // performDisplayOverrideConfigUpdate in order to send the new display configuration + // (even if there are no actual changes) to unfreeze the window. + performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY); + return 0; + } + + if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION, + "Updating global configuration to: " + values); + + EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); + StatsLog.write(StatsLog.RESOURCE_CONFIGURATION_CHANGED, + values.colorMode, + values.densityDpi, + values.fontScale, + values.hardKeyboardHidden, + values.keyboard, + values.keyboardHidden, + values.mcc, + values.mnc, + values.navigation, + values.navigationHidden, + values.orientation, + values.screenHeightDp, + values.screenLayout, + values.screenWidthDp, + values.smallestScreenWidthDp, + values.touchscreen, + values.uiMode); + + + if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) { + final LocaleList locales = values.getLocales(); + int bestLocaleIndex = 0; + if (locales.size() > 1) { + if (mSupportedSystemLocales == null) { + mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales(); + } + bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales)); + } + SystemProperties.set("persist.sys.locale", + locales.get(bestLocaleIndex).toLanguageTag()); + LocaleList.setDefault(locales, bestLocaleIndex); + mAm.mHandler.sendMessage(mAm.mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, + locales.get(bestLocaleIndex))); + } + + mConfigurationSeq = Math.max(++mConfigurationSeq, 1); + mTempConfig.seq = mConfigurationSeq; + + // Update stored global config and notify everyone about the change. + mStackSupervisor.onConfigurationChanged(mTempConfig); + + Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig); + // TODO(multi-display): Update UsageEvents#Event to include displayId. + mAm.mUsageStatsService.reportConfigurationChange( + mTempConfig, mAmInternal.getCurrentUserId()); + + // TODO: If our config changes, should we auto dismiss any currently showing dialogs? + mAm.updateShouldShowDialogsLocked(mTempConfig); + + AttributeCache ac = AttributeCache.instance(); + if (ac != null) { + ac.updateConfiguration(mTempConfig); + } + + // Make sure all resources in our process are updated right now, so that anyone who is going + // to retrieve resource values after we return will be sure to get the new ones. This is + // especially important during boot, where the first config change needs to guarantee all + // resources have that config before following boot code is executed. + mAm.mSystemThread.applyConfigurationToResources(mTempConfig); + + // We need another copy of global config because we're scheduling some calls instead of + // running them in place. We need to be sure that object we send will be handled unchanged. + final Configuration configCopy = new Configuration(mTempConfig); + if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { + Message msg = mAm.mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); + msg.obj = configCopy; + msg.arg1 = userId; + mAm.mHandler.sendMessage(msg); + } + + for (int i = mAm.mLruProcesses.size() - 1; i >= 0; i--) { + ProcessRecord app = mAm.mLruProcesses.get(i); + try { + if (app.thread != null) { + if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc " + + app.processName + " new config " + configCopy); + getLifecycleManager().scheduleTransaction(app.thread, + ConfigurationChangeItem.obtain(configCopy)); + } + } catch (Exception e) { + Slog.e(TAG_CONFIGURATION, "Failed to schedule configuration change", e); + } + } + + Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING + | Intent.FLAG_RECEIVER_FOREGROUND + | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); + mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, + OP_NONE, null, false, false, MY_PID, SYSTEM_UID, + UserHandle.USER_ALL); + if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) { + intent = new Intent(Intent.ACTION_LOCALE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND + | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS); + if (initLocale || !mAm.mProcessesReady) { + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + } + mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null, + OP_NONE, null, false, false, MY_PID, SYSTEM_UID, + UserHandle.USER_ALL); + } + + // Send a broadcast to PackageInstallers if the configuration change is interesting + // for the purposes of installing additional splits. + if (!initLocale && isSplitConfigurationChange(changes)) { + intent = new Intent(Intent.ACTION_SPLIT_CONFIGURATION_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING + | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); + + // Typically only app stores will have this permission. + String[] permissions = new String[] { android.Manifest.permission.INSTALL_PACKAGES }; + mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, permissions, + OP_NONE, null, false, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL); + } + + // Override configuration of the default display duplicates global config, so we need to + // update it also. This will also notify WindowManager about changes. + performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume, + DEFAULT_DISPLAY); + + return changes; + } + + boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting, + boolean deferResume, int displayId) { + return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */, + displayId, null /* result */); + } + + /** + * Updates override configuration specific for the selected display. If no config is provided, + * new one will be computed in WM based on current display info. + */ + boolean updateDisplayOverrideConfigurationLocked(Configuration values, + ActivityRecord starting, boolean deferResume, int displayId, + ActivityTaskManagerService.UpdateConfigurationResult result) { + int changes = 0; + boolean kept = true; + + if (mWindowManager != null) { + mWindowManager.deferSurfaceLayout(); + } + try { + if (values != null) { + if (displayId == DEFAULT_DISPLAY) { + // Override configuration of the default display duplicates global config, so + // we're calling global config update instead for default display. It will also + // apply the correct override config. + changes = updateGlobalConfigurationLocked(values, false /* initLocale */, + false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume); + } else { + changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId); + } + } + + kept = ensureConfigAndVisibilityAfterUpdate(starting, changes); + } finally { + if (mWindowManager != null) { + mWindowManager.continueSurfaceLayout(); + } + } + + if (result != null) { + result.changes = changes; + result.activityRelaunched = !kept; + } + return kept; + } + + private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume, + int displayId) { + mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId)); + final int changes = mTempConfig.updateFrom(values); + if (changes != 0) { + Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " " + + mTempConfig + " for displayId=" + displayId); + mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId); + + final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0; + if (isDensityChange && displayId == DEFAULT_DISPLAY) { + mAm.mAppWarnings.onDensityChanged(); + + mAm.killAllBackgroundProcessesExcept(N, + ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); + } + } + + // Update the configuration with WM first and check if any of the stacks need to be resized + // due to the configuration change. If so, resize the stacks now and do any relaunches if + // necessary. This way we don't need to relaunch again afterwards in + // ensureActivityConfiguration(). + if (mWindowManager != null) { + final int[] resizedStacks = + mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId); + if (resizedStacks != null) { + for (int stackId : resizedStacks) { + resizeStackWithBoundsFromWindowManager(stackId, deferResume); + } + } + } + + return changes; + } + + /** Helper method that requests bounds from WM and applies them to stack. */ + private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) { + final Rect newStackBounds = new Rect(); + final ActivityStack stack = mStackSupervisor.getStack(stackId); + + // TODO(b/71548119): Revert CL introducing below once cause of mismatch is found. + if (stack == null) { + final StringWriter writer = new StringWriter(); + final PrintWriter printWriter = new PrintWriter(writer); + mStackSupervisor.dumpDisplays(printWriter); + printWriter.flush(); + + Log.wtf(TAG, "stack not found:" + stackId + " displays:" + writer); + } + + stack.getBoundsForNewConfiguration(newStackBounds); + mStackSupervisor.resizeStackLocked( + stack, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */, + null /* tempTaskBounds */, null /* tempTaskInsetBounds */, + false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume); + } + + /** Applies latest configuration and/or visibility updates if needed. */ + private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) { + boolean kept = true; + final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); + // mainStack is null during startup. + if (mainStack != null) { + if (changes != 0 && starting == null) { + // If the configuration changed, and the caller is not already + // in the process of starting an activity, then find the top + // activity to check if its configuration needs to change. + starting = mainStack.topRunningActivityLocked(); + } + + if (starting != null) { + kept = starting.ensureActivityConfiguration(changes, + false /* preserveWindow */); + // And we need to make sure at this point that all other activities + // are made visible with the correct configuration. + mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes, + !PRESERVE_WINDOWS); + } + } + + return kept; + } + final class H extends Handler { public H(Looper looper) { super(looper, null, true); } } + final class UiHandler extends Handler { + + public UiHandler() { + super(com.android.server.UiThread.get().getLooper(), null, true); + } + } + final class LocalService extends ActivityTaskManagerInternal { @Override public SleepToken acquireSleepToken(String tag, int displayId) { @@ -3657,9 +4431,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // We might change the visibilities here, so prepare an empty app transition which // might be overridden later if we actually change visibilities. final boolean wasTransitionSet = - mAm.mWindowManager.getPendingAppTransition() != TRANSIT_NONE; + mWindowManager.getPendingAppTransition() != TRANSIT_NONE; if (!wasTransitionSet) { - mAm.mWindowManager.prepareAppTransition(TRANSIT_NONE, + mWindowManager.prepareAppTransition(TRANSIT_NONE, false /* alwaysKeepCurrent */); } mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); @@ -3667,7 +4441,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { // If there was a transition set already we don't want to interfere with it as we // might be starting it too early. if (!wasTransitionSet) { - mAm.mWindowManager.executeAppTransition(); + mWindowManager.executeAppTransition(); } } if (callback != null) { @@ -3693,7 +4467,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { public void setVr2dDisplayId(int vr2dDisplayId) { if (DEBUG_STACK) Slog.d(TAG, "setVr2dDisplayId called for: " + vr2dDisplayId); synchronized (mGlobalLock) { - mAm.mVr2dDisplayId = vr2dDisplayId; + mVr2dDisplayId = vr2dDisplayId; } } @@ -3734,7 +4508,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void registerScreenObserver(ScreenObserver observer) { - mAm.mScreenObservers.add(observer); + mScreenObservers.add(observer); } @Override @@ -3754,7 +4528,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @Override public void enforceCallerIsRecentsOrHasPermission(String permission, String func) { - mAm.enforceCallerIsRecentsOrHasPermission(permission, func); + ActivityTaskManagerService.this.enforceCallerIsRecentsOrHasPermission(permission, func); } @Override @@ -3763,5 +4537,43 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { mActiveVoiceInteractionServiceComponent = component; } } + + @Override + public void setAllowAppSwitches(@NonNull String type, int uid, int userId) { + if (!mAmInternal.isUserRunning(userId, ActivityManager.FLAG_OR_STOPPED)) { + return; + } + synchronized (mGlobalLock) { + ArrayMap<String, Integer> types = mAllowAppSwitchUids.get(userId); + if (types == null) { + if (uid < 0) { + return; + } + types = new ArrayMap<>(); + mAllowAppSwitchUids.put(userId, types); + } + if (uid < 0) { + types.remove(type); + } else { + types.put(type, uid); + } + } + } + + @Override + public void onUserStopped(int userId) { + synchronized (mGlobalLock) { + getRecentTasks().unloadUserDataFromMemoryLocked(userId); + mAllowAppSwitchUids.remove(userId); + } + } + + @Override + public boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { + synchronized (mGlobalLock) { + return ActivityTaskManagerService.this.isGetTasksAllowed( + caller, callingPid, callingUid); + } + } } } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index eac35011549e..5719490ad1ba 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -532,7 +532,7 @@ class AppErrors { String shortMsg, String longMsg, String stackTrace, long timeMillis, int callingPid, int callingUid) { - if (mService.mController == null) { + if (mService.mActivityTaskManager.mController == null) { return false; } @@ -540,7 +540,7 @@ class AppErrors { String name = r != null ? r.processName : null; int pid = r != null ? r.pid : callingPid; int uid = r != null ? r.info.uid : callingUid; - if (!mService.mController.appCrashed(name, pid, + if (!mService.mActivityTaskManager.mController.appCrashed(name, pid, shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) && "Native crash".equals(crashInfo.exceptionClassName)) { @@ -563,7 +563,7 @@ class AppErrors { return true; } } catch (RemoteException e) { - mService.mController = null; + mService.mActivityTaskManager.mController = null; Watchdog.getInstance().setActivityController(null); } return false; @@ -887,16 +887,16 @@ class AppErrors { ArrayList<Integer> firstPids = new ArrayList<Integer>(5); SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); - if (mService.mController != null) { + if (mService.mActivityTaskManager.mController != null) { try { // 0 == continue, -1 = kill process immediately - int res = mService.mController.appEarlyNotResponding( + int res = mService.mActivityTaskManager.mController.appEarlyNotResponding( app.processName, app.pid, annotation); if (res < 0 && app.pid != MY_PID) { app.kill("anr", true); } } catch (RemoteException e) { - mService.mController = null; + mService.mActivityTaskManager.mController = null; Watchdog.getInstance().setActivityController(null); } } @@ -1054,10 +1054,10 @@ class AppErrors { mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, cpuInfo, tracesFile, null); - if (mService.mController != null) { + if (mService.mActivityTaskManager.mController != null) { try { // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately - int res = mService.mController.appNotResponding( + int res = mService.mActivityTaskManager.mController.appNotResponding( app.processName, app.pid, info.toString()); if (res != 0) { if (res < 0 && app.pid != MY_PID) { @@ -1070,7 +1070,7 @@ class AppErrors { return; } } catch (RemoteException e) { - mService.mController = null; + mService.mActivityTaskManager.mController = null; Watchdog.getInstance().setActivityController(null); } } diff --git a/services/core/java/com/android/server/am/AppTaskImpl.java b/services/core/java/com/android/server/am/AppTaskImpl.java index 953d3b817078..c22dedc4073f 100644 --- a/services/core/java/com/android/server/am/AppTaskImpl.java +++ b/services/core/java/com/android/server/am/AppTaskImpl.java @@ -20,7 +20,6 @@ import static com.android.server.am.ActivityStackSupervisor.MATCH_TASK_IN_STACKS import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import android.app.ActivityManager; -import android.app.ActivityOptions; import android.app.IAppTask; import android.app.IApplicationThread; import android.content.Intent; diff --git a/services/core/java/com/android/server/am/AssistDataRequester.java b/services/core/java/com/android/server/am/AssistDataRequester.java index b54441a7343e..037f245dfc1f 100644 --- a/services/core/java/com/android/server/am/AssistDataRequester.java +++ b/services/core/java/com/android/server/am/AssistDataRequester.java @@ -49,7 +49,6 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { public static final String KEY_RECEIVER_EXTRA_COUNT = "count"; public static final String KEY_RECEIVER_EXTRA_INDEX = "index"; - private IActivityManager mService; private IWindowManager mWindowManager; private Context mContext; private AppOpsManager mAppOpsManager; @@ -118,14 +117,13 @@ public class AssistDataRequester extends IAssistDataReceiver.Stub { * This can be {@link AppOpsManager#OP_NONE} to indicate that * screenshots should never be fetched. */ - public AssistDataRequester(Context context, IActivityManager service, + public AssistDataRequester(Context context, IWindowManager windowManager, AppOpsManager appOpsManager, AssistDataRequesterCallbacks callbacks, Object callbacksLock, int requestStructureAppOps, int requestScreenshotAppOps) { mCallbacks = callbacks; mCallbacksLock = callbacksLock; mWindowManager = windowManager; - mService = service; mContext = context; mAppOpsManager = appOpsManager; mRequestStructureAppOps = requestStructureAppOps; diff --git a/services/core/java/com/android/server/am/CompatModePackages.java b/services/core/java/com/android/server/am/CompatModePackages.java index c6947abf9a26..38254b881f46 100644 --- a/services/core/java/com/android/server/am/CompatModePackages.java +++ b/services/core/java/com/android/server/am/CompatModePackages.java @@ -219,25 +219,10 @@ public final class CompatModePackages { : ActivityManager.COMPAT_MODE_DISABLED; } - public boolean getFrontActivityAskCompatModeLocked() { - ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(); - if (r == null) { - return false; - } - return getPackageAskCompatModeLocked(r.packageName); - } - public boolean getPackageAskCompatModeLocked(String packageName) { return (getPackageFlags(packageName)&COMPAT_FLAG_DONT_ASK) == 0; } - public void setFrontActivityAskCompatModeLocked(boolean ask) { - ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(); - if (r != null) { - setPackageAskCompatModeLocked(r.packageName, ask); - } - } - public void setPackageAskCompatModeLocked(String packageName, boolean ask) { setPackageFlagLocked(packageName, COMPAT_FLAG_DONT_ASK, ask); } @@ -255,23 +240,6 @@ public final class CompatModePackages { } } - public int getFrontActivityScreenCompatModeLocked() { - ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(); - if (r == null) { - return ActivityManager.COMPAT_MODE_UNKNOWN; - } - return computeCompatModeLocked(r.info.applicationInfo); - } - - public void setFrontActivityScreenCompatModeLocked(int mode) { - ActivityRecord r = mService.getFocusedStack().topRunningActivityLocked(); - if (r == null) { - Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity"); - return; - } - setPackageScreenCompatModeLocked(r.info.applicationInfo, mode); - } - public int getPackageScreenCompatModeLocked(String packageName) { ApplicationInfo ai = null; try { @@ -297,7 +265,7 @@ public final class CompatModePackages { setPackageScreenCompatModeLocked(ai, mode); } - private void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) { + void setPackageScreenCompatModeLocked(ApplicationInfo ai, int mode) { final String packageName = ai.packageName; int curFlags = getPackageFlags(packageName); @@ -349,7 +317,7 @@ public final class CompatModePackages { scheduleWrite(); - final ActivityStack stack = mService.getFocusedStack(); + final ActivityStack stack = mService.mActivityTaskManager.getFocusedStack(); ActivityRecord starting = stack.restartPackage(packageName); // Tell all processes that loaded this package about the change. diff --git a/services/core/java/com/android/server/am/LaunchParamsController.java b/services/core/java/com/android/server/am/LaunchParamsController.java index 4330d2c6efaf..6415c3ee7f72 100644 --- a/services/core/java/com/android/server/am/LaunchParamsController.java +++ b/services/core/java/com/android/server/am/LaunchParamsController.java @@ -38,7 +38,7 @@ import static com.android.server.am.LaunchParamsController.LaunchParamsModifier. * registered {@link LaunchParamsModifier}s. */ class LaunchParamsController { - private final ActivityManagerService mService; + private final ActivityTaskManagerService mService; private final List<LaunchParamsModifier> mModifiers = new ArrayList<>(); // Temporary {@link LaunchParams} for internal calculations. This is kept separate from @@ -48,7 +48,7 @@ class LaunchParamsController { private final LaunchParams mTmpCurrent = new LaunchParams(); private final LaunchParams mTmpResult = new LaunchParams(); - LaunchParamsController(ActivityManagerService service) { + LaunchParamsController(ActivityTaskManagerService service) { mService = service; } @@ -125,7 +125,7 @@ class LaunchParamsController { try { if (mTmpParams.hasPreferredDisplay() && mTmpParams.mPreferredDisplayId != task.getStack().getDisplay().mDisplayId) { - mService.mActivityTaskManager.moveStackToDisplay(task.getStackId(), mTmpParams.mPreferredDisplayId); + mService.moveStackToDisplay(task.getStackId(), mTmpParams.mPreferredDisplayId); } if (mTmpParams.hasWindowingMode() diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java index bd49bd193773..1c7ad3f33310 100644 --- a/services/core/java/com/android/server/am/RecentsAnimation.java +++ b/services/core/java/com/android/server/am/RecentsAnimation.java @@ -54,11 +54,10 @@ class RecentsAnimation implements RecentsAnimationCallbacks, private static final String TAG = RecentsAnimation.class.getSimpleName(); private static final boolean DEBUG = false; - private final ActivityManagerService mService; + private final ActivityTaskManagerService mService; private final ActivityStackSupervisor mStackSupervisor; private final ActivityStartController mActivityStartController; private final WindowManagerService mWindowManager; - private final UserController mUserController; private final ActivityDisplay mDefaultDisplay; private final int mCallingPid; @@ -68,15 +67,14 @@ class RecentsAnimation implements RecentsAnimationCallbacks, // The stack to restore the target stack behind when the animation is finished private ActivityStack mRestoreTargetBehindStack; - RecentsAnimation(ActivityManagerService am, ActivityStackSupervisor stackSupervisor, + RecentsAnimation(ActivityTaskManagerService atm, ActivityStackSupervisor stackSupervisor, ActivityStartController activityStartController, WindowManagerService wm, - UserController userController, int callingPid) { - mService = am; + int callingPid) { + mService = atm; mStackSupervisor = stackSupervisor; mDefaultDisplay = stackSupervisor.getDefaultDisplay(); mActivityStartController = activityStartController; mWindowManager = wm; - mUserController = userController; mCallingPid = callingPid; } @@ -122,7 +120,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(); - mService.setRunningRemoteAnimation(mCallingPid, true); + mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, true); mWindowManager.deferSurfaceLayout(); try { @@ -132,7 +130,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mService.mContext.getSystemService(Context.APP_OPS_SERVICE); final AssistDataReceiverProxy proxy = new AssistDataReceiverProxy( assistDataReceiver, recentsComponent.getPackageName()); - mAssistDataRequester = new AssistDataRequester(mService.mContext, mService, + mAssistDataRequester = new AssistDataRequester(mService.mContext, mWindowManager, appOpsManager, proxy, this, OP_ASSIST_STRUCTURE, OP_NONE); mAssistDataRequester.requestAssistData(mStackSupervisor.getTopVisibleActivities(), true /* fetchData */, false /* fetchScreenshots */, @@ -165,7 +163,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, .setCallingUid(recentsUid) .setCallingPackage(recentsComponent.getPackageName()) .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle())) - .setMayWait(mUserController.getCurrentUserId()) + .setMayWait(mService.getCurrentUserId()) .execute(); mWindowManager.prepareAppTransition(TRANSIT_NONE, false); mWindowManager.executeAppTransition(); @@ -210,7 +208,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, } private void finishAnimation(@RecentsAnimationController.ReorderMode int reorderMode) { - synchronized (mService) { + synchronized (mService.mGlobalLock) { if (DEBUG) Slog.d(TAG, "onAnimationFinished(): controller=" + mWindowManager.getRecentsAnimationController() + " reorderMode=" + reorderMode); @@ -232,7 +230,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, mStackSupervisor.sendPowerHintForLaunchEndIfNeeded(); } - mService.setRunningRemoteAnimation(mCallingPid, false); + mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, false); mWindowManager.inSurfaceTransaction(() -> { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, @@ -317,7 +315,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, if (runSychronously) { finishAnimation(reorderMode); } else { - mService.mHandler.post(() -> finishAnimation(reorderMode)); + mService.mH.post(() -> finishAnimation(reorderMode)); } } diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java index 778990bf6c6a..b87b948f672f 100644 --- a/services/core/java/com/android/server/am/SafeActivityOptions.java +++ b/services/core/java/com/android/server/am/SafeActivityOptions.java @@ -192,7 +192,7 @@ class SafeActivityOptions { // component or has the START_TASKS_FROM_RECENTS permission if (options.getLaunchTaskId() != INVALID_TASK_ID && !supervisor.mRecentTasks.isCallerRecents(callingUid)) { - final int startInTaskPerm = supervisor.mService.mAm.checkPermission( + final int startInTaskPerm = ActivityTaskManagerService.checkPermission( START_TASKS_FROM_RECENTS, callingPid, callingUid); if (startInTaskPerm == PERMISSION_DENIED) { final String msg = "Permission Denial: starting " + getIntentString(intent) diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java index 465fa674d166..481bb2bbe118 100644 --- a/services/core/java/com/android/server/am/TaskPersister.java +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -655,7 +655,7 @@ public class TaskPersister { synchronized (mService.mGlobalLock) { if (DEBUG) Slog.d(TAG, "mRecents=" + mRecentTasks); mRecentTasks.getPersistableTaskIds(persistentTaskIds); - mService.mAm.mWindowManager.removeObsoleteTaskFiles(persistentTaskIds, + mService.mWindowManager.removeObsoleteTaskFiles(persistentTaskIds, mRecentTasks.usersWithRecentsLoadedLocked()); } removeObsoleteFiles(persistentTaskIds); diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 6eac4bcb0a33..ba012abfd432 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1494,7 +1494,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi } private boolean isResizeable(boolean checkSupportsPip) { - return (mService.mAm.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode) + return (mService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode) || (checkSupportsPip && mSupportsPictureInPicture)); } @@ -1507,8 +1507,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi // A task can not be docked even if it is considered resizeable because it only supports // picture-in-picture mode but has a non-resizeable resizeMode return super.supportsSplitScreenWindowingMode() - && mService.mAm.mSupportsSplitScreenMultiWindow - && (mService.mAm.mForceResizableActivities + && mService.mSupportsSplitScreenMultiWindow + && (mService.mForceResizableActivities || (isResizeable(false /* checkSupportsPip */) && !ActivityInfo.isPreserveOrientationMode(mResizeMode))); } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index b500bbfc47d1..3b478443215b 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -28,9 +28,9 @@ import static android.os.Process.SYSTEM_UID; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; -import static com.android.server.am.ActivityManagerService.ALLOW_FULL_ONLY; -import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL; -import static com.android.server.am.ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE; +import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; +import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; +import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE; import static com.android.server.am.ActivityManagerService.MY_PID; import static com.android.server.am.UserState.STATE_BOOTING; import static com.android.server.am.UserState.STATE_RUNNING_LOCKED; @@ -41,6 +41,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager; +import android.app.ActivityTaskManagerInternal; import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.Dialog; @@ -80,7 +81,6 @@ import android.os.storage.StorageManager; import android.text.format.DateUtils; import android.util.ArraySet; import android.util.IntArray; -import android.util.Log; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; @@ -88,7 +88,6 @@ import android.util.SparseIntArray; import android.util.TimingsTraceLog; import android.util.proto.ProtoOutputStream; -import android.view.Window; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -2097,9 +2096,7 @@ class UserController implements Handler.Callback { return mService.mWindowManager; } void activityManagerOnUserStopped(int userId) { - synchronized (mService) { - mService.onUserStoppedLocked(userId); - } + LocalServices.getService(ActivityTaskManagerInternal.class).onUserStopped(userId); } void systemServiceManagerCleanupUser(int userId) { @@ -2174,9 +2171,7 @@ class UserController implements Handler.Callback { } void updateUserConfiguration() { - synchronized (mService) { - mService.updateUserConfigurationLocked(); - } + mService.mActivityTaskManager.updateUserConfiguration(); } void clearBroadcastQueueForUser(int userId) { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 407cb93531f1..6e7eae17a28a 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -27,11 +27,11 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityManagerNative; +import android.app.ActivityTaskManagerInternal; import android.app.IActivityManager; import android.app.IStopUserCallback; import android.app.KeyguardManager; import android.app.PendingIntent; -import android.app.admin.DevicePolicyManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -72,7 +72,6 @@ import android.os.UserManager.EnforcingUser; import android.os.UserManagerInternal; import android.os.UserManagerInternal.UserRestrictionsListener; import android.os.storage.StorageManager; -import android.provider.Settings; import android.security.GateKeeper; import android.service.gatekeeper.IGateKeeperService; import android.util.AtomicFile; @@ -82,7 +81,6 @@ import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.SparseIntArray; -import android.util.SparseLongArray; import android.util.TimeUtils; import android.util.Xml; @@ -2968,9 +2966,9 @@ public class UserManagerService extends IUserManager.Stub { new Thread() { @Override public void run() { - // Clean up any ActivityManager state - LocalServices.getService(ActivityManagerInternal.class) - .onUserRemoved(userHandle); + // Clean up any ActivityTaskManager state + LocalServices.getService(ActivityTaskManagerInternal.class) + .onUserStopped(userHandle); removeUserState(userHandle); } }.start(); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java index f741c70e4821..077b4558f402 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityLaunchParamsModifierTests.java @@ -104,12 +104,12 @@ public class ActivityLaunchParamsModifierTests extends ActivityTestsBase { mActivity, null /*source*/, options /*options*/, mCurrent, mResult)); // Does not support freeform - mService.mSupportsFreeformWindowManagement = false; + mService.mActivityTaskManager.mSupportsFreeformWindowManagement = false; assertFalse(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options)); assertEquals(RESULT_SKIP, mModifier.onCalculate(null /*task*/, null /*layout*/, mActivity, null /*source*/, options /*options*/, mCurrent, mResult)); - mService.mSupportsFreeformWindowManagement = true; + mService.mActivityTaskManager.mSupportsFreeformWindowManagement = true; options.setLaunchBounds(new Rect()); assertTrue(mService.mStackSupervisor.canUseActivityOptionsLaunchBounds(options)); @@ -130,7 +130,7 @@ public class ActivityLaunchParamsModifierTests extends ActivityTestsBase { public void testBoundsExtraction() throws Exception { // Make activity resizeable and enable freeform mode. mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE; - mService.mSupportsFreeformWindowManagement = true; + mService.mActivityTaskManager.mSupportsFreeformWindowManagement = true; ActivityOptions options = ActivityOptions.makeBasic(); final Rect proposedBounds = new Rect(20, 30, 45, 40); diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java index 5ee1c405bb0e..3172323713ea 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java @@ -236,7 +236,7 @@ public class ActivityRecordTests extends ActivityTestsBase { private void testSupportsLaunchingResizeable(boolean taskPresent, boolean taskResizeable, boolean activityResizeable, boolean expected) { - mService.mSupportsMultiWindow = true; + mService.mActivityTaskManager.mSupportsMultiWindow = true; final TaskRecord task = taskPresent ? new TaskBuilder(mService.mStackSupervisor).setStack(mStack).build() : null; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java index a86372a51900..df31042ab589 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStartControllerTests.java @@ -60,8 +60,8 @@ public class ActivityStartControllerTests extends ActivityTestsBase { mService = createActivityManagerService(); mFactory = mock(Factory.class); mController = new ActivityStartController(mService.mActivityTaskManager, mService.mStackSupervisor, mFactory); - mStarter = spy(new ActivityStarter(mController, mService.mActivityTaskManager, mService.mStackSupervisor, - mock(ActivityStartInterceptor.class))); + mStarter = spy(new ActivityStarter(mController, mService.mActivityTaskManager, + mService.mStackSupervisor, mock(ActivityStartInterceptor.class))); doReturn(mStarter).when(mFactory).obtain(); } diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java index 10d255e7e283..274d9e5683f8 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java @@ -236,8 +236,8 @@ public class ActivityStarterTests extends ActivityTestsBase { } if (containsConditions(preconditions, PRECONDITION_DISALLOW_APP_SWITCHING)) { - doReturn(false).when(service).checkAppSwitchAllowedLocked(anyInt(), anyInt(), anyInt(), - anyInt(), any()); + doReturn(false).when(service.mActivityTaskManager).checkAppSwitchAllowedLocked( + anyInt(), anyInt(), anyInt(), anyInt(), any()); } if (containsConditions(preconditions,PRECONDITION_CANNOT_START_ANY_ACTIVITY)) { diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index 06ac3b0213ec..dd30e7075b18 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -29,11 +29,14 @@ import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; +import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import com.android.server.wm.DisplayWindowController; import org.junit.Rule; +import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import android.app.IApplicationThread; @@ -114,6 +117,7 @@ public class ActivityTestsBase { // Makes sure activity task is created with the spy object. atm = spy(atm); service.setActivityTaskManager(atm); + atm.mAmInternal = service.new LocalService(); // Makes sure the supervisor is using with the spy object. atm.mStackSupervisor.setService(atm); doReturn(mock(IPackageManager.class)).when(service).getPackageManager(); @@ -351,6 +355,16 @@ public class ActivityTestsBase { TestActivityTaskManagerService(Context context) { super(context); + mSupportsMultiWindow = true; + mSupportsMultiDisplay = true; + mSupportsSplitScreenMultiWindow = true; + mSupportsFreeformWindowManagement = true; + mSupportsPictureInPicture = true; + } + + @Override + int handleIncomingUser(int callingPid, int callingUid, int userId, String name) { + return userId; } @Override @@ -400,11 +414,6 @@ public class ActivityTestsBase { TestActivityManagerService(Context context) { super(context); - mSupportsMultiWindow = true; - mSupportsMultiDisplay = true; - mSupportsSplitScreenMultiWindow = true; - mSupportsFreeformWindowManagement = true; - mSupportsPictureInPicture = true; } @Override diff --git a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java index 0a436b956abc..f74d11645be4 100644 --- a/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java +++ b/services/tests/servicestests/src/com/android/server/am/AssistDataRequesterTest.java @@ -113,7 +113,7 @@ public class AssistDataRequesterTest extends ActivityTestsBase { mHandler = new Handler(Looper.getMainLooper()); mCallbacksLock = new Object(); mCallbacks = new Callbacks(); - mDataRequester = new AssistDataRequester(mContext, mAm, mWm, mAppOpsManager, mCallbacks, + mDataRequester = new AssistDataRequester(mContext, mWm, mAppOpsManager, mCallbacks, mCallbacksLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT); // Gate the continuation of the assist data callbacks until we are ready within the tests diff --git a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java index 93e0b5aa9082..aaec2382f403 100644 --- a/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java +++ b/services/tests/servicestests/src/com/android/server/am/LaunchParamsControllerTests.java @@ -65,7 +65,7 @@ public class LaunchParamsControllerTests extends ActivityTestsBase { public void setUp() throws Exception { super.setUp(); mService = createActivityManagerService(); - mController = new LaunchParamsController(mService); + mController = new LaunchParamsController(mService.mActivityTaskManager); } /** diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java index cd7067755ea7..982809a3a175 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java @@ -94,7 +94,7 @@ public class RecentTasksTest extends ActivityTestsBase { private static int INVALID_STACK_ID = 999; private Context mContext = InstrumentationRegistry.getContext(); - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ActivityDisplay mDisplay; private ActivityDisplay mOtherDisplay; private ActivityStack mStack; @@ -146,8 +146,8 @@ public class RecentTasksTest extends ActivityTestsBase { mTaskPersister = new TestTaskPersister(mContext.getFilesDir()); mService = setupActivityManagerService(new MyTestActivityManagerService(mContext), - new MyTestActivityTaskManagerService(mContext)); - mRecentTasks = (TestRecentTasks) mService.mActivityTaskManager.getRecentTasks(); + new MyTestActivityTaskManagerService(mContext)).mActivityTaskManager; + mRecentTasks = (TestRecentTasks) mService.getRecentTasks(); mRecentTasks.loadParametersFromResources(mContext.getResources()); mHomeStack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */); @@ -674,9 +674,8 @@ public class RecentTasksTest extends ActivityTestsBase { @Test public void testNotRecentsComponent_denyApiAccess() throws Exception { - doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(), - anyInt(), anyInt()); - + doReturn(PackageManager.PERMISSION_DENIED).when(mService) + .checkGetTasksPermission(anyString(), anyInt(), anyInt()); // Expect the following methods to fail due to recents component not being set mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.DENY_THROW_SECURITY_EXCEPTION); testRecentTasksApis(false /* expectNoSecurityException */); @@ -687,8 +686,8 @@ public class RecentTasksTest extends ActivityTestsBase { @Test public void testRecentsComponent_allowApiAccessWithoutPermissions() throws Exception { - doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(), - anyInt(), anyInt()); + doReturn(PackageManager.PERMISSION_DENIED).when(mService) + .checkGetTasksPermission(anyString(), anyInt(), anyInt()); // Set the recents component and ensure that the following calls do not fail mRecentTasks.setIsCallerRecentsOverride(TestRecentTasks.GRANT); @@ -697,58 +696,52 @@ public class RecentTasksTest extends ActivityTestsBase { } private void testRecentTasksApis(boolean expectCallable) { - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.removeStack(INVALID_STACK_ID)); + assertSecurityException(expectCallable, () -> mService.removeStack(INVALID_STACK_ID)); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.removeStacksInWindowingModes( - new int[] {WINDOWING_MODE_UNDEFINED})); + () -> mService.removeStacksInWindowingModes(new int[] {WINDOWING_MODE_UNDEFINED})); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.removeStacksWithActivityTypes( - new int[] {ACTIVITY_TYPE_UNDEFINED})); + () -> mService.removeStacksWithActivityTypes(new int[] {ACTIVITY_TYPE_UNDEFINED})); assertSecurityException(expectCallable, () -> mService.removeTask(0)); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.setTaskWindowingMode( - 0, WINDOWING_MODE_UNDEFINED, true)); + () -> mService.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true)); assertSecurityException(expectCallable, () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true)); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.setTaskWindowingModeSplitScreenPrimary(0, + () -> mService.setTaskWindowingModeSplitScreenPrimary(0, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true, true, new Rect(), true)); - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.dismissSplitScreenMode(true)); - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.dismissPip(true, 0)); + assertSecurityException(expectCallable, () -> mService.dismissSplitScreenMode(true)); + assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0)); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect())); + () -> mService.moveTopActivityToPinnedStack(INVALID_STACK_ID, new Rect())); assertSecurityException(expectCallable, () -> mService.resizeStack(INVALID_STACK_ID, new Rect(), true, true, true, 0)); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(), + () -> mService.resizeDockedStack(new Rect(), new Rect(), new Rect(), new Rect(), new Rect())); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.resizePinnedStack(new Rect(), new Rect())); - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.getAllStackInfos()); + () -> mService.resizePinnedStack(new Rect(), new Rect())); + assertSecurityException(expectCallable, () -> mService.getAllStackInfos()); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED)); + () -> mService.getStackInfo(WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_UNDEFINED)); assertSecurityException(expectCallable, () -> { try { - mService.mActivityTaskManager.getFocusedStackInfo(); + mService.getFocusedStackInfo(); } catch (RemoteException e) { // Ignore } }); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.moveTasksToFullscreenStack(INVALID_STACK_ID, true)); - assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.startActivityFromRecents(0, new Bundle())); - assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.getTaskSnapshot(0, true)); - assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.registerTaskStackListener(null)); + () -> mService.moveTasksToFullscreenStack(INVALID_STACK_ID, true)); assertSecurityException(expectCallable, - () -> mService.mActivityTaskManager.unregisterTaskStackListener(null)); - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.getTaskDescription(0)); - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.cancelTaskWindowTransition(0)); - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.startRecentsActivity(null, null, + () -> mService.startActivityFromRecents(0, new Bundle())); + assertSecurityException(expectCallable,() -> mService.getTaskSnapshot(0, true)); + assertSecurityException(expectCallable,() -> mService.registerTaskStackListener(null)); + assertSecurityException(expectCallable,() -> mService.unregisterTaskStackListener(null)); + assertSecurityException(expectCallable, () -> mService.getTaskDescription(0)); + assertSecurityException(expectCallable, () -> mService.cancelTaskWindowTransition(0)); + assertSecurityException(expectCallable, () -> mService.startRecentsActivity(null, null, null)); - assertSecurityException(expectCallable, () -> mService.mActivityTaskManager.cancelRecentsAnimation(true)); + assertSecurityException(expectCallable, () -> mService.cancelRecentsAnimation(true)); assertSecurityException(expectCallable, () -> mService.stopAppSwitches()); assertSecurityException(expectCallable, () -> mService.resumeAppSwitches()); } diff --git a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java index 91a02e4f74b6..1f2bca64ca4a 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentsAnimationTest.java @@ -16,12 +16,9 @@ package com.android.server.am; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK; -import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; @@ -51,10 +48,9 @@ import org.junit.runner.RunWith; @Presubmit @RunWith(AndroidJUnit4.class) public class RecentsAnimationTest extends ActivityTestsBase { - private static final int TEST_CALLING_PID = 3; private Context mContext = InstrumentationRegistry.getContext(); - private ActivityManagerService mService; + private ActivityTaskManagerService mService; private ComponentName mRecentsComponent; @Before @@ -64,7 +60,7 @@ public class RecentsAnimationTest extends ActivityTestsBase { mRecentsComponent = new ComponentName(mContext.getPackageName(), "RecentsActivity"); mService = setupActivityManagerService(new TestActivityManagerService(mContext), - new MyTestActivityTaskManagerService(mContext)); + new MyTestActivityTaskManagerService(mContext)).mActivityTaskManager; AttributeCache.init(mContext); } @@ -74,14 +70,14 @@ public class RecentsAnimationTest extends ActivityTestsBase { WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); ActivityStack recentsStack = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_RECENTS, true /* onTop */); - ActivityRecord recentsActivity = new ActivityBuilder(mService) + ActivityRecord recentsActivity = new ActivityBuilder(mService.mAm) .setComponent(mRecentsComponent) .setCreateTask(true) .setStack(recentsStack) .build(); ActivityStack fullscreenStack2 = mService.mStackSupervisor.getDefaultDisplay().createStack( WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */); - ActivityRecord fsActivity = new ActivityBuilder(mService) + ActivityRecord fsActivity = new ActivityBuilder(mService.mAm) .setComponent(new ComponentName(mContext.getPackageName(), "App1")) .setCreateTask(true) .setStack(fullscreenStack2) diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java index cd1b83549f92..4e49782085df 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java @@ -433,11 +433,11 @@ public class VoiceInteractionManagerService extends SystemService { if (hasComponent) { mShortcutServiceInternal.setShortcutHostPackage(TAG, serviceComponent.getPackageName(), mCurUser); - mAmInternal.setAllowAppSwitches(TAG, + mAtmInternal.setAllowAppSwitches(TAG, serviceInfo.applicationInfo.uid, mCurUser); } else { mShortcutServiceInternal.setShortcutHostPackage(TAG, null, mCurUser); - mAmInternal.setAllowAppSwitches(TAG, -1, mCurUser); + mAtmInternal.setAllowAppSwitches(TAG, -1, mCurUser); } } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index 4eaed34489fa..606d0275e60a 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -144,7 +144,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection, mIWindowManager = IWindowManager.Stub.asInterface( ServiceManager.getService(Context.WINDOW_SERVICE)); mAppOps = context.getSystemService(AppOpsManager.class); - mAssistDataRequester = new AssistDataRequester(mContext, mAm, mIWindowManager, + mAssistDataRequester = new AssistDataRequester(mContext, mIWindowManager, (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE), this, mLock, OP_ASSIST_STRUCTURE, OP_ASSIST_SCREENSHOT); IBinder permOwner = null; |