Loading data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -2887,6 +2887,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "1252594551": { "message": "Window types in WindowContext and LayoutParams.type should match! Type from LayoutParams is %d, but type from WindowContext is %d", "level": "WARN", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "1254403969": { "message": "Surface returned was null: %s", "level": "VERBOSE", Loading services/core/java/com/android/server/wm/WindowContainer.java +5 −0 Original line number Diff line number Diff line Loading @@ -3049,6 +3049,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return null; } /** Cheap way of doing cast and instanceof. */ WindowToken asWindowToken() { return null; } /** Cheap way of doing cast and instanceof. */ ActivityRecord asActivityRecord() { return null; Loading services/core/java/com/android/server/wm/WindowContextListenerController.java +62 −5 Original line number Diff line number Diff line Loading @@ -17,23 +17,26 @@ package com.android.server.wm; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; import static com.android.internal.protolog.ProtoLogGroup.WM_ERROR; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.IWindowToken; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; import android.view.View; import android.view.WindowManager.LayoutParams.WindowType; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import java.util.Map; import java.util.Objects; /** Loading Loading @@ -61,7 +64,7 @@ import java.util.Objects; */ class WindowContextListenerController { @VisibleForTesting final Map<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>(); final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>(); /** * Registers the listener to a {@code container} which is associated with Loading @@ -73,12 +76,16 @@ class WindowContextListenerController { * @param clientToken the token to associate with the listener * @param container the {@link WindowContainer} which the listener is going to listen to. * @param ownerUid the caller UID * @param type the window type * @param options a bundle used to pass window-related options. */ void registerWindowContainerListener(@NonNull IBinder clientToken, @NonNull WindowContainer container, int ownerUid) { @NonNull WindowContainer container, int ownerUid, @WindowType int type, @Nullable Bundle options) { WindowContextListenerImpl listener = mListeners.get(clientToken); if (listener == null) { listener = new WindowContextListenerImpl(clientToken, container, ownerUid); listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type, options); listener.register(); } else { listener.updateContainer(container); Loading Loading @@ -113,11 +120,53 @@ class WindowContextListenerController { return true; } boolean hasListener(IBinder clientToken) { return mListeners.containsKey(clientToken); } @WindowType int getWindowType(IBinder clientToken) { final WindowContextListenerImpl listener = mListeners.get(clientToken); return listener != null ? listener.mType : INVALID_WINDOW_TYPE; } @Nullable Bundle getOptions(IBinder clientToken) { final WindowContextListenerImpl listener = mListeners.get(clientToken); return listener != null ? listener.mOptions : null; } @Nullable WindowContainer getContainer(IBinder clientToken) { final WindowContextListenerImpl listener = mListeners.get(clientToken); return listener != null ? listener.mContainer : null; } @Override public String toString() { final StringBuilder builder = new StringBuilder("WindowContextListenerController{"); builder.append("mListeners=["); final int size = mListeners.values().size(); for (int i = 0; i < size; i++) { builder.append(mListeners.valueAt(i)); if (i != size - 1) { builder.append(", "); } } builder.append("]}"); return builder.toString(); } @VisibleForTesting class WindowContextListenerImpl implements WindowContainerListener { @NonNull private final IBinder mClientToken; private final int mOwnerUid; @NonNull private WindowContainer mContainer; /** * The options from {@link Context#createWindowContext(int, Bundle)}. * <p>It can be used for choosing the {@link DisplayArea} where the window context * is located. </p> */ @Nullable private final Bundle mOptions; @WindowType private final int mType; private DeathRecipient mDeathRecipient; Loading @@ -125,10 +174,12 @@ class WindowContextListenerController { private Configuration mLastReportedConfig; private WindowContextListenerImpl(IBinder clientToken, WindowContainer container, int ownerUid) { int ownerUid, @WindowType int type, @Nullable Bundle options) { mClientToken = clientToken; mContainer = Objects.requireNonNull(container); mOwnerUid = ownerUid; mType = type; mOptions = options; final DeathRecipient deathRecipient = new DeathRecipient(); try { Loading Loading @@ -226,6 +277,12 @@ class WindowContextListenerController { unregister(); } @Override public String toString() { return "WindowContextListenerImpl{clientToken=" + mClientToken + ", " + "container=" + mContainer + "}"; } private class DeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { Loading services/core/java/com/android/server/wm/WindowManagerService.java +47 −15 Original line number Diff line number Diff line Loading @@ -1466,7 +1466,7 @@ public class WindowManagerService extends IWindowManager.Stub & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0; int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName, appOp); if (res != WindowManagerGlobal.ADD_OKAY) { if (res != ADD_OKAY) { return res; } Loading Loading @@ -1556,6 +1556,8 @@ public class WindowManagerService extends IWindowManager.Stub boolean addToastWindowRequiresToken = false; final IBinder windowContextToken = attrs.mWindowContextToken; if (token == null) { if (!unprivilegedAppCanCreateTokenWith(parentWindow, callingUid, type, rootType, attrs.token, attrs.packageName)) { Loading @@ -1564,6 +1566,14 @@ public class WindowManagerService extends IWindowManager.Stub if (hasParent) { // Use existing parent window token for child windows. token = parentWindow.mToken; } else if (mWindowContextListenerController.hasListener(windowContextToken)) { // Respect the window context token if the user provided it. final IBinder binder = attrs.token != null ? attrs.token : windowContextToken; final Bundle options = mWindowContextListenerController .getOptions(windowContextToken); token = new WindowToken(this, binder, type, false /* persistOnEmpty */, displayContent, session.mCanAddInternalSystemWindow, callingUid, isRoundedCornerOverlay, true /* fromClientToken */, options); } else { final IBinder binder = attrs.token != null ? attrs.token : client.asBinder(); token = new WindowToken(this, binder, type, false, displayContent, Loading Loading @@ -1632,8 +1642,8 @@ public class WindowManagerService extends IWindowManager.Stub // It is not valid to use an app token with other system types; we will // instead make a new token for it (as if null had been passed in for the token). attrs.token = null; token = new WindowToken(this, client.asBinder(), type, false, displayContent, session.mCanAddInternalSystemWindow); token = new WindowToken(this, client.asBinder(), type, false /* persistOnEmpty */, displayContent, session.mCanAddInternalSystemWindow); } final WindowState win = new WindowState(this, session, client, token, parentWindow, Loading @@ -1657,7 +1667,7 @@ public class WindowManagerService extends IWindowManager.Stub win.updateRequestedVisibility(requestedVisibility); res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid); if (res != WindowManagerGlobal.ADD_OKAY) { if (res != ADD_OKAY) { return res; } Loading Loading @@ -1688,7 +1698,7 @@ public class WindowManagerService extends IWindowManager.Stub // show a focusable toasts while it has focus which will be kept on // the screen after the activity goes away. if (addToastWindowRequiresToken || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0 || (attrs.flags & FLAG_NOT_FOCUSABLE) == 0 || displayContent.mCurrentFocus == null || displayContent.mCurrentFocus.mOwnerUid != callingUid) { mH.sendMessageDelayed( Loading @@ -1697,9 +1707,26 @@ public class WindowManagerService extends IWindowManager.Stub } } // Switch to listen to the {@link WindowToken token}'s configuration changes when // adding a window to the window context. if (mWindowContextListenerController.hasListener(windowContextToken)) { final int windowContextType = mWindowContextListenerController .getWindowType(windowContextToken); if (type != windowContextType) { ProtoLog.w(WM_ERROR, "Window types in WindowContext and" + " LayoutParams.type should match! Type from LayoutParams is %d," + " but type from WindowContext is %d", type, windowContextType); return WindowManagerGlobal.ADD_INVALID_TYPE; } final Bundle options = mWindowContextListenerController .getOptions(windowContextToken); mWindowContextListenerController.registerWindowContainerListener( windowContextToken, token, callingUid, type, options); } // From now on, no exceptions or errors allowed! res = WindowManagerGlobal.ADD_OKAY; res = ADD_OKAY; if (mUseBLAST) { res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST; Loading Loading @@ -2763,7 +2790,7 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayArea da = dc.getAreaForWindowToken(type, options, callerCanManageAppTokens, false /* roundedCornerOverlay */); mWindowContextListenerController.registerWindowContainerListener(clientToken, da, callingUid); callingUid, type, options); return true; } } finally { Loading @@ -2779,9 +2806,18 @@ public class WindowManagerService extends IWindowManager.Stub final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { if (mWindowContextListenerController.assertCallerCanRemoveListener(clientToken, if (!mWindowContextListenerController.assertCallerCanRemoveListener(clientToken, callerCanManageAppTokens, callingUid)) { return; } final WindowContainer wc = mWindowContextListenerController .getContainer(clientToken); mWindowContextListenerController.unregisterWindowContainerListener(clientToken); final WindowToken token = wc.asWindowToken(); if (token != null && token.isFromClient()) { removeWindowToken(token.token, token.getDisplayContent().getDisplayId()); } } } finally { Loading @@ -2792,13 +2828,9 @@ public class WindowManagerService extends IWindowManager.Stub @Override public boolean isWindowToken(IBinder binder) { synchronized (mGlobalLock) { final WindowToken windowToken = mRoot.getWindowToken(binder); if (windowToken == null) { return false; } // We don't allow activity tokens in WindowContext. TODO(window-context): rename method return windowToken.asActivityRecord() == null; return mRoot.getWindowToken(binder) != null; } } @Override Loading services/core/java/com/android/server/wm/WindowToken.java +9 −0 Original line number Diff line number Diff line Loading @@ -820,6 +820,11 @@ class WindowToken extends WindowContainer<WindowState> { return toString(); } @Override WindowToken asWindowToken() { return this; } /** * Return whether windows from this token can layer above the * system bars, or in other words extend outside of the "Decor Frame" Loading @@ -839,4 +844,8 @@ class WindowToken extends WindowContainer<WindowState> { int getOwnerUid() { return mOwnerUid; } boolean isFromClient() { return mFromClientToken; } } Loading
data/etc/services.core.protolog.json +6 −0 Original line number Diff line number Diff line Loading @@ -2887,6 +2887,12 @@ "group": "WM_DEBUG_ORIENTATION", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "1252594551": { "message": "Window types in WindowContext and LayoutParams.type should match! Type from LayoutParams is %d, but type from WindowContext is %d", "level": "WARN", "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, "1254403969": { "message": "Surface returned was null: %s", "level": "VERBOSE", Loading
services/core/java/com/android/server/wm/WindowContainer.java +5 −0 Original line number Diff line number Diff line Loading @@ -3049,6 +3049,11 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer< return null; } /** Cheap way of doing cast and instanceof. */ WindowToken asWindowToken() { return null; } /** Cheap way of doing cast and instanceof. */ ActivityRecord asActivityRecord() { return null; Loading
services/core/java/com/android/server/wm/WindowContextListenerController.java +62 −5 Original line number Diff line number Diff line Loading @@ -17,23 +17,26 @@ package com.android.server.wm; import static android.view.Display.INVALID_DISPLAY; import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; import static com.android.internal.protolog.ProtoLogGroup.WM_ERROR; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.IWindowToken; import android.content.Context; import android.content.res.Configuration; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.util.ArrayMap; import android.view.View; import android.view.WindowManager.LayoutParams.WindowType; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import java.util.Map; import java.util.Objects; /** Loading Loading @@ -61,7 +64,7 @@ import java.util.Objects; */ class WindowContextListenerController { @VisibleForTesting final Map<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>(); final ArrayMap<IBinder, WindowContextListenerImpl> mListeners = new ArrayMap<>(); /** * Registers the listener to a {@code container} which is associated with Loading @@ -73,12 +76,16 @@ class WindowContextListenerController { * @param clientToken the token to associate with the listener * @param container the {@link WindowContainer} which the listener is going to listen to. * @param ownerUid the caller UID * @param type the window type * @param options a bundle used to pass window-related options. */ void registerWindowContainerListener(@NonNull IBinder clientToken, @NonNull WindowContainer container, int ownerUid) { @NonNull WindowContainer container, int ownerUid, @WindowType int type, @Nullable Bundle options) { WindowContextListenerImpl listener = mListeners.get(clientToken); if (listener == null) { listener = new WindowContextListenerImpl(clientToken, container, ownerUid); listener = new WindowContextListenerImpl(clientToken, container, ownerUid, type, options); listener.register(); } else { listener.updateContainer(container); Loading Loading @@ -113,11 +120,53 @@ class WindowContextListenerController { return true; } boolean hasListener(IBinder clientToken) { return mListeners.containsKey(clientToken); } @WindowType int getWindowType(IBinder clientToken) { final WindowContextListenerImpl listener = mListeners.get(clientToken); return listener != null ? listener.mType : INVALID_WINDOW_TYPE; } @Nullable Bundle getOptions(IBinder clientToken) { final WindowContextListenerImpl listener = mListeners.get(clientToken); return listener != null ? listener.mOptions : null; } @Nullable WindowContainer getContainer(IBinder clientToken) { final WindowContextListenerImpl listener = mListeners.get(clientToken); return listener != null ? listener.mContainer : null; } @Override public String toString() { final StringBuilder builder = new StringBuilder("WindowContextListenerController{"); builder.append("mListeners=["); final int size = mListeners.values().size(); for (int i = 0; i < size; i++) { builder.append(mListeners.valueAt(i)); if (i != size - 1) { builder.append(", "); } } builder.append("]}"); return builder.toString(); } @VisibleForTesting class WindowContextListenerImpl implements WindowContainerListener { @NonNull private final IBinder mClientToken; private final int mOwnerUid; @NonNull private WindowContainer mContainer; /** * The options from {@link Context#createWindowContext(int, Bundle)}. * <p>It can be used for choosing the {@link DisplayArea} where the window context * is located. </p> */ @Nullable private final Bundle mOptions; @WindowType private final int mType; private DeathRecipient mDeathRecipient; Loading @@ -125,10 +174,12 @@ class WindowContextListenerController { private Configuration mLastReportedConfig; private WindowContextListenerImpl(IBinder clientToken, WindowContainer container, int ownerUid) { int ownerUid, @WindowType int type, @Nullable Bundle options) { mClientToken = clientToken; mContainer = Objects.requireNonNull(container); mOwnerUid = ownerUid; mType = type; mOptions = options; final DeathRecipient deathRecipient = new DeathRecipient(); try { Loading Loading @@ -226,6 +277,12 @@ class WindowContextListenerController { unregister(); } @Override public String toString() { return "WindowContextListenerImpl{clientToken=" + mClientToken + ", " + "container=" + mContainer + "}"; } private class DeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() { Loading
services/core/java/com/android/server/wm/WindowManagerService.java +47 −15 Original line number Diff line number Diff line Loading @@ -1466,7 +1466,7 @@ public class WindowManagerService extends IWindowManager.Stub & PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY) != 0; int res = mPolicy.checkAddPermission(attrs.type, isRoundedCornerOverlay, attrs.packageName, appOp); if (res != WindowManagerGlobal.ADD_OKAY) { if (res != ADD_OKAY) { return res; } Loading Loading @@ -1556,6 +1556,8 @@ public class WindowManagerService extends IWindowManager.Stub boolean addToastWindowRequiresToken = false; final IBinder windowContextToken = attrs.mWindowContextToken; if (token == null) { if (!unprivilegedAppCanCreateTokenWith(parentWindow, callingUid, type, rootType, attrs.token, attrs.packageName)) { Loading @@ -1564,6 +1566,14 @@ public class WindowManagerService extends IWindowManager.Stub if (hasParent) { // Use existing parent window token for child windows. token = parentWindow.mToken; } else if (mWindowContextListenerController.hasListener(windowContextToken)) { // Respect the window context token if the user provided it. final IBinder binder = attrs.token != null ? attrs.token : windowContextToken; final Bundle options = mWindowContextListenerController .getOptions(windowContextToken); token = new WindowToken(this, binder, type, false /* persistOnEmpty */, displayContent, session.mCanAddInternalSystemWindow, callingUid, isRoundedCornerOverlay, true /* fromClientToken */, options); } else { final IBinder binder = attrs.token != null ? attrs.token : client.asBinder(); token = new WindowToken(this, binder, type, false, displayContent, Loading Loading @@ -1632,8 +1642,8 @@ public class WindowManagerService extends IWindowManager.Stub // It is not valid to use an app token with other system types; we will // instead make a new token for it (as if null had been passed in for the token). attrs.token = null; token = new WindowToken(this, client.asBinder(), type, false, displayContent, session.mCanAddInternalSystemWindow); token = new WindowToken(this, client.asBinder(), type, false /* persistOnEmpty */, displayContent, session.mCanAddInternalSystemWindow); } final WindowState win = new WindowState(this, session, client, token, parentWindow, Loading @@ -1657,7 +1667,7 @@ public class WindowManagerService extends IWindowManager.Stub win.updateRequestedVisibility(requestedVisibility); res = displayPolicy.validateAddingWindowLw(attrs, callingPid, callingUid); if (res != WindowManagerGlobal.ADD_OKAY) { if (res != ADD_OKAY) { return res; } Loading Loading @@ -1688,7 +1698,7 @@ public class WindowManagerService extends IWindowManager.Stub // show a focusable toasts while it has focus which will be kept on // the screen after the activity goes away. if (addToastWindowRequiresToken || (attrs.flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0 || (attrs.flags & FLAG_NOT_FOCUSABLE) == 0 || displayContent.mCurrentFocus == null || displayContent.mCurrentFocus.mOwnerUid != callingUid) { mH.sendMessageDelayed( Loading @@ -1697,9 +1707,26 @@ public class WindowManagerService extends IWindowManager.Stub } } // Switch to listen to the {@link WindowToken token}'s configuration changes when // adding a window to the window context. if (mWindowContextListenerController.hasListener(windowContextToken)) { final int windowContextType = mWindowContextListenerController .getWindowType(windowContextToken); if (type != windowContextType) { ProtoLog.w(WM_ERROR, "Window types in WindowContext and" + " LayoutParams.type should match! Type from LayoutParams is %d," + " but type from WindowContext is %d", type, windowContextType); return WindowManagerGlobal.ADD_INVALID_TYPE; } final Bundle options = mWindowContextListenerController .getOptions(windowContextToken); mWindowContextListenerController.registerWindowContainerListener( windowContextToken, token, callingUid, type, options); } // From now on, no exceptions or errors allowed! res = WindowManagerGlobal.ADD_OKAY; res = ADD_OKAY; if (mUseBLAST) { res |= WindowManagerGlobal.ADD_FLAG_USE_BLAST; Loading Loading @@ -2763,7 +2790,7 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayArea da = dc.getAreaForWindowToken(type, options, callerCanManageAppTokens, false /* roundedCornerOverlay */); mWindowContextListenerController.registerWindowContainerListener(clientToken, da, callingUid); callingUid, type, options); return true; } } finally { Loading @@ -2779,9 +2806,18 @@ public class WindowManagerService extends IWindowManager.Stub final long origId = Binder.clearCallingIdentity(); try { synchronized (mGlobalLock) { if (mWindowContextListenerController.assertCallerCanRemoveListener(clientToken, if (!mWindowContextListenerController.assertCallerCanRemoveListener(clientToken, callerCanManageAppTokens, callingUid)) { return; } final WindowContainer wc = mWindowContextListenerController .getContainer(clientToken); mWindowContextListenerController.unregisterWindowContainerListener(clientToken); final WindowToken token = wc.asWindowToken(); if (token != null && token.isFromClient()) { removeWindowToken(token.token, token.getDisplayContent().getDisplayId()); } } } finally { Loading @@ -2792,13 +2828,9 @@ public class WindowManagerService extends IWindowManager.Stub @Override public boolean isWindowToken(IBinder binder) { synchronized (mGlobalLock) { final WindowToken windowToken = mRoot.getWindowToken(binder); if (windowToken == null) { return false; } // We don't allow activity tokens in WindowContext. TODO(window-context): rename method return windowToken.asActivityRecord() == null; return mRoot.getWindowToken(binder) != null; } } @Override Loading
services/core/java/com/android/server/wm/WindowToken.java +9 −0 Original line number Diff line number Diff line Loading @@ -820,6 +820,11 @@ class WindowToken extends WindowContainer<WindowState> { return toString(); } @Override WindowToken asWindowToken() { return this; } /** * Return whether windows from this token can layer above the * system bars, or in other words extend outside of the "Decor Frame" Loading @@ -839,4 +844,8 @@ class WindowToken extends WindowContainer<WindowState> { int getOwnerUid() { return mOwnerUid; } boolean isFromClient() { return mFromClientToken; } }