Fix WindowContext cannot add window with sub window type
Bug: 184717383 Test: atest WindowManagerServiceTests Test: atest WindowContextTest Change-Id: Ie523902a8ec1a1de96b961da1204bf7c923052be
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package android.window;
|
||||
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
|
||||
|
||||
@@ -209,6 +210,38 @@ public class WindowContextTest {
|
||||
mWms.removeWindowToken(existingToken, DEFAULT_DISPLAY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWindowContextAddViewWithSubWindowType_NotCrash() throws Throwable {
|
||||
final WindowContext windowContext = createWindowContext(TYPE_INPUT_METHOD);
|
||||
final WindowManager wm = windowContext.getSystemService(WindowManager.class);
|
||||
|
||||
// Create a WindowToken with system window type.
|
||||
final IBinder existingToken = new Binder();
|
||||
mWms.addWindowToken(existingToken, TYPE_INPUT_METHOD, windowContext.getDisplayId(),
|
||||
null /* options */);
|
||||
|
||||
final WindowManager.LayoutParams params =
|
||||
new WindowManager.LayoutParams(TYPE_INPUT_METHOD);
|
||||
params.token = existingToken;
|
||||
final View parentWindow = new View(windowContext);
|
||||
|
||||
final AttachStateListener listener = new AttachStateListener();
|
||||
parentWindow.addOnAttachStateChangeListener(listener);
|
||||
|
||||
// Add the parent window
|
||||
mInstrumentation.runOnMainSync(() -> wm.addView(parentWindow, params));
|
||||
|
||||
assertTrue(listener.mLatch.await(4, TimeUnit.SECONDS));
|
||||
|
||||
final WindowManager.LayoutParams subWindowAttrs =
|
||||
new WindowManager.LayoutParams(TYPE_APPLICATION_ATTACHED_DIALOG);
|
||||
subWindowAttrs.token = parentWindow.getWindowToken();
|
||||
final View subWindow = new View(windowContext);
|
||||
|
||||
// Add a window with sub-window type.
|
||||
mInstrumentation.runOnMainSync(() -> wm.addView(subWindow, subWindowAttrs));
|
||||
}
|
||||
|
||||
private WindowContext createWindowContext() {
|
||||
return createWindowContext(TYPE_APPLICATION_OVERLAY);
|
||||
}
|
||||
@@ -219,4 +252,16 @@ public class WindowContextTest {
|
||||
.getDisplay(DEFAULT_DISPLAY);
|
||||
return (WindowContext) instContext.createWindowContext(display, type, null /* options */);
|
||||
}
|
||||
|
||||
private static class AttachStateListener implements View.OnAttachStateChangeListener {
|
||||
final CountDownLatch mLatch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(View v) {
|
||||
mLatch.countDown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(View v) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1740,8 +1740,11 @@ 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)) {
|
||||
// adding a window to the window context. Filter sub window type here because the sub
|
||||
// window must be attached to the parent window, which is attached to the window context
|
||||
// created window token.
|
||||
if (!win.isChildWindow()
|
||||
&& mWindowContextListenerController.hasListener(windowContextToken)) {
|
||||
final int windowContextType = mWindowContextListenerController
|
||||
.getWindowType(windowContextToken);
|
||||
if (type != windowContextType) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
|
||||
@@ -50,7 +51,13 @@ import android.content.pm.PackageManager;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.view.IWindowSessionCallback;
|
||||
import android.view.InsetsSourceControl;
|
||||
import android.view.InsetsState;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
@@ -250,4 +257,31 @@ public class WindowManagerServiceTests extends WindowTestsBase {
|
||||
eq(clientToken), eq(windowToken), anyInt(), eq(TYPE_INPUT_METHOD),
|
||||
eq(windowToken.mOptions));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddWindowWithSubWindowTypeByWindowContext() {
|
||||
spyOn(mWm.mWindowContextListenerController);
|
||||
|
||||
final WindowToken windowToken = createTestWindowToken(TYPE_INPUT_METHOD, mDefaultDisplay);
|
||||
final Session session = new Session(mWm, new IWindowSessionCallback.Stub() {
|
||||
@Override
|
||||
public void onAnimatorScaleChanged(float v) throws RemoteException {}
|
||||
});
|
||||
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
|
||||
TYPE_APPLICATION_ATTACHED_DIALOG);
|
||||
params.token = windowToken.token;
|
||||
final IBinder windowContextToken = new Binder();
|
||||
params.setWindowContextToken(windowContextToken);
|
||||
doReturn(true).when(mWm.mWindowContextListenerController)
|
||||
.hasListener(eq(windowContextToken));
|
||||
doReturn(TYPE_INPUT_METHOD).when(mWm.mWindowContextListenerController)
|
||||
.getWindowType(eq(windowContextToken));
|
||||
|
||||
mWm.addWindow(session, new TestIWindow(), params, View.VISIBLE, DEFAULT_DISPLAY,
|
||||
UserHandle.USER_SYSTEM, new InsetsState(), null, new InsetsState(),
|
||||
new InsetsSourceControl[0]);
|
||||
|
||||
verify(mWm.mWindowContextListenerController, never()).registerWindowContainerListener(any(),
|
||||
any(), anyInt(), anyInt(), any());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user