diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 9d29a22bf290f..d78aa32cb000c 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -22,6 +22,8 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; +import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; +import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; @@ -64,7 +66,7 @@ class AppTokenList extends ArrayList { * Version of WindowToken that is specifically for a particular application (or * really activity) that is displaying windows. */ -class AppWindowToken extends WindowToken { +class AppWindowToken extends WindowToken implements WindowManagerService.AppFreezeListener { private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowToken" : TAG_WM; // Non-null only for application tokens. @@ -375,6 +377,14 @@ class AppWindowToken extends WindowToken { } } + @Override + boolean checkCompleteDeferredRemoval() { + if (mIsExiting) { + removeIfPossible(); + } + return super.checkCompleteDeferredRemoval(); + } + void clearAnimatingFlags() { boolean wallpaperMightChange = false; for (int i = mChildren.size() - 1; i >= 0; i--) { @@ -830,6 +840,7 @@ class AppWindowToken extends WindowToken { if (!hiddenRequested) { if (!mAppAnimator.freezingScreen) { mAppAnimator.freezingScreen = true; + mService.registerAppFreezeListener(this); mAppAnimator.lastFreezeDuration = 0; mService.mAppsFreezingScreen++; if (mService.mAppsFreezingScreen == 1) { @@ -860,6 +871,7 @@ class AppWindowToken extends WindowToken { if (force || unfrozeWindows) { if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this); mAppAnimator.freezingScreen = false; + mService.unregisterAppFreezeListener(this); mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime() - mService.mDisplayFreezeTime); mService.mAppsFreezingScreen--; @@ -873,6 +885,12 @@ class AppWindowToken extends WindowToken { } } + @Override + public void onAppFreezeTimeout() { + Slog.w(TAG_WM, "Force clearing freeze: " + this); + stopFreezingScreen(true, true); + } + boolean transferStartingWindow(IBinder transferFrom) { final AppWindowToken fromToken = mService.findAppWindowToken(transferFrom); if (fromToken == null) { @@ -1001,6 +1019,84 @@ class AppWindowToken extends WindowToken { return mOrientation; } + @Override + void checkAppWindowsReadyToShow(int displayId) { + if (allDrawn == mAppAnimator.allDrawn) { + return; + } + + mAppAnimator.allDrawn = allDrawn; + if (!allDrawn) { + return; + } + + // The token has now changed state to having all windows shown... what to do, what to do? + if (mAppAnimator.freezingScreen) { + mAppAnimator.showAllWindowsLocked(); + stopFreezingScreen(false, true); + if (DEBUG_ORIENTATION) Slog.i(TAG, + "Setting mOrientationChangeComplete=true because wtoken " + this + + " numInteresting=" + numInterestingWindows + " numDrawn=" + numDrawnWindows); + // This will set mOrientationChangeComplete and cause a pass through layout. + setAppLayoutChanges(FINISH_LAYOUT_REDO_WALLPAPER, + "checkAppWindowsReadyToShow: freezingScreen", displayId); + } else { + setAppLayoutChanges(FINISH_LAYOUT_REDO_ANIM, "checkAppWindowsReadyToShow", displayId); + + // We can now show all of the drawn windows! + if (!mService.mOpeningApps.contains(this)) { + mService.mAnimator.orAnimating(mAppAnimator.showAllWindowsLocked()); + } + } + } + + @Override + void updateAllDrawn(int displayId) { + final DisplayContent displayContent = mService.getDisplayContentLocked(displayId); + + if (!allDrawn) { + final int numInteresting = numInterestingWindows; + if (numInteresting > 0 && numDrawnWindows >= numInteresting) { + if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawn: " + this + + " interesting=" + numInteresting + " drawn=" + numDrawnWindows); + allDrawn = true; + // Force an additional layout pass where + // WindowStateAnimator#commitFinishDrawingLocked() will call performShowLocked(). + displayContent.layoutNeeded = true; + mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, token).sendToTarget(); + } + } + if (!allDrawnExcludingSaved) { + int numInteresting = numInterestingWindowsExcludingSaved; + if (numInteresting > 0 && numDrawnWindowsExcludingSaved >= numInteresting) { + if (DEBUG_VISIBILITY) Slog.v(TAG, "allDrawnExcludingSaved: " + this + + " interesting=" + numInteresting + + " drawn=" + numDrawnWindowsExcludingSaved); + allDrawnExcludingSaved = true; + displayContent.layoutNeeded = true; + if (isAnimatingInvisibleWithSavedSurface() + && !mService.mFinishedEarlyAnim.contains(this)) { + mService.mFinishedEarlyAnim.add(this); + } + } + } + } + + @Override + void stepAppWindowsAnimation(long currentTime, int displayId) { + mAppAnimator.wasAnimating = mAppAnimator.animating; + if (mAppAnimator.stepAnimationLocked(currentTime, displayId)) { + mAppAnimator.animating = true; + mService.mAnimator.setAnimating(true); + mService.mAnimator.mAppWindowAnimating = true; + } else if (mAppAnimator.wasAnimating) { + // stopped animating, do one more pass through the layout + setAppLayoutChanges( + FINISH_LAYOUT_REDO_WALLPAPER, "appToken " + this + " done", displayId); + if (DEBUG_ANIM) Slog.v(TAG, "updateWindowsApps...: done animating " + this); + } + } + @Override int rebuildWindowList(DisplayContent dc, int addIndex) { if (mIsExiting && !waitingForReplacement()) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 155c46fbb6f72..f764eed1a4130 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -120,9 +120,6 @@ class DisplayContent { private final Rect mTmpRect2 = new Rect(); private final Region mTmpRegion = new Region(); - /** For gathering Task objects in order. */ - private final ArrayList mTmpTaskHistory = new ArrayList(); - final WindowManagerService mService; /** Remove this display when animation on it has completed. */ @@ -137,6 +134,11 @@ class DisplayContent { /** Used when rebuilding window list to keep track of windows that have been removed. */ private WindowState[] mRebuildTmp = new WindowState[20]; + private final TaskForResizePointSearchResult mTmpTaskForResizePointSearchResult = + new TaskForResizePointSearchResult(); + private final GetWindowOnDisplaySearchResult mTmpGetWindowOnDisplaySearchResult = + new GetWindowOnDisplaySearchResult(); + /** * @param display May not be null. * @param service You know. @@ -192,19 +194,6 @@ class DisplayContent { return mStacks; } - /** - * Retrieve the tasks on this display in stack order from the bottommost TaskStack up. - * @return All the Tasks, in order, on this display. - */ - ArrayList getTasks() { - mTmpTaskHistory.clear(); - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - mTmpTaskHistory.addAll(mStacks.get(stackNdx).getTasks()); - } - return mTmpTaskHistory; - } - TaskStack getHomeStack() { if (mHomeStack == null && mDisplayId == Display.DEFAULT_DISPLAY) { Slog.e(TAG_WM, "getHomeStack: Returning null from this=" + this); @@ -222,6 +211,27 @@ class DisplayContent { return null; } + void checkAppWindowsReadyToShow() { + for (int i = mStacks.size() - 1; i >= 0; --i) { + final TaskStack stack = mStacks.get(i); + stack.checkAppWindowsReadyToShow(mDisplayId); + } + } + + void updateAllDrawn() { + for (int i = mStacks.size() - 1; i >= 0; --i) { + final TaskStack stack = mStacks.get(i); + stack.updateAllDrawn(mDisplayId); + } + } + + void stepAppWindowsAnimation(long currentTime) { + for (int i = mStacks.size() - 1; i >= 0; --i) { + final TaskStack stack = mStacks.get(i); + stack.stepAppWindowsAnimation(currentTime, mDisplayId); + } + } + void onAppTransitionDone() { for (int i = mStacks.size() - 1; i >= 0; --i) { final TaskStack stack = mStacks.get(i); @@ -360,6 +370,19 @@ class DisplayContent { mStacks.add(addIndex, stack); } + // TODO: Don't forget to switch to WC.detachChild + void detachChild(TaskStack stack) { + detachStack(stack); + if (stack.detachFromDisplay()) { + mService.mWindowPlacerLocked.requestTraversal(); + } + if (stack.mStackId == DOCKED_STACK_ID) { + mService.getDefaultDisplayContentLocked().mDividerControllerLocked + .notifyDockedStackExistsChanged(false); + } + } + + // TODO: See about removing this by untangling the use case in WMS.attachStack() void detachStack(TaskStack stack) { mDimLayerController.removeDimLayerUser(stack); mStacks.remove(stack); @@ -375,27 +398,10 @@ class DisplayContent { int taskIdFromPoint(int x, int y) { for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - TaskStack stack = mStacks.get(stackNdx); - stack.getBounds(mTmpRect); - if (!mTmpRect.contains(x, y) || stack.isAdjustedForMinimizedDockedStack()) { - continue; - } - final ArrayList tasks = stack.getTasks(); - for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { - final Task task = tasks.get(taskNdx); - final WindowState win = task.getTopVisibleAppMainWindow(); - if (win == null) { - continue; - } - // We need to use the task's dim bounds (which is derived from the visible - // bounds of its apps windows) for any touch-related tests. Can't use - // the task's original bounds because it might be adjusted to fit the - // content frame. For example, the presence of the IME adjusting the - // windows frames when the app window is the IME target. - task.getDimBounds(mTmpRect); - if (mTmpRect.contains(x, y)) { - return task.mTaskId; - } + final TaskStack stack = mStacks.get(stackNdx); + final int taskId = stack.taskIdFromPoint(x, y); + if (taskId != -1) { + return taskId; } } return -1; @@ -407,35 +413,16 @@ class DisplayContent { */ Task findTaskForResizePoint(int x, int y) { final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); + mTmpTaskForResizePointSearchResult.reset(); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { TaskStack stack = mStacks.get(stackNdx); if (!StackId.isTaskResizeAllowed(stack.mStackId)) { - break; + return null; } - final ArrayList tasks = stack.getTasks(); - for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { - final Task task = tasks.get(taskNdx); - if (task.isFullscreen()) { - return null; - } - // We need to use the task's dim bounds (which is derived from the visible - // bounds of its apps windows) for any touch-related tests. Can't use - // the task's original bounds because it might be adjusted to fit the - // content frame. One example is when the task is put to top-left quadrant, - // the actual visible area would not start at (0,0) after it's adjusted - // for the status bar. - task.getDimBounds(mTmpRect); - mTmpRect.inset(-delta, -delta); - if (mTmpRect.contains(x, y)) { - mTmpRect.inset(delta, delta); - if (!mTmpRect.contains(x, y)) { - return task; - } - // User touched inside the task. No need to look further, - // focus transfer will be handled in ACTION_UP. - return null; - } + stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult); + if (mTmpTaskForResizePointSearchResult.searchDone) { + return mTmpTaskForResizePointSearchResult.taskForResize; } } return null; @@ -444,54 +431,16 @@ class DisplayContent { void setTouchExcludeRegion(Task focusedTask) { mTouchExcludeRegion.set(mBaseDisplayRect); final int delta = mService.dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics); - boolean addBackFocusedTask = false; + mTmpRect2.setEmpty(); for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { - TaskStack stack = mStacks.get(stackNdx); - final ArrayList tasks = stack.getTasks(); - for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { - final Task task = tasks.get(taskNdx); - AppWindowToken token = task.getTopVisibleAppToken(); - if (token == null || !token.isVisible()) { - continue; - } - - /** - * Exclusion region is the region that TapDetector doesn't care about. - * Here we want to remove all non-focused tasks from the exclusion region. - * We also remove the outside touch area for resizing for all freeform - * tasks (including the focused). - * - * We save the focused task region once we find it, and add it back at the end. - */ - - task.getDimBounds(mTmpRect); - - if (task == focusedTask) { - addBackFocusedTask = true; - mTmpRect2.set(mTmpRect); - } - - final boolean isFreeformed = task.inFreeformWorkspace(); - if (task != focusedTask || isFreeformed) { - if (isFreeformed) { - // If the task is freeformed, enlarge the area to account for outside - // touch area for resize. - mTmpRect.inset(-delta, -delta); - // Intersect with display content rect. If we have system decor (status bar/ - // navigation bar), we want to exclude that from the tap detection. - // Otherwise, if the app is partially placed under some system button (eg. - // Recents, Home), pressing that button would cause a full series of - // unwanted transfer focus/resume/pause, before we could go home. - mTmpRect.intersect(mContentRect); - } - mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE); - } - } + final TaskStack stack = mStacks.get(stackNdx); + stack.setTouchExcludeRegion( + focusedTask, delta, mTouchExcludeRegion, mContentRect, mTmpRect2); } // If we removed the focused task above, add it back and only leave its // outside touch area in the exclusion. TapDectector is not interested in // any touch inside the focused task itself. - if (addBackFocusedTask) { + if (!mTmpRect2.isEmpty()) { mTouchExcludeRegion.op(mTmpRect2, Region.Op.UNION); } final WindowState inputMethod = mService.mInputMethodWindow; @@ -574,32 +523,18 @@ class DisplayContent { return false; } - void onCompleteDeferredRemoval() { - boolean animating = false; + /** Returns true if a removal action is still being deferred. */ + boolean checkCompleteDeferredRemoval() { + boolean stillDeferringRemoval = false; for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final TaskStack stack = mStacks.get(stackNdx); - if (stack.isAnimating()) { - animating = true; - } else { - if (stack.mDeferDetach) { - mService.detachStackLocked(this, stack); - } - final ArrayList tasks = stack.getTasks(); - for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { - final Task task = tasks.get(taskNdx); - AppTokenList tokens = task.mAppTokens; - for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { - AppWindowToken wtoken = tokens.get(tokenNdx); - if (wtoken.mIsExiting) { - wtoken.removeIfPossible(); - } - } - } - } + stillDeferringRemoval |= stack.checkCompleteDeferredRemoval(); } - if (!animating && mDeferredRemoval) { + if (!stillDeferringRemoval && mDeferredRemoval) { mService.onDisplayRemoved(mDisplayId); + return false; } + return true; } void rotateBounds(int oldRotation, int newRotation, Rect bounds) { @@ -870,17 +805,17 @@ class DisplayContent { final WindowToken wToken = win.mToken; // Figure out where the window should go, based on the order of applications. - final GetWindowOnDisplaySearchResults result = new GetWindowOnDisplaySearchResults(); + mTmpGetWindowOnDisplaySearchResult.reset(); for (int i = mStacks.size() - 1; i >= 0; --i) { final TaskStack stack = mStacks.get(i); - stack.getWindowOnDisplayBeforeToken(this, wToken, result); - if (result.reachedToken) { + stack.getWindowOnDisplayBeforeToken(this, wToken, mTmpGetWindowOnDisplaySearchResult); + if (mTmpGetWindowOnDisplaySearchResult.reachedToken) { // We have reach the token we are interested in. End search. break; } } - WindowState pos = result.foundWindow; + WindowState pos = mTmpGetWindowOnDisplaySearchResult.foundWindow; // We now know the index into the apps. If we found an app window above, that gives us the // position; else we need to look some more. @@ -902,17 +837,17 @@ class DisplayContent { } // Continue looking down until we find the first token that has windows on this display. - result.reset(); + mTmpGetWindowOnDisplaySearchResult.reset(); for (int i = mStacks.size() - 1; i >= 0; --i) { final TaskStack stack = mStacks.get(i); - stack.getWindowOnDisplayAfterToken(this, wToken, result); - if (result.foundWindow != null) { + stack.getWindowOnDisplayAfterToken(this, wToken, mTmpGetWindowOnDisplaySearchResult); + if (mTmpGetWindowOnDisplaySearchResult.foundWindow != null) { // We have found a window after the token. End search. break; } } - pos = result.foundWindow; + pos = mTmpGetWindowOnDisplaySearchResult.foundWindow; if (pos != null) { // Move in front of any windows attached to this one. @@ -1224,7 +1159,7 @@ class DisplayContent { } } - static final class GetWindowOnDisplaySearchResults { + static final class GetWindowOnDisplaySearchResult { boolean reachedToken; WindowState foundWindow; @@ -1233,4 +1168,14 @@ class DisplayContent { foundWindow = null; } } + + static final class TaskForResizePointSearchResult { + boolean searchDone; + Task taskForResize; + + void reset() { + searchDone = false; + taskForResize = null; + } + } } diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 5c6cb6b14e4aa..837f0d3b451d8 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -54,7 +54,7 @@ class Task implements DimLayer.DimLayerUser { static final int BOUNDS_CHANGE_SIZE = 1 << 1; TaskStack mStack; - final AppTokenList mAppTokens = new AppTokenList(); + private final AppTokenList mAppTokens = new AppTokenList(); final int mTaskId; final int mUserId; boolean mDeferRemoval = false; @@ -182,6 +182,17 @@ class Task implements DimLayer.DimLayerUser { } } + boolean checkCompleteDeferredRemoval() { + boolean stillDeferringRemoval = false; + + for (int tokenNdx = mAppTokens.size() - 1; tokenNdx >= 0; --tokenNdx) { + final AppWindowToken token = mAppTokens.get(tokenNdx); + stillDeferringRemoval |= token.checkCompleteDeferredRemoval(); + } + + return stillDeferringRemoval; + } + // TODO: Don't forget to switch to WC.detachChild void detachChild(AppWindowToken wtoken) { if (!removeAppToken(wtoken)) { @@ -684,6 +695,27 @@ class Task implements DimLayer.DimLayerUser { return false; } + void checkAppWindowsReadyToShow(int displayId) { + for (int i = mAppTokens.size() - 1; i >= 0; --i) { + final AppWindowToken aToken = mAppTokens.get(i); + aToken.checkAppWindowsReadyToShow(displayId); + } + } + + void updateAllDrawn(int displayId) { + for (int i = mAppTokens.size() - 1; i >= 0; --i) { + final AppWindowToken aToken = mAppTokens.get(i); + aToken.updateAllDrawn(displayId); + } + } + + void stepAppWindowsAnimation(long currentTime, int displayId) { + for (int i = mAppTokens.size() - 1; i >= 0; --i) { + final AppWindowToken aToken = mAppTokens.get(i); + aToken.stepAppWindowsAnimation(currentTime, displayId); + } + } + void onAppTransitionDone() { for (int i = mAppTokens.size() - 1; i >= 0; --i) { final AppWindowToken token = mAppTokens.get(i); @@ -706,7 +738,7 @@ class Task implements DimLayer.DimLayerUser { } void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResults result) { + DisplayContent.GetWindowOnDisplaySearchResult result) { for (int i = mAppTokens.size() - 1; i >= 0; --i) { final AppWindowToken current = mAppTokens.get(i); if (current == token) { @@ -725,7 +757,7 @@ class Task implements DimLayer.DimLayerUser { } void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResults result) { + DisplayContent.GetWindowOnDisplaySearchResult result) { for (int i = mAppTokens.size() - 1; i >= 0; --i) { final AppWindowToken current = mAppTokens.get(i); if (!result.reachedToken) { diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 25f3c0af6738e..39ec03200fc07 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -32,6 +32,7 @@ import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_TOP; import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.RESIZE_STACK; @@ -39,6 +40,7 @@ import static com.android.server.wm.WindowManagerService.H.RESIZE_STACK; import android.app.ActivityManager.StackId; import android.content.res.Configuration; import android.graphics.Rect; +import android.graphics.Region; import android.os.Debug; import android.os.RemoteException; import android.util.EventLog; @@ -48,6 +50,7 @@ import android.view.DisplayInfo; import android.view.Surface; import android.view.animation.Animation; +import android.view.WindowManagerPolicy; import com.android.internal.policy.DividerSnapAlgorithm; import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; @@ -113,6 +116,7 @@ public class TaskStack implements DimLayer.DimLayerUser, final AppTokenList mExitingAppTokens = new AppTokenList(); /** Detach this stack from its display when animation completes. */ + // TODO: maybe tie this to WindowContainer#detachChild some how... boolean mDeferDetach; private final Rect mTmpAdjustedBounds = new Rect(); @@ -147,10 +151,6 @@ public class TaskStack implements DimLayer.DimLayerUser, return mDisplayContent; } - ArrayList getTasks() { - return mTasks; - } - Task findHomeTask() { if (mStackId != HOME_STACK_ID) { return null; @@ -1232,6 +1232,122 @@ public class TaskStack implements DimLayer.DimLayerUser, return false; } + boolean hasTaskForUser(int userId) { + for (int i = mTasks.size() - 1; i >= 0; i--) { + final Task task = mTasks.get(i); + if (task.mUserId == userId) { + return true; + } + } + return false; + } + + int taskIdFromPoint(int x, int y) { + getBounds(mTmpRect); + if (!mTmpRect.contains(x, y) || isAdjustedForMinimizedDockedStack()) { + return -1; + } + + for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { + final Task task = mTasks.get(taskNdx); + final WindowState win = task.getTopVisibleAppMainWindow(); + if (win == null) { + continue; + } + // We need to use the task's dim bounds (which is derived from the visible bounds of its + // apps windows) for any touch-related tests. Can't use the task's original bounds + // because it might be adjusted to fit the content frame. For example, the presence of + // the IME adjusting the windows frames when the app window is the IME target. + task.getDimBounds(mTmpRect); + if (mTmpRect.contains(x, y)) { + return task.mTaskId; + } + } + + return -1; + } + + void findTaskForResizePoint(int x, int y, int delta, + DisplayContent.TaskForResizePointSearchResult results) { + if (!StackId.isTaskResizeAllowed(mStackId)) { + results.searchDone = true; + return; + } + + for (int i = mTasks.size() - 1; i >= 0; --i) { + final Task task = mTasks.get(i); + if (task.isFullscreen()) { + results.searchDone = true; + return; + } + + // We need to use the task's dim bounds (which is derived from the visible bounds of + // its apps windows) for any touch-related tests. Can't use the task's original + // bounds because it might be adjusted to fit the content frame. One example is when + // the task is put to top-left quadrant, the actual visible area would not start at + // (0,0) after it's adjusted for the status bar. + task.getDimBounds(mTmpRect); + mTmpRect.inset(-delta, -delta); + if (mTmpRect.contains(x, y)) { + mTmpRect.inset(delta, delta); + + results.searchDone = true; + + if (!mTmpRect.contains(x, y)) { + results.taskForResize = task; + return; + } + // User touched inside the task. No need to look further, + // focus transfer will be handled in ACTION_UP. + return; + } + } + } + + void setTouchExcludeRegion(Task focusedTask, int delta, Region touchExcludeRegion, + Rect contentRect, Rect postExclude) { + for (int i = mTasks.size() - 1; i >= 0; --i) { + final Task task = mTasks.get(i); + AppWindowToken token = task.getTopVisibleAppToken(); + if (token == null || !token.hasContentToDisplay()) { + continue; + } + + /** + * Exclusion region is the region that TapDetector doesn't care about. + * Here we want to remove all non-focused tasks from the exclusion region. + * We also remove the outside touch area for resizing for all freeform + * tasks (including the focused). + * + * We save the focused task region once we find it, and add it back at the end. + */ + + task.getDimBounds(mTmpRect); + + if (task == focusedTask) { + // Add the focused task rect back into the exclude region once we are done + // processing stacks. + postExclude.set(mTmpRect); + } + + final boolean isFreeformed = task.inFreeformWorkspace(); + if (task != focusedTask || isFreeformed) { + if (isFreeformed) { + // If the task is freeformed, enlarge the area to account for outside + // touch area for resize. + mTmpRect.inset(-delta, -delta); + // Intersect with display content rect. If we have system decor (status bar/ + // navigation bar), we want to exclude that from the tap detection. + // Otherwise, if the app is partially placed under some system button (eg. + // Recents, Home), pressing that button would cause a full series of + // unwanted transfer focus/resume/pause, before we could go home. + mTmpRect.intersect(contentRect); + } + touchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE); + } + } + } + @Override // AnimatesBounds public boolean setSize(Rect bounds) { synchronized (mService.mWindowMap) { @@ -1322,6 +1438,63 @@ public class TaskStack implements DimLayer.DimLayerUser, } } + /** Returns true if a removal action is still being deferred. */ + boolean checkCompleteDeferredRemoval() { + if (isAnimating()) { + return true; + } + if (mDeferDetach) { + mDisplayContent.detachChild(this); + } + + boolean stillDeferringRemoval = false; + for (int i = mTasks.size() - 1; i >= 0; --i) { + final Task task = mTasks.get(i); + stillDeferringRemoval |= task.checkCompleteDeferredRemoval(); + } + return stillDeferringRemoval; + } + + void checkAppWindowsReadyToShow(int displayId) { + for (int i = mTasks.size() - 1; i >= 0; --i) { + final Task task = mTasks.get(i); + task.checkAppWindowsReadyToShow(displayId); + } + } + + void updateAllDrawn(int displayId) { + for (int i = mTasks.size() - 1; i >= 0; --i) { + final Task task = mTasks.get(i); + task.updateAllDrawn(displayId); + } + } + + void stepAppWindowsAnimation(long currentTime, int displayId) { + for (int i = mTasks.size() - 1; i >= 0; --i) { + final Task task = mTasks.get(i); + task.stepAppWindowsAnimation(currentTime, displayId); + } + + // TODO: Why aren't we just using the loop above for this? mAppAnimator.animating isn't set + // below but is set in the loop above. See if it really matters... + final int exitingCount = mExitingAppTokens.size(); + for (int i = 0; i < exitingCount; i++) { + final AppWindowAnimator appAnimator = mExitingAppTokens.get(i).mAppAnimator; + appAnimator.wasAnimating = appAnimator.animating; + if (appAnimator.stepAnimationLocked(currentTime, displayId)) { + mService.mAnimator.setAnimating(true); + mService.mAnimator.mAppWindowAnimating = true; + } else if (appAnimator.wasAnimating) { + // stopped animating, do one more pass through the layout + appAnimator.mAppToken.setAppLayoutChanges( + WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, + "exiting appToken " + appAnimator.mAppToken + " done", displayId); + if (DEBUG_ANIM) Slog.v(TAG_WM, + "updateWindowsApps...: done animating exiting " + appAnimator.mAppToken); + } + } + } + void onAppTransitionDone() { for (int i = mTasks.size() - 1; i >= 0; --i) { final Task task = mTasks.get(i); @@ -1350,7 +1523,7 @@ public class TaskStack implements DimLayer.DimLayerUser, } void getWindowOnDisplayBeforeToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResults result) { + DisplayContent.GetWindowOnDisplaySearchResult result) { for (int i = mTasks.size() - 1; i >= 0; --i) { final Task task = mTasks.get(i); task.getWindowOnDisplayBeforeToken(dc, token, result); @@ -1362,7 +1535,7 @@ public class TaskStack implements DimLayer.DimLayerUser, } void getWindowOnDisplayAfterToken(DisplayContent dc, WindowToken token, - DisplayContent.GetWindowOnDisplaySearchResults result) { + DisplayContent.GetWindowOnDisplaySearchResult result) { for (int i = mTasks.size() - 1; i >= 0; --i) { final Task task = mTasks.get(i); task.getWindowOnDisplayAfterToken(dc, token, result); diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 38f7e6409504b..6665a937516d4 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -29,7 +29,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEYGUARD; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE; @@ -169,61 +168,6 @@ public class WindowAnimator { mDisplayContentsAnimators.delete(displayId); } - private void updateAppWindowsLocked(int displayId) { - ArrayList stacks = mService.getDisplayContentLocked(displayId).getStacks(); - for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { - final TaskStack stack = stacks.get(stackNdx); - final ArrayList tasks = stack.getTasks(); - for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { - final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; - for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { - final AppWindowAnimator appAnimator = tokens.get(tokenNdx).mAppAnimator; - appAnimator.wasAnimating = appAnimator.animating; - if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) { - appAnimator.animating = true; - setAnimating(true); - mAppWindowAnimating = true; - } else if (appAnimator.wasAnimating) { - // stopped animating, do one more pass through the layout - setAppLayoutChanges(appAnimator, - WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, - "appToken " + appAnimator.mAppToken + " done", displayId); - if (DEBUG_ANIM) Slog.v(TAG, - "updateWindowsApps...: done animating " + appAnimator.mAppToken); - } - } - } - - mTmpExitingAppTokens.clear(); - mTmpExitingAppTokens.addAll(stack.mExitingAppTokens); - - final int exitingCount = mTmpExitingAppTokens.size(); - for (int i = 0; i < exitingCount; i++) { - final AppWindowAnimator appAnimator = mTmpExitingAppTokens.get(i).mAppAnimator; - // stepAnimation can trigger finishExit->removeWindowInnerLocked - // ->performSurfacePlacement - // performSurfacePlacement will directly manipulate the mExitingAppTokens list - // so we need to iterate over a copy and check for modifications. - if (!stack.mExitingAppTokens.contains(appAnimator)) { - continue; - } - appAnimator.wasAnimating = appAnimator.animating; - if (appAnimator.stepAnimationLocked(mCurrentTime, displayId)) { - setAnimating(true); - mAppWindowAnimating = true; - } else if (appAnimator.wasAnimating) { - // stopped animating, do one more pass through the layout - setAppLayoutChanges(appAnimator, - WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, - "exiting appToken " + appAnimator.mAppToken + " done", displayId); - if (DEBUG_ANIM) Slog.v(TAG, - "updateWindowsApps...: done animating exiting " - + appAnimator.mAppToken); - } - } - } - } - /** * @return The window that is currently hiding the Keyguard, or if it was hiding the Keyguard, * and it's still animating. @@ -648,54 +592,6 @@ public class WindowAnimator { } } - /** See if any windows have been drawn, so they (and others associated with them) can now be - * shown. */ - private void testTokenMayBeDrawnLocked(int displayId) { - // See if any windows have been drawn, so they (and others - // associated with them) can now be shown. - final ArrayList tasks = mService.getDisplayContentLocked(displayId).getTasks(); - final int numTasks = tasks.size(); - for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { - final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; - final int numTokens = tokens.size(); - for (int tokenNdx = 0; tokenNdx < numTokens; ++tokenNdx) { - final AppWindowToken wtoken = tokens.get(tokenNdx); - AppWindowAnimator appAnimator = wtoken.mAppAnimator; - final boolean allDrawn = wtoken.allDrawn; - if (allDrawn != appAnimator.allDrawn) { - appAnimator.allDrawn = allDrawn; - if (allDrawn) { - // The token has now changed state to having all - // windows shown... what to do, what to do? - if (appAnimator.freezingScreen) { - appAnimator.showAllWindowsLocked(); - wtoken.stopFreezingScreen(false, true); - if (DEBUG_ORIENTATION) Slog.i(TAG, - "Setting mOrientationChangeComplete=true because wtoken " - + wtoken + " numInteresting=" + wtoken.numInterestingWindows - + " numDrawn=" + wtoken.numDrawnWindows); - // This will set mOrientationChangeComplete and cause a pass through - // layout. - setAppLayoutChanges(appAnimator, - WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER, - "testTokenMayBeDrawnLocked: freezingScreen", displayId); - } else { - setAppLayoutChanges(appAnimator, - WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM, - "testTokenMayBeDrawnLocked", displayId); - - // We can now show all of the drawn windows! - if (!mService.mOpeningApps.contains(wtoken)) { - orAnimating(appAnimator.showAllWindowsLocked()); - } - } - } - } - } - } - } - - /** Locked on mService.mWindowMap. */ private void animateLocked(long frameTimeNs) { if (!mInitialized) { @@ -719,7 +615,8 @@ public class WindowAnimator { final int numDisplays = mDisplayContentsAnimators.size(); for (int i = 0; i < numDisplays; i++) { final int displayId = mDisplayContentsAnimators.keyAt(i); - updateAppWindowsLocked(displayId); + final DisplayContent displayContent = mService.getDisplayContentLocked(displayId); + displayContent.stepAppWindowsAnimation(mCurrentTime); DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i); final ScreenRotationAnimation screenRotationAnimation = @@ -757,8 +654,9 @@ public class WindowAnimator { for (int i = 0; i < numDisplays; i++) { final int displayId = mDisplayContentsAnimators.keyAt(i); + final DisplayContent displayContent = mService.getDisplayContentLocked(displayId); - testTokenMayBeDrawnLocked(displayId); + displayContent.checkAppWindowsReadyToShow(); final ScreenRotationAnimation screenRotationAnimation = mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation; @@ -766,12 +664,10 @@ public class WindowAnimator { screenRotationAnimation.updateSurfacesInTransaction(); } - orAnimating(mService.getDisplayContentLocked(displayId).animateDimLayers()); - orAnimating(mService.getDisplayContentLocked(displayId).getDockedDividerController() - .animate(mCurrentTime)); + orAnimating(displayContent.animateDimLayers()); + orAnimating(displayContent.getDockedDividerController().animate(mCurrentTime)); //TODO (multidisplay): Magnification is supported only for the default display. - if (mService.mAccessibilityController != null - && displayId == Display.DEFAULT_DISPLAY) { + if (mService.mAccessibilityController != null && displayContent.isDefaultDisplay) { mService.mAccessibilityController.drawMagnifiedRegionBorderIfNeededLocked(); } } @@ -950,11 +846,6 @@ public class WindowAnimator { } } - void setAppLayoutChanges( - AppWindowAnimator appAnimator, int changes, String reason, int displayId) { - appAnimator.mAppToken.setAppLayoutChanges(changes, reason, displayId); - } - private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) { DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.get(displayId); if (displayAnimator == null) { diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java index eaf6aaae995c6..7273a06191490 100644 --- a/services/core/java/com/android/server/wm/WindowContainer.java +++ b/services/core/java/com/android/server/wm/WindowContainer.java @@ -251,6 +251,51 @@ class WindowContainer implements Comparable { return mChildren.isEmpty() ? this : mChildren.peekLast(); } + /** Returns true if there is still a removal being deferred */ + boolean checkCompleteDeferredRemoval() { + boolean stillDeferringRemoval = false; + + for (int i = mChildren.size() - 1; i >= 0; --i) { + final WindowContainer wc = mChildren.get(i); + stillDeferringRemoval |= wc.checkCompleteDeferredRemoval(); + } + + return stillDeferringRemoval; + } + + /** Checks if all windows in an app are all drawn and shows them if needed. */ + // TODO: The displayId shouldn't be needed as there shouldn't be a container on more than one + // display. Remove once we migrate DisplayContent to use WindowContainer. + void checkAppWindowsReadyToShow(int displayId) { + for (int i = mChildren.size() - 1; i >= 0; --i) { + final WindowContainer wc = mChildren.get(i); + wc.checkAppWindowsReadyToShow(displayId); + } + } + + /** + * Updates the current all drawn status for this container. That is all its children + * that should draw something have done so. + */ + // TODO: The displayId shouldn't be needed as there shouldn't be a container on more than one + // display. Remove once we migrate DisplayContent to use WindowContainer. + void updateAllDrawn(int displayId) { + for (int i = mChildren.size() - 1; i >= 0; --i) { + final WindowContainer wc = mChildren.get(i); + wc.updateAllDrawn(displayId); + } + } + + /** Step currently ongoing animation for App window containers. */ + // TODO: The displayId shouldn't be needed as there shouldn't be a container on more than one + // display. Remove once we migrate DisplayContent to use WindowContainer. + void stepAppWindowsAnimation(long currentTime, int displayId) { + for (int i = mChildren.size() - 1; i >= 0; --i) { + final WindowContainer wc = mChildren.get(i); + wc.stepAppWindowsAnimation(currentTime, displayId); + } + } + void onAppTransitionDone() { for (int i = mChildren.size() - 1; i >= 0; --i) { final WindowContainer wc = mChildren.get(i); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 39544c0a3132b..507db7cb439bf 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -162,7 +162,6 @@ import java.lang.annotation.RetentionPolicy; import java.net.Socket; import java.text.DateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; @@ -170,7 +169,6 @@ import java.util.List; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; -import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.app.StatusBarManager.DISABLE_MASK; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; @@ -216,7 +214,6 @@ import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; @@ -927,6 +924,12 @@ public class WindowManagerService extends IWindowManager.Stub } }; + final ArrayList mAppFreezeListeners = new ArrayList<>(); + + interface AppFreezeListener { + void onAppFreezeTimeout(); + } + public static WindowManagerService main(final Context context, final InputManagerService im, final boolean haveInputMethods, final boolean showBootMsgs, @@ -3967,20 +3970,9 @@ public class WindowManagerService extends IWindowManager.Stub return null; } - void detachStackLocked(DisplayContent displayContent, TaskStack stack) { - displayContent.detachStack(stack); - if (stack.detachFromDisplay()) { - mWindowPlacerLocked.requestTraversal(); - } - if (stack.mStackId == DOCKED_STACK_ID) { - getDefaultDisplayContentLocked().mDividerControllerLocked - .notifyDockedStackExistsChanged(false); - } - } - public void detachStack(int stackId) { synchronized (mWindowMap) { - TaskStack stack = mStackIdToStack.get(stackId); + final TaskStack stack = mStackIdToStack.get(stackId); if (stack != null) { final DisplayContent displayContent = stack.getDisplayContent(); if (displayContent != null) { @@ -3988,7 +3980,7 @@ public class WindowManagerService extends IWindowManager.Stub stack.mDeferDetach = true; return; } - detachStackLocked(displayContent, stack); + displayContent.detachChild(stack); } } } @@ -4675,22 +4667,13 @@ public class WindowManagerService extends IWindowManager.Stub } } - /** - * Returns whether there is a docked task for the current user. - */ + /** Returns whether there is a docked task for the current user. */ boolean hasDockedTasksForUser(int userId) { final TaskStack stack = mStackIdToStack.get(DOCKED_STACK_ID); if (stack == null) { return false; } - - final ArrayList tasks = stack.getTasks(); - boolean hasUserTask = false; - for (int i = tasks.size() - 1; i >= 0 && !hasUserTask; i--) { - final Task task = tasks.get(i); - hasUserTask = (task.mUserId == userId); - } - return hasUserTask; + return stack.hasTaskForUser(userId); } /* Called by WindowState */ @@ -7382,20 +7365,8 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { Slog.w(TAG_WM, "App freeze timeout expired."); mWindowsFreezingScreen = WINDOWS_FREEZING_SCREENS_TIMEOUT; - final int numStacks = mStackIdToStack.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { - final TaskStack stack = mStackIdToStack.valueAt(stackNdx); - final ArrayList tasks = stack.getTasks(); - for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { - AppTokenList tokens = tasks.get(taskNdx).mAppTokens; - for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { - AppWindowToken tok = tokens.get(tokenNdx); - if (tok.mAppAnimator.freezingScreen) { - Slog.w(TAG_WM, "Force clearing freeze: " + tok); - tok.stopFreezingScreen(true, true); - } - } - } + for (int i = mAppFreezeListeners.size() - 1; i >=0 ; --i) { + mAppFreezeListeners.get(i).onAppFreezeTimeout(); } } break; @@ -10326,4 +10297,15 @@ public class WindowManagerService extends IWindowManager.Stub } } } + + void registerAppFreezeListener(AppFreezeListener listener) { + if (!mAppFreezeListeners.contains(listener)) { + mAppFreezeListeners.add(listener); + } + } + + void unregisterAppFreezeListener(AppFreezeListener listener) { + mAppFreezeListeners.remove(listener); + } + } diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index f128cf96def36..cd93a8c543e40 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -37,7 +37,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerService.H.DO_TRAVERSAL; -import static com.android.server.wm.WindowManagerService.H.NOTIFY_ACTIVITY_DRAWN; import static com.android.server.wm.WindowManagerService.H.NOTIFY_APP_TRANSITION_STARTING; import static com.android.server.wm.WindowManagerService.H.NOTIFY_STARTING_WINDOW_DRAWN; import static com.android.server.wm.WindowManagerService.H.REPORT_LOSING_FOCUS; @@ -560,7 +559,7 @@ class WindowSurfacePlacer { // Remove all deferred displays stacks, tasks, and activities. for (int displayNdx = mService.mDisplayContents.size() - 1; displayNdx >= 0; --displayNdx) { - mService.mDisplayContents.valueAt(displayNdx).onCompleteDeferredRemoval(); + mService.mDisplayContents.valueAt(displayNdx).checkCompleteDeferredRemoval(); } if (updateInputWindowsNeeded) { @@ -865,7 +864,9 @@ class WindowSurfacePlacer { displayContent.stopDimmingIfNeeded(); if (updateAllDrawn) { - updateAllDrawnLocked(displayContent); + // See if any windows have been drawn, so they (and others associated with them) + // can now be shown. + displayContent.updateAllDrawn(); } } @@ -1516,52 +1517,6 @@ class WindowSurfacePlacer { } } - private void updateAllDrawnLocked(DisplayContent displayContent) { - // See if any windows have been drawn, so they (and others - // associated with them) can now be shown. - ArrayList stacks = displayContent.getStacks(); - for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { - final ArrayList tasks = stacks.get(stackNdx).getTasks(); - for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { - final AppTokenList tokens = tasks.get(taskNdx).mAppTokens; - for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { - final AppWindowToken wtoken = tokens.get(tokenNdx); - if (!wtoken.allDrawn) { - int numInteresting = wtoken.numInterestingWindows; - if (numInteresting > 0 && wtoken.numDrawnWindows >= numInteresting) { - if (DEBUG_VISIBILITY) - Slog.v(TAG, "allDrawn: " + wtoken - + " interesting=" + numInteresting - + " drawn=" + wtoken.numDrawnWindows); - wtoken.allDrawn = true; - // Force an additional layout pass where WindowStateAnimator# - // commitFinishDrawingLocked() will call performShowLocked(). - displayContent.layoutNeeded = true; - mService.mH.obtainMessage(NOTIFY_ACTIVITY_DRAWN, - wtoken.token).sendToTarget(); - } - } - if (!wtoken.allDrawnExcludingSaved) { - int numInteresting = wtoken.numInterestingWindowsExcludingSaved; - if (numInteresting > 0 - && wtoken.numDrawnWindowsExcludingSaved >= numInteresting) { - if (DEBUG_VISIBILITY) - Slog.v(TAG, "allDrawnExcludingSaved: " + wtoken - + " interesting=" + numInteresting - + " drawn=" + wtoken.numDrawnWindowsExcludingSaved); - wtoken.allDrawnExcludingSaved = true; - displayContent.layoutNeeded = true; - if (wtoken.isAnimatingInvisibleWithSavedSurface() - && !mService.mFinishedEarlyAnim.contains(wtoken)) { - mService.mFinishedEarlyAnim.add(wtoken); - } - } - } - } - } - } - } - private static int toBrightnessOverride(float value) { return (int)(value * PowerManager.BRIGHTNESS_ON); } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index d1d612bde4090..2f9ed501aa56d 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; -import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;