diff options
author | Craig Mautner <cmautner@google.com> | 2014-02-04 23:38:28 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-02-04 23:38:28 +0000 |
commit | 323601475e15296bf7bb9a20aa0af130bc561bc2 (patch) | |
tree | 1a903cf17c8769ab8b8b8bac1085823596f75815 /services/core/java | |
parent | 35a254554787196cf835536cc3bc28f9ee890af4 (diff) | |
parent | df88d73092c62a1a3cd2b2056ca63ae2e70cc238 (diff) | |
download | frameworks_base-323601475e15296bf7bb9a20aa0af130bc561bc2.zip frameworks_base-323601475e15296bf7bb9a20aa0af130bc561bc2.tar.gz frameworks_base-323601475e15296bf7bb9a20aa0af130bc561bc2.tar.bz2 |
am df88d730: Add IIntentSender to ActivityContainer.startActivity
* commit 'df88d73092c62a1a3cd2b2056ca63ae2e70cc238':
Add IIntentSender to ActivityContainer.startActivity
Diffstat (limited to 'services/core/java')
13 files changed, 400 insertions, 209 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9ea242c..019e6f5 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3124,7 +3124,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, - resultTo, resultWho, requestCode, flagsMask, flagsValues, options); + resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); return ret; } @@ -3236,7 +3236,8 @@ public final class ActivityManagerService extends ActivityManagerNative final int startActivityInPackage(int uid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, - String resultWho, int requestCode, int startFlags, Bundle options, int userId) { + String resultWho, int requestCode, int startFlags, Bundle options, int userId, + IActivityContainer container) { userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, true, "startActivityInPackage", null); @@ -3244,7 +3245,7 @@ public final class ActivityManagerService extends ActivityManagerNative // TODO: Switch to user app stacks here. int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, - null, null, null, null, options, userId, null); + null, null, null, null, options, userId, container); return ret; } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index a7b8067..4047940 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -736,6 +736,12 @@ final class ActivityStack { mStackSupervisor.resumeTopActivitiesLocked(); return; } + + if (mActivityContainer.mParentActivity == null) { + // Top level stack, not a child. Look for child stacks. + mStackSupervisor.pauseChildStacks(prev, userLeaving, uiSleeping); + } + if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev); else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev); mResumedActivity = null; @@ -1254,6 +1260,13 @@ final class ActivityStack { final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) { if (ActivityManagerService.DEBUG_LOCKSCREEN) mService.logLockScreen(""); + ActivityRecord parent = mActivityContainer.mParentActivity; + if (parent != null && parent.state != ActivityState.RESUMED) { + // Do not resume this stack if its parent is not resumed. + // TODO: If in a loop, make sure that parent stack resumeTopActivity is called 1st. + return false; + } + // Find the first activity that is not finishing. ActivityRecord next = topRunningActivityLocked(null); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 13616b3..a7442c6 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -277,6 +277,10 @@ public final class ActivityStackSupervisor implements DisplayListener { // TODO: Split into two methods isFrontStack for any visible stack and isFrontmostStack for the // top of all visible stacks. boolean isFrontStack(ActivityStack stack) { + final ActivityRecord parent = stack.mActivityContainer.mParentActivity; + if (parent != null) { + stack = parent.task.stack; + } ArrayList<ActivityStack> stacks = stack.mStacks; if (stacks != null && !stacks.isEmpty()) { return stack == stacks.get(stacks.size() - 1); @@ -510,6 +514,20 @@ public final class ActivityStackSupervisor implements DisplayListener { return pausing; } + void pauseChildStacks(ActivityRecord parent, boolean userLeaving, boolean uiSleeping) { + // TODO: Put all stacks in supervisor and iterate through them instead. + for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { + ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks; + for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) { + final ActivityStack stack = stacks.get(stackNdx); + if (stack.mResumedActivity != null && + stack.mActivityContainer.mParentActivity == parent) { + stack.startPausingLocked(userLeaving, uiSleeping); + } + } + } + } + void reportActivityVisibleLocked(ActivityRecord r) { for (int i = mWaitingActivityVisible.size()-1; i >= 0; i--) { WaitResult w = mWaitingActivityVisible.get(i); @@ -2914,7 +2932,7 @@ public final class ActivityStackSupervisor implements DisplayListener { mStack.mStacks = activityDisplay.mStacks; activityDisplay.attachActivities(mStack); - mWindowManager.createStack(mStackId, activityDisplay.mDisplayId); + mWindowManager.attachStack(mStackId, activityDisplay.mDisplayId); } @Override @@ -2944,6 +2962,7 @@ public final class ActivityStackSupervisor implements DisplayListener { mActivityDisplay = null; mStack.mDisplayId = -1; mStack.mStacks = null; + mWindowManager.detachStack(mStackId); } } @@ -2956,7 +2975,7 @@ public final class ActivityStackSupervisor implements DisplayListener { @Override public final int startActivity(Intent intent) { - mService.enforceNotIsolatedCaller("ActivityContainer"); + mService.enforceNotIsolatedCaller("ActivityContainer.startActivity"); int userId = mService.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), mCurrentUser, false, true, "ActivityContainer", null); // TODO: Switch to user app stacks here. @@ -2970,20 +2989,40 @@ public final class ActivityStackSupervisor implements DisplayListener { } @Override + public final int startActivityIntentSender(IIntentSender intentSender) { + mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender"); + + if (!(intentSender instanceof PendingIntentRecord)) { + throw new IllegalArgumentException("Bad PendingIntent object"); + } + + return ((PendingIntentRecord)intentSender).sendInner(0, null, null, null, null, null, + null, 0, 0, 0, null, this); + } + + @Override public IBinder asBinder() { return this; } @Override public void attachToSurface(Surface surface, int width, int height, int density) { - synchronized (mService) { - ActivityDisplay activityDisplay = - new ActivityDisplay(surface, width, height, density); - mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay); - attachToDisplayLocked(activityDisplay); + mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface"); + + final long origId = Binder.clearCallingIdentity(); + try { + synchronized (mService) { + ActivityDisplay activityDisplay = + new ActivityDisplay(surface, width, height, density); + mActivityDisplays.put(activityDisplay.mDisplayId, activityDisplay); + attachToDisplayLocked(activityDisplay); + mStack.resumeTopActivityLocked(null); + } + if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display=" + + mActivityDisplay); + } finally { + Binder.restoreCallingIdentity(origId); } - if (DEBUG_STACK) Slog.d(TAG, "attachToSurface: " + this + " to display=" - + mActivityDisplay); } ActivityStackSupervisor getOuter() { diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index 17f24a9..00fa216 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -17,6 +17,7 @@ package com.android.server.am; import android.app.ActivityManager; +import android.app.IActivityContainer; import android.content.IIntentSender; import android.content.IIntentReceiver; import android.app.PendingIntent; @@ -190,13 +191,13 @@ final class PendingIntentRecord extends IIntentSender.Stub { public int send(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission) { return sendInner(code, intent, resolvedType, finishedReceiver, - requiredPermission, null, null, 0, 0, 0, null); + requiredPermission, null, null, 0, 0, 0, null, null); } int sendInner(int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, IBinder resultTo, String resultWho, int requestCode, - int flagsMask, int flagsValues, Bundle options) { + int flagsMask, int flagsValues, Bundle options, IActivityContainer container) { synchronized(owner) { if (!canceled) { sent = true; @@ -251,7 +252,7 @@ final class PendingIntentRecord extends IIntentSender.Stub { } else { owner.startActivityInPackage(uid, key.packageName, finalIntent, resolvedType, resultTo, resultWho, requestCode, 0, - options, userId); + options, userId, container); } } catch (RuntimeException e) { Slog.w(ActivityManagerService.TAG, @@ -302,7 +303,8 @@ final class PendingIntentRecord extends IIntentSender.Stub { } return ActivityManager.START_CANCELED; } - + + @Override protected void finalize() throws Throwable { try { if (!canceled) { diff --git a/services/core/java/com/android/server/wm/DimLayer.java b/services/core/java/com/android/server/wm/DimLayer.java index 978d5b7..30eaf45 100644 --- a/services/core/java/com/android/server/wm/DimLayer.java +++ b/services/core/java/com/android/server/wm/DimLayer.java @@ -51,9 +51,9 @@ public class DimLayer { /** Owning stack */ final TaskStack mStack; - DimLayer(WindowManagerService service, TaskStack stack) { + DimLayer(WindowManagerService service, TaskStack stack, DisplayContent displayContent) { mStack = stack; - mDisplayContent = stack.getDisplayContent(); + mDisplayContent = displayContent; final int displayId = mDisplayContent.getDisplayId(); if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId); SurfaceControl.openTransaction(); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 0a070c1..9f45e88 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -17,7 +17,6 @@ package com.android.server.wm; import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; -import static com.android.server.wm.WindowManagerService.DEBUG_STACK; import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY; import static com.android.server.wm.WindowManagerService.TAG; @@ -116,7 +115,7 @@ class DisplayContent { /** * @param display May not be null. - * @param service TODO(cmautner): + * @param service You know. */ DisplayContent(Display display, WindowManagerService service) { mDisplay = display; @@ -236,19 +235,16 @@ class DisplayContent { return count; } - /** Refer to {@link WindowManagerService#createStack(int, int)} */ - TaskStack createStack(int stackId) { - if (DEBUG_STACK) Slog.d(TAG, "createStack: stackId=" + stackId); - TaskStack newStack = new TaskStack(mService, stackId, this); - if (stackId == HOME_STACK_ID) { + /** Refer to {@link WindowManagerService#attachStack(int, int)} */ + void attachStack(TaskStack stack) { + if (stack.mStackId == HOME_STACK_ID) { if (mHomeStack != null) { - throw new IllegalArgumentException("createStack: HOME_STACK_ID (0) not first."); + throw new IllegalArgumentException("attachStack: HOME_STACK_ID (0) not first."); } - mHomeStack = newStack; + mHomeStack = stack; } - mStacks.add(newStack); + mStacks.add(stack); layoutNeeded = true; - return newStack; } void moveStack(TaskStack stack, boolean toTop) { @@ -256,12 +252,15 @@ class DisplayContent { mStacks.add(toTop ? mStacks.size() : 0, stack); } - TaskStack removeStack(TaskStack stack) { - mStacks.remove(stack); - if (!mStacks.isEmpty()) { - return mStacks.get(mStacks.size() - 1); + void detachStack(TaskStack stack) { + for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { + final Task task = mTaskHistory.get(taskNdx); + if (task.mStack == stack) { + mService.tmpRemoveTaskWindowsLocked(task); + mTaskHistory.remove(taskNdx); + } } - return null; + mStacks.remove(stack); } /** diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 87cabc9..ca9076f 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -293,7 +293,11 @@ final class Session extends IWindowSession.Stub // !!! FIXME: put all this heavy stuff onto the mH looper, as well as // the actual drag event dispatch stuff in the dragstate - Display display = callingWin.mDisplayContent.getDisplay(); + final DisplayContent displayContent = callingWin.getDisplayContent(); + if (displayContent == null) { + return false; + } + Display display = displayContent.getDisplay(); mService.mDragState.register(display); mService.mInputMonitor.updateInputWindowsLw(true /*force*/); if (!mService.mInputManager.transferTouchFocus(callingWin.mInputChannel, diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 13fdbc8..9f72663 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -46,7 +46,6 @@ class Task { if (mAppTokens.size() == 0) { EventLog.writeEvent(com.android.server.EventLogTags.WM_TASK_REMOVED, taskId, "removeAppToken: last token"); - mStack.removeTask(this); return true; } return false; diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index aa6b0c9..1ada6c2 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -41,7 +41,7 @@ public class TaskStack { private final WindowManagerService mService; /** The display this stack sits under. */ - private final DisplayContent mDisplayContent; + private DisplayContent mDisplayContent; /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match * mTaskHistory in the ActivityStack with the same mStackId */ @@ -52,13 +52,13 @@ public class TaskStack { Rect mBounds = new Rect(); /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */ - final DimLayer mDimLayer; + DimLayer mDimLayer; /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */ WindowStateAnimator mDimWinAnimator; /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */ - final DimLayer mAnimationBackgroundSurface; + DimLayer mAnimationBackgroundSurface; /** The particular window with an Animation with non-zero background color. */ WindowStateAnimator mAnimationBackgroundAnimator; @@ -67,12 +67,9 @@ public class TaskStack { * then stop any dimming. */ boolean mDimmingTag; - TaskStack(WindowManagerService service, int stackId, DisplayContent displayContent) { + TaskStack(WindowManagerService service, int stackId) { mService = service; mStackId = stackId; - mDisplayContent = displayContent; - mDimLayer = new DimLayer(service, this); - mAnimationBackgroundSurface = new DimLayer(service, this); // TODO: remove bounds from log, they are always 0. EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top, mBounds.right, mBounds.bottom); @@ -121,12 +118,16 @@ public class TaskStack { } void getBounds(Rect out) { - if (mBounds.isEmpty()) { - mDisplayContent.getLogicalDisplayRect(out); + if (mDisplayContent != null) { + if (mBounds.isEmpty()) { + mDisplayContent.getLogicalDisplayRect(out); + } else { + out.set(mBounds); + } + out.intersect(mDisplayContent.mContentRect); } else { out.set(mBounds); } - out.intersect(mDisplayContent.mContentRect); } boolean isFullscreen() { @@ -198,22 +199,37 @@ public class TaskStack { void removeTask(Task task) { if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task); mTasks.remove(task); - mDisplayContent.removeTask(task); - if (mTasks.isEmpty()) { - mDisplayContent.moveStack(this, false); + if (mDisplayContent != null) { + mDisplayContent.removeTask(task); + if (mTasks.isEmpty()) { + mDisplayContent.moveStack(this, false); + } + mDisplayContent.layoutNeeded = true; + } + } + + void attachDisplayContent(DisplayContent displayContent) { + if (mDisplayContent != null) { + throw new IllegalStateException("attachDisplayContent: Already attached"); + } + + mDisplayContent = displayContent; + mDimLayer = new DimLayer(mService, this, displayContent); + mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent); + + for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) { + Task task = mTasks.get(taskNdx); + displayContent.addTask(task, true); } - mDisplayContent.layoutNeeded = true; } - int remove() { + void detach() { + EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId); mAnimationBackgroundSurface.destroySurface(); + mAnimationBackgroundSurface = null; mDimLayer.destroySurface(); - EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId); - TaskStack next = mDisplayContent.removeStack(this); - if (next != null) { - return next.mStackId; - } - return -1; + mDimLayer = null; + mDisplayContent = null; } void resetAnimationBackgroundAnimator() { diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 91f15f3..b4285c6 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -642,11 +642,16 @@ public class WindowAnimator { } int getPendingLayoutChanges(final int displayId) { + if (displayId < 0) { + return 0; + } return mService.getDisplayContentLocked(displayId).pendingLayoutChanges; } void setPendingLayoutChanges(final int displayId, final int changes) { - mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes; + if (displayId >= 0) { + mService.getDisplayContentLocked(displayId).pendingLayoutChanges |= changes; + } } void setAppLayoutChanges(final AppWindowAnimator appAnimator, final int changes, String s) { @@ -655,7 +660,7 @@ public class WindowAnimator { WindowList windows = appAnimator.mAppToken.allAppWindows; for (int i = windows.size() - 1; i >= 0; i--) { final int displayId = windows.get(i).getDisplayId(); - if (displays.indexOfKey(displayId) < 0) { + if (displayId >= 0 && displays.indexOfKey(displayId) < 0) { setPendingLayoutChanges(displayId, changes); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) { mService.debugLayoutRepeats(s, getPendingLayoutChanges(displayId)); @@ -676,10 +681,15 @@ public class WindowAnimator { } void setScreenRotationAnimationLocked(int displayId, ScreenRotationAnimation animation) { - getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; + if (displayId >= 0) { + getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation = animation; + } } ScreenRotationAnimation getScreenRotationAnimationLocked(int displayId) { + if (displayId < 0) { + return null; + } return getDisplayContentsAnimatorLocked(displayId).mScreenRotationAnimation; } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 59134f9..2cd8bb1 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -155,8 +155,7 @@ import java.util.List; /** {@hide} */ public class WindowManagerService extends IWindowManager.Stub - implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs, - DisplayManager.DisplayListener { + implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { static final String TAG = "WindowManager"; static final boolean DEBUG = false; static final boolean DEBUG_ADD_REMOVE = false; @@ -272,10 +271,10 @@ public class WindowManagerService extends IWindowManager.Stub // Default input dispatching timeout in nanoseconds. static final long DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS = 5000 * 1000000L; - /** Minimum value for createStack and resizeStack weight value */ + /** Minimum value for attachStack and resizeStack weight value */ public static final float STACK_WEIGHT_MIN = 0.2f; - /** Maximum value for createStack and resizeStack weight value */ + /** Maximum value for attachStack and resizeStack weight value */ public static final float STACK_WEIGHT_MAX = 0.8f; static final int UPDATE_FOCUS_NORMAL = 0; @@ -738,7 +737,6 @@ public class WindowManagerService extends IWindowManager.Stub mFxSession = new SurfaceSession(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); - mDisplayManager.registerDisplayListener(this, null); Display[] displays = mDisplayManager.getDisplays(); for (Display display : displays) { createDisplayContentLocked(display); @@ -870,7 +868,7 @@ public class WindowManagerService extends IWindowManager.Stub final int count = token.windows.size(); for (int i = 0; i < count; i++) { final WindowState win = token.windows.get(i); - if (win.mDisplayContent == displayContent) { + if (win.getDisplayContent() == displayContent) { windowList.add(win); } } @@ -901,7 +899,7 @@ public class WindowManagerService extends IWindowManager.Stub private int addAppWindowToListLocked(final WindowState win) { final IWindow client = win.mClient; final WindowToken token = win.mToken; - final DisplayContent displayContent = win.mDisplayContent; + final DisplayContent displayContent = win.getDisplayContent(); final WindowList windows = win.getWindowList(); final int N = windows.size(); @@ -1078,7 +1076,7 @@ public class WindowManagerService extends IWindowManager.Stub private void addAttachedWindowToListLocked(final WindowState win, boolean addToToken) { final WindowToken token = win.mToken; - final DisplayContent displayContent = win.mDisplayContent; + final DisplayContent displayContent = win.getDisplayContent(); final WindowState attached = win.mAttachedWindow; WindowList tokenWindowList = getTokenWindowsOnDisplay(token, displayContent); @@ -2012,7 +2010,10 @@ public class WindowManagerService extends IWindowManager.Stub } void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) { - final DisplayContent displayContent = changingTarget.mDisplayContent; + final DisplayContent displayContent = changingTarget.getDisplayContent(); + if (displayContent == null) { + return; + } final DisplayInfo displayInfo = displayContent.getDisplayInfo(); final int dw = displayInfo.logicalWidth; final int dh = displayInfo.logicalHeight; @@ -2072,7 +2073,10 @@ public class WindowManagerService extends IWindowManager.Stub void updateWallpaperVisibilityLocked() { final boolean visible = isWallpaperVisible(mWallpaperTarget); - final DisplayContent displayContent = mWallpaperTarget.mDisplayContent; + final DisplayContent displayContent = mWallpaperTarget.getDisplayContent(); + if (displayContent == null) { + return; + } final DisplayInfo displayInfo = displayContent.getDisplayInfo(); final int dw = displayInfo.logicalWidth; final int dh = displayInfo.logicalHeight; @@ -2427,7 +2431,10 @@ public class WindowManagerService extends IWindowManager.Stub //Slog.i(TAG, "*** Running exit animation..."); win.mExiting = true; win.mRemoveOnExit = true; - win.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = win.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } updateFocusedWindowLocked(UPDATE_FOCUS_WILL_PLACE_SURFACES, false /*updateInputWindows*/); performLayoutAndPlaceSurfacesLocked(); @@ -2484,8 +2491,6 @@ public class WindowManagerService extends IWindowManager.Stub mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage()); } - final WindowList windows = win.getWindowList(); - windows.remove(win); mPendingRemove.remove(win); mResizingWindows.remove(win); mWindowsChanged = true; @@ -2541,12 +2546,19 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; } - if (!mInLayout) { - assignLayersLocked(windows); - win.mDisplayContent.layoutNeeded = true; - performLayoutAndPlaceSurfacesLocked(); - if (win.mAppToken != null) { - win.mAppToken.updateReportedVisibilityLocked(); + final WindowList windows = win.getWindowList(); + if (windows != null) { + windows.remove(win); + if (!mInLayout) { + assignLayersLocked(windows); + final DisplayContent displayContent = win.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } + performLayoutAndPlaceSurfacesLocked(); + if (win.mAppToken != null) { + win.mAppToken.updateReportedVisibilityLocked(); + } } } @@ -2621,7 +2633,10 @@ public class WindowManagerService extends IWindowManager.Stub w.mGivenVisibleInsets.scale(w.mGlobalScale); w.mGivenTouchableRegion.scale(w.mGlobalScale); } - w.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = w.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } performLayoutAndPlaceSurfacesLocked(); } } @@ -2707,7 +2722,12 @@ public class WindowManagerService extends IWindowManager.Stub mTmpFloats[Matrix.MSKEW_X] = dsdy; mTmpFloats[Matrix.MSCALE_Y] = dtdy; matrix.setValues(mTmpFloats); - final DisplayInfo displayInfo = window.mDisplayContent.getDisplayInfo(); + final DisplayContent displayContent = window.getDisplayContent(); + if (displayContent == null) { + return; + } + + final DisplayInfo displayInfo = window.getDisplayContent().getDisplayInfo(); final RectF dispRect = new RectF(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight); matrix.mapRect(dispRect); @@ -2716,7 +2736,7 @@ public class WindowManagerService extends IWindowManager.Stub window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top, (int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE); window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; - window.mDisplayContent.layoutNeeded = true; + displayContent.layoutNeeded = true; performLayoutAndPlaceSurfacesLocked(); } @@ -2997,7 +3017,10 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; } - win.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = win.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } win.mGivenInsetsPending = (flags&WindowManagerGlobal.RELAYOUT_INSETS_PENDING) != 0; configChanged = updateOrientationFromAppTokensLocked(false); performLayoutAndPlaceSurfacesLocked(); @@ -3091,7 +3114,10 @@ public class WindowManagerService extends IWindowManager.Stub getDefaultDisplayContentLocked().pendingLayoutChanges |= WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; } - win.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = win.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } requestTraversalLocked(); } } @@ -3349,7 +3375,7 @@ public class WindowManagerService extends IWindowManager.Stub for (int i=0; i<N; i++) { WindowState win = wtoken.windows.get(i); - displayContent = win.mDisplayContent; + displayContent = win.getDisplayContent(); if (win.mWinAnimator.isAnimating()) { delayed = true; @@ -3364,7 +3390,9 @@ public class WindowManagerService extends IWindowManager.Stub WindowManagerPolicy.TRANSIT_EXIT); } changed = true; - displayContent.layoutNeeded = true; + if (displayContent != null) { + displayContent.layoutNeeded = true; + } } } @@ -3377,7 +3405,9 @@ public class WindowManagerService extends IWindowManager.Stub } if (delayed) { - displayContent.mExitingTokens.add(wtoken); + if (displayContent != null) { + displayContent.mExitingTokens.add(wtoken); + } } else if (wtoken.windowType == TYPE_WALLPAPER) { mWallpaperTokens.remove(wtoken); } @@ -3473,8 +3503,8 @@ public class WindowManagerService extends IWindowManager.Stub Slog.w(TAG, "Attempted to set group id of non-existing app token: " + token); return; } - Task oldTask = mTaskIdToTask.get(atoken.groupId); - oldTask.removeAppToken(atoken); + final Task oldTask = mTaskIdToTask.get(atoken.groupId); + removeAppFromTask(atoken); atoken.groupId = groupId; Task newTask = mTaskIdToTask.get(groupId); @@ -3767,7 +3797,10 @@ public class WindowManagerService extends IWindowManager.Stub if (mFocusedApp != null) { Task task = mTaskIdToTask.get(mFocusedApp.groupId); stack = task.mStack; - task.getDisplayContent().setTouchExcludeRegion(stack); + final DisplayContent displayContent = task.getDisplayContent(); + if (displayContent != null) { + displayContent.setTouchExcludeRegion(stack); + } } else { stack = null; } @@ -4216,7 +4249,10 @@ public class WindowManagerService extends IWindowManager.Stub } } changed = true; - win.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = win.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } } } else if (win.isVisibleNow()) { if (!runningAppAnimation) { @@ -4230,7 +4266,10 @@ public class WindowManagerService extends IWindowManager.Stub } } changed = true; - win.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = win.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } } } @@ -4378,7 +4417,10 @@ public class WindowManagerService extends IWindowManager.Stub } w.mLastFreezeDuration = 0; unfrozeWindows = true; - w.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = w.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } } } if (force || unfrozeWindows) { @@ -4472,6 +4514,14 @@ public class WindowManagerService extends IWindowManager.Stub } } + void removeAppFromTask(AppWindowToken wtoken) { + final Task task = mTaskIdToTask.get(wtoken.groupId); + if (task != null && task.removeAppToken(wtoken)) { + task.mStack.removeTask(task); + mTaskIdToTask.delete(wtoken.groupId); + } + } + @Override public void removeAppToken(IBinder token) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, @@ -4506,7 +4556,7 @@ public class WindowManagerService extends IWindowManager.Stub + " animating=" + wtoken.mAppAnimator.animating); final Task task = mTaskIdToTask.get(wtoken.groupId); DisplayContent displayContent = task.getDisplayContent(); - if (delayed) { + if (displayContent != null && delayed) { // set the token aside because it has an active animation to be finished if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken make exiting: " + wtoken); @@ -4521,9 +4571,8 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "removeAppToken: " + wtoken); - if (task.removeAppToken(wtoken)) { - mTaskIdToTask.delete(wtoken.groupId); - } + removeAppFromTask(wtoken); + wtoken.removed = true; if (wtoken.startingData != null) { startingToken = wtoken; @@ -4568,13 +4617,15 @@ public class WindowManagerService extends IWindowManager.Stub mH.sendMessage(m); } } + private boolean tmpRemoveAppWindowsLocked(WindowToken token) { - final int NW = token.windows.size(); + WindowList windows = token.windows; + final int NW = windows.size(); if (NW > 0) { mWindowsChanged = true; } - for (int i=0; i<NW; i++) { - WindowState win = token.windows.get(i); + for (int i = 0; i < NW; i++) { + WindowState win = windows.get(i); if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Tmp removing app window " + win); win.getWindowList().remove(win); int j = win.mChildWindows.size(); @@ -4607,12 +4658,13 @@ public class WindowManagerService extends IWindowManager.Stub } void dumpWindowsLocked() { - int i = 0; final int numDisplays = mDisplayContents.size(); for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) { - final WindowList windows = mDisplayContents.valueAt(displayNdx).getWindowList(); + final DisplayContent displayContent = mDisplayContents.valueAt(displayNdx); + Slog.v(TAG, " Display #" + displayContent.getDisplayId()); + final WindowList windows = displayContent.getWindowList(); for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { - Slog.v(TAG, " #" + i++ + ": " + windows.get(winNdx)); + Slog.v(TAG, " #" + winNdx + ": " + windows.get(winNdx)); } } } @@ -4724,23 +4776,28 @@ public class WindowManagerService extends IWindowManager.Stub final int NW = token.windows.size(); for (int i=0; i<NW; i++) { final WindowState win = token.windows.get(i); - if (win.mDisplayContent == displayContent) { + final DisplayContent winDisplayContent = win.getDisplayContent(); + if (winDisplayContent == displayContent || winDisplayContent == null) { + win.mDisplayContent = displayContent; index = reAddWindowLocked(index, win); } } return index; } + void tmpRemoveTaskWindowsLocked(Task task) { + AppTokenList tokens = task.mAppTokens; + for (int tokenNdx = tokens.size() - 1; tokenNdx >= 0; --tokenNdx) { + tmpRemoveAppWindowsLocked(tokens.get(tokenNdx)); + } + } + void moveStackWindowsLocked(DisplayContent displayContent) { // First remove all of the windows from the list. final ArrayList<Task> tasks = displayContent.getTasks(); final int numTasks = tasks.size(); for (int taskNdx = 0; taskNdx < numTasks; ++taskNdx) { - AppTokenList tokens = tasks.get(taskNdx).mAppTokens; - final int numTokens = tokens.size(); - for (int tokenNdx = numTokens - 1; tokenNdx >= 0; --tokenNdx) { - tmpRemoveAppWindowsLocked(tokens.get(tokenNdx)); - } + tmpRemoveTaskWindowsLocked(tasks.get(taskNdx)); } // And now add them back at the correct place. @@ -4824,15 +4881,25 @@ public class WindowManagerService extends IWindowManager.Stub * @param stackId The unique identifier of the new stack. * @param displayId The unique identifier of the DisplayContent. */ - public void createStack(int stackId, int displayId) { + public void attachStack(int stackId, int displayId) { final long origId = Binder.clearCallingIdentity(); try { synchronized (mWindowMap) { final DisplayContent displayContent = mDisplayContents.get(displayId); if (displayContent != null) { - TaskStack stack = displayContent.createStack(stackId); - mStackIdToStack.put(stackId, stack); - performLayoutAndPlaceSurfacesLocked(); + TaskStack stack = mStackIdToStack.get(stackId); + if (stack == null) { + if (DEBUG_STACK) Slog.d(TAG, "attachStack: stackId=" + stackId); + stack = new TaskStack(this, stackId); + mStackIdToStack.put(stackId, stack); + } + stack.attachDisplayContent(displayContent); + displayContent.attachStack(stack); + moveStackWindowsLocked(displayContent); + final WindowList windows = displayContent.getWindowList(); + for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { + windows.get(winNdx).reportResized(); + } } } } finally { @@ -4840,6 +4907,19 @@ public class WindowManagerService extends IWindowManager.Stub } } + public void detachStack(int stackId) { + synchronized (mWindowMap) { + TaskStack stack = mStackIdToStack.get(stackId); + if (stack != null) { + final DisplayContent displayContent = stack.getDisplayContent(); + if (displayContent != null) { + displayContent.detachStack(stack); + stack.detach(); + } + } + } + } + public void removeTask(int taskId) { synchronized (mWindowMap) { Task task = mTaskIdToTask.get(taskId); @@ -7890,7 +7970,6 @@ public class WindowManagerService extends IWindowManager.Stub } final void rebuildAppWindowListLocked() { - // TODO: Multidisplay, when ActivityStacks and tasks exist on more than one display. rebuildAppWindowListLocked(getDefaultDisplayContentLocked()); } @@ -7955,7 +8034,8 @@ public class WindowManagerService extends IWindowManager.Stub i -= lastBelow; if (i != numRemoved) { - Slog.w(TAG, "Rebuild removed " + numRemoved + " windows but added " + i, + Slog.w(TAG, "On display=" + displayContent.getDisplayId() + " Rebuild removed " + + numRemoved + " windows but added " + i, new RuntimeException("here").fillInStackTrace()); for (i=0; i<numRemoved; i++) { WindowState ws = mRebuildTmp[i]; @@ -8765,8 +8845,8 @@ public class WindowManagerService extends IWindowManager.Stub if (canBeSeen) { // This function assumes that the contents of the default display are // processed first before secondary displays. - final DisplayContent displayContent = w.mDisplayContent; - if (displayContent.isDefaultDisplay) { + final DisplayContent displayContent = w.getDisplayContent(); + if (displayContent != null && displayContent.isDefaultDisplay) { // While a dream or keyguard is showing, obscure ordinary application // content on secondary displays (by forcibly enabling mirroring unless // there is other content we want to show) but still allow opaque @@ -8775,8 +8855,9 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mObscureApplicationContentOnSecondaryDisplays = true; } mInnerFields.mDisplayHasContent = true; - } else if (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays - || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG)) { + } else if (displayContent != null && + (!mInnerFields.mObscureApplicationContentOnSecondaryDisplays + || (mInnerFields.mObscured && type == TYPE_KEYGUARD_DIALOG))) { // Allow full screen keyguard presentation dialogs to be seen. mInnerFields.mDisplayHasContent = true; } @@ -9201,56 +9282,22 @@ public class WindowManagerService extends IWindowManager.Stub continue; } final WindowStateAnimator winAnimator = win.mWinAnimator; - try { - if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, - "Reporting new frame to " + win + ": " + win.mCompatFrame); - int diff = 0; - boolean configChanged = win.isConfigChanged(); - if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) - && configChanged) { - Slog.i(TAG, "Sending new config to window " + win + ": " - + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH - + " / " + mCurConfiguration + " / 0x" - + Integer.toHexString(diff)); - } - win.setConfiguration(mCurConfiguration); - if (DEBUG_ORIENTATION && - winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i( - TAG, "Resizing " + win + " WITH DRAW PENDING"); - final IWindow client = win.mClient; - final Rect frame = win.mFrame; - final Rect overscanInsets = win.mLastOverscanInsets; - final Rect contentInsets = win.mLastContentInsets; - final Rect visibleInsets = win.mLastVisibleInsets; - final boolean reportDraw - = winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING; - final Configuration newConfig = configChanged ? win.mConfiguration : null; - if (win.mClient instanceof IWindow.Stub) { - // To prevent deadlock simulate one-way call if win.mClient is a local object. - mH.post(new Runnable() { - @Override - public void run() { - try { - client.resized(frame, overscanInsets, contentInsets, - visibleInsets, reportDraw, newConfig); - } catch (RemoteException e) { - // Not a remote call, RemoteException won't be raised. - } - } - }); - } else { - client.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw, - newConfig); - } - win.mOverscanInsetsChanged = false; - win.mContentInsetsChanged = false; - win.mVisibleInsetsChanged = false; - winAnimator.mSurfaceResized = false; - } catch (RemoteException e) { - win.mOrientationChanging = false; - win.mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() - - mDisplayFreezeTime); - } + if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, + "Reporting new frame to " + win + ": " + win.mCompatFrame); + int diff = 0; + boolean configChanged = win.isConfigChanged(); + if ((DEBUG_RESIZE || DEBUG_ORIENTATION || DEBUG_CONFIGURATION) + && configChanged) { + Slog.i(TAG, "Sending new config to window " + win + ": " + + winAnimator.mSurfaceW + "x" + winAnimator.mSurfaceH + + " / " + mCurConfiguration + " / 0x" + + Integer.toHexString(diff)); + } + win.setConfiguration(mCurConfiguration); + if (DEBUG_ORIENTATION && + winAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING) Slog.i( + TAG, "Resizing " + win + " WITH DRAW PENDING"); + win.reportResized(); mResizingWindows.remove(i); } @@ -9311,10 +9358,7 @@ public class WindowManagerService extends IWindowManager.Stub token.mAppAnimator.animating = false; if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG, "performLayout: App token exiting now removed" + token); - final Task task = mTaskIdToTask.get(token.groupId); - if (task != null && task.removeAppToken(token)) { - mTaskIdToTask.delete(token.groupId); - } + removeAppFromTask(token); exitingAppTokens.remove(i); } } @@ -9395,8 +9439,9 @@ public class WindowManagerService extends IWindowManager.Stub for (i = 0; i < N; i++) { WindowState w = mPendingRemoveTmp[i]; removeWindowInnerLocked(w.mSession, w); - if (!displayList.contains(w.mDisplayContent)) { - displayList.add(w.mDisplayContent); + final DisplayContent displayContent = w.getDisplayContent(); + if (displayContent != null && !displayList.contains(displayContent)) { + displayList.add(displayContent); } } @@ -10761,7 +10806,6 @@ public class WindowManagerService extends IWindowManager.Stub return displayContent != null ? displayContent.getWindowList() : null; } - @Override public void onDisplayAdded(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0)); } @@ -10776,7 +10820,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - @Override public void onDisplayRemoved(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0)); } @@ -10789,16 +10832,10 @@ public class WindowManagerService extends IWindowManager.Stub if (displayId == Display.DEFAULT_DISPLAY) { unregisterPointerEventListener(displayContent.mTapDetector); } - WindowList windows = displayContent.getWindowList(); - while (!windows.isEmpty()) { - final WindowState win = windows.get(windows.size() - 1); - removeWindowLocked(win.mSession, win); - } } mAnimator.removeDisplayLocked(displayId); } - @Override public void onDisplayChanged(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0)); } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 77a36b8..2f778b1 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -29,7 +29,9 @@ import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD; import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import android.app.AppOpsManager; +import android.os.Debug; import android.os.RemoteCallbackList; +import android.os.SystemClock; import android.util.TimeUtils; import android.view.IWindowFocusObserver; import android.view.IWindowId; @@ -593,9 +595,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { } if (mIsWallpaper && (fw != mFrame.width() || fh != mFrame.height())) { - final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo(); - mService.updateWallpaperOffsetLocked(this, - displayInfo.logicalWidth, displayInfo.logicalHeight, false); + final DisplayContent displayContent = getDisplayContent(); + if (displayContent != null) { + final DisplayInfo displayInfo = displayContent.getDisplayInfo(); + mService.updateWallpaperOffsetLocked(this, + displayInfo.logicalWidth, displayInfo.logicalHeight, false); + } } if (DEBUG_LAYOUT || WindowManagerService.localLOGV) Slog.v(TAG, @@ -708,8 +713,16 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mOverscanInsetsChanged || mContentInsetsChanged || mVisibleInsetsChanged; } + public DisplayContent getDisplayContent() { + return mAppToken == null ? mDisplayContent : getStack().getDisplayContent(); + } + public int getDisplayId() { - return mDisplayContent.getDisplayId(); + final DisplayContent displayContent = getDisplayContent(); + if (displayContent == null) { + return -1; + } + return displayContent.getDisplayId(); } TaskStack getStack() { @@ -722,7 +735,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { } Slog.e(TAG, "getStack: mStack null for task=" + task); } else { - Slog.e(TAG, "getStack: couldn't find taskId=" + wtoken.groupId); + Slog.e(TAG, "getStack: " + this + " couldn't find taskId=" + wtoken.groupId + + " Callers=" + Debug.getCallers(4)); } } return mDisplayContent.getHomeStack(); @@ -1196,7 +1210,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { @Override public boolean isDefaultDisplay() { - return mDisplayContent.isDefaultDisplay; + final DisplayContent displayContent = getDisplayContent(); + if (displayContent == null) { + // Only a window that was on a non-default display can be detached from it. + return false; + } + return getDisplayContent().isDefaultDisplay; } public void setShowToOwnerOnlyLocked(boolean showToOwnerOnly) { @@ -1213,7 +1232,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { && win.mAppToken != null && win.mAppToken.showWhenLocked) { // Save some cycles by not calling getDisplayInfo unless it is an application // window intended for all users. - final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo(); + final DisplayContent displayContent = win.getDisplayContent(); + if (displayContent == null) { + return true; + } + final DisplayInfo displayInfo = displayContent.getDisplayInfo(); if (win.mFrame.left <= 0 && win.mFrame.top <= 0 && win.mFrame.right >= displayInfo.appWidth && win.mFrame.bottom >= displayInfo.appHeight) { @@ -1255,7 +1278,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { } WindowList getWindowList() { - return mDisplayContent.getWindowList(); + final DisplayContent displayContent = getDisplayContent(); + return displayContent == null ? null : displayContent.getWindowList(); } /** @@ -1284,6 +1308,43 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } + void reportResized() { + try { + final Rect frame = mFrame; + final Rect overscanInsets = mLastOverscanInsets; + final Rect contentInsets = mLastContentInsets; + final Rect visibleInsets = mLastVisibleInsets; + final boolean reportDraw + = mWinAnimator.mDrawState == WindowStateAnimator.DRAW_PENDING; + final Configuration newConfig = isConfigChanged() ? mConfiguration : null; + if (mClient instanceof IWindow.Stub) { + // To prevent deadlock simulate one-way call if win.mClient is a local object. + mService.mH.post(new Runnable() { + @Override + public void run() { + try { + mClient.resized(frame, overscanInsets, contentInsets, + visibleInsets, reportDraw, newConfig); + } catch (RemoteException e) { + // Not a remote call, RemoteException won't be raised. + } + } + }); + } else { + mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, reportDraw, + newConfig); + } + mOverscanInsetsChanged = false; + mContentInsetsChanged = false; + mVisibleInsetsChanged = false; + mWinAnimator.mSurfaceResized = false; + } catch (RemoteException e) { + mOrientationChanging = false; + mLastFreezeDuration = (int)(SystemClock.elapsedRealtime() + - mService.mDisplayFreezeTime); + } + } + public void registerFocusObserver(IWindowFocusObserver observer) { synchronized(mService.mWindowMap) { if (mFocusCallbacks == null) { @@ -1308,7 +1369,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { } void dump(PrintWriter pw, String prefix, boolean dumpAll) { - pw.print(prefix); pw.print("mDisplayId="); pw.print(mDisplayContent.getDisplayId()); + pw.print(prefix); pw.print("mDisplayId="); pw.print(getDisplayId()); pw.print(" mSession="); pw.print(mSession); pw.print(" mClient="); pw.println(mClient.asBinder()); pw.print(prefix); pw.print("mOwnerUid="); pw.print(mOwnerUid); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index c405170..76e885f 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -150,8 +150,6 @@ class WindowStateAnimator { int mAttrFlags; int mAttrType; - final int mLayerStack; - public WindowStateAnimator(final WindowState win) { final WindowManagerService service = win.mService; @@ -159,7 +157,7 @@ class WindowStateAnimator { mAnimator = service.mAnimator; mPolicy = service.mPolicy; mContext = service.mContext; - final DisplayInfo displayInfo = win.mDisplayContent.getDisplayInfo(); + final DisplayInfo displayInfo = win.getDisplayContent().getDisplayInfo(); mAnimDw = displayInfo.appWidth; mAnimDh = displayInfo.appHeight; @@ -171,7 +169,6 @@ class WindowStateAnimator { mAttrFlags = win.mAttrs.flags; mAttrType = win.mAttrs.type; mIsWallpaper = win.mIsWallpaper; - mLayerStack = win.mDisplayContent.getDisplay().getLayerStack(); } public void setAnimation(Animation anim) { @@ -243,7 +240,8 @@ class WindowStateAnimator { // Save the animation state as it was before this step so WindowManagerService can tell if // we just started or just stopped animating by comparing mWasAnimating with isAnimating(). mWasAnimating = mAnimating; - if (mService.okToDisplay()) { + final DisplayContent displayContent = mWin.getDisplayContent(); + if (displayContent != null && mService.okToDisplay()) { // We will run animations as long as the display isn't frozen. if (mWin.isDrawnLw() && mAnimation != null) { @@ -258,7 +256,7 @@ class WindowStateAnimator { " scale=" + mService.mWindowAnimationScale); mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDw, mAnimDh); - final DisplayInfo displayInfo = mWin.mDisplayContent.getDisplayInfo(); + final DisplayInfo displayInfo = displayContent.getDisplayInfo(); mAnimDw = displayInfo.appWidth; mAnimDh = displayInfo.appHeight; mAnimation.setStartTime(currentTime); @@ -337,7 +335,9 @@ class WindowStateAnimator { + mWin.mPolicyVisibilityAfterAnim); } mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim; - mWin.mDisplayContent.layoutNeeded = true; + if (displayContent != null) { + displayContent.layoutNeeded = true; + } if (!mWin.mPolicyVisibility) { if (mService.mCurrentFocus == mWin) { if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG, @@ -363,11 +363,13 @@ class WindowStateAnimator { } else if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) { // Upon completion of a not-visible to visible status bar animation a relayout is // required. - mWin.mDisplayContent.layoutNeeded = true; + if (displayContent != null) { + displayContent.layoutNeeded = true; + } } finishExit(); - final int displayId = mWin.mDisplayContent.getDisplayId(); + final int displayId = mWin.getDisplayId(); mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM); if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats( "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId)); @@ -732,7 +734,10 @@ class WindowStateAnimator { mSurfaceY = mWin.mFrame.top + mWin.mYOffset; mSurfaceControl.setPosition(mSurfaceX, mSurfaceY); mSurfaceLayer = mAnimLayer; - mSurfaceControl.setLayerStack(mLayerStack); + final DisplayContent displayContent = mWin.getDisplayContent(); + if (displayContent != null) { + mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack()); + } mSurfaceControl.setLayer(mAnimLayer); mSurfaceControl.setAlpha(0); mSurfaceShown = false; @@ -921,8 +926,7 @@ class WindowStateAnimator { tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix()); } //TODO (multidisplay): Magnification is supported only for the default display. - if (mService.mDisplayMagnifier != null - && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) { + if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) { MagnificationSpec spec = mService.mDisplayMagnifier .getMagnificationSpecForWindowLocked(mWin); if (spec != null && !spec.isNop()) { @@ -1002,7 +1006,7 @@ class WindowStateAnimator { && mWin.mBaseLayer < mAnimator.mAboveUniverseLayer); MagnificationSpec spec = null; //TODO (multidisplay): Magnification is supported only for the default display. - if (mService.mDisplayMagnifier != null && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) { + if (mService.mDisplayMagnifier != null && displayId == Display.DEFAULT_DISPLAY) { spec = mService.mDisplayMagnifier.getMagnificationSpecForWindowLocked(mWin); } if (applyUniverseTransformation || spec != null) { @@ -1080,7 +1084,11 @@ class WindowStateAnimator { void updateSurfaceWindowCrop(final boolean recoveringMemory) { final WindowState w = mWin; - DisplayInfo displayInfo = w.mDisplayContent.getDisplayInfo(); + final DisplayContent displayContent = w.getDisplayContent(); + if (displayContent == null) { + return; + } + DisplayInfo displayInfo = displayContent.getDisplayInfo(); // Need to recompute a new system decor rect each time. if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) { @@ -1181,8 +1189,7 @@ class WindowStateAnimator { "SIZE " + width + "x" + height, null); mSurfaceResized = true; mSurfaceControl.setSize(width, height); - final int displayId = w.mDisplayContent.getDisplayId(); - mAnimator.setPendingLayoutChanges(displayId, + mAnimator.setPendingLayoutChanges(w.getDisplayId(), WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER); if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) { w.getStack().startDimmingIfNeeded(this); @@ -1444,7 +1451,10 @@ class WindowStateAnimator { // do a layout. If called from within the transaction // loop, this will cause it to restart with a new // layout. - c.mDisplayContent.layoutNeeded = true; + final DisplayContent displayContent = c.getDisplayContent(); + if (displayContent != null) { + displayContent.layoutNeeded = true; + } } } } |