From ac2561e8206ac42921bb6ddbb0a5972fb360e394 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Tue, 1 Nov 2016 15:43:46 -0700 Subject: Make window token add/remove APIs require displayId Window tokens can now only be on one display, so we now require clients that want to add/remove window tokens to specify the display they would like the token to be created on. This simplifies the token handling code in WM and will be useful moving forward for clients that want to add windows to external displays. Test: Existing tests pass Change-Id: I6b2d8d58a913b3624f1a9a7bebbb99315613f103 --- core/java/android/view/IWindowManager.aidl | 6 +- core/java/android/view/WindowManagerInternal.java | 7 +- .../android/systemui/qs/external/CustomTile.java | 11 +- .../accessibility/AccessibilityManagerService.java | 8 +- .../android/server/InputMethodManagerService.java | 7 +- .../java/com/android/server/am/ActivityStack.java | 2 +- .../com/android/server/dreams/DreamController.java | 7 +- .../notification/NotificationManagerService.java | 7 +- .../server/wallpaper/WallpaperManagerService.java | 9 +- .../java/com/android/server/wm/AppWindowToken.java | 62 ++++++++ .../java/com/android/server/wm/DisplayContent.java | 20 ++- .../com/android/server/wm/RootWindowContainer.java | 173 --------------------- .../android/server/wm/WindowManagerService.java | 105 ++++++++----- .../java/com/android/server/wm/WindowToken.java | 1 - .../VoiceInteractionSessionConnection.java | 8 +- .../tests/WindowManagerPermissionTests.java | 8 +- .../src/android/view/IWindowManagerImpl.java | 6 +- 17 files changed, 196 insertions(+), 251 deletions(-) diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 39d7883046a0..bccb822a6519 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -85,8 +85,8 @@ interface IWindowManager void pauseKeyDispatching(IBinder token); void resumeKeyDispatching(IBinder token); void setEventDispatching(boolean enabled); - void addWindowToken(IBinder token, int type); - void removeWindowToken(IBinder token); + void addWindowToken(IBinder token, int type, int displayId); + void removeWindowToken(IBinder token, int displayId); /** * Adds an application token to the specified task Id. * @param addPos The position to add the token to in the task. @@ -183,7 +183,7 @@ interface IWindowManager void notifyAppStopped(IBinder token); void startAppFreezingScreen(IBinder token, int configChanges); void stopAppFreezingScreen(IBinder token, boolean force); - void removeAppToken(IBinder token); + void removeAppToken(IBinder token, int displayId); /** Used by system ui to report that recents has shown itself. */ void endProlongedAnimations(); diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java index f61a63773e5e..6e2a92cd4ee9 100644 --- a/core/java/android/view/WindowManagerInternal.java +++ b/core/java/android/view/WindowManagerInternal.java @@ -241,16 +241,19 @@ public abstract class WindowManagerInternal { * * @param token The token to add. * @param type The window type. + * @param displayId The display to add the token to. */ - public abstract void addWindowToken(android.os.IBinder token, int type); + public abstract void addWindowToken(android.os.IBinder token, int type, int displayId); /** * Removes a window token. * * @param token The toke to remove. * @param removeWindows Whether to also remove the windows associated with the token. + * @param displayId The display to remove the token from. */ - public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows); + public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows, + int displayId); /** * Registers a listener to be notified about app transition events. diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java index 484e008b3714..dc68112c6bbc 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/external/CustomTile.java @@ -44,6 +44,9 @@ import com.android.systemui.qs.external.TileLifecycleManager.TileChangeListener; import com.android.systemui.statusbar.phone.QSTileHost; import libcore.util.Objects; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG; + public class CustomTile extends QSTile implements TileChangeListener { public static final String PREFIX = "custom("; @@ -171,7 +174,7 @@ public class CustomTile extends QSTile implements TileChangeListen mIsShowingDialog = false; try { if (DEBUG) Log.d(TAG, "Removing token"); - mWindowManager.removeWindowToken(mToken); + mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY); } catch (RemoteException e) { } } @@ -193,7 +196,7 @@ public class CustomTile extends QSTile implements TileChangeListen if (mIsTokenGranted && !mIsShowingDialog) { try { if (DEBUG) Log.d(TAG, "Removing token"); - mWindowManager.removeWindowToken(mToken); + mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY); } catch (RemoteException e) { } mIsTokenGranted = false; @@ -212,7 +215,7 @@ public class CustomTile extends QSTile implements TileChangeListen if (mIsTokenGranted) { try { if (DEBUG) Log.d(TAG, "Removing token"); - mWindowManager.removeWindowToken(mToken); + mWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY); } catch (RemoteException e) { } } @@ -252,7 +255,7 @@ public class CustomTile extends QSTile implements TileChangeListen } try { if (DEBUG) Log.d(TAG, "Adding token"); - mWindowManager.addWindowToken(mToken, WindowManager.LayoutParams.TYPE_QS_DIALOG); + mWindowManager.addWindowToken(mToken, TYPE_QS_DIALOG, DEFAULT_DISPLAY); mIsTokenGranted = true; } catch (RemoteException e) { } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 4819c0a23177..c89f158671f9 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -17,6 +17,8 @@ package com.android.server.accessibility; import static android.accessibilityservice.AccessibilityServiceInfo.DEFAULT; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import android.Manifest; import android.accessibilityservice.AccessibilityService; @@ -3129,7 +3131,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { final long identity = Binder.clearCallingIdentity(); try { mWindowManagerService.addWindowToken(mOverlayWindowToken, - WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY); + TYPE_ACCESSIBILITY_OVERLAY, DEFAULT_DISPLAY); } finally { Binder.restoreCallingIdentity(identity); } @@ -3138,7 +3140,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { public void onRemoved() { final long identity = Binder.clearCallingIdentity(); try { - mWindowManagerService.removeWindowToken(mOverlayWindowToken, true); + mWindowManagerService.removeWindowToken(mOverlayWindowToken, true, DEFAULT_DISPLAY); } finally { Binder.restoreCallingIdentity(identity); } @@ -3668,7 +3670,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return AccessibilityWindowInfo.TYPE_SPLIT_SCREEN_DIVIDER; } - case WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY: { + case TYPE_ACCESSIBILITY_OVERLAY: { return AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY; } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index df1b6f51bc33..6e871a8e919c 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -15,6 +15,8 @@ package com.android.server; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD; import static java.lang.annotation.RetentionPolicy.SOURCE; import com.android.internal.content.PackageMonitor; @@ -1481,8 +1483,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mCurToken = new Binder(); try { if (true || DEBUG) Slog.v(TAG, "Adding window token: " + mCurToken); - mIWindowManager.addWindowToken(mCurToken, - WindowManager.LayoutParams.TYPE_INPUT_METHOD); + mIWindowManager.addWindowToken(mCurToken, TYPE_INPUT_METHOD, DEFAULT_DISPLAY); } catch (RemoteException e) { } return new InputBindResult(null, null, mCurId, mCurSeq, @@ -1590,7 +1591,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // The current IME is shown. Hence an IME switch (transition) is happening. mWindowManagerInternal.saveLastInputMethodWindowForTransition(); } - mIWindowManager.removeWindowToken(mCurToken); + mIWindowManager.removeWindowToken(mCurToken, DEFAULT_DISPLAY); } catch (RemoteException e) { } mCurToken = null; diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index ffe2185468c8..1c3a885176a0 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -3714,7 +3714,7 @@ final class ActivityStack extends ConfigurationContainer { r.state = ActivityState.DESTROYED; if (DEBUG_APP) Slog.v(TAG_APP, "Clearing app during remove for activity " + r); r.app = null; - mWindowManager.removeAppToken(r.appToken); + mWindowManager.removeAppToken(r.appToken, r.getDisplayId()); final TaskRecord task = r.task; if (task != null && task.removeActivity(r)) { if (DEBUG_STACK) Slog.i(TAG_STACK, diff --git a/services/core/java/com/android/server/dreams/DreamController.java b/services/core/java/com/android/server/dreams/DreamController.java index 3072f4387fb9..393199dd6183 100644 --- a/services/core/java/com/android/server/dreams/DreamController.java +++ b/services/core/java/com/android/server/dreams/DreamController.java @@ -44,6 +44,9 @@ import android.view.WindowManagerGlobal; import java.io.PrintWriter; import java.util.NoSuchElementException; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_DREAM; + /** * Internal controller for starting and stopping the current dream and managing related state. * @@ -138,7 +141,7 @@ final class DreamController { mCurrentDream.mCanDoze ? MetricsEvent.DOZING : MetricsEvent.DREAMING); try { - mIWindowManager.addWindowToken(token, WindowManager.LayoutParams.TYPE_DREAM); + mIWindowManager.addWindowToken(token, TYPE_DREAM, DEFAULT_DISPLAY); } catch (RemoteException ex) { Slog.e(TAG, "Unable to add window token for dream.", ex); stopDream(true /*immediate*/); @@ -236,7 +239,7 @@ final class DreamController { oldDream.releaseWakeLockIfNeeded(); try { - mIWindowManager.removeWindowToken(oldDream.mToken); + mIWindowManager.removeWindowToken(oldDream.mToken, DEFAULT_DISPLAY); } catch (RemoteException ex) { Slog.w(TAG, "Error removing window token for dream.", ex); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index d78221173ed8..6ebdb3cd696b 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -43,6 +43,8 @@ import static android.service.notification.NotificationListenerService.SUPPRESSE import static android.service.notification.NotificationListenerService.TRIM_FULL; import static android.service.notification.NotificationListenerService.TRIM_LIGHT; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_TOAST; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import android.Manifest; @@ -1402,8 +1404,7 @@ public class NotificationManagerService extends SystemService { } Binder token = new Binder(); - mWindowManagerInternal.addWindowToken(token, - WindowManager.LayoutParams.TYPE_TOAST); + mWindowManagerInternal.addWindowToken(token, TYPE_TOAST, DEFAULT_DISPLAY); record = new ToastRecord(callingPid, pkg, callback, duration, token); mToastQueue.add(record); index = mToastQueue.size() - 1; @@ -3253,7 +3254,7 @@ public class NotificationManagerService extends SystemService { } ToastRecord lastToast = mToastQueue.remove(index); - mWindowManagerInternal.removeWindowToken(lastToast.token, true); + mWindowManagerInternal.removeWindowToken(lastToast.token, true, DEFAULT_DISPLAY); keepProcessAliveIfNeededLocked(record.pid); if (mToastQueue.size() > 0) { diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 7439f5359a50..96662b5b28c3 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -22,6 +22,8 @@ import static android.os.ParcelFileDescriptor.MODE_CREATE; import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; import static android.os.ParcelFileDescriptor.MODE_TRUNCATE; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER; import android.app.ActivityManager; import android.app.ActivityManagerNative; @@ -1692,8 +1694,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { if (wallpaper.userId == mCurrentUserId) { if (DEBUG) Slog.v(TAG, "Adding window token: " + newConn.mToken); - mIWindowManager.addWindowToken(newConn.mToken, - WindowManager.LayoutParams.TYPE_WALLPAPER); + mIWindowManager.addWindowToken(newConn.mToken, TYPE_WALLPAPER, DEFAULT_DISPLAY); mLastWallpaper = wallpaper; } } catch (RemoteException e) { @@ -1728,7 +1729,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { try { if (DEBUG) Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken); - mIWindowManager.removeWindowToken(wallpaper.connection.mToken); + mIWindowManager.removeWindowToken(wallpaper.connection.mToken, DEFAULT_DISPLAY); } catch (RemoteException e) { } wallpaper.connection.mService = null; @@ -1745,7 +1746,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) { try { conn.mService.attach(conn, conn.mToken, - WindowManager.LayoutParams.TYPE_WALLPAPER, false, + TYPE_WALLPAPER, false, wallpaper.width, wallpaper.height, wallpaper.padding); } catch (RemoteException e) { Slog.w(TAG, "Failed attaching wallpaper; clearing", e); diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index a44c8aa3da81..622eece52ca1 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -26,22 +26,27 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; +import static com.android.server.wm.AppTransition.TRANSIT_UNSET; 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_FOCUS_LIGHT; 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_STARTING_WINDOW; +import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMENT; 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.H.NOTIFY_STARTING_WINDOW_DRAWN; +import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL; import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE; import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES; import static com.android.server.wm.WindowManagerService.logWithStack; +import android.os.Debug; import com.android.server.input.InputApplicationHandle; import com.android.server.wm.WindowManagerService.H; @@ -398,6 +403,63 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree return super.checkCompleteDeferredRemoval(); } + void onRemovedFromDisplay() { + AppWindowToken startingToken = null; + + if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + this); + + boolean delayed = setVisibility(null, false, TRANSIT_UNSET, true, voiceInteraction); + + mService.mOpeningApps.remove(this); + waitingToShow = false; + if (mService.mClosingApps.contains(this)) { + delayed = true; + } else if (mService.mAppTransition.isTransitionSet()) { + mService.mClosingApps.add(this); + delayed = true; + } + + if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + this + " delayed=" + delayed + + " animation=" + mAppAnimator.animation + " animating=" + mAppAnimator.animating); + + if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: " + + this + " delayed=" + delayed + " Callers=" + Debug.getCallers(4)); + + final TaskStack stack = mTask.mStack; + if (delayed && !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: " + this); + stack.mExitingAppTokens.add(this); + mIsExiting = true; + } else { + // 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 + mAppAnimator.clearAnimation(); + mAppAnimator.animating = false; + removeIfPossible(); + } + + removed = true; + if (startingData != null) { + startingToken = this; + } + stopFreezingScreen(true, true); + if (mService.mFocusedApp == this) { + if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + this); + mService.mFocusedApp = null; + mService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/); + mService.mInputMonitor.setFocusedAppLw(null); + } + + if (!delayed) { + updateReportedVisibilityLocked(); + } + + // Will only remove if startingToken non null. + mService.scheduleRemoveStartingWindowLocked(startingToken); + } + void clearAnimatingFlags() { boolean wallpaperMightChange = false; for (int i = mChildren.size() - 1; i >= 0; i--) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 1960285be76f..13099dc76f80 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -62,7 +62,6 @@ import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_CONFIG; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT; import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER; - import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DISPLAY; @@ -314,6 +313,23 @@ class DisplayContent extends WindowContainer tokens = getWindowTokens(binder); - - if (!tokens.isEmpty()) { - Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder - + " for already created window tokens: " + tokens); - return; - } - - mUnattachedBinderTokens.put(binder, type); - - // TODO(multi-display): By default we add this to the default display, but maybe we - // should provide an API for a token to be added to any display? - final DisplayContent dc = getDisplayContent(DEFAULT_DISPLAY); - final WindowToken token = new WindowToken(mService, binder, type, true, dc); - if (type == TYPE_WALLPAPER) { - dc.mWallpaperController.addWallpaperToken(token); - } - } - - ArrayList removeWindowToken(IBinder binder) { - mUnattachedBinderTokens.remove(binder); - - mTmpTokensList.clear(); - for (int i = mChildren.size() - 1; i >= 0; --i) { - final DisplayContent dc = mChildren.get(i); - final WindowToken token = dc.removeWindowToken(binder); - if (token != null) { - mTmpTokensList.add(token); - } - } - return mTmpTokensList; - } - - /** - * Removed the mapping to the input binder for the system if it no longer as a window token - * associated with it on any display. - */ - void removeWindowTokenIfPossible(IBinder binder) { - for (int i = mChildren.size() - 1; i >= 0; --i) { - final DisplayContent dc = mChildren.get(i); - final WindowToken token = dc.getWindowToken(binder); - if (token != null) { - return; - } - } - - mUnattachedBinderTokens.remove(binder); - } - - void removeAppToken(IBinder binder) { - final ArrayList removedTokens = removeWindowToken(binder); - if (removedTokens == null || removedTokens.isEmpty()) { - Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder); - return; - } - - for (int i = removedTokens.size() - 1; i >= 0; --i) { - WindowToken wtoken = removedTokens.get(i); - AppWindowToken appToken = wtoken.asAppWindowToken(); - - if (appToken == null) { - Slog.w(TAG_WM, - "Attempted to remove non-App token: " + binder + " wtoken=" + wtoken); - continue; - } - - AppWindowToken startingToken = null; - - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app token: " + appToken); - - boolean delayed = appToken.setVisibility(null, false, TRANSIT_UNSET, true, - appToken.voiceInteraction); - - mService.mOpeningApps.remove(appToken); - mService.mUnknownAppVisibilityController.appRemoved(appToken); - appToken.waitingToShow = false; - if (mService.mClosingApps.contains(appToken)) { - delayed = true; - } else if (mService.mAppTransition.isTransitionSet()) { - mService.mClosingApps.add(appToken); - delayed = true; - } - - if (DEBUG_APP_TRANSITIONS) Slog.v(TAG_WM, "Removing app " + appToken - + " delayed=" + delayed - + " animation=" + appToken.mAppAnimator.animation - + " animating=" + appToken.mAppAnimator.animating); - - if (DEBUG_ADD_REMOVE || DEBUG_TOKEN_MOVEMENT) Slog.v(TAG_WM, "removeAppToken: " - + appToken + " delayed=" + delayed + " Callers=" + Debug.getCallers(4)); - - final TaskStack stack = appToken.mTask.mStack; - if (delayed && !appToken.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: " + appToken); - stack.mExitingAppTokens.add(appToken); - appToken.mIsExiting = true; - } else { - // 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 - appToken.mAppAnimator.clearAnimation(); - appToken.mAppAnimator.animating = false; - appToken.removeIfPossible(); - } - - appToken.removed = true; - if (appToken.startingData != null) { - startingToken = appToken; - } - appToken.stopFreezingScreen(true, true); - if (mService.mFocusedApp == appToken) { - if (DEBUG_FOCUS_LIGHT) Slog.v(TAG_WM, "Removing focused app token:" + appToken); - mService.mFocusedApp = null; - mService.updateFocusedWindowLocked( - UPDATE_FOCUS_NORMAL, true /*updateInputWindows*/); - mService.mInputMonitor.setFocusedAppLw(null); - } - - if (!delayed) { - appToken.updateReportedVisibilityLocked(); - } - - // Will only remove if startingToken non null. - mService.scheduleRemoveStartingWindowLocked(startingToken); - } - } - // TODO: Users would have their own window containers under the display container? void switchUser() { final int count = mChildren.size(); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 2fef92826ecb..66b2cbc3c7a5 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1166,8 +1166,8 @@ public class WindowManagerService extends IWindowManager.Stub final boolean hasParent = parentWindow != null; // Use existing parent window token for child windows since they go in the same token // as there parent window so we can apply the same policy on them. - WindowToken token = mRoot.getWindowToken( - hasParent ? parentWindow.mAttrs.token : attrs.token, displayContent); + WindowToken token = displayContent.getWindowToken( + hasParent ? parentWindow.mAttrs.token : attrs.token); // If this is a child window, we want to apply the same type checking rules as the // parent window type. final int rootType = hasParent ? parentWindow.mAttrs.type : type; @@ -2395,18 +2395,29 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void addWindowToken(IBinder token, int type) { + public void addWindowToken(IBinder binder, int type, int displayId) { if (!checkCallingPermission(MANAGE_APP_TOKENS, "addWindowToken()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } synchronized(mWindowMap) { - mRoot.addWindowToken(token, type); + final DisplayContent dc = mRoot.getDisplayContentOrCreate(displayId); + WindowToken token = dc.getWindowToken(binder); + if (token != null) { + Slog.w(TAG_WM, "addWindowToken: Attempted to add binder token: " + binder + + " for already created window token: " + token + + " displayId=" + displayId); + return; + } + token = new WindowToken(this, binder, type, true, dc); + if (type == TYPE_WALLPAPER) { + dc.mWallpaperController.addWallpaperToken(token); + } } } @Override - public void removeWindowToken(IBinder token) { + public void removeWindowToken(IBinder binder, int displayId) { if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeWindowToken()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } @@ -2414,22 +2425,26 @@ public class WindowManagerService extends IWindowManager.Stub final long origId = Binder.clearCallingIdentity(); try { synchronized (mWindowMap) { - final ArrayList removedTokens = mRoot.removeWindowToken(token); - if (removedTokens == null || removedTokens.isEmpty()) { - Slog.w(TAG_WM, - "removeWindowToken: Attempted to remove non-existing token: " + token); + final DisplayContent dc = mRoot.getDisplayContent(displayId); + if (dc == null) { + Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder + + " for non-exiting displayId=" + displayId); return; } - for (int i = removedTokens.size() - 1; i >= 0; --i) { - final WindowToken wtoken = removedTokens.get(i); - wtoken.setExiting(); - if (wtoken.windowType == TYPE_WALLPAPER) { - wtoken.getDisplayContent().mWallpaperController.removeWallpaperToken(wtoken); - } + final WindowToken token = dc.removeWindowToken(binder); + if (token == null) { + Slog.w(TAG_WM, + "removeWindowToken: Attempted to remove non-existing token: " + binder); + return; + } - mInputMonitor.updateInputWindowsLw(true /*force*/); + token.setExiting(); + if (token.windowType == TYPE_WALLPAPER) { + dc.mWallpaperController.removeWallpaperToken(token); } + + mInputMonitor.updateInputWindowsLw(true /*force*/); } } finally { Binder.restoreCallingIdentity(origId); @@ -3262,7 +3277,7 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void removeAppToken(IBinder token) { + public void removeAppToken(IBinder binder, int displayId) { if (!checkCallingPermission(MANAGE_APP_TOKENS, "removeAppToken()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } @@ -3270,7 +3285,13 @@ public class WindowManagerService extends IWindowManager.Stub final long origId = Binder.clearCallingIdentity(); try { synchronized(mWindowMap) { - mRoot.removeAppToken(token); + final DisplayContent dc = mRoot.getDisplayContent(displayId); + if (dc == null) { + Slog.w(TAG_WM, "removeAppToken: Attempted to remove binder token: " + binder + + " from non-existing displayId=" + displayId); + return; + } + dc.removeAppToken(binder); } } finally { Binder.restoreCallingIdentity(origId); @@ -5790,33 +5811,29 @@ public class WindowManagerService extends IWindowManager.Stub private boolean mEventDispatchingEnabled; @Override - public void pauseKeyDispatching(IBinder _token) { + public void pauseKeyDispatching(IBinder binder) { if (!checkCallingPermission(MANAGE_APP_TOKENS, "pauseKeyDispatching()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } synchronized (mWindowMap) { - final ArrayList tokens = mRoot.getWindowTokens(_token); - if (tokens != null && !tokens.isEmpty()) { - for (int i = tokens.size() - 1; i >= 0; --i) { - mInputMonitor.pauseDispatchingLw(tokens.get(i)); - } + WindowToken token = mRoot.getAppWindowToken(binder); + if (token != null) { + mInputMonitor.pauseDispatchingLw(token); } } } @Override - public void resumeKeyDispatching(IBinder _token) { + public void resumeKeyDispatching(IBinder binder) { if (!checkCallingPermission(MANAGE_APP_TOKENS, "resumeKeyDispatching()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); } synchronized (mWindowMap) { - final ArrayList tokens = mRoot.getWindowTokens(_token); - if (tokens != null && !tokens.isEmpty()) { - for (int i = tokens.size() - 1; i >= 0; --i) { - mInputMonitor.resumeDispatchingLw(tokens.get(i)); - } + WindowToken token = mRoot.getAppWindowToken(binder); + if (token != null) { + mInputMonitor.resumeDispatchingLw(token); } } } @@ -8807,23 +8824,31 @@ public class WindowManagerService extends IWindowManager.Stub } @Override - public void addWindowToken(IBinder token, int type) { - WindowManagerService.this.addWindowToken(token, type); + public void addWindowToken(IBinder token, int type, int displayId) { + WindowManagerService.this.addWindowToken(token, type, displayId); } @Override - public void removeWindowToken(IBinder token, boolean removeWindows) { + public void removeWindowToken(IBinder binder, boolean removeWindows, int displayId) { synchronized(mWindowMap) { if (removeWindows) { - final ArrayList removedTokens = mRoot.removeWindowToken(token); - if (removedTokens != null && !removedTokens.isEmpty()) { - for (int i = removedTokens.size() - 1; i >= 0; --i) { - final WindowToken wtoken = removedTokens.get(i); - wtoken.removeAllWindows(); - } + final DisplayContent dc = mRoot.getDisplayContent(displayId); + if (dc == null) { + Slog.w(TAG_WM, "removeWindowToken: Attempted to remove token: " + binder + + " for non-exiting displayId=" + displayId); + return; } + + final WindowToken token = dc.removeWindowToken(binder); + if (token == null) { + Slog.w(TAG_WM, "removeWindowToken: Attempted to remove non-existing token: " + + binder); + return; + } + + token.removeAllWindows(); } - WindowManagerService.this.removeWindowToken(token); + WindowManagerService.this.removeWindowToken(binder, displayId); } } diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index cf1a98a9c639..b821f0900e65 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -469,7 +469,6 @@ class WindowToken extends WindowContainer { void removeImmediately() { if (mDisplayContent != null) { mDisplayContent.removeWindowToken(token); - mService.mRoot.removeWindowTokenIfPossible(token); } // Needs to occur after the token is removed from the display above to avoid attempt at // duplicate removal of this window container from it's parent. diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index 8268b4065ec8..7dacf160ce4f 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -59,6 +59,9 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION; + final class VoiceInteractionSessionConnection implements ServiceConnection { final static String TAG = "VoiceInteractionServiceManager"; @@ -198,8 +201,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection { | Context.BIND_ALLOW_OOM_MANAGEMENT, new UserHandle(mUser)); if (mBound) { try { - mIWindowManager.addWindowToken(mToken, - WindowManager.LayoutParams.TYPE_VOICE_INTERACTION); + mIWindowManager.addWindowToken(mToken, TYPE_VOICE_INTERACTION, DEFAULT_DISPLAY); } catch (RemoteException e) { Slog.w(TAG, "Failed adding window token", e); } @@ -501,7 +503,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection { } mContext.unbindService(this); try { - mIWindowManager.removeWindowToken(mToken); + mIWindowManager.removeWindowToken(mToken, DEFAULT_DISPLAY); } catch (RemoteException e) { Slog.w(TAG, "Failed removing window token", e); } diff --git a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java index f737b247a7f5..7d6f32bd8f88 100644 --- a/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/WindowManagerPermissionTests.java @@ -73,7 +73,7 @@ public class WindowManagerPermissionTests extends TestCase { } try { - mWm.addWindowToken(null, 0); + mWm.addWindowToken(null, 0, DEFAULT_DISPLAY); fail("IWindowManager.addWindowToken did not throw SecurityException as" + " expected"); } catch (SecurityException e) { @@ -83,7 +83,7 @@ public class WindowManagerPermissionTests extends TestCase { } try { - mWm.removeWindowToken(null); + mWm.removeWindowToken(null, DEFAULT_DISPLAY); fail("IWindowManager.removeWindowToken did not throw SecurityException as" + " expected"); } catch (SecurityException e) { @@ -126,7 +126,7 @@ public class WindowManagerPermissionTests extends TestCase { try { mWm.setAppOrientation(null, 0); - mWm.addWindowToken(null, 0); + mWm.addWindowToken(null, 0, DEFAULT_DISPLAY); fail("IWindowManager.setAppOrientation did not throw SecurityException as" + " expected"); } catch (SecurityException e) { @@ -206,7 +206,7 @@ public class WindowManagerPermissionTests extends TestCase { } try { - mWm.removeAppToken(null); + mWm.removeAppToken(null, DEFAULT_DISPLAY); fail("IWindowManager.removeAppToken did not throw SecurityException as" + " expected"); } catch (SecurityException e) { diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index c86f5c3ebf67..4596210b82d5 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -86,7 +86,7 @@ public class IWindowManagerImpl implements IWindowManager { } @Override - public void addWindowToken(IBinder arg0, int arg1) throws RemoteException { + public void addWindowToken(IBinder arg0, int arg1, int arg2) throws RemoteException { // TODO Auto-generated method stub } @@ -277,13 +277,13 @@ public class IWindowManagerImpl implements IWindowManager { } @Override - public void removeAppToken(IBinder arg0) throws RemoteException { + public void removeAppToken(IBinder arg0, int arg1) throws RemoteException { // TODO Auto-generated method stub } @Override - public void removeWindowToken(IBinder arg0) throws RemoteException { + public void removeWindowToken(IBinder arg0, int arg1) throws RemoteException { // TODO Auto-generated method stub } -- cgit v1.2.3-59-g8ed1b