Made AppWindowToken.allAppWindows private
Pre-clean-up before switching class to using WindowContainer. Bug: 30060889 Change-Id: Ic3d47d47b922668eeb70988ce883267b46ca9d72
This commit is contained in:
@@ -157,11 +157,9 @@ public class AppWindowAnimator {
|
||||
}
|
||||
|
||||
// Since we are finally starting our animation, we don't need the logic anymore to prevent
|
||||
// the app from showing again if we just moved between stacks. See
|
||||
// {@link WindowState#notifyMovedInStack}.
|
||||
for (int i = mAppToken.allAppWindows.size() - 1; i >= 0; i--) {
|
||||
mAppToken.allAppWindows.get(i).resetJustMovedInStack();
|
||||
}
|
||||
// the app from showing again if we just moved between stacks.
|
||||
// See {@link WindowState#notifyMovedInStack}.
|
||||
mAppToken.resetJustMovedInStack();
|
||||
}
|
||||
|
||||
public void setDummyAnimation() {
|
||||
@@ -234,23 +232,7 @@ public class AppWindowAnimator {
|
||||
}
|
||||
|
||||
void updateLayers() {
|
||||
final int windowCount = mAppToken.allAppWindows.size();
|
||||
final int adj = animLayerAdjustment;
|
||||
thumbnailLayer = -1;
|
||||
final WallpaperController wallpaperController = mService.mWallpaperControllerLocked;
|
||||
for (int i = 0; i < windowCount; i++) {
|
||||
final WindowState w = mAppToken.allAppWindows.get(i);
|
||||
final WindowStateAnimator winAnimator = w.mWinAnimator;
|
||||
winAnimator.mAnimLayer = w.mLayer + adj;
|
||||
if (winAnimator.mAnimLayer > thumbnailLayer) {
|
||||
thumbnailLayer = winAnimator.mAnimLayer;
|
||||
}
|
||||
if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + winAnimator.mAnimLayer);
|
||||
if (w == mService.mInputMethodTarget && !mService.mInputMethodTargetWaitingAnim) {
|
||||
mService.mLayersController.setInputMethodAnimLayerAdjustment(adj);
|
||||
}
|
||||
wallpaperController.setAnimLayerAdjustment(w, adj);
|
||||
}
|
||||
thumbnailLayer = mAppToken.adjustAnimLayer(animLayerAdjustment);
|
||||
}
|
||||
|
||||
private void stepThumbnailAnimation(long currentTime) {
|
||||
|
||||
@@ -17,18 +17,27 @@
|
||||
package com.android.server.wm;
|
||||
|
||||
import static android.app.ActivityManager.StackId;
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
|
||||
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
|
||||
import static android.view.WindowManagerPolicy.TRANSIT_ENTER;
|
||||
import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
|
||||
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;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYERS;
|
||||
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_RESIZE;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
|
||||
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.NOTIFY_ACTIVITY_DRAWN;
|
||||
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
|
||||
import static com.android.server.wm.WindowManagerService.WINDOWS_FREEZING_SCREENS_TIMEOUT;
|
||||
import static com.android.server.wm.WindowManagerService.logWithStack;
|
||||
|
||||
import com.android.server.input.InputApplicationHandle;
|
||||
import com.android.server.wm.WindowManagerService.H;
|
||||
@@ -37,8 +46,11 @@ import android.annotation.NonNull;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Slog;
|
||||
import android.view.IApplicationToken;
|
||||
import android.view.View;
|
||||
@@ -63,7 +75,7 @@ class AppWindowToken extends WindowToken {
|
||||
|
||||
// All of the windows and child windows that are included in this
|
||||
// application token. Note this list is NOT sorted!
|
||||
final WindowList allAppWindows = new WindowList();
|
||||
private final WindowList allAppWindows = new WindowList();
|
||||
@NonNull final AppWindowAnimator mAppAnimator;
|
||||
|
||||
final boolean voiceInteraction;
|
||||
@@ -280,6 +292,149 @@ class AppWindowToken extends WindowToken {
|
||||
}
|
||||
}
|
||||
|
||||
boolean setVisibility(WindowManager.LayoutParams lp,
|
||||
boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
|
||||
|
||||
boolean delayed = false;
|
||||
inPendingTransaction = false;
|
||||
|
||||
if (clientHidden == visible) {
|
||||
clientHidden = !visible;
|
||||
sendAppVisibilityToClients();
|
||||
}
|
||||
|
||||
// Allow for state changes and animation to be applied if:
|
||||
// * token is transitioning visibility state
|
||||
// * or the token was marked as hidden and is exiting before we had a chance to play the
|
||||
// transition animation
|
||||
// * or this is an opening app and windows are being replaced.
|
||||
boolean visibilityChanged = false;
|
||||
if (hidden == visible || (hidden && mIsExiting) || (visible && waitingForReplacement())) {
|
||||
final AccessibilityController accessibilityController = service.mAccessibilityController;
|
||||
boolean changed = false;
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
|
||||
"Changing app " + this + " hidden=" + hidden + " performLayout=" + performLayout);
|
||||
|
||||
boolean runningAppAnimation = false;
|
||||
|
||||
if (transit != AppTransition.TRANSIT_UNSET) {
|
||||
if (mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
|
||||
mAppAnimator.setNullAnimation();
|
||||
}
|
||||
if (service.applyAnimationLocked(this, lp, transit, visible, isVoiceInteraction)) {
|
||||
delayed = runningAppAnimation = true;
|
||||
}
|
||||
final WindowState window = findMainWindow();
|
||||
//TODO (multidisplay): Magnification is supported only for the default display.
|
||||
if (window != null && accessibilityController != null
|
||||
&& window.getDisplayId() == DEFAULT_DISPLAY) {
|
||||
accessibilityController.onAppWindowTransitionLocked(window, transit);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
final int windowsCount = allAppWindows.size();
|
||||
for (int i = 0; i < windowsCount; i++) {
|
||||
final WindowState win = allAppWindows.get(i);
|
||||
if (win == startingWindow) {
|
||||
// Starting window that's exiting will be removed when the animation finishes.
|
||||
// Mark all relevant flags for that onExitAnimationDone will proceed all the way
|
||||
// to actually remove it.
|
||||
if (!visible && win.isVisibleNow() && mAppAnimator.isAnimating()) {
|
||||
win.mAnimatingExit = true;
|
||||
win.mRemoveOnExit = true;
|
||||
win.mWindowRemovalAllowed = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//Slog.i(TAG_WM, "Window " + win + ": vis=" + win.isVisible());
|
||||
//win.dump(" ");
|
||||
if (visible) {
|
||||
if (!win.isVisibleNow()) {
|
||||
if (!runningAppAnimation) {
|
||||
win.mWinAnimator.applyAnimationLocked(TRANSIT_ENTER, true);
|
||||
//TODO (multidisplay): Magnification is supported only for the default
|
||||
if (accessibilityController != null
|
||||
&& win.getDisplayId() == DEFAULT_DISPLAY) {
|
||||
accessibilityController.onWindowTransitionLocked(win, TRANSIT_ENTER);
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
win.setDisplayLayoutNeeded();
|
||||
}
|
||||
} else if (win.isVisibleNow()) {
|
||||
if (!runningAppAnimation) {
|
||||
win.mWinAnimator.applyAnimationLocked(TRANSIT_EXIT, false);
|
||||
//TODO (multidisplay): Magnification is supported only for the default
|
||||
if (accessibilityController != null
|
||||
&& win.getDisplayId() == DEFAULT_DISPLAY) {
|
||||
accessibilityController.onWindowTransitionLocked(win,TRANSIT_EXIT);
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
win.setDisplayLayoutNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
hidden = hiddenRequested = !visible;
|
||||
visibilityChanged = true;
|
||||
if (!visible) {
|
||||
stopFreezingScreen(true, true);
|
||||
} else {
|
||||
// If we are being set visible, and the starting window is
|
||||
// not yet displayed, then make sure it doesn't get displayed.
|
||||
WindowState swin = startingWindow;
|
||||
if (swin != null && !swin.isDrawnLw()) {
|
||||
swin.mPolicyVisibility = false;
|
||||
swin.mPolicyVisibilityAfterAnim = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setVisibility: " + this
|
||||
+ ": hidden=" + hidden + " hiddenRequested=" + hiddenRequested);
|
||||
|
||||
if (changed) {
|
||||
service.mInputMonitor.setUpdateInputWindowsNeededLw();
|
||||
if (performLayout) {
|
||||
service.updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
|
||||
false /*updateInputWindows*/);
|
||||
service.mWindowPlacerLocked.performSurfacePlacement();
|
||||
}
|
||||
service.mInputMonitor.updateInputWindowsLw(false /*force*/);
|
||||
}
|
||||
}
|
||||
|
||||
if (mAppAnimator.animation != null) {
|
||||
delayed = true;
|
||||
}
|
||||
|
||||
for (int i = allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
|
||||
if (allAppWindows.get(i).mWinAnimator.isWindowAnimationSet()) {
|
||||
delayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (visibilityChanged) {
|
||||
if (visible && !delayed) {
|
||||
// The token was made immediately visible, there will be no entrance animation.
|
||||
// We need to inform the client the enter animation was finished.
|
||||
mEnteringAnimation = true;
|
||||
service.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(token);
|
||||
}
|
||||
|
||||
if (!service.mClosingApps.contains(this) && !service.mOpeningApps.contains(this)) {
|
||||
// The token is not closing nor opening, so even if there is an animation set, that
|
||||
// doesn't mean that it goes through the normal app transition cycle so we have
|
||||
// to inform the docked controller about visibility change.
|
||||
service.getDefaultDisplayContentLocked().getDockedDividerController()
|
||||
.notifyAppVisibilityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
return delayed;
|
||||
}
|
||||
|
||||
WindowState findMainWindow() {
|
||||
WindowState candidate = null;
|
||||
int j = allAppWindows.size();
|
||||
@@ -323,6 +478,16 @@ class AppWindowToken extends WindowToken {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isVisibleForUser() {
|
||||
for (int j = allAppWindows.size() - 1; j >= 0; j--) {
|
||||
final WindowState w = allAppWindows.get(j);
|
||||
if (!w.isHiddenFromUserLocked()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void removeAppFromTaskLocked() {
|
||||
mIsExiting = false;
|
||||
removeAllWindows();
|
||||
@@ -585,6 +750,27 @@ class AppWindowToken extends WindowToken {
|
||||
windows.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
void removeWindow(WindowState win) {
|
||||
super.removeWindow(win);
|
||||
|
||||
allAppWindows.remove(win);
|
||||
|
||||
if (startingWindow == win) {
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
|
||||
service.scheduleRemoveStartingWindowLocked(this);
|
||||
} else if (allAppWindows.size() == 0 && startingData != null) {
|
||||
// If this is the last window and we had requested a starting transition window,
|
||||
// well there is no point now.
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
|
||||
startingData = null;
|
||||
} else if (allAppWindows.size() == 1 && startingView != null) {
|
||||
// If this is the last window except for a starting transition window,
|
||||
// we need to get rid of the starting transition.
|
||||
service.scheduleRemoveStartingWindowLocked(this);
|
||||
}
|
||||
}
|
||||
|
||||
void removeAllDeadWindows() {
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0;
|
||||
// removeWindowLocked at bottom of loop may remove multiple entries from
|
||||
@@ -691,6 +877,10 @@ class AppWindowToken extends WindowToken {
|
||||
}
|
||||
|
||||
void addWindow(WindowState w) {
|
||||
if (allAppWindows.contains(w)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
|
||||
WindowState candidate = allAppWindows.get(i);
|
||||
if (candidate.mWillReplaceWindow && candidate.mReplacingWindow == null &&
|
||||
@@ -819,6 +1009,350 @@ class AppWindowToken extends WindowToken {
|
||||
}
|
||||
}
|
||||
|
||||
void resetJustMovedInStack() {
|
||||
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
|
||||
allAppWindows.get(i).resetJustMovedInStack();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
int adjustAnimLayer(int adj) {
|
||||
int highestAnimLayer = super.adjustAnimLayer(adj);
|
||||
|
||||
final int windowCount = allAppWindows.size();
|
||||
|
||||
for (int i = 0; i < windowCount; i++) {
|
||||
final WindowState w = allAppWindows.get(i);
|
||||
w.adjustAnimLayer(adj);
|
||||
|
||||
final int animLayer = w.mWinAnimator.mAnimLayer;
|
||||
if (DEBUG_LAYERS) Slog.v(TAG, "Updating layer " + w + ": " + animLayer);
|
||||
if (animLayer > highestAnimLayer) {
|
||||
highestAnimLayer = animLayer;
|
||||
}
|
||||
if (w == service.mInputMethodTarget && !service.mInputMethodTargetWaitingAnim) {
|
||||
service.mLayersController.setInputMethodAnimLayerAdjustment(adj);
|
||||
}
|
||||
}
|
||||
|
||||
return highestAnimLayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
int getHighestAnimLayer() {
|
||||
int layer = super.getHighestAnimLayer();
|
||||
for (int j = 0; j < allAppWindows.size(); j++) {
|
||||
final WindowState win = allAppWindows.get(j);
|
||||
if (win.mWinAnimator.mAnimLayer > layer) {
|
||||
layer = win.mWinAnimator.mAnimLayer;
|
||||
}
|
||||
}
|
||||
return layer;
|
||||
}
|
||||
|
||||
void setWaitingForDrawnIfResizingChanged() {
|
||||
for (int i = allAppWindows.size() - 1; i >= 0; --i) {
|
||||
final WindowState win = allAppWindows.get(i);
|
||||
if (win.isDragResizeChanged()) {
|
||||
service.mWaitingForDrawn.add(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void resizeWindows() {
|
||||
final ArrayList<WindowState> resizingWindows = service.mResizingWindows;
|
||||
// Some windows won't go through the resizing process, if they don't have a surface, so
|
||||
// destroy all saved surfaces here.
|
||||
destroySavedSurfaces();
|
||||
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = allAppWindows.get(winNdx);
|
||||
if (win.mHasSurface && !resizingWindows.contains(win)) {
|
||||
if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
|
||||
resizingWindows.add(win);
|
||||
|
||||
// If we are not drag resizing, force recreating of a new surface so updating
|
||||
// the content and positioning that surface will be in sync.
|
||||
//
|
||||
// As we use this flag as a hint to freeze surface boundary updates,
|
||||
// we'd like to only apply this to TYPE_BASE_APPLICATION,
|
||||
// windows of TYPE_APPLICATION like dialogs, could appear
|
||||
// to not be drag resizing while they resize, but we'd
|
||||
// still like to manipulate their frame to update crop, etc...
|
||||
//
|
||||
// Anyway we don't need to synchronize position and content updates for these
|
||||
// windows since they aren't at the base layer and could be moved around anyway.
|
||||
if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
|
||||
!mTask.mStack.getBoundsAnimating() && !win.isGoneForLayoutLw() &&
|
||||
!mTask.inPinnedWorkspace()) {
|
||||
win.setResizedWhileNotDragResizing(true);
|
||||
}
|
||||
}
|
||||
if (win.isGoneForLayoutLw()) {
|
||||
win.mResizedWhileGone = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void moveWindows() {
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = allAppWindows.get(winNdx);
|
||||
if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
|
||||
win.mMovedByResize = true;
|
||||
}
|
||||
}
|
||||
|
||||
void notifyMovedInStack() {
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = allAppWindows.get(winNdx);
|
||||
win.notifyMovedInStack();
|
||||
}
|
||||
}
|
||||
|
||||
void resetDragResizingChangeReported() {
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = allAppWindows.get(winNdx);
|
||||
win.resetDragResizingChangeReported();
|
||||
}
|
||||
}
|
||||
|
||||
void detachDisplay() {
|
||||
boolean doAnotherLayoutPass = false;
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
// We are in the middle of changing the state of displays/stacks/tasks. We need
|
||||
// to finish that, before we let layout interfere with it.
|
||||
service.removeWindowLocked(allAppWindows.get(winNdx));
|
||||
doAnotherLayoutPass = true;
|
||||
}
|
||||
if (doAnotherLayoutPass) {
|
||||
service.mWindowPlacerLocked.requestTraversal();
|
||||
}
|
||||
}
|
||||
|
||||
void forceWindowsScaleableInTransaction(boolean force) {
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowStateAnimator winAnimator = allAppWindows.get(winNdx).mWinAnimator;
|
||||
if (winAnimator == null || !winAnimator.hasSurface()) {
|
||||
continue;
|
||||
}
|
||||
winAnimator.mSurfaceController.forceScaleableInTransaction(force);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAnimating() {
|
||||
for (int winNdx = allAppWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowStateAnimator winAnimator = allAppWindows.get(winNdx).mWinAnimator;
|
||||
if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setAppLayoutChanges(int changes, String reason, int displayId) {
|
||||
final WindowAnimator windowAnimator = mAppAnimator.mAnimator;
|
||||
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
|
||||
if (displayId == allAppWindows.get(i).getDisplayId()) {
|
||||
windowAnimator.setPendingLayoutChanges(displayId, changes);
|
||||
if (DEBUG_LAYOUT_REPEATS) {
|
||||
service.mWindowPlacerLocked.debugLayoutRepeats(
|
||||
reason, windowAnimator.getPendingLayoutChanges(displayId));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void removeReplacedWindowIfNeeded(WindowState replacement) {
|
||||
for (int i = allAppWindows.size() - 1; i >= 0; i--) {
|
||||
final WindowState win = allAppWindows.get(i);
|
||||
if (win.mWillReplaceWindow && win.mReplacingWindow == replacement
|
||||
&& replacement.hasDrawnLw()) {
|
||||
replacement.mSkipEnterAnimationForSeamlessReplacement = false;
|
||||
win.removeReplacedWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void startFreezingScreen() {
|
||||
if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + appToken + ": hidden="
|
||||
+ hidden + " freezing=" + mAppAnimator.freezingScreen);
|
||||
if (!hiddenRequested) {
|
||||
if (!mAppAnimator.freezingScreen) {
|
||||
mAppAnimator.freezingScreen = true;
|
||||
mAppAnimator.lastFreezeDuration = 0;
|
||||
service.mAppsFreezingScreen++;
|
||||
if (service.mAppsFreezingScreen == 1) {
|
||||
service.startFreezingDisplayLocked(false, 0, 0);
|
||||
service.mH.removeMessages(H.APP_FREEZE_TIMEOUT);
|
||||
service.mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
|
||||
}
|
||||
}
|
||||
final int count = allAppWindows.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
final WindowState w = allAppWindows.get(i);
|
||||
w.mAppFreezing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stopFreezingScreen(boolean unfreezeSurfaceNow, boolean force) {
|
||||
if (!mAppAnimator.freezingScreen) {
|
||||
return;
|
||||
}
|
||||
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + this + " force=" + force);
|
||||
final int count = allAppWindows.size();
|
||||
boolean unfrozeWindows = false;
|
||||
for (int i = 0; i < count; i++) {
|
||||
final WindowState w = allAppWindows.get(i);
|
||||
if (w.mAppFreezing) {
|
||||
w.mAppFreezing = false;
|
||||
if (w.mHasSurface && !w.mOrientationChanging
|
||||
&& service.mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
|
||||
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
|
||||
w.mOrientationChanging = true;
|
||||
service.mWindowPlacerLocked.mOrientationChangeComplete = false;
|
||||
}
|
||||
w.mLastFreezeDuration = 0;
|
||||
unfrozeWindows = true;
|
||||
w.setDisplayLayoutNeeded();
|
||||
}
|
||||
}
|
||||
if (force || unfrozeWindows) {
|
||||
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + this);
|
||||
mAppAnimator.freezingScreen = false;
|
||||
mAppAnimator.lastFreezeDuration =
|
||||
(int)(SystemClock.elapsedRealtime() - service.mDisplayFreezeTime);
|
||||
service.mAppsFreezingScreen--;
|
||||
service.mLastFinishedFreezeSource = this;
|
||||
}
|
||||
if (unfreezeSurfaceNow) {
|
||||
if (unfrozeWindows) {
|
||||
service.mWindowPlacerLocked.performSurfacePlacement();
|
||||
}
|
||||
service.stopFreezingDisplayLocked();
|
||||
}
|
||||
}
|
||||
|
||||
boolean transferStartingWindow(IBinder transferFrom) {
|
||||
final AppWindowToken fromToken = service.findAppWindowToken(transferFrom);
|
||||
if (fromToken == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final WindowState tStartingWindow = fromToken.startingWindow;
|
||||
if (tStartingWindow != null && fromToken.startingView != null) {
|
||||
// In this case, the starting icon has already been displayed, so start
|
||||
// letting windows get shown immediately without any more transitions.
|
||||
service.mSkipAppTransitionAnimation = true;
|
||||
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving existing starting " + tStartingWindow
|
||||
+ " from " + fromToken + " to " + this);
|
||||
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
|
||||
// Transfer the starting window over to the new token.
|
||||
startingData = fromToken.startingData;
|
||||
startingView = fromToken.startingView;
|
||||
startingDisplayed = fromToken.startingDisplayed;
|
||||
fromToken.startingDisplayed = false;
|
||||
startingWindow = tStartingWindow;
|
||||
reportedVisible = fromToken.reportedVisible;
|
||||
fromToken.startingData = null;
|
||||
fromToken.startingView = null;
|
||||
fromToken.startingWindow = null;
|
||||
fromToken.startingMoved = true;
|
||||
tStartingWindow.mToken = this;
|
||||
tStartingWindow.mRootToken = this;
|
||||
tStartingWindow.mAppToken = this;
|
||||
|
||||
if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
|
||||
"Removing starting window: " + tStartingWindow);
|
||||
tStartingWindow.getWindowList().remove(tStartingWindow);
|
||||
service.mWindowsChanged = true;
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
|
||||
"Removing starting " + tStartingWindow + " from " + fromToken);
|
||||
fromToken.removeWindow(tStartingWindow);
|
||||
fromToken.allAppWindows.remove(tStartingWindow);
|
||||
addWindowToList(tStartingWindow);
|
||||
|
||||
// Propagate other interesting state between the tokens. If the old token is displayed,
|
||||
// we should immediately force the new one to be displayed. If it is animating, we need
|
||||
// to move that animation to the new one.
|
||||
if (fromToken.allDrawn) {
|
||||
allDrawn = true;
|
||||
deferClearAllDrawn = fromToken.deferClearAllDrawn;
|
||||
}
|
||||
if (fromToken.firstWindowDrawn) {
|
||||
firstWindowDrawn = true;
|
||||
}
|
||||
if (!fromToken.hidden) {
|
||||
hidden = false;
|
||||
hiddenRequested = false;
|
||||
}
|
||||
if (clientHidden != fromToken.clientHidden) {
|
||||
clientHidden = fromToken.clientHidden;
|
||||
sendAppVisibilityToClients();
|
||||
}
|
||||
fromToken.mAppAnimator.transferCurrentAnimation(
|
||||
mAppAnimator, tStartingWindow.mWinAnimator);
|
||||
|
||||
service.updateFocusedWindowLocked(
|
||||
UPDATE_FOCUS_WILL_PLACE_SURFACES, true /*updateInputWindows*/);
|
||||
service.getDefaultDisplayContentLocked().layoutNeeded = true;
|
||||
service.mWindowPlacerLocked.performSurfacePlacement();
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return true;
|
||||
} else if (fromToken.startingData != null) {
|
||||
// The previous app was getting ready to show a
|
||||
// starting window, but hasn't yet done so. Steal it!
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
|
||||
"Moving pending starting from " + fromToken + " to " + this);
|
||||
startingData = fromToken.startingData;
|
||||
fromToken.startingData = null;
|
||||
fromToken.startingMoved = true;
|
||||
final Message m = service.mH.obtainMessage(H.ADD_STARTING, this);
|
||||
// Note: we really want to do sendMessageAtFrontOfQueue() because we want to process the
|
||||
// message ASAP, before any other queued messages.
|
||||
service.mH.sendMessageAtFrontOfQueue(m);
|
||||
return true;
|
||||
}
|
||||
|
||||
final AppWindowAnimator tAppAnimator = fromToken.mAppAnimator;
|
||||
final AppWindowAnimator wAppAnimator = mAppAnimator;
|
||||
if (tAppAnimator.thumbnail != null) {
|
||||
// The old token is animating with a thumbnail, transfer that to the new token.
|
||||
if (wAppAnimator.thumbnail != null) {
|
||||
wAppAnimator.thumbnail.destroy();
|
||||
}
|
||||
wAppAnimator.thumbnail = tAppAnimator.thumbnail;
|
||||
wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
|
||||
wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
|
||||
tAppAnimator.thumbnail = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int getWindowsCount() {
|
||||
return allAppWindows.size();
|
||||
}
|
||||
|
||||
void setAllAppWinAnimators() {
|
||||
final ArrayList<WindowStateAnimator> allAppWinAnimators = mAppAnimator.mAllAppWinAnimators;
|
||||
allAppWinAnimators.clear();
|
||||
|
||||
final int windowsCount = allAppWindows.size();
|
||||
for (int j = 0; j < windowsCount; j++) {
|
||||
allAppWinAnimators.add(allAppWindows.get(j).mWinAnimator);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns true if the app token windows list is empty. */
|
||||
@Override
|
||||
boolean isEmpty() {
|
||||
return allAppWindows.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
void dump(PrintWriter pw, String prefix) {
|
||||
super.dump(pw, prefix);
|
||||
|
||||
@@ -39,6 +39,7 @@ import android.util.Slog;
|
||||
import android.view.DisplayInfo;
|
||||
import android.view.Surface;
|
||||
|
||||
import android.view.SurfaceControl;
|
||||
import com.android.server.EventLogTags;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -178,11 +179,7 @@ class Task implements DimLayer.DimLayerUser {
|
||||
resizeLocked(bounds, config, false /* force */);
|
||||
|
||||
for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
|
||||
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = windows.get(winNdx);
|
||||
win.notifyMovedInStack();
|
||||
}
|
||||
mAppTokens.get(activityNdx).notifyMovedInStack();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,11 +475,7 @@ class Task implements DimLayer.DimLayerUser {
|
||||
|
||||
void resetDragResizingChangeReported() {
|
||||
for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
|
||||
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = windows.get(winNdx);
|
||||
win.resetDragResizingChangeReported();
|
||||
}
|
||||
mAppTokens.get(activityNdx).resetDragResizingChangeReported();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,15 +491,15 @@ class Task implements DimLayer.DimLayerUser {
|
||||
* Adds all of the tasks windows to {@link WindowManagerService#mWaitingForDrawn} if drag
|
||||
* resizing state of the window has been changed.
|
||||
*/
|
||||
void addWindowsWaitingForDrawnIfResizingChanged() {
|
||||
for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
|
||||
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = windows.get(winNdx);
|
||||
if (win.isDragResizeChanged()) {
|
||||
mService.mWaitingForDrawn.add(win);
|
||||
}
|
||||
}
|
||||
void setWaitingForDrawnIfResizingChanged() {
|
||||
for (int i = mAppTokens.size() - 1; i >= 0; --i) {
|
||||
mAppTokens.get(i).setWaitingForDrawnIfResizingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void detachDisplay() {
|
||||
for (int i = mAppTokens.size() - 1; i >= 0; --i) {
|
||||
mAppTokens.get(i).detachDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,52 +539,14 @@ class Task implements DimLayer.DimLayerUser {
|
||||
}
|
||||
|
||||
void resizeWindows() {
|
||||
final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
|
||||
for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final AppWindowToken atoken = mAppTokens.get(activityNdx);
|
||||
|
||||
// Some windows won't go through the resizing process, if they don't have a surface, so
|
||||
// destroy all saved surfaces here.
|
||||
atoken.destroySavedSurfaces();
|
||||
final ArrayList<WindowState> windows = atoken.allAppWindows;
|
||||
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = windows.get(winNdx);
|
||||
if (win.mHasSurface && !resizingWindows.contains(win)) {
|
||||
if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win);
|
||||
resizingWindows.add(win);
|
||||
|
||||
// If we are not drag resizing, force recreating of a new surface so updating
|
||||
// the content and positioning that surface will be in sync.
|
||||
//
|
||||
// As we use this flag as a hint to freeze surface boundary updates,
|
||||
// we'd like to only apply this to TYPE_BASE_APPLICATION,
|
||||
// windows of TYPE_APPLICATION like dialogs, could appear
|
||||
// to not be drag resizing while they resize, but we'd
|
||||
// still like to manipulate their frame to update crop, etc...
|
||||
//
|
||||
// Anyway we don't need to synchronize position and content updates for these
|
||||
// windows since they aren't at the base layer and could be moved around anyway.
|
||||
if (!win.computeDragResizing() && win.mAttrs.type == TYPE_BASE_APPLICATION &&
|
||||
!mStack.getBoundsAnimating() && !win.isGoneForLayoutLw() &&
|
||||
!inPinnedWorkspace()) {
|
||||
win.setResizedWhileNotDragResizing(true);
|
||||
}
|
||||
}
|
||||
if (win.isGoneForLayoutLw()) {
|
||||
win.mResizedWhileGone = true;
|
||||
}
|
||||
}
|
||||
mAppTokens.get(activityNdx).resizeWindows();
|
||||
}
|
||||
}
|
||||
|
||||
void moveWindows() {
|
||||
for (int activityNdx = mAppTokens.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final ArrayList<WindowState> windows = mAppTokens.get(activityNdx).allAppWindows;
|
||||
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowState win = windows.get(winNdx);
|
||||
if (DEBUG_RESIZE) Slog.d(TAG, "moveWindows: Moving " + win);
|
||||
win.mMovedByResize = true;
|
||||
}
|
||||
for (int i = mAppTokens.size() - 1; i >= 0; --i) {
|
||||
mAppTokens.get(i).moveWindows();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -621,11 +576,8 @@ class Task implements DimLayer.DimLayerUser {
|
||||
boolean isVisibleForUser() {
|
||||
for (int i = mAppTokens.size() - 1; i >= 0; i--) {
|
||||
final AppWindowToken appToken = mAppTokens.get(i);
|
||||
for (int j = appToken.allAppWindows.size() - 1; j >= 0; j--) {
|
||||
WindowState window = appToken.allAppWindows.get(j);
|
||||
if (!window.isHiddenFromUserLocked()) {
|
||||
return true;
|
||||
}
|
||||
if (appToken.isVisibleForUser()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -697,6 +649,27 @@ class Task implements DimLayer.DimLayerUser {
|
||||
return mStack.getDisplayContent().getDisplayInfo();
|
||||
}
|
||||
|
||||
void forceWindowsScaleable(boolean force) {
|
||||
SurfaceControl.openTransaction();
|
||||
try {
|
||||
for (int i = mAppTokens.size() - 1; i >= 0; i--) {
|
||||
mAppTokens.get(i).forceWindowsScaleableInTransaction(force);
|
||||
}
|
||||
} finally {
|
||||
SurfaceControl.closeTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAnimating() {
|
||||
for (int i = mAppTokens.size() - 1; i >= 0; i--) {
|
||||
final AppWindowToken aToken = mAppTokens.get(i);
|
||||
if (aToken.isAnimating()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{taskId=" + mTaskId + " appTokens=" + mAppTokens + " mdr=" + mDeferRemoval + "}";
|
||||
|
||||
@@ -477,15 +477,9 @@ public class TaskStack implements DimLayer.DimLayerUser,
|
||||
|
||||
boolean isAnimating() {
|
||||
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
|
||||
final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
|
||||
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
|
||||
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
|
||||
if (winAnimator.isAnimationSet() || winAnimator.mWin.mAnimatingExit) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
final Task task = mTasks.get(taskNdx);
|
||||
if (task.isAnimating()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -532,12 +526,11 @@ public class TaskStack implements DimLayer.DimLayerUser,
|
||||
}
|
||||
|
||||
if (StackId.windowsAreScaleable(mStackId)) {
|
||||
// We force windows out of SCALING_MODE_FREEZE
|
||||
// so that we can continue to animate them
|
||||
// We force windows out of SCALING_MODE_FREEZE so that we can continue to animate them
|
||||
// while a resize is pending.
|
||||
forceWindowsScaleable(task, true);
|
||||
task.forceWindowsScaleable(true);
|
||||
} else {
|
||||
forceWindowsScaleable(task, false);
|
||||
task.forceWindowsScaleable(false);
|
||||
}
|
||||
EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.mTaskId, toTop ? 1 : 0, position);
|
||||
}
|
||||
@@ -773,21 +766,8 @@ public class TaskStack implements DimLayer.DimLayerUser,
|
||||
void detachDisplay() {
|
||||
EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
|
||||
|
||||
boolean doAnotherLayoutPass = false;
|
||||
for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
|
||||
final AppTokenList appWindowTokens = mTasks.get(taskNdx).mAppTokens;
|
||||
for (int appNdx = appWindowTokens.size() - 1; appNdx >= 0; --appNdx) {
|
||||
final WindowList appWindows = appWindowTokens.get(appNdx).allAppWindows;
|
||||
for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
// We are in the middle of changing the state of displays/stacks/tasks. We need
|
||||
// to finish that, before we let layout interfere with it.
|
||||
mService.removeWindowLocked(appWindows.get(winNdx));
|
||||
doAnotherLayoutPass = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doAnotherLayoutPass) {
|
||||
mService.mWindowPlacerLocked.requestTraversal();
|
||||
mTasks.get(taskNdx).detachDisplay();
|
||||
}
|
||||
|
||||
close();
|
||||
@@ -922,7 +902,7 @@ public class TaskStack implements DimLayer.DimLayerUser,
|
||||
final Task task = mTasks.get(j);
|
||||
if (task.isVisibleForUser()) {
|
||||
task.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
|
||||
task.addWindowsWaitingForDrawnIfResizingChanged();
|
||||
task.setWaitingForDrawnIfResizingChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1290,25 +1270,6 @@ public class TaskStack implements DimLayer.DimLayerUser,
|
||||
return true;
|
||||
}
|
||||
|
||||
void forceWindowsScaleable(Task task, boolean force) {
|
||||
SurfaceControl.openTransaction();
|
||||
try {
|
||||
final ArrayList<AppWindowToken> activities = task.mAppTokens;
|
||||
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
|
||||
final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
|
||||
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
|
||||
final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
|
||||
if (winAnimator == null || !winAnimator.hasSurface()) {
|
||||
continue;
|
||||
}
|
||||
winAnimator.mSurfaceController.forceScaleableInTransaction(force);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
SurfaceControl.closeTransaction();
|
||||
}
|
||||
}
|
||||
|
||||
@Override // AnimatesBounds
|
||||
public void onAnimationStart() {
|
||||
synchronized (mService.mWindowMap) {
|
||||
|
||||
@@ -624,7 +624,7 @@ public class WindowAnimator {
|
||||
// windows shown... what to do, what to do?
|
||||
if (appAnimator.freezingScreen) {
|
||||
appAnimator.showAllWindowsLocked();
|
||||
mService.unsetAppFreezingScreenLocked(wtoken, false, true);
|
||||
wtoken.stopFreezingScreen(false, true);
|
||||
if (DEBUG_ORIENTATION) Slog.i(TAG,
|
||||
"Setting mOrientationChangeComplete=true because wtoken "
|
||||
+ wtoken + " numInteresting=" + wtoken.numInterestingWindows
|
||||
@@ -800,21 +800,23 @@ public class WindowAnimator {
|
||||
}
|
||||
|
||||
private void removeReplacedWindowsLocked() {
|
||||
if (SHOW_TRANSACTIONS) Slog.i(
|
||||
TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
|
||||
if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION removeReplacedWindows");
|
||||
SurfaceControl.openTransaction();
|
||||
try {
|
||||
for (int i = mService.mDisplayContents.size() - 1; i >= 0; i--) {
|
||||
DisplayContent display = mService.mDisplayContents.valueAt(i);
|
||||
final WindowList windows = mService.getWindowListLocked(display.getDisplayId());
|
||||
for (int j = windows.size() - 1; j >= 0; j--) {
|
||||
windows.get(j).maybeRemoveReplacedWindow();
|
||||
final WindowState win = windows.get(j);
|
||||
final AppWindowToken aToken = win.mAppToken;
|
||||
if (aToken != null) {
|
||||
aToken.removeReplacedWindowIfNeeded(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
SurfaceControl.closeTransaction();
|
||||
if (SHOW_TRANSACTIONS) Slog.i(
|
||||
TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
|
||||
if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION removeReplacedWindows");
|
||||
}
|
||||
mRemoveReplacedWindows = false;
|
||||
}
|
||||
@@ -903,19 +905,9 @@ public class WindowAnimator {
|
||||
}
|
||||
}
|
||||
|
||||
void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String reason,
|
||||
final int displayId) {
|
||||
WindowList windows = appAnimator.mAppToken.allAppWindows;
|
||||
for (int i = windows.size() - 1; i >= 0; i--) {
|
||||
if (displayId == windows.get(i).getDisplayId()) {
|
||||
setPendingLayoutChanges(displayId, changes);
|
||||
if (DEBUG_LAYOUT_REPEATS) {
|
||||
mWindowPlacerLocked.debugLayoutRepeats(reason,
|
||||
getPendingLayoutChanges(displayId));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
void setAppLayoutChanges(
|
||||
AppWindowAnimator appAnimator, int changes, String reason, int displayId) {
|
||||
appAnimator.mAppToken.setAppLayoutChanges(changes, reason, displayId);
|
||||
}
|
||||
|
||||
private DisplayContentsAnimator getDisplayContentsAnimatorLocked(int displayId) {
|
||||
|
||||
@@ -204,8 +204,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
|
||||
import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
|
||||
import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
|
||||
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
|
||||
import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
|
||||
import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
|
||||
import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
|
||||
import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
|
||||
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
|
||||
@@ -886,7 +885,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
private final DisplayContentList mReconfigureOnConfigurationChanged = new DisplayContentList();
|
||||
|
||||
/** Listener to notify activity manager about app transitions. */
|
||||
private final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
|
||||
final WindowManagerInternal.AppTransitionListener mActivityManagerAppTransitionNotifier
|
||||
= new WindowManagerInternal.AppTransitionListener() {
|
||||
|
||||
@Override
|
||||
@@ -1872,19 +1871,6 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private void setupWindowForRemoveOnExit(WindowState win) {
|
||||
win.mRemoveOnExit = true;
|
||||
win.setDisplayLayoutNeeded();
|
||||
// Request a focus update as this window's input channel is already gone. Otherwise
|
||||
// we could have no focused window in input manager.
|
||||
final boolean focusChanged = updateFocusedWindowLocked(
|
||||
UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
|
||||
mWindowPlacerLocked.performSurfacePlacement();
|
||||
if (focusChanged) {
|
||||
mInputMonitor.updateInputWindowsLw(false /*force*/);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeWindow(Session session, IWindow client) {
|
||||
synchronized(mWindowMap) {
|
||||
WindowState win = windowForClientLocked(session, client, false);
|
||||
@@ -1896,145 +1882,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
void removeWindowLocked(WindowState win) {
|
||||
removeWindowLocked(win, false);
|
||||
}
|
||||
|
||||
void removeWindowLocked(WindowState win, boolean keepVisibleDeadWindow) {
|
||||
win.mWindowRemovalAllowed = true;
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG,
|
||||
"removeWindowLocked: " + win + " callers=" + Debug.getCallers(4));
|
||||
|
||||
final boolean startingWindow = win.mAttrs.type == TYPE_APPLICATION_STARTING;
|
||||
if (startingWindow) {
|
||||
if (DEBUG_STARTING_WINDOW) Slog.d(TAG_WM, "Starting window removed " + win);
|
||||
}
|
||||
|
||||
if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && win == mCurrentFocus) Slog.v(
|
||||
TAG_WM, "Remove " + win + " client="
|
||||
+ Integer.toHexString(System.identityHashCode(win.mClient.asBinder()))
|
||||
+ ", surfaceController=" + win.mWinAnimator.mSurfaceController + " Callers="
|
||||
+ Debug.getCallers(4));
|
||||
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
|
||||
win.disposeInputChannel();
|
||||
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM,
|
||||
"Remove " + win + ": mSurfaceController=" + win.mWinAnimator.mSurfaceController
|
||||
+ " mAnimatingExit=" + win.mAnimatingExit
|
||||
+ " mRemoveOnExit=" + win.mRemoveOnExit
|
||||
+ " mHasSurface=" + win.mHasSurface
|
||||
+ " surfaceShowing=" + win.mWinAnimator.getShown()
|
||||
+ " isAnimationSet=" + win.mWinAnimator.isAnimationSet()
|
||||
+ " app-animation="
|
||||
+ (win.mAppToken != null ? win.mAppToken.mAppAnimator.animation : null)
|
||||
+ " mWillReplaceWindow=" + win.mWillReplaceWindow
|
||||
+ " inPendingTransaction="
|
||||
+ (win.mAppToken != null ? win.mAppToken.inPendingTransaction : false)
|
||||
+ " mDisplayFrozen=" + mDisplayFrozen
|
||||
+ " callers=" + Debug.getCallers(6));
|
||||
// Visibility of the removed window. Will be used later to update orientation later on.
|
||||
boolean wasVisible = false;
|
||||
// First, see if we need to run an animation. If we do, we have to hold off on removing the
|
||||
// window until the animation is done. If the display is frozen, just remove immediately,
|
||||
// since the animation wouldn't be seen.
|
||||
if (win.mHasSurface && okToDisplay()) {
|
||||
final AppWindowToken appToken = win.mAppToken;
|
||||
if (win.mWillReplaceWindow) {
|
||||
// This window is going to be replaced. We need to keep it around until the new one
|
||||
// gets added, then we will get rid of this one.
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Preserving " + win + " until the new one is "
|
||||
+ "added");
|
||||
// TODO: We are overloading mAnimatingExit flag to prevent the window state from
|
||||
// been removed. We probably need another flag to indicate that window removal
|
||||
// should be deffered vs. overloading the flag that says we are playing an exit
|
||||
// animation.
|
||||
win.mAnimatingExit = true;
|
||||
win.mReplacingRemoveRequested = true;
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (win.isAnimatingWithSavedSurface() && !appToken.allDrawnExcludingSaved) {
|
||||
// We started enter animation early with a saved surface, now the app asks to remove
|
||||
// this window. If we remove it now and the app is not yet drawn, we'll show a
|
||||
// flicker. Delay the removal now until it's really drawn.
|
||||
if (DEBUG_ADD_REMOVE) {
|
||||
Slog.d(TAG_WM, "removeWindowLocked: delay removal of " + win
|
||||
+ " due to early animation");
|
||||
}
|
||||
// Do not set mAnimatingExit to true here, it will cause the surface to be hidden
|
||||
// immediately after the enter animation is done. If the app is not yet drawn then
|
||||
// it will show up as a flicker.
|
||||
setupWindowForRemoveOnExit(win);
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
// If we are not currently running the exit animation, we need to see about starting one
|
||||
wasVisible = win.isWinVisibleLw();
|
||||
|
||||
if (keepVisibleDeadWindow) {
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
|
||||
"Not removing " + win + " because app died while it's visible");
|
||||
|
||||
win.mAppDied = true;
|
||||
win.setDisplayLayoutNeeded();
|
||||
mWindowPlacerLocked.performSurfacePlacement();
|
||||
|
||||
// Set up a replacement input channel since the app is now dead.
|
||||
// We need to catch tapping on the dead window to restart the app.
|
||||
win.openInputChannel(null);
|
||||
mInputMonitor.updateInputWindowsLw(true /*force*/);
|
||||
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
|
||||
final WindowStateAnimator winAnimator = win.mWinAnimator;
|
||||
if (wasVisible) {
|
||||
final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
|
||||
|
||||
// Try starting an animation.
|
||||
if (winAnimator.applyAnimationLocked(transit, false)) {
|
||||
win.mAnimatingExit = true;
|
||||
}
|
||||
//TODO (multidisplay): Magnification is supported only for the default display.
|
||||
if (mAccessibilityController != null
|
||||
&& win.getDisplayId() == Display.DEFAULT_DISPLAY) {
|
||||
mAccessibilityController.onWindowTransitionLocked(win, transit);
|
||||
}
|
||||
}
|
||||
final boolean isAnimating =
|
||||
winAnimator.isAnimationSet() && !winAnimator.isDummyAnimation();
|
||||
final boolean lastWindowIsStartingWindow = startingWindow && appToken != null
|
||||
&& appToken.allAppWindows.size() == 1;
|
||||
// We delay the removal of a window if it has a showing surface that can be used to run
|
||||
// exit animation and it is marked as exiting.
|
||||
// Also, If isn't the an animating starting window that is the last window in the app.
|
||||
// We allow the removal of the non-animating starting window now as there is no
|
||||
// additional window or animation that will trigger its removal.
|
||||
if (winAnimator.getShown() && win.mAnimatingExit
|
||||
&& (!lastWindowIsStartingWindow || isAnimating)) {
|
||||
// The exit animation is running or should run... wait for it!
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
|
||||
"Not removing " + win + " due to exit animation ");
|
||||
setupWindowForRemoveOnExit(win);
|
||||
if (appToken != null) {
|
||||
appToken.updateReportedVisibilityLocked();
|
||||
}
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
win.remove();
|
||||
// Removing a visible window will effect the computed orientation
|
||||
// So just update orientation if needed.
|
||||
if (wasVisible && updateOrientationFromAppTokensLocked(false)) {
|
||||
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
|
||||
}
|
||||
updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
win.removeIfPossible(false /*keepVisibleDeadWindow*/);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2063,42 +1911,26 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
final AppWindowToken atoken = win.mAppToken;
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM, "Removing " + win + " from " + token);
|
||||
token.removeWindow(win);
|
||||
if (atoken != null) {
|
||||
atoken.allAppWindows.remove(win);
|
||||
}
|
||||
if (token.isEmpty()) {
|
||||
if (!token.explicit) {
|
||||
mTokenMap.remove(token.token);
|
||||
} else if (atoken != null) {
|
||||
// TODO: Should this be moved into AppWindowToken.removeWindow? Might go away after
|
||||
// re-factor.
|
||||
atoken.firstWindowDrawn = false;
|
||||
atoken.clearAllDrawn();
|
||||
}
|
||||
}
|
||||
|
||||
if (atoken != null) {
|
||||
if (atoken.startingWindow == win) {
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Notify removed startingWindow " + win);
|
||||
scheduleRemoveStartingWindowLocked(atoken);
|
||||
} else
|
||||
if (atoken.allAppWindows.size() == 0 && atoken.startingData != null) {
|
||||
// If this is the last window and we had requested a starting
|
||||
// transition window, well there is no point now.
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Nulling last startingWindow");
|
||||
atoken.startingData = null;
|
||||
} else if (atoken.allAppWindows.size() == 1 && atoken.startingView != null) {
|
||||
// If this is the last window except for a starting transition
|
||||
// window, we need to get rid of the starting transition.
|
||||
scheduleRemoveStartingWindowLocked(atoken);
|
||||
}
|
||||
atoken.removeWindow(win);
|
||||
}
|
||||
|
||||
if (win.mAttrs.type == TYPE_WALLPAPER) {
|
||||
mWallpaperControllerLocked.clearLastWallpaperTimeoutTime();
|
||||
getDefaultDisplayContentLocked().pendingLayoutChanges |=
|
||||
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
} else if ((win.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0) {
|
||||
getDefaultDisplayContentLocked().pendingLayoutChanges |=
|
||||
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
getDefaultDisplayContentLocked().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
} else if ((win.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0) {
|
||||
getDefaultDisplayContentLocked().pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
}
|
||||
|
||||
final WindowList windows = win.getWindowList();
|
||||
@@ -2735,7 +2567,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
private boolean applyAnimationLocked(AppWindowToken atoken, WindowManager.LayoutParams lp,
|
||||
boolean applyAnimationLocked(AppWindowToken atoken, WindowManager.LayoutParams lp,
|
||||
int transit, boolean enter, boolean isVoiceInteraction) {
|
||||
// Only apply an animation if the display isn't frozen. If it is
|
||||
// frozen, there is no reason to animate and it can cause strange
|
||||
@@ -3231,9 +3063,9 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
|
||||
if (updateOrientationFromAppTokensLocked(false)) {
|
||||
if (freezeThisOneIfNeeded != null) {
|
||||
AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
|
||||
final AppWindowToken atoken = findAppWindowToken(freezeThisOneIfNeeded);
|
||||
if (atoken != null) {
|
||||
startAppFreezingScreenLocked(atoken);
|
||||
atoken.startFreezingScreen();
|
||||
}
|
||||
}
|
||||
config = computeNewConfigurationLocked();
|
||||
@@ -3677,7 +3509,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
if (transferStartingWindow(transferFrom, wtoken)) {
|
||||
if (wtoken != null && wtoken.transferStartingWindow(transferFrom)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3700,108 +3532,6 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean transferStartingWindow(IBinder transferFrom, AppWindowToken wtoken) {
|
||||
if (transferFrom == null) {
|
||||
return false;
|
||||
}
|
||||
AppWindowToken ttoken = findAppWindowToken(transferFrom);
|
||||
if (ttoken == null) {
|
||||
return false;
|
||||
}
|
||||
WindowState startingWindow = ttoken.startingWindow;
|
||||
if (startingWindow != null && ttoken.startingView != null) {
|
||||
// In this case, the starting icon has already been displayed, so start
|
||||
// letting windows get shown immediately without any more transitions.
|
||||
mSkipAppTransitionAnimation = true;
|
||||
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
|
||||
"Moving existing starting " + startingWindow + " from " + ttoken
|
||||
+ " to " + wtoken);
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
|
||||
// Transfer the starting window over to the new token.
|
||||
wtoken.startingData = ttoken.startingData;
|
||||
wtoken.startingView = ttoken.startingView;
|
||||
wtoken.startingDisplayed = ttoken.startingDisplayed;
|
||||
ttoken.startingDisplayed = false;
|
||||
wtoken.startingWindow = startingWindow;
|
||||
wtoken.reportedVisible = ttoken.reportedVisible;
|
||||
ttoken.startingData = null;
|
||||
ttoken.startingView = null;
|
||||
ttoken.startingWindow = null;
|
||||
ttoken.startingMoved = true;
|
||||
startingWindow.mToken = wtoken;
|
||||
startingWindow.mRootToken = wtoken;
|
||||
startingWindow.mAppToken = wtoken;
|
||||
|
||||
if (DEBUG_WINDOW_MOVEMENT || DEBUG_ADD_REMOVE || DEBUG_STARTING_WINDOW) {
|
||||
Slog.v(TAG_WM, "Removing starting window: " + startingWindow);
|
||||
}
|
||||
startingWindow.getWindowList().remove(startingWindow);
|
||||
mWindowsChanged = true;
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
|
||||
"Removing starting " + startingWindow + " from " + ttoken);
|
||||
ttoken.removeWindow(startingWindow);
|
||||
ttoken.allAppWindows.remove(startingWindow);
|
||||
wtoken.addWindowToList(startingWindow);
|
||||
|
||||
// Propagate other interesting state between the tokens. If the old token is displayed,
|
||||
// we should immediately force the new one to be displayed. If it is animating, we need
|
||||
// to move that animation to the new one.
|
||||
if (ttoken.allDrawn) {
|
||||
wtoken.allDrawn = true;
|
||||
wtoken.deferClearAllDrawn = ttoken.deferClearAllDrawn;
|
||||
}
|
||||
if (ttoken.firstWindowDrawn) {
|
||||
wtoken.firstWindowDrawn = true;
|
||||
}
|
||||
if (!ttoken.hidden) {
|
||||
wtoken.hidden = false;
|
||||
wtoken.hiddenRequested = false;
|
||||
}
|
||||
if (wtoken.clientHidden != ttoken.clientHidden) {
|
||||
wtoken.clientHidden = ttoken.clientHidden;
|
||||
wtoken.sendAppVisibilityToClients();
|
||||
}
|
||||
ttoken.mAppAnimator.transferCurrentAnimation(
|
||||
wtoken.mAppAnimator, startingWindow.mWinAnimator);
|
||||
|
||||
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
|
||||
true /*updateInputWindows*/);
|
||||
getDefaultDisplayContentLocked().layoutNeeded = true;
|
||||
mWindowPlacerLocked.performSurfacePlacement();
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return true;
|
||||
} else if (ttoken.startingData != null) {
|
||||
// The previous app was getting ready to show a
|
||||
// starting window, but hasn't yet done so. Steal it!
|
||||
if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Moving pending starting from " + ttoken
|
||||
+ " to " + wtoken);
|
||||
wtoken.startingData = ttoken.startingData;
|
||||
ttoken.startingData = null;
|
||||
ttoken.startingMoved = true;
|
||||
Message m = mH.obtainMessage(H.ADD_STARTING, wtoken);
|
||||
// Note: we really want to do sendMessageAtFrontOfQueue() because we
|
||||
// want to process the message ASAP, before any other queued
|
||||
// messages.
|
||||
mH.sendMessageAtFrontOfQueue(m);
|
||||
return true;
|
||||
}
|
||||
final AppWindowAnimator tAppAnimator = ttoken.mAppAnimator;
|
||||
final AppWindowAnimator wAppAnimator = wtoken.mAppAnimator;
|
||||
if (tAppAnimator.thumbnail != null) {
|
||||
// The old token is animating with a thumbnail, transfer that to the new token.
|
||||
if (wAppAnimator.thumbnail != null) {
|
||||
wAppAnimator.thumbnail.destroy();
|
||||
}
|
||||
wAppAnimator.thumbnail = tAppAnimator.thumbnail;
|
||||
wAppAnimator.thumbnailLayer = tAppAnimator.thumbnailLayer;
|
||||
wAppAnimator.thumbnailAnimation = tAppAnimator.thumbnailAnimation;
|
||||
tAppAnimator.thumbnail = null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void removeAppStartingWindow(IBinder token) {
|
||||
synchronized (mWindowMap) {
|
||||
final AppWindowToken wtoken = mTokenMap.get(token).appWindowToken;
|
||||
@@ -3836,155 +3566,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
}
|
||||
|
||||
boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
|
||||
boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) {
|
||||
boolean delayed = false;
|
||||
|
||||
if (wtoken.clientHidden == visible) {
|
||||
wtoken.clientHidden = !visible;
|
||||
wtoken.sendAppVisibilityToClients();
|
||||
}
|
||||
|
||||
// Allow for state changes and animation to be applied if:
|
||||
// * token is transitioning visibility state
|
||||
// * or the token was marked as hidden and is exiting before we had a chance to play the
|
||||
// transition animation
|
||||
// * or this is an opening app and windows are being replaced.
|
||||
boolean visibilityChanged = false;
|
||||
if (wtoken.hidden == visible || (wtoken.hidden && wtoken.mIsExiting) ||
|
||||
(visible && wtoken.waitingForReplacement())) {
|
||||
boolean changed = false;
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(
|
||||
TAG_WM, "Changing app " + wtoken + " hidden=" + wtoken.hidden
|
||||
+ " performLayout=" + performLayout);
|
||||
|
||||
boolean runningAppAnimation = false;
|
||||
|
||||
if (transit != AppTransition.TRANSIT_UNSET) {
|
||||
if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
|
||||
wtoken.mAppAnimator.setNullAnimation();
|
||||
}
|
||||
if (applyAnimationLocked(wtoken, lp, transit, visible, isVoiceInteraction)) {
|
||||
delayed = runningAppAnimation = true;
|
||||
}
|
||||
WindowState window = wtoken.findMainWindow();
|
||||
//TODO (multidisplay): Magnification is supported only for the default display.
|
||||
if (window != null && mAccessibilityController != null
|
||||
&& window.getDisplayId() == Display.DEFAULT_DISPLAY) {
|
||||
mAccessibilityController.onAppWindowTransitionLocked(window, transit);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
final int windowsCount = wtoken.allAppWindows.size();
|
||||
for (int i = 0; i < windowsCount; i++) {
|
||||
WindowState win = wtoken.allAppWindows.get(i);
|
||||
if (win == wtoken.startingWindow) {
|
||||
// Starting window that's exiting will be removed when the animation
|
||||
// finishes. Mark all relevant flags for that onExitAnimationDone will proceed
|
||||
// all the way to actually remove it.
|
||||
if (!visible && win.isVisibleNow() && wtoken.mAppAnimator.isAnimating()) {
|
||||
win.mAnimatingExit = true;
|
||||
win.mRemoveOnExit = true;
|
||||
win.mWindowRemovalAllowed = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
//Slog.i(TAG_WM, "Window " + win + ": vis=" + win.isVisible());
|
||||
//win.dump(" ");
|
||||
if (visible) {
|
||||
if (!win.isVisibleNow()) {
|
||||
if (!runningAppAnimation) {
|
||||
win.mWinAnimator.applyAnimationLocked(
|
||||
WindowManagerPolicy.TRANSIT_ENTER, true);
|
||||
//TODO (multidisplay): Magnification is supported only for the default
|
||||
if (mAccessibilityController != null
|
||||
&& win.getDisplayId() == Display.DEFAULT_DISPLAY) {
|
||||
mAccessibilityController.onWindowTransitionLocked(win,
|
||||
WindowManagerPolicy.TRANSIT_ENTER);
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
win.setDisplayLayoutNeeded();
|
||||
}
|
||||
} else if (win.isVisibleNow()) {
|
||||
if (!runningAppAnimation) {
|
||||
win.mWinAnimator.applyAnimationLocked(
|
||||
WindowManagerPolicy.TRANSIT_EXIT, false);
|
||||
//TODO (multidisplay): Magnification is supported only for the default
|
||||
if (mAccessibilityController != null
|
||||
&& win.getDisplayId() == Display.DEFAULT_DISPLAY) {
|
||||
mAccessibilityController.onWindowTransitionLocked(win,
|
||||
WindowManagerPolicy.TRANSIT_EXIT);
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
win.setDisplayLayoutNeeded();
|
||||
}
|
||||
}
|
||||
|
||||
wtoken.hidden = wtoken.hiddenRequested = !visible;
|
||||
visibilityChanged = true;
|
||||
if (!visible) {
|
||||
unsetAppFreezingScreenLocked(wtoken, true, true);
|
||||
} else {
|
||||
// If we are being set visible, and the starting window is
|
||||
// not yet displayed, then make sure it doesn't get displayed.
|
||||
WindowState swin = wtoken.startingWindow;
|
||||
if (swin != null && !swin.isDrawnLw()) {
|
||||
swin.mPolicyVisibility = false;
|
||||
swin.mPolicyVisibilityAfterAnim = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "setTokenVisibilityLocked: " + wtoken
|
||||
+ ": hidden=" + wtoken.hidden + " hiddenRequested="
|
||||
+ wtoken.hiddenRequested);
|
||||
|
||||
if (changed) {
|
||||
mInputMonitor.setUpdateInputWindowsNeededLw();
|
||||
if (performLayout) {
|
||||
updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES,
|
||||
false /*updateInputWindows*/);
|
||||
mWindowPlacerLocked.performSurfacePlacement();
|
||||
}
|
||||
mInputMonitor.updateInputWindowsLw(false /*force*/);
|
||||
}
|
||||
}
|
||||
|
||||
if (wtoken.mAppAnimator.animation != null) {
|
||||
delayed = true;
|
||||
}
|
||||
|
||||
for (int i = wtoken.allAppWindows.size() - 1; i >= 0 && !delayed; i--) {
|
||||
if (wtoken.allAppWindows.get(i).mWinAnimator.isWindowAnimationSet()) {
|
||||
delayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (visibilityChanged) {
|
||||
if (visible && !delayed) {
|
||||
// The token was made immediately visible, there will be no entrance animation.
|
||||
// We need to inform the client the enter animation was finished.
|
||||
wtoken.mEnteringAnimation = true;
|
||||
mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(wtoken.token);
|
||||
}
|
||||
|
||||
if (!mClosingApps.contains(wtoken) && !mOpeningApps.contains(wtoken)) {
|
||||
// The token is not closing nor opening, so even if there is an animation set, that
|
||||
// doesn't mean that it goes through the normal app transition cycle so we have
|
||||
// to inform the docked controller about visibility change.
|
||||
getDefaultDisplayContentLocked().getDockedDividerController()
|
||||
.notifyAppVisibilityChanged();
|
||||
}
|
||||
}
|
||||
|
||||
return delayed;
|
||||
}
|
||||
|
||||
void updateTokenInPlaceLocked(AppWindowToken wtoken, int transit) {
|
||||
if (transit != AppTransition.TRANSIT_UNSET) {
|
||||
if (transit != TRANSIT_UNSET) {
|
||||
if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) {
|
||||
wtoken.mAppAnimator.setNullAnimation();
|
||||
}
|
||||
@@ -4141,75 +3724,12 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
}
|
||||
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
wtoken.inPendingTransaction = false;
|
||||
setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET,
|
||||
true, wtoken.voiceInteraction);
|
||||
wtoken.setVisibility(null, visible, TRANSIT_UNSET, true, wtoken.voiceInteraction);
|
||||
wtoken.updateReportedVisibilityLocked();
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
|
||||
void unsetAppFreezingScreenLocked(AppWindowToken wtoken,
|
||||
boolean unfreezeSurfaceNow, boolean force) {
|
||||
if (wtoken.mAppAnimator.freezingScreen) {
|
||||
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + wtoken
|
||||
+ " force=" + force);
|
||||
final int N = wtoken.allAppWindows.size();
|
||||
boolean unfrozeWindows = false;
|
||||
for (int i=0; i<N; i++) {
|
||||
WindowState w = wtoken.allAppWindows.get(i);
|
||||
if (w.mAppFreezing) {
|
||||
w.mAppFreezing = false;
|
||||
if (w.mHasSurface && !w.mOrientationChanging
|
||||
&& mWindowsFreezingScreen != WINDOWS_FREEZING_SCREENS_TIMEOUT) {
|
||||
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "set mOrientationChanging of " + w);
|
||||
w.mOrientationChanging = true;
|
||||
mWindowPlacerLocked.mOrientationChangeComplete = false;
|
||||
}
|
||||
w.mLastFreezeDuration = 0;
|
||||
unfrozeWindows = true;
|
||||
w.setDisplayLayoutNeeded();
|
||||
}
|
||||
}
|
||||
if (force || unfrozeWindows) {
|
||||
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "No longer freezing: " + wtoken);
|
||||
wtoken.mAppAnimator.freezingScreen = false;
|
||||
wtoken.mAppAnimator.lastFreezeDuration = (int)(SystemClock.elapsedRealtime()
|
||||
- mDisplayFreezeTime);
|
||||
mAppsFreezingScreen--;
|
||||
mLastFinishedFreezeSource = wtoken;
|
||||
}
|
||||
if (unfreezeSurfaceNow) {
|
||||
if (unfrozeWindows) {
|
||||
mWindowPlacerLocked.performSurfacePlacement();
|
||||
}
|
||||
stopFreezingDisplayLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startAppFreezingScreenLocked(AppWindowToken wtoken) {
|
||||
if (DEBUG_ORIENTATION) logWithStack(TAG, "Set freezing of " + wtoken.appToken + ": hidden="
|
||||
+ wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
|
||||
if (!wtoken.hiddenRequested) {
|
||||
if (!wtoken.mAppAnimator.freezingScreen) {
|
||||
wtoken.mAppAnimator.freezingScreen = true;
|
||||
wtoken.mAppAnimator.lastFreezeDuration = 0;
|
||||
mAppsFreezingScreen++;
|
||||
if (mAppsFreezingScreen == 1) {
|
||||
startFreezingDisplayLocked(false, 0, 0);
|
||||
mH.removeMessages(H.APP_FREEZE_TIMEOUT);
|
||||
mH.sendEmptyMessageDelayed(H.APP_FREEZE_TIMEOUT, 2000);
|
||||
}
|
||||
}
|
||||
final int N = wtoken.allAppWindows.size();
|
||||
for (int i=0; i<N; i++) {
|
||||
WindowState w = wtoken.allAppWindows.get(i);
|
||||
w.mAppFreezing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startAppFreezingScreen(IBinder token, int configChanges) {
|
||||
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
|
||||
@@ -4223,13 +3743,13 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return;
|
||||
}
|
||||
|
||||
AppWindowToken wtoken = findAppWindowToken(token);
|
||||
final AppWindowToken wtoken = findAppWindowToken(token);
|
||||
if (wtoken == null || wtoken.appToken == null) {
|
||||
Slog.w(TAG_WM, "Attempted to freeze screen with non-existing app token: " + wtoken);
|
||||
return;
|
||||
}
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
startAppFreezingScreenLocked(wtoken);
|
||||
wtoken.startFreezingScreen();
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
@@ -4249,7 +3769,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
if (DEBUG_ORIENTATION) Slog.v(TAG_WM, "Clear freezing of " + token
|
||||
+ ": hidden=" + wtoken.hidden + " freezing=" + wtoken.mAppAnimator.freezingScreen);
|
||||
unsetAppFreezingScreenLocked(wtoken, true, force);
|
||||
wtoken.stopFreezingScreen(true, force);
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
}
|
||||
@@ -4270,9 +3790,8 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
WindowToken basewtoken = mTokenMap.remove(token);
|
||||
if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) {
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + wtoken);
|
||||
delayed = setTokenVisibilityLocked(wtoken, null, false,
|
||||
AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction);
|
||||
wtoken.inPendingTransaction = false;
|
||||
delayed = wtoken.setVisibility(null, false,
|
||||
TRANSIT_UNSET, true, wtoken.voiceInteraction);
|
||||
mOpeningApps.remove(wtoken);
|
||||
wtoken.waitingToShow = false;
|
||||
if (mClosingApps.contains(wtoken)) {
|
||||
@@ -4288,7 +3807,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: "
|
||||
+ wtoken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4));
|
||||
final TaskStack stack = wtoken.mTask.mStack;
|
||||
if (delayed && !wtoken.allAppWindows.isEmpty()) {
|
||||
if (delayed && !wtoken.isEmpty()) {
|
||||
// set the token aside because it has an active animation to be finished
|
||||
if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM,
|
||||
"removeAppToken make exiting: " + wtoken);
|
||||
@@ -4307,7 +3826,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
if (wtoken.startingData != null) {
|
||||
startingToken = wtoken;
|
||||
}
|
||||
unsetAppFreezingScreenLocked(wtoken, true, true);
|
||||
wtoken.stopFreezingScreen(true, true);
|
||||
if (mFocusedApp == wtoken) {
|
||||
if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + wtoken);
|
||||
mFocusedApp = null;
|
||||
@@ -7909,7 +7428,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
AppWindowToken tok = tokens.get(tokenNdx);
|
||||
if (tok.mAppAnimator.freezingScreen) {
|
||||
Slog.w(TAG_WM, "Force clearing freeze: " + tok);
|
||||
unsetAppFreezingScreenLocked(tok, true, true);
|
||||
tok.stopFreezingScreen(true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9292,7 +8811,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
||||
return null;
|
||||
}
|
||||
|
||||
private void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
|
||||
void startFreezingDisplayLocked(boolean inTransaction, int exitAnim, int enterAnim) {
|
||||
if (mDisplayFrozen) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Region;
|
||||
import android.os.Binder;
|
||||
import android.os.Debug;
|
||||
import android.os.IBinder;
|
||||
import android.os.PowerManager;
|
||||
@@ -97,6 +98,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
|
||||
import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
|
||||
import static android.view.WindowManagerPolicy.TRANSIT_EXIT;
|
||||
import static android.view.WindowManagerPolicy.TRANSIT_PREVIEW_DONE;
|
||||
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
|
||||
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
|
||||
@@ -117,8 +120,12 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIG
|
||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
|
||||
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.SEND_NEW_CONFIGURATION;
|
||||
import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
|
||||
import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
|
||||
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
|
||||
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
|
||||
import static com.android.server.wm.WindowManagerService.localLOGV;
|
||||
import static com.android.server.wm.WindowStateAnimator.COMMIT_DRAW_PENDING;
|
||||
import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
|
||||
import static com.android.server.wm.WindowStateAnimator.READY_TO_SHOW;
|
||||
@@ -570,7 +577,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
|
||||
DeathRecipient deathRecipient = new DeathRecipient();
|
||||
mSeq = seq;
|
||||
mEnforceSizeCompat = (mAttrs.privateFlags & PRIVATE_FLAG_COMPATIBLE_WINDOW) != 0;
|
||||
if (WindowManagerService.localLOGV) Slog.v(
|
||||
if (localLOGV) Slog.v(
|
||||
TAG, "Window " + this + " client=" + c.asBinder()
|
||||
+ " token=" + token + " (" + mAttrs.token + ")" + " params=" + a);
|
||||
try {
|
||||
@@ -658,7 +665,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
|
||||
}
|
||||
|
||||
void attach() {
|
||||
if (WindowManagerService.localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
|
||||
if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
|
||||
mSession.windowAddedLocked();
|
||||
}
|
||||
|
||||
@@ -943,7 +950,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
|
||||
}
|
||||
}
|
||||
|
||||
if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG,
|
||||
if (DEBUG_LAYOUT || localLOGV) Slog.v(TAG,
|
||||
"Resolving (mRequestedWidth="
|
||||
+ mRequestedWidth + ", mRequestedheight="
|
||||
+ mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
|
||||
@@ -1489,6 +1496,154 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
|
||||
mService.postWindowRemoveCleanupLocked(this);
|
||||
}
|
||||
|
||||
void removeIfPossible(boolean keepVisibleDeadWindow) {
|
||||
mWindowRemovalAllowed = true;
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG,
|
||||
"removeIfPossible: " + this + " callers=" + Debug.getCallers(5));
|
||||
|
||||
final boolean startingWindow = mAttrs.type == TYPE_APPLICATION_STARTING;
|
||||
if (startingWindow && DEBUG_STARTING_WINDOW) Slog.d(TAG_WM,
|
||||
"Starting window removed " + this);
|
||||
|
||||
if (localLOGV || DEBUG_FOCUS || DEBUG_FOCUS_LIGHT && this == mService.mCurrentFocus)
|
||||
Slog.v(TAG_WM, "Remove " + this + " client="
|
||||
+ Integer.toHexString(System.identityHashCode(mClient.asBinder()))
|
||||
+ ", surfaceController=" + mWinAnimator.mSurfaceController + " Callers="
|
||||
+ Debug.getCallers(5));
|
||||
|
||||
final long origId = Binder.clearCallingIdentity();
|
||||
|
||||
disposeInputChannel();
|
||||
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Remove " + this
|
||||
+ ": mSurfaceController=" + mWinAnimator.mSurfaceController
|
||||
+ " mAnimatingExit=" + mAnimatingExit
|
||||
+ " mRemoveOnExit=" + mRemoveOnExit
|
||||
+ " mHasSurface=" + mHasSurface
|
||||
+ " surfaceShowing=" + mWinAnimator.getShown()
|
||||
+ " isAnimationSet=" + mWinAnimator.isAnimationSet()
|
||||
+ " app-animation="
|
||||
+ (mAppToken != null ? mAppToken.mAppAnimator.animation : null)
|
||||
+ " mWillReplaceWindow=" + mWillReplaceWindow
|
||||
+ " inPendingTransaction="
|
||||
+ (mAppToken != null ? mAppToken.inPendingTransaction : false)
|
||||
+ " mDisplayFrozen=" + mService.mDisplayFrozen
|
||||
+ " callers=" + Debug.getCallers(6));
|
||||
|
||||
// Visibility of the removed window. Will be used later to update orientation later on.
|
||||
boolean wasVisible = false;
|
||||
|
||||
// First, see if we need to run an animation. If we do, we have to hold off on removing the
|
||||
// window until the animation is done. If the display is frozen, just remove immediately,
|
||||
// since the animation wouldn't be seen.
|
||||
if (mHasSurface && mService.okToDisplay()) {
|
||||
if (mWillReplaceWindow) {
|
||||
// This window is going to be replaced. We need to keep it around until the new one
|
||||
// gets added, then we will get rid of this one.
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
|
||||
"Preserving " + this + " until the new one is " + "added");
|
||||
// TODO: We are overloading mAnimatingExit flag to prevent the window state from
|
||||
// been removed. We probably need another flag to indicate that window removal
|
||||
// should be deffered vs. overloading the flag that says we are playing an exit
|
||||
// animation.
|
||||
mAnimatingExit = true;
|
||||
mReplacingRemoveRequested = true;
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isAnimatingWithSavedSurface() && !mAppToken.allDrawnExcludingSaved) {
|
||||
// We started enter animation early with a saved surface, now the app asks to remove
|
||||
// this window. If we remove it now and the app is not yet drawn, we'll show a
|
||||
// flicker. Delay the removal now until it's really drawn.
|
||||
if (DEBUG_ADD_REMOVE) Slog.d(TAG_WM,
|
||||
"removeWindowLocked: delay removal of " + this + " due to early animation");
|
||||
// Do not set mAnimatingExit to true here, it will cause the surface to be hidden
|
||||
// immediately after the enter animation is done. If the app is not yet drawn then
|
||||
// it will show up as a flicker.
|
||||
setupWindowForRemoveOnExit();
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
// If we are not currently running the exit animation, we need to see about starting one
|
||||
wasVisible = isWinVisibleLw();
|
||||
|
||||
if (keepVisibleDeadWindow) {
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
|
||||
"Not removing " + this + " because app died while it's visible");
|
||||
|
||||
mAppDied = true;
|
||||
setDisplayLayoutNeeded();
|
||||
mService.mWindowPlacerLocked.performSurfacePlacement();
|
||||
|
||||
// Set up a replacement input channel since the app is now dead.
|
||||
// We need to catch tapping on the dead window to restart the app.
|
||||
openInputChannel(null);
|
||||
mService.mInputMonitor.updateInputWindowsLw(true /*force*/);
|
||||
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wasVisible) {
|
||||
final int transit = (!startingWindow) ? TRANSIT_EXIT : TRANSIT_PREVIEW_DONE;
|
||||
|
||||
// Try starting an animation.
|
||||
if (mWinAnimator.applyAnimationLocked(transit, false)) {
|
||||
mAnimatingExit = true;
|
||||
}
|
||||
//TODO (multidisplay): Magnification is supported only for the default display.
|
||||
if (mService.mAccessibilityController != null
|
||||
&& getDisplayId() == Display.DEFAULT_DISPLAY) {
|
||||
mService.mAccessibilityController.onWindowTransitionLocked(this, transit);
|
||||
}
|
||||
}
|
||||
final boolean isAnimating =
|
||||
mWinAnimator.isAnimationSet() && !mWinAnimator.isDummyAnimation();
|
||||
final boolean lastWindowIsStartingWindow = startingWindow && mAppToken != null
|
||||
&& mAppToken.getWindowsCount() == 1;
|
||||
// We delay the removal of a window if it has a showing surface that can be used to run
|
||||
// exit animation and it is marked as exiting.
|
||||
// Also, If isn't the an animating starting window that is the last window in the app.
|
||||
// We allow the removal of the non-animating starting window now as there is no
|
||||
// additional window or animation that will trigger its removal.
|
||||
if (mWinAnimator.getShown() && mAnimatingExit
|
||||
&& (!lastWindowIsStartingWindow || isAnimating)) {
|
||||
// The exit animation is running or should run... wait for it!
|
||||
if (DEBUG_ADD_REMOVE) Slog.v(TAG_WM,
|
||||
"Not removing " + this + " due to exit animation ");
|
||||
setupWindowForRemoveOnExit();
|
||||
if (mAppToken != null) {
|
||||
mAppToken.updateReportedVisibilityLocked();
|
||||
}
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
remove();
|
||||
// Removing a visible window will effect the computed orientation
|
||||
// So just update orientation if needed.
|
||||
if (wasVisible && mService.updateOrientationFromAppTokensLocked(false)) {
|
||||
mService.mH.sendEmptyMessage(SEND_NEW_CONFIGURATION);
|
||||
}
|
||||
mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/);
|
||||
Binder.restoreCallingIdentity(origId);
|
||||
}
|
||||
|
||||
private void setupWindowForRemoveOnExit() {
|
||||
mRemoveOnExit = true;
|
||||
setDisplayLayoutNeeded();
|
||||
// Request a focus update as this window's input channel is already gone. Otherwise
|
||||
// we could have no focused window in input manager.
|
||||
final boolean focusChanged = mService.updateFocusedWindowLocked(
|
||||
UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/);
|
||||
mService.mWindowPlacerLocked.performSurfacePlacement();
|
||||
if (focusChanged) {
|
||||
mService.mInputMonitor.updateInputWindowsLw(false /*force*/);
|
||||
}
|
||||
}
|
||||
|
||||
void setHasSurface(boolean hasSurface) {
|
||||
mHasSurface = hasSurface;
|
||||
}
|
||||
@@ -1637,27 +1792,17 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
|
||||
return getStack();
|
||||
}
|
||||
|
||||
void maybeRemoveReplacedWindow() {
|
||||
if (mAppToken == null) {
|
||||
return;
|
||||
void removeReplacedWindow() {
|
||||
if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + this);
|
||||
if (isDimming()) {
|
||||
transferDimToReplacement();
|
||||
}
|
||||
for (int i = mAppToken.allAppWindows.size() - 1; i >= 0; i--) {
|
||||
final WindowState win = mAppToken.allAppWindows.get(i);
|
||||
if (win.mWillReplaceWindow && win.mReplacingWindow == this && hasDrawnLw()) {
|
||||
if (DEBUG_ADD_REMOVE) Slog.d(TAG, "Removing replaced window: " + win);
|
||||
if (win.isDimming()) {
|
||||
win.transferDimToReplacement();
|
||||
}
|
||||
win.mWillReplaceWindow = false;
|
||||
final boolean animateReplacingWindow = win.mAnimateReplacingWindow;
|
||||
win.mAnimateReplacingWindow = false;
|
||||
win.mReplacingRemoveRequested = false;
|
||||
win.mReplacingWindow = null;
|
||||
mSkipEnterAnimationForSeamlessReplacement = false;
|
||||
if (win.mAnimatingExit || !animateReplacingWindow) {
|
||||
win.remove();
|
||||
}
|
||||
}
|
||||
mWillReplaceWindow = false;
|
||||
mAnimateReplacingWindow = false;
|
||||
mReplacingRemoveRequested = false;
|
||||
mReplacingWindow = null;
|
||||
if (mAnimatingExit || !mAnimateReplacingWindow) {
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1797,10 +1942,10 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
|
||||
public void binderDied() {
|
||||
try {
|
||||
synchronized(mService.mWindowMap) {
|
||||
WindowState win = mService.windowForClientLocked(mSession, mClient, false);
|
||||
final WindowState win = mService.windowForClientLocked(mSession, mClient, false);
|
||||
Slog.i(TAG, "WIN DEATH: " + win);
|
||||
if (win != null) {
|
||||
mService.removeWindowLocked(win, shouldKeepVisibleDeadAppWindow());
|
||||
win.removeIfPossible(shouldKeepVisibleDeadAppWindow());
|
||||
if (win.mAttrs.type == TYPE_DOCK_DIVIDER) {
|
||||
// The owner of the docked divider died :( We reset the docked stack,
|
||||
// just in case they have the divider at an unstable position. Better
|
||||
@@ -3178,7 +3323,7 @@ class WindowState extends WindowContainer implements WindowManagerPolicy.WindowS
|
||||
return;
|
||||
}
|
||||
|
||||
if (WindowManagerService.localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG,
|
||||
if (localLOGV || DEBUG_ADD_REMOVE) Slog.v(TAG,
|
||||
"Exit animation finished in " + this + ": remove=" + mRemoveOnExit);
|
||||
|
||||
mDestroying = true;
|
||||
|
||||
@@ -453,7 +453,7 @@ class WindowSurfacePlacer {
|
||||
for (i = exitingAppTokens.size() - 1; i >= 0; i--) {
|
||||
AppWindowToken token = exitingAppTokens.get(i);
|
||||
if (!token.hasVisible && !mService.mClosingApps.contains(token) &&
|
||||
(!token.mIsExiting || token.allAppWindows.isEmpty())) {
|
||||
(!token.mIsExiting || token.isEmpty())) {
|
||||
// Make sure there is no animation running on this token,
|
||||
// so any windows associated with it will be removed as
|
||||
// soon as their animations are complete
|
||||
@@ -1248,10 +1248,8 @@ class WindowSurfacePlacer {
|
||||
appAnimator.clearThumbnail();
|
||||
appAnimator.setNullAnimation();
|
||||
}
|
||||
wtoken.inPendingTransaction = false;
|
||||
|
||||
if (!mService.setTokenVisibilityLocked(
|
||||
wtoken, animLp, true, transit, false, voiceInteraction)){
|
||||
if (!wtoken.setVisibility(animLp, true, transit, false, voiceInteraction)){
|
||||
// This token isn't going to be animating. Add it to the list of tokens to
|
||||
// be notified of app transition complete since the notification will not be
|
||||
// sent be the app window animator.
|
||||
@@ -1259,12 +1257,8 @@ class WindowSurfacePlacer {
|
||||
}
|
||||
wtoken.updateReportedVisibilityLocked();
|
||||
wtoken.waitingToShow = false;
|
||||
wtoken.setAllAppWinAnimators();
|
||||
|
||||
appAnimator.mAllAppWinAnimators.clear();
|
||||
final int windowsCount = wtoken.allAppWindows.size();
|
||||
for (int j = 0; j < windowsCount; j++) {
|
||||
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
|
||||
}
|
||||
if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
|
||||
">>> OPEN TRANSACTION handleAppTransitionReadyLocked()");
|
||||
SurfaceControl.openTransaction();
|
||||
@@ -1279,13 +1273,7 @@ class WindowSurfacePlacer {
|
||||
|
||||
int topOpeningLayer = 0;
|
||||
if (animLp != null) {
|
||||
int layer = -1;
|
||||
for (int j = 0; j < wtoken.allAppWindows.size(); j++) {
|
||||
final WindowState win = wtoken.allAppWindows.get(j);
|
||||
if (win.mWinAnimator.mAnimLayer > layer) {
|
||||
layer = win.mWinAnimator.mAnimLayer;
|
||||
}
|
||||
}
|
||||
final int layer = wtoken.getHighestAnimLayer();
|
||||
if (topOpeningApp == null || layer > topOpeningLayer) {
|
||||
topOpeningApp = wtoken;
|
||||
topOpeningLayer = layer;
|
||||
@@ -1316,9 +1304,7 @@ class WindowSurfacePlacer {
|
||||
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Now closing app " + wtoken);
|
||||
appAnimator.clearThumbnail();
|
||||
appAnimator.setNullAnimation();
|
||||
wtoken.inPendingTransaction = false;
|
||||
mService.setTokenVisibilityLocked(wtoken, animLp, false, transit, false,
|
||||
voiceInteraction);
|
||||
wtoken.setVisibility(animLp, false, transit, false, voiceInteraction);
|
||||
wtoken.updateReportedVisibilityLocked();
|
||||
// Force the allDrawn flag, because we want to start
|
||||
// this guy's animations regardless of whether it's
|
||||
@@ -1604,12 +1590,7 @@ class WindowSurfacePlacer {
|
||||
appAnimator.setNullAnimation();
|
||||
mService.updateTokenInPlaceLocked(wtoken, transit);
|
||||
wtoken.updateReportedVisibilityLocked();
|
||||
|
||||
appAnimator.mAllAppWinAnimators.clear();
|
||||
final int N = wtoken.allAppWindows.size();
|
||||
for (int j = 0; j < N; j++) {
|
||||
appAnimator.mAllAppWinAnimators.add(wtoken.allAppWindows.get(j).mWinAnimator);
|
||||
}
|
||||
wtoken.setAllAppWinAnimators();
|
||||
mService.mAnimator.mAppWindowAnimating |= appAnimator.isAnimating();
|
||||
mService.mAnimator.orAnimating(appAnimator.showAllWindowsLocked());
|
||||
}
|
||||
|
||||
@@ -148,13 +148,19 @@ class WindowToken {
|
||||
}
|
||||
}
|
||||
|
||||
void adjustAnimLayer(int adj) {
|
||||
int adjustAnimLayer(int adj) {
|
||||
int highestAnimLayer = -1;
|
||||
for (int j = windows.size() - 1; j >= 0; j--) {
|
||||
final WindowState w = windows.get(j);
|
||||
w.adjustAnimLayer(adj);
|
||||
if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG, "adjustAnimLayer win "
|
||||
+ w + " anim layer: " + w.mWinAnimator.mAnimLayer);
|
||||
final int animLayer = w.mWinAnimator.mAnimLayer;
|
||||
if (DEBUG_LAYERS || DEBUG_WALLPAPER) Slog.v(TAG,
|
||||
"adjustAnimLayer win " + w + " anim layer: " + animLayer);
|
||||
if (animLayer > highestAnimLayer) {
|
||||
highestAnimLayer = animLayer;
|
||||
}
|
||||
}
|
||||
return highestAnimLayer;
|
||||
}
|
||||
|
||||
private WindowState getTopWindow() {
|
||||
@@ -274,7 +280,7 @@ class WindowToken {
|
||||
}
|
||||
|
||||
final AppWindowToken appToken = win.mAppToken;
|
||||
if (appToken != null && !appToken.allAppWindows.contains(win)) {
|
||||
if (appToken != null) {
|
||||
appToken.addWindow(win);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user