diff options
| author | Wale Ogunwale <ogunwale@google.com> | 2015-02-24 18:32:56 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-02-24 18:32:57 +0000 |
| commit | 9fc3cef1c7d85f764f00be40b62388a4cc0f3e82 (patch) | |
| tree | 8f1a5901cd1ac9cf6c3fb2ac659aa21b0aa06b81 /services | |
| parent | df4943d5e08360223e2b8c16d4b578a229cad411 (diff) | |
| parent | 53a29a90f35f72462c0d6ad650921d5566c1f8f0 (diff) | |
| download | frameworks_base-9fc3cef1c7d85f764f00be40b62388a4cc0f3e82.zip frameworks_base-9fc3cef1c7d85f764f00be40b62388a4cc0f3e82.tar.gz frameworks_base-9fc3cef1c7d85f764f00be40b62388a4cc0f3e82.tar.bz2 | |
Merge "Added ActivityManager API and AM command to resize a task."
Diffstat (limited to 'services')
5 files changed, 137 insertions, 9 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 6229778..966dc88 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7909,6 +7909,25 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override + public void resizeTask(int taskId, Rect bounds) { + enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, + "resizeTask()"); + long ident = Binder.clearCallingIdentity(); + try { + synchronized (this) { + TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, true); + if (task == null) { + Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found"); + return; + } + mStackSupervisor.resizeTaskLocked(task, bounds); + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + @Override public Bitmap getTaskDescriptionIcon(String filename) { if (!FileUtils.isValidExtFilename(filename) || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 607af86..b51f862 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -152,25 +152,25 @@ final class ActivityStack { * The back history of all previous (and possibly still * running) activities. It contains #TaskRecord objects. */ - private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>(); + private ArrayList<TaskRecord> mTaskHistory = new ArrayList<>(); /** * Used for validating app tokens with window manager. */ - final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<TaskGroup>(); + final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<>(); /** * List of running activities, sorted by recent usage. * The first entry in the list is the least recently used. * It contains HistoryRecord objects. */ - final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<ActivityRecord>(); + final ArrayList<ActivityRecord> mLRUActivities = new ArrayList<>(); /** * Animations that for the current transition have requested not to * be considered for the transition animation. */ - final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<ActivityRecord>(); + final ArrayList<ActivityRecord> mNoAnimActivities = new ArrayList<>(); /** * When we are in the process of pausing an activity, before starting the @@ -346,6 +346,10 @@ final class ActivityStack { return count; } + int numTasks() { + return mTaskHistory.size(); + } + ActivityStack(ActivityStackSupervisor.ActivityContainer activityContainer, RecentTasks recentTasks) { mActivityContainer = activityContainer; @@ -4177,8 +4181,14 @@ final class ActivityStack { } void removeTask(TaskRecord task, String reason) { + removeTask(task, reason, true); + } + + void removeTask(TaskRecord task, String reason, boolean removeFromWindowManager) { mStackSupervisor.endLockTaskModeIfTaskEnding(task); - mWindowManager.removeTask(task.taskId); + if (removeFromWindowManager) { + mWindowManager.removeTask(task.taskId); + } final ActivityRecord r = mResumedActivity; if (r != null && r.task == task) { mResumedActivity = null; diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index fb7a56c..907381e 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2641,6 +2641,48 @@ public final class ActivityStackSupervisor implements DisplayListener { } } + /** Makes sure the input task is in a stack with the specified bounds by either resizing the + * current task stack if it only has one entry, moving the task to a stack that matches the + * bounds, or creating a new stack with the required bounds. Also, makes the task resizeable.*/ + void resizeTaskLocked(TaskRecord task, Rect bounds) { + task.mResizeable = true; + final ActivityStack currentStack = task.stack; + if (currentStack.isHomeStack()) { + // Can't move task off the home stack. Sorry! + return; + } + + final int matchingStackId = mWindowManager.getStackIdWithBounds(bounds); + if (matchingStackId != -1) { + // There is already a stack with the right bounds! + if (currentStack != null && currentStack.mStackId == matchingStackId) { + // Nothing to do here. Already in the right stack... + return; + } + // Move task to stack with matching bounds. + moveTaskToStackLocked(task.taskId, matchingStackId, true); + return; + } + + if (currentStack != null && currentStack.numTasks() == 1) { + // Just resize the current stack since this is the task in it. + resizeStackLocked(currentStack.mStackId, bounds); + return; + } + + // Create new stack and move the task to it. + final int displayId = (currentStack != null && currentStack.mDisplayId != -1) + ? currentStack.mDisplayId : Display.DEFAULT_DISPLAY; + ActivityStack newStack = createStackOnDisplay(getNextStackId(), displayId); + + if (newStack == null) { + Slog.e(TAG, "resizeTaskLocked: Can't create stack for task=" + task); + return; + } + moveTaskToStackLocked(task.taskId, newStack.mStackId, true); + resizeStackLocked(newStack.mStackId, bounds); + } + ActivityStack createStackOnDisplay(int stackId, int displayId) { ActivityDisplay activityDisplay = mActivityDisplays.get(displayId); if (activityDisplay == null) { @@ -2719,6 +2761,7 @@ public final class ActivityStackSupervisor implements DisplayListener { void moveTaskToStackLocked(int taskId, int stackId, boolean toTop) { final TaskRecord task = anyTaskForIdLocked(taskId); if (task == null) { + Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId); return; } final ActivityStack stack = getStack(stackId); @@ -2726,9 +2769,11 @@ public final class ActivityStackSupervisor implements DisplayListener { Slog.w(TAG, "moveTaskToStack: no stack for id=" + stackId); return; } - task.stack.removeTask(task, "moveTaskToStack"); + mWindowManager.moveTaskToStack(taskId, stackId, toTop); + if (task.stack != null) { + task.stack.removeTask(task, "moveTaskToStack", false); + } stack.addTask(task, toTop, true); - mWindowManager.addTask(taskId, stackId, toTop); resumeTopActivitiesLocked(); } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index a9b26e2..b8f26c9 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -72,6 +72,19 @@ class Task { mService.mTaskIdToTask.delete(mTaskId); } + void moveTaskToStack(TaskStack stack, boolean toTop) { + if (stack == mStack) { + return; + } + if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: removing taskId=" + mTaskId + + " from stack=" + mStack); + EventLog.writeEvent(EventLogTags.WM_TASK_REMOVED, mTaskId, "removeTask"); + if (mStack != null) { + mStack.removeTask(this); + } + stack.addTask(this, toTop); + } + boolean removeAppToken(AppWindowToken wtoken) { boolean removed = mAppTokens.remove(wtoken); if (mAppTokens.size() == 0) { diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index d4a15af5..fde0bd5 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; import static android.view.WindowManager.LayoutParams.*; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; @@ -682,11 +683,11 @@ public class WindowManagerService extends IWindowManager.Stub final WindowAnimator mAnimator; - SparseArray<Task> mTaskIdToTask = new SparseArray<Task>(); + SparseArray<Task> mTaskIdToTask = new SparseArray<>(); /** All of the TaskStacks in the window manager, unordered. For an ordered list call * DisplayContent.getStacks(). */ - SparseArray<TaskStack> mStackIdToStack = new SparseArray<TaskStack>(); + SparseArray<TaskStack> mStackIdToStack = new SparseArray<>(); private final PointerEventDispatcher mPointerEventDispatcher; @@ -5088,6 +5089,7 @@ public class WindowManagerService extends IWindowManager.Stub + " to " + (toTop ? "top" : "bottom")); Task task = mTaskIdToTask.get(taskId); if (task == null) { + if (DEBUG_STACK) Slog.i(TAG, "addTask: could not find taskId=" + taskId); return; } TaskStack stack = mStackIdToStack.get(stackId); @@ -5098,6 +5100,27 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void moveTaskToStack(int taskId, int stackId, boolean toTop) { + synchronized (mWindowMap) { + if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: moving taskId=" + taskId + + " to stackId=" + stackId + " at " + (toTop ? "top" : "bottom")); + Task task = mTaskIdToTask.get(taskId); + if (task == null) { + if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: could not find taskId=" + taskId); + return; + } + TaskStack stack = mStackIdToStack.get(stackId); + if (stack == null) { + if (DEBUG_STACK) Slog.i(TAG, "moveTaskToStack: could not find stackId=" + stackId); + return; + } + task.moveTaskToStack(stack, toTop); + final DisplayContent displayContent = stack.getDisplayContent(); + displayContent.layoutNeeded = true; + performLayoutAndPlaceSurfacesLocked(); + } + } + /** * Re-sizes the specified stack and its containing windows. * Returns a {@link Configuration} object that contains configurations settings @@ -5128,6 +5151,24 @@ public class WindowManagerService extends IWindowManager.Stub bounds.setEmpty(); } + /** Returns the id of an application (non-home stack) stack that match the input bounds. + * -1 if no stack matches.*/ + public int getStackIdWithBounds(Rect bounds) { + Rect stackBounds = new Rect(); + synchronized (mWindowMap) { + for (int i = mStackIdToStack.size() - 1; i >= 0; --i) { + TaskStack stack = mStackIdToStack.valueAt(i); + if (stack.mStackId != HOME_STACK_ID) { + stack.getBounds(stackBounds); + if (stackBounds.equals(bounds)) { + return stack.mStackId; + } + } + } + } + return -1; + } + /** Forces the stack to fullscreen if input is true, else un-forces the stack from fullscreen. * Returns a {@link Configuration} object that contains configurations settings * that should be overridden due to the operation. |
