Merge "Made Task.mAppTokens private scoped"
This commit is contained in:
committed by
Android (Google) Code Review
commit
76f856ac0c
@@ -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<AppWindowToken> {
|
||||
* 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()) {
|
||||
|
||||
@@ -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<Task> mTmpTaskHistory = new ArrayList<Task>();
|
||||
|
||||
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<Task> 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<Task> 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<Task> 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<Task> 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<Task> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<Task> 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);
|
||||
|
||||
@@ -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<TaskStack> stacks = mService.getDisplayContentLocked(displayId).getStacks();
|
||||
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
final TaskStack stack = stacks.get(stackNdx);
|
||||
final ArrayList<Task> 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<Task> 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) {
|
||||
|
||||
@@ -251,6 +251,51 @@ class WindowContainer implements Comparable<WindowContainer> {
|
||||
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);
|
||||
|
||||
@@ -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<AppFreezeListener> 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<Task> 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<Task> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<TaskStack> stacks = displayContent.getStacks();
|
||||
for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
|
||||
final ArrayList<Task> 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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user