diff options
Diffstat (limited to 'com/android/server/am/TaskRecord.java')
-rw-r--r-- | com/android/server/am/TaskRecord.java | 135 |
1 files changed, 72 insertions, 63 deletions
diff --git a/com/android/server/am/TaskRecord.java b/com/android/server/am/TaskRecord.java index a1b45a1e..0d8df796 100644 --- a/com/android/server/am/TaskRecord.java +++ b/com/android/server/am/TaskRecord.java @@ -18,7 +18,10 @@ package com.android.server.am; import static android.app.ActivityManager.RESIZE_MODE_FORCED; import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; +import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; +import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; @@ -28,7 +31,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; -import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS; import static android.content.pm.ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY; @@ -43,6 +45,7 @@ import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE_DEPRECATED; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION; +import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED; import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER; import static android.provider.Settings.Secure.USER_SETUP_COMPLETE; import static android.view.Display.DEFAULT_DISPLAY; @@ -83,6 +86,7 @@ import android.annotation.IntDef; import android.annotation.Nullable; import android.app.Activity; import android.app.ActivityManager; +import android.app.ActivityManager.StackId; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityOptions; @@ -98,7 +102,6 @@ import android.content.res.Configuration; import android.graphics.Rect; import android.os.Debug; import android.os.RemoteException; -import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; @@ -152,6 +155,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi private static final String ATTR_EFFECTIVE_UID = "effective_uid"; @Deprecated private static final String ATTR_TASKTYPE = "task_type"; + private static final String ATTR_FIRSTACTIVETIME = "first_active_time"; + private static final String ATTR_LASTACTIVETIME = "last_active_time"; private static final String ATTR_LASTDESCRIPTION = "last_description"; private static final String ATTR_LASTTIMEMOVED = "last_time_moved"; private static final String ATTR_NEVERRELINQUISH = "never_relinquish_identity"; @@ -163,6 +168,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi private static final String ATTR_CALLING_PACKAGE = "calling_package"; private static final String ATTR_SUPPORTS_PICTURE_IN_PICTURE = "supports_picture_in_picture"; private static final String ATTR_RESIZE_MODE = "resize_mode"; + private static final String ATTR_PRIVILEGED = "privileged"; private static final String ATTR_NON_FULLSCREEN_BOUNDS = "non_fullscreen_bounds"; private static final String ATTR_MIN_WIDTH = "min_width"; private static final String ATTR_MIN_HEIGHT = "min_height"; @@ -206,10 +212,9 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi ComponentName realActivity; // The actual activity component that started the task. boolean realActivitySuspended; // True if the actual activity component that started the // task is suspended. + long firstActiveTime; // First time this task was active. + long lastActiveTime; // Last time this task was active, including sleep. boolean inRecents; // Actually in the recents list? - long lastActiveTime; // Last time this task was active in the current device session, - // including sleep. This time is initialized to the elapsed time when - // restored from disk. boolean isAvailable; // Is the activity available to be launched? boolean rootWasReset; // True if the intent at the root of the task had // the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag. @@ -232,6 +237,10 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi // of the root activity. boolean mTemporarilyUnresizable; // Separate flag from mResizeMode used to suppress resize // changes on a temporary basis. + private int mLockTaskMode; // Which tasklock mode to launch this task in. One of + // ActivityManager.LOCK_TASK_LAUNCH_MODE_* + private boolean mPrivileged; // The root activity application of this task holds + // privileged permissions. /** Can't be put in lockTask mode. */ final static int LOCK_TASK_AUTH_DONT_LOCK = 0; @@ -330,7 +339,6 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi TaskPersister.IMAGE_EXTENSION; userId = UserHandle.getUserId(info.applicationInfo.uid); taskId = _taskId; - lastActiveTime = SystemClock.elapsedRealtime(); mAffiliatedTaskId = _taskId; voiceSession = _voiceSession; voiceInteractor = _voiceInteractor; @@ -351,7 +359,6 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi TaskPersister.IMAGE_EXTENSION; userId = UserHandle.getUserId(info.applicationInfo.uid); taskId = _taskId; - lastActiveTime = SystemClock.elapsedRealtime(); mAffiliatedTaskId = _taskId; voiceSession = null; voiceInteractor = null; @@ -378,11 +385,12 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset, boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId, int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities, - long lastTimeMoved, boolean neverRelinquishIdentity, - TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId, - int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage, - int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended, - boolean userSetupComplete, int minWidth, int minHeight) { + long _firstActiveTime, long _lastActiveTime, long lastTimeMoved, + boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription, + int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor, + int callingUid, String callingPackage, int resizeMode, boolean supportsPictureInPicture, + boolean privileged, boolean _realActivitySuspended, boolean userSetupComplete, + int minWidth, int minHeight) { mService = service; mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX + TaskPersister.IMAGE_EXTENSION; @@ -404,7 +412,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi userId = _userId; mUserSetupComplete = userSetupComplete; effectiveUid = _effectiveUid; - lastActiveTime = SystemClock.elapsedRealtime(); + firstActiveTime = _firstActiveTime; + lastActiveTime = _lastActiveTime; lastDescription = _lastDescription; mActivities = activities; mLastTimeMoved = lastTimeMoved; @@ -418,6 +427,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi mCallingPackage = callingPackage; mResizeMode = resizeMode; mSupportsPictureInPicture = supportsPictureInPicture; + mPrivileged = privileged; mMinWidth = minWidth; mMinHeight = minHeight; mService.mTaskChangeNotificationController.notifyTaskCreated(_taskId, realActivity); @@ -510,7 +520,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi // All we can do for now is update the bounds so it can be used when the task is // added to window manager. updateOverrideConfiguration(bounds); - if (!inFreeformWindowingMode()) { + if (getStackId() != FREEFORM_WORKSPACE_STACK_ID) { // re-restore the task so it can have the proper stack association. mService.mStackSupervisor.restoreRecentTaskLocked(this, null); } @@ -606,7 +616,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi * @return whether the task was reparented */ // TODO: Inspect all call sites and change to just changing windowing mode of the stack vs. - // re-parenting the task. Can only be done when we are no longer using static stack Ids. + // re-parenting the task. Can only be done when we are no longer using static stack Ids like + /** {@link ActivityManager.StackId#FULLSCREEN_WORKSPACE_STACK_ID} */ boolean reparent(ActivityStack preferredStack, int position, @ReparentMoveStackMode int moveStackMode, boolean animate, boolean deferResume, boolean schedulePictureInPictureModeChange, String reason) { @@ -619,12 +630,12 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi return false; } - final int toStackWindowingMode = toStack.getWindowingMode(); + final int sourceStackId = getStackId(); + final int stackId = toStack.getStackId(); final ActivityRecord topActivity = getTopActivity(); - final boolean mightReplaceWindow = - replaceWindowsOnTaskMove(getWindowingMode(), toStackWindowingMode) - && topActivity != null; + final boolean mightReplaceWindow = StackId.replaceWindowsOnTaskMove(sourceStackId, stackId) + && topActivity != null; if (mightReplaceWindow) { // We are about to relaunch the activity because its configuration changed due to // being maximized, i.e. size change. The activity will first remove the old window @@ -649,7 +660,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi // In some cases the focused stack isn't the front stack. E.g. pinned stack. // Whenever we are moving the top activity from the front stack we want to make sure to // move the stack to the front. - final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay() + final boolean wasFront = r != null && supervisor.isFrontStackOnDisplay(sourceStack) && (sourceStack.topRunningActivityLocked() == r); // Adjust the position for the new parent stack as needed. @@ -696,10 +707,10 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi toStack.prepareFreezingTaskBounds(); // Make sure the task has the appropriate bounds/size for the stack it is in. + final int toStackWindowingMode = toStack.getWindowingMode(); final boolean toStackSplitScreenPrimary = toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; - if ((toStackWindowingMode == WINDOWING_MODE_FULLSCREEN - || toStackWindowingMode == WINDOWING_MODE_SPLIT_SCREEN_SECONDARY) + if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && !Objects.equals(mBounds, toStack.mBounds)) { kept = resize(toStack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow, deferResume); @@ -738,9 +749,9 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi } // TODO: Handle incorrect request to move before the actual move, not after. - final boolean inSplitScreenMode = supervisor.getDefaultDisplay().hasSplitScreenPrimaryStack(); + final boolean inSplitScreenMode = supervisor.getDefaultDisplay().hasSplitScreenStack(); supervisor.handleNonResizableTaskIfNeeded(this, preferredStack.getWindowingMode(), - DEFAULT_DISPLAY, toStack); + DEFAULT_DISPLAY, stackId); boolean successful = (preferredStack == toStack); if (successful && toStack.getWindowingMode() == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { @@ -750,18 +761,6 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi return successful; } - /** - * Returns true if the windows of tasks being moved to the target stack from the source - * stack should be replaced, meaning that window manager will keep the old window around - * until the new is ready. - * @hide - */ - private static boolean replaceWindowsOnTaskMove( - int sourceWindowingMode, int targetWindowingMode) { - return sourceWindowingMode == WINDOWING_MODE_FREEFORM - || targetWindowingMode == WINDOWING_MODE_FREEFORM; - } - void cancelWindowTransition() { mWindowContainerController.cancelWindowTransition(); } @@ -781,11 +780,14 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi } void touchActiveTime() { - lastActiveTime = SystemClock.elapsedRealtime(); + lastActiveTime = System.currentTimeMillis(); + if (firstActiveTime == 0) { + firstActiveTime = lastActiveTime; + } } long getInactiveDuration() { - return SystemClock.elapsedRealtime() - lastActiveTime; + return System.currentTimeMillis() - lastActiveTime; } /** Sets the original intent, and the calling uid and package. */ @@ -793,7 +795,6 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi mCallingUid = r.launchedFromUid; mCallingPackage = r.launchedFromPackage; setIntent(r.intent, r.info); - setLockTaskAuth(r); } /** Sets the original intent, _without_ updating the calling uid or package. */ @@ -877,6 +878,14 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi } mResizeMode = info.resizeMode; mSupportsPictureInPicture = info.supportsPictureInPicture(); + mPrivileged = (info.applicationInfo.privateFlags & PRIVATE_FLAG_PRIVILEGED) != 0; + mLockTaskMode = info.lockTaskLaunchMode; + if (!mPrivileged && (mLockTaskMode == LOCK_TASK_LAUNCH_MODE_ALWAYS + || mLockTaskMode == LOCK_TASK_LAUNCH_MODE_NEVER)) { + // Non-priv apps are not allowed to use always or never, fall back to default + mLockTaskMode = LOCK_TASK_LAUNCH_MODE_DEFAULT; + } + setLockTaskAuth(); } /** Sets the original minimal width and height. */ @@ -1254,7 +1263,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi mService.notifyTaskPersisterLocked(this, false); } - if (inPinnedWindowingMode()) { + if (getStackId() == PINNED_STACK_ID) { // We normally notify listeners of task stack changes on pause, however pinned stack // activities are normally in the paused state so no notification will be sent there // before the activity is removed. We send it here so instead. @@ -1413,17 +1422,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi } void setLockTaskAuth() { - setLockTaskAuth(getRootActivity()); - } - - private void setLockTaskAuth(@Nullable ActivityRecord r) { - if (r == null) { - mLockTaskAuth = LOCK_TASK_AUTH_PINNABLE; - return; - } - final String pkg = (realActivity != null) ? realActivity.getPackageName() : null; - switch (r.lockTaskLaunchMode) { + switch (mLockTaskMode) { case LOCK_TASK_LAUNCH_MODE_DEFAULT: mLockTaskAuth = mService.mLockTaskController.isPackageWhitelisted(userId, pkg) ? LOCK_TASK_AUTH_WHITELISTED : LOCK_TASK_AUTH_PINNABLE; @@ -1493,7 +1493,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi * @return True if the requested bounds are okay for a resizing request. */ private boolean canResizeToBounds(Rect bounds) { - if (bounds == null || !inFreeformWindowingMode()) { + if (bounds == null || getStackId() != FREEFORM_WORKSPACE_STACK_ID) { // Note: If not on the freeform workspace, we ignore the bounds. return true; } @@ -1559,7 +1559,6 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi // values in the TaskRecord. String label = null; String iconFilename = null; - int iconResource = -1; int colorPrimary = 0; int colorBackground = 0; int statusBarColor = 0; @@ -1571,9 +1570,6 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi if (label == null) { label = r.taskDescription.getLabel(); } - if (iconResource == -1) { - iconResource = r.taskDescription.getIconResource(); - } if (iconFilename == null) { iconFilename = r.taskDescription.getIconFilename(); } @@ -1588,8 +1584,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi } topActivity = false; } - lastTaskDescription = new TaskDescription(label, null, iconResource, iconFilename, - colorPrimary, colorBackground, statusBarColor, navigationBarColor); + lastTaskDescription = new TaskDescription(label, null, iconFilename, colorPrimary, + colorBackground, statusBarColor, navigationBarColor); if (mWindowContainerController != null) { mWindowContainerController.setTaskDescription(lastTaskDescription); } @@ -1651,6 +1647,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi out.attribute(null, ATTR_USERID, String.valueOf(userId)); out.attribute(null, ATTR_USER_SETUP_COMPLETE, String.valueOf(mUserSetupComplete)); out.attribute(null, ATTR_EFFECTIVE_UID, String.valueOf(effectiveUid)); + out.attribute(null, ATTR_FIRSTACTIVETIME, String.valueOf(firstActiveTime)); + out.attribute(null, ATTR_LASTACTIVETIME, String.valueOf(lastActiveTime)); out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved)); out.attribute(null, ATTR_NEVERRELINQUISH, String.valueOf(mNeverRelinquishIdentity)); if (lastDescription != null) { @@ -1668,6 +1666,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi out.attribute(null, ATTR_RESIZE_MODE, String.valueOf(mResizeMode)); out.attribute(null, ATTR_SUPPORTS_PICTURE_IN_PICTURE, String.valueOf(mSupportsPictureInPicture)); + out.attribute(null, ATTR_PRIVILEGED, String.valueOf(mPrivileged)); if (mLastNonFullscreenBounds != null) { out.attribute( null, ATTR_NON_FULLSCREEN_BOUNDS, mLastNonFullscreenBounds.flattenToString()); @@ -1722,6 +1721,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi boolean userSetupComplete = true; int effectiveUid = -1; String lastDescription = null; + long firstActiveTime = -1; + long lastActiveTime = -1; long lastTimeOnTop = 0; boolean neverRelinquishIdentity = true; int taskId = INVALID_TASK_ID; @@ -1735,6 +1736,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi String callingPackage = ""; int resizeMode = RESIZE_MODE_FORCE_RESIZEABLE; boolean supportsPictureInPicture = false; + boolean privileged = false; Rect bounds = null; int minWidth = INVALID_MIN_SIZE; int minHeight = INVALID_MIN_SIZE; @@ -1772,6 +1774,10 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi effectiveUid = Integer.parseInt(attrValue); } else if (ATTR_TASKTYPE.equals(attrName)) { taskType = Integer.parseInt(attrValue); + } else if (ATTR_FIRSTACTIVETIME.equals(attrName)) { + firstActiveTime = Long.parseLong(attrValue); + } else if (ATTR_LASTACTIVETIME.equals(attrName)) { + lastActiveTime = Long.parseLong(attrValue); } else if (ATTR_LASTDESCRIPTION.equals(attrName)) { lastDescription = attrValue; } else if (ATTR_LASTTIMEMOVED.equals(attrName)) { @@ -1796,6 +1802,8 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi resizeMode = Integer.parseInt(attrValue); } else if (ATTR_SUPPORTS_PICTURE_IN_PICTURE.equals(attrName)) { supportsPictureInPicture = Boolean.parseBoolean(attrValue); + } else if (ATTR_PRIVILEGED.equals(attrName)) { + privileged = Boolean.parseBoolean(attrValue); } else if (ATTR_NON_FULLSCREEN_BOUNDS.equals(attrName)) { bounds = Rect.unflattenFromString(attrValue); } else if (ATTR_MIN_WIDTH.equals(attrName)) { @@ -1880,10 +1888,10 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent, affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset, autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription, - activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription, - taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid, - callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended, - userSetupComplete, minWidth, minHeight); + activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity, + taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, + callingUid, callingPackage, resizeMode, supportsPictureInPicture, privileged, + realActivitySuspended, userSetupComplete, minWidth, minHeight); task.updateOverrideConfiguration(bounds); for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) { @@ -1903,7 +1911,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi // If the task has no requested minimal size, we'd like to enforce a minimal size // so that the user can not render the task too small to manipulate. We don't need // to do this for the pinned stack as the bounds are controlled by the system. - if (!inPinnedWindowingMode()) { + if (getStackId() != PINNED_STACK_ID) { if (minWidth == INVALID_MIN_SIZE) { minWidth = mService.mStackSupervisor.mDefaultMinSizeOfResizeableTask; } @@ -2077,7 +2085,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi return; } - if (inStack.inFreeformWindowingMode()) { + if (inStack.mStackId == FREEFORM_WORKSPACE_STACK_ID) { if (!isResizeable()) { throw new IllegalArgumentException("Can not position non-resizeable task=" + this + " in stack=" + inStack); @@ -2212,6 +2220,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi pw.print(" mResizeMode=" + ActivityInfo.resizeModeToString(mResizeMode)); pw.print(" mSupportsPictureInPicture=" + mSupportsPictureInPicture); pw.print(" isResizeable=" + isResizeable()); + pw.print(" firstActiveTime=" + firstActiveTime); pw.print(" lastActiveTime=" + lastActiveTime); pw.println(" (inactive for " + (getInactiveDuration() / 1000) + "s)"); } |