diff options
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<QSTile.State> implements TileChangeListener { public static final String PREFIX = "custom("; @@ -171,7 +174,7 @@ public class CustomTile extends QSTile<QSTile.State> 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<QSTile.State> 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<QSTile.State> 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<QSTile.State> 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<DisplayContent.DisplayChildWindowCo return token; } + void removeAppToken(IBinder binder) { + final WindowToken token = removeWindowToken(binder); + if (token == null) { + Slog.w(TAG_WM, "removeAppToken: Attempted to remove non-existing token: " + binder); + return; + } + + final AppWindowToken appToken = token.asAppWindowToken(); + + if (appToken == null) { + Slog.w(TAG_WM, "Attempted to remove non-App token: " + binder + " token=" + token); + return; + } + + appToken.onRemovedFromDisplay(); + } + Display getDisplay() { return mDisplay; } @@ -638,7 +654,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo rebuildAppWindowList(); } - void resetAnimationBackgroundAnimator() { + private void resetAnimationBackgroundAnimator() { for (int stackNdx = mTaskStackContainers.size() - 1; stackNdx >= 0; --stackNdx) { mTaskStackContainers.get(stackNdx).resetAnimationBackgroundAnimator(); } diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 26f79a97401b..6325cdaaf1c1 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -126,15 +126,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { private final ArrayList<Integer> mChangedStackList = new ArrayList(); - private final ArrayList<WindowToken> mTmpTokensList = new ArrayList(); - - // Collection of binder tokens mapped to their window type we are allowed to create window - // tokens for but that are not current attached to any display. We need to track this here - // because a binder token can be added through {@link WindowManagerService#addWindowToken}, - // but we don't know what display windows for the token will be added to until - // {@link WindowManagerService#addWindow} is called. - private final HashMap<IBinder, Integer> mUnattachedBinderTokens = new HashMap(); - // State for the RemoteSurfaceTrace system used in testing. If this is enabled SurfaceControl // instances will be replaced with an instance that writes a binary representation of all // commands to mSurfaceTraceFd. @@ -340,36 +331,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { return null; } - /** Return the window token associated with the input binder token on the input display */ - WindowToken getWindowToken(IBinder binder, DisplayContent dc) { - final WindowToken token = dc.getWindowToken(binder); - if (token != null) { - return token; - } - - // There is no window token mapped to the binder on the display. Create and map a window - // token if it is currently allowed. - if (!mUnattachedBinderTokens.containsKey(binder)) { - return null; - } - - final int type = mUnattachedBinderTokens.get(binder); - return new WindowToken(mService, binder, type, true, dc); - } - - /** Returns all window tokens mapped to the input binder. */ - ArrayList<WindowToken> getWindowTokens(IBinder binder) { - mTmpTokensList.clear(); - for (int i = mChildren.size() - 1; i >= 0; --i) { - final DisplayContent dc = mChildren.get(i); - final WindowToken token = dc.getWindowToken(binder); - if (token != null) { - mTmpTokensList.add(token); - } - } - return mTmpTokensList; - } - /** * Returns the app window token for the input binder if it exist in the system. * NOTE: Only one AppWindowToken is allowed to exist in the system for a binder token, since @@ -403,140 +364,6 @@ class RootWindowContainer extends WindowContainer<DisplayContent> { return null; } - void addWindowToken(IBinder binder, int type) { - if (mUnattachedBinderTokens.containsKey(binder)) { - Slog.w(TAG_WM, "addWindowToken: Attempted to add existing binder token: " + binder); - return; - } - - final ArrayList<WindowToken> 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<WindowToken> 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<WindowToken> 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<WindowToken> 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<WindowToken> 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<WindowToken> 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<WindowToken> 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<WindowState> { 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 } |