Merge "[RESTRICT AUTOMERGE] Send WindowContext config only when Display is active" into sc-v2-dev
This commit is contained in:
@@ -44,6 +44,8 @@ import static android.view.Display.FLAG_PRIVATE;
|
|||||||
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
|
||||||
import static android.view.Display.INVALID_DISPLAY;
|
import static android.view.Display.INVALID_DISPLAY;
|
||||||
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
|
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
|
||||||
|
import static android.view.Display.STATE_UNKNOWN;
|
||||||
|
import static android.view.Display.isSuspendedState;
|
||||||
import static android.view.InsetsState.ITYPE_IME;
|
import static android.view.InsetsState.ITYPE_IME;
|
||||||
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
|
import static android.view.InsetsState.ITYPE_LEFT_GESTURES;
|
||||||
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
|
||||||
@@ -322,11 +324,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
*/
|
*/
|
||||||
private Rect mLastMirroredDisplayAreaBounds = null;
|
private Rect mLastMirroredDisplayAreaBounds = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* The last state of the display.
|
|
||||||
*/
|
|
||||||
private int mLastDisplayState;
|
|
||||||
|
|
||||||
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
|
// Contains all IME window containers. Note that the z-ordering of the IME windows will depend
|
||||||
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
|
// on the IME target. We mainly have this container grouping so we can keep track of all the IME
|
||||||
// window containers together and move them in-sync if/when needed. We use a subclass of
|
// window containers together and move them in-sync if/when needed. We use a subclass of
|
||||||
@@ -5623,12 +5620,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
void onDisplayChanged() {
|
void onDisplayChanged() {
|
||||||
mDisplay.getRealSize(mTmpDisplaySize);
|
mDisplay.getRealSize(mTmpDisplaySize);
|
||||||
setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
|
setBounds(0, 0, mTmpDisplaySize.x, mTmpDisplaySize.y);
|
||||||
|
final int lastDisplayState = mDisplayInfo.state;
|
||||||
updateDisplayInfo();
|
updateDisplayInfo();
|
||||||
|
|
||||||
// The window policy is responsible for stopping activities on the default display.
|
// The window policy is responsible for stopping activities on the default display.
|
||||||
final int displayId = mDisplay.getDisplayId();
|
final int displayId = mDisplay.getDisplayId();
|
||||||
|
final int displayState = mDisplayInfo.state;
|
||||||
if (displayId != DEFAULT_DISPLAY) {
|
if (displayId != DEFAULT_DISPLAY) {
|
||||||
final int displayState = mDisplay.getState();
|
|
||||||
if (displayState == Display.STATE_OFF) {
|
if (displayState == Display.STATE_OFF) {
|
||||||
mOffTokenAcquirer.acquire(mDisplayId);
|
mOffTokenAcquirer.acquire(mDisplayId);
|
||||||
} else if (displayState == Display.STATE_ON) {
|
} else if (displayState == Display.STATE_ON) {
|
||||||
@@ -5637,12 +5635,18 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
|||||||
ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
|
ProtoLog.v(WM_DEBUG_LAYER_MIRRORING,
|
||||||
"Display %d state is now (%d), so update layer mirroring?",
|
"Display %d state is now (%d), so update layer mirroring?",
|
||||||
mDisplayId, displayState);
|
mDisplayId, displayState);
|
||||||
if (mLastDisplayState != displayState) {
|
if (lastDisplayState != displayState) {
|
||||||
// If state is on due to surface being added, then start layer mirroring.
|
// If state is on due to surface being added, then start layer mirroring.
|
||||||
// If state is off due to surface being removed, then stop layer mirroring.
|
// If state is off due to surface being removed, then stop layer mirroring.
|
||||||
updateMirroring();
|
updateMirroring();
|
||||||
}
|
}
|
||||||
mLastDisplayState = displayState;
|
}
|
||||||
|
// Dispatch pending Configuration to WindowContext if the associated display changes to
|
||||||
|
// un-suspended state from suspended.
|
||||||
|
if (isSuspendedState(lastDisplayState)
|
||||||
|
&& !isSuspendedState(displayState) && displayState != STATE_UNKNOWN) {
|
||||||
|
mWmService.mWindowContextListenerController
|
||||||
|
.dispatchPendingConfigurationIfNeeded(mDisplayId);
|
||||||
}
|
}
|
||||||
mWmService.requestTraversal();
|
mWmService.requestTraversal();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.view.Display.INVALID_DISPLAY;
|
import static android.view.Display.INVALID_DISPLAY;
|
||||||
|
import static android.view.Display.isSuspendedState;
|
||||||
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
|
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
|
||||||
|
import static android.window.WindowProviderService.isWindowProviderService;
|
||||||
|
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
|
||||||
import static com.android.internal.protolog.ProtoLogGroup.WM_ERROR;
|
import static com.android.internal.protolog.ProtoLogGroup.WM_ERROR;
|
||||||
@@ -80,7 +82,7 @@ class WindowContextListenerController {
|
|||||||
* @param options a bundle used to pass window-related options.
|
* @param options a bundle used to pass window-related options.
|
||||||
*/
|
*/
|
||||||
void registerWindowContainerListener(@NonNull IBinder clientToken,
|
void registerWindowContainerListener(@NonNull IBinder clientToken,
|
||||||
@NonNull WindowContainer container, int ownerUid, @WindowType int type,
|
@NonNull WindowContainer<?> container, int ownerUid, @WindowType int type,
|
||||||
@Nullable Bundle options) {
|
@Nullable Bundle options) {
|
||||||
WindowContextListenerImpl listener = mListeners.get(clientToken);
|
WindowContextListenerImpl listener = mListeners.get(clientToken);
|
||||||
if (listener == null) {
|
if (listener == null) {
|
||||||
@@ -103,6 +105,16 @@ class WindowContextListenerController {
|
|||||||
listener.unregister();
|
listener.unregister();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dispatchPendingConfigurationIfNeeded(int displayId) {
|
||||||
|
for (int i = mListeners.size() - 1; i >= 0; --i) {
|
||||||
|
final WindowContextListenerImpl listener = mListeners.valueAt(i);
|
||||||
|
if (listener.getWindowContainer().getDisplayContent().getDisplayId() == displayId
|
||||||
|
&& listener.mHasPendingConfiguration) {
|
||||||
|
listener.reportConfigToWindowTokenClient();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies if the caller is allowed to do the operation to the listener specified by
|
* Verifies if the caller is allowed to do the operation to the listener specified by
|
||||||
* {@code clientToken}.
|
* {@code clientToken}.
|
||||||
@@ -138,7 +150,7 @@ class WindowContextListenerController {
|
|||||||
return listener != null ? listener.mOptions : null;
|
return listener != null ? listener.mOptions : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable WindowContainer getContainer(IBinder clientToken) {
|
@Nullable WindowContainer<?> getContainer(IBinder clientToken) {
|
||||||
final WindowContextListenerImpl listener = mListeners.get(clientToken);
|
final WindowContextListenerImpl listener = mListeners.get(clientToken);
|
||||||
return listener != null ? listener.mContainer : null;
|
return listener != null ? listener.mContainer : null;
|
||||||
}
|
}
|
||||||
@@ -163,7 +175,7 @@ class WindowContextListenerController {
|
|||||||
class WindowContextListenerImpl implements WindowContainerListener {
|
class WindowContextListenerImpl implements WindowContainerListener {
|
||||||
@NonNull private final IBinder mClientToken;
|
@NonNull private final IBinder mClientToken;
|
||||||
private final int mOwnerUid;
|
private final int mOwnerUid;
|
||||||
@NonNull private WindowContainer mContainer;
|
@NonNull private WindowContainer<?> mContainer;
|
||||||
/**
|
/**
|
||||||
* The options from {@link Context#createWindowContext(int, Bundle)}.
|
* The options from {@link Context#createWindowContext(int, Bundle)}.
|
||||||
* <p>It can be used for choosing the {@link DisplayArea} where the window context
|
* <p>It can be used for choosing the {@link DisplayArea} where the window context
|
||||||
@@ -177,7 +189,9 @@ class WindowContextListenerController {
|
|||||||
private int mLastReportedDisplay = INVALID_DISPLAY;
|
private int mLastReportedDisplay = INVALID_DISPLAY;
|
||||||
private Configuration mLastReportedConfig;
|
private Configuration mLastReportedConfig;
|
||||||
|
|
||||||
private WindowContextListenerImpl(IBinder clientToken, WindowContainer container,
|
private boolean mHasPendingConfiguration;
|
||||||
|
|
||||||
|
private WindowContextListenerImpl(IBinder clientToken, WindowContainer<?> container,
|
||||||
int ownerUid, @WindowType int type, @Nullable Bundle options) {
|
int ownerUid, @WindowType int type, @Nullable Bundle options) {
|
||||||
mClientToken = clientToken;
|
mClientToken = clientToken;
|
||||||
mContainer = Objects.requireNonNull(container);
|
mContainer = Objects.requireNonNull(container);
|
||||||
@@ -197,11 +211,11 @@ class WindowContextListenerController {
|
|||||||
|
|
||||||
/** TEST ONLY: returns the {@link WindowContainer} of the listener */
|
/** TEST ONLY: returns the {@link WindowContainer} of the listener */
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
WindowContainer getWindowContainer() {
|
WindowContainer<?> getWindowContainer() {
|
||||||
return mContainer;
|
return mContainer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateContainer(@NonNull WindowContainer newContainer) {
|
private void updateContainer(@NonNull WindowContainer<?> newContainer) {
|
||||||
Objects.requireNonNull(newContainer);
|
Objects.requireNonNull(newContainer);
|
||||||
|
|
||||||
if (mContainer.equals(newContainer)) {
|
if (mContainer.equals(newContainer)) {
|
||||||
@@ -246,12 +260,20 @@ class WindowContextListenerController {
|
|||||||
if (mDeathRecipient == null) {
|
if (mDeathRecipient == null) {
|
||||||
throw new IllegalStateException("Invalid client token: " + mClientToken);
|
throw new IllegalStateException("Invalid client token: " + mClientToken);
|
||||||
}
|
}
|
||||||
|
// If the display of window context associated window container is suspended, don't
|
||||||
if (mLastReportedConfig == null) {
|
// report the configuration update. Note that we still dispatch the configuration update
|
||||||
mLastReportedConfig = new Configuration();
|
// to WindowProviderService to make it compatible with Service#onConfigurationChanged.
|
||||||
|
// Service always receives #onConfigurationChanged callback regardless of display state.
|
||||||
|
if (!isWindowProviderService(mOptions)
|
||||||
|
&& isSuspendedState(mContainer.getDisplayContent().getDisplayInfo().state)) {
|
||||||
|
mHasPendingConfiguration = true;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
final Configuration config = mContainer.getConfiguration();
|
final Configuration config = mContainer.getConfiguration();
|
||||||
final int displayId = mContainer.getDisplayContent().getDisplayId();
|
final int displayId = mContainer.getDisplayContent().getDisplayId();
|
||||||
|
if (mLastReportedConfig == null) {
|
||||||
|
mLastReportedConfig = new Configuration();
|
||||||
|
}
|
||||||
if (config.equals(mLastReportedConfig) && displayId == mLastReportedDisplay) {
|
if (config.equals(mLastReportedConfig) && displayId == mLastReportedDisplay) {
|
||||||
// No changes since last reported time.
|
// No changes since last reported time.
|
||||||
return;
|
return;
|
||||||
@@ -266,6 +288,7 @@ class WindowContextListenerController {
|
|||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
ProtoLog.w(WM_ERROR, "Could not report config changes to the window token client.");
|
ProtoLog.w(WM_ERROR, "Could not report config changes to the window token client.");
|
||||||
}
|
}
|
||||||
|
mHasPendingConfiguration = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -283,7 +306,7 @@ class WindowContextListenerController {
|
|||||||
// If we cannot obtain the DisplayContent, the DisplayContent may also be removed.
|
// If we cannot obtain the DisplayContent, the DisplayContent may also be removed.
|
||||||
// We should proceed the removal process.
|
// We should proceed the removal process.
|
||||||
if (dc != null) {
|
if (dc != null) {
|
||||||
final DisplayArea da = dc.findAreaForToken(windowToken);
|
final DisplayArea<?> da = dc.findAreaForToken(windowToken);
|
||||||
updateContainer(da);
|
updateContainer(da);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
|
import static android.view.Display.STATE_ON;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
||||||
|
|
||||||
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
|
||||||
@@ -70,7 +71,7 @@ public class InputMethodMenuControllerTest extends WindowTestsBase {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
// Let the Display to be created with the DualDisplay policy.
|
// Let the Display be created with the DualDisplay policy.
|
||||||
final DisplayAreaPolicy.Provider policyProvider =
|
final DisplayAreaPolicy.Provider policyProvider =
|
||||||
new DualDisplayAreaGroupPolicyTest.DualDisplayTestPolicyProvider();
|
new DualDisplayAreaGroupPolicyTest.DualDisplayTestPolicyProvider();
|
||||||
Mockito.doReturn(policyProvider).when(mWm).getDisplayAreaPolicyProvider();
|
Mockito.doReturn(policyProvider).when(mWm).getDisplayAreaPolicyProvider();
|
||||||
@@ -78,6 +79,7 @@ public class InputMethodMenuControllerTest extends WindowTestsBase {
|
|||||||
mController = new InputMethodMenuController(mock(InputMethodManagerService.class));
|
mController = new InputMethodMenuController(mock(InputMethodManagerService.class));
|
||||||
mSecondaryDisplay = new DualDisplayAreaGroupPolicyTest.DualDisplayContent
|
mSecondaryDisplay = new DualDisplayAreaGroupPolicyTest.DualDisplayContent
|
||||||
.Builder(mAtm, 1000, 1000).build();
|
.Builder(mAtm, 1000, 1000).build();
|
||||||
|
mSecondaryDisplay.getDisplayInfo().state = STATE_ON;
|
||||||
|
|
||||||
// Mock addWindowTokenWithOptions to create a test window token.
|
// Mock addWindowTokenWithOptions to create a test window token.
|
||||||
mIWindowManager = WindowManagerGlobal.getWindowManagerService();
|
mIWindowManager = WindowManagerGlobal.getWindowManagerService();
|
||||||
|
|||||||
@@ -17,22 +17,35 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import static android.view.Display.DEFAULT_DISPLAY;
|
import static android.view.Display.DEFAULT_DISPLAY;
|
||||||
|
import static android.view.Display.STATE_OFF;
|
||||||
|
import static android.view.Display.STATE_ON;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
|
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
|
||||||
|
import static android.window.WindowProvider.KEY_IS_WINDOW_PROVIDER_SERVICE;
|
||||||
|
|
||||||
|
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.app.IWindowToken;
|
import android.app.IWindowToken;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
|
import android.view.Display;
|
||||||
|
import android.view.DisplayInfo;
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
@@ -55,12 +68,15 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
|
|||||||
private static final int ANOTHER_UID = 1000;
|
private static final int ANOTHER_UID = 1000;
|
||||||
|
|
||||||
private final IBinder mClientToken = new Binder();
|
private final IBinder mClientToken = new Binder();
|
||||||
private WindowContainer mContainer;
|
private WindowContainer<?> mContainer;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
mController = new WindowContextListenerController();
|
mController = new WindowContextListenerController();
|
||||||
mContainer = createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
|
mContainer = createTestWindowToken(TYPE_APPLICATION_OVERLAY, mDisplayContent);
|
||||||
|
// Make display on to verify configuration propagation.
|
||||||
|
mDefaultDisplay.getDisplayInfo().state = STATE_ON;
|
||||||
|
mDisplayContent.getDisplayInfo().state = STATE_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -76,7 +92,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
|
|||||||
|
|
||||||
assertEquals(2, mController.mListeners.size());
|
assertEquals(2, mController.mListeners.size());
|
||||||
|
|
||||||
final WindowContainer container = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
|
final WindowContainer<?> container = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
|
||||||
mDefaultDisplay);
|
mDefaultDisplay);
|
||||||
mController.registerWindowContainerListener(mClientToken, container, -1,
|
mController.registerWindowContainerListener(mClientToken, container, -1,
|
||||||
TYPE_APPLICATION_OVERLAY, null /* options */);
|
TYPE_APPLICATION_OVERLAY, null /* options */);
|
||||||
@@ -89,6 +105,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
|
|||||||
assertEquals(container, listener.getWindowContainer());
|
assertEquals(container, listener.getWindowContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@UseTestDisplay
|
||||||
@Test
|
@Test
|
||||||
public void testRegisterWindowContextListenerClientConfigPropagation() {
|
public void testRegisterWindowContextListenerClientConfigPropagation() {
|
||||||
final TestWindowTokenClient clientToken = new TestWindowTokenClient();
|
final TestWindowTokenClient clientToken = new TestWindowTokenClient();
|
||||||
@@ -107,7 +124,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
|
|||||||
assertEquals(mDisplayContent.mDisplayId, clientToken.mDisplayId);
|
assertEquals(mDisplayContent.mDisplayId, clientToken.mDisplayId);
|
||||||
|
|
||||||
// Update the WindowContainer.
|
// Update the WindowContainer.
|
||||||
final WindowContainer container = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
|
final WindowContainer<?> container = createTestWindowToken(TYPE_APPLICATION_OVERLAY,
|
||||||
mDefaultDisplay);
|
mDefaultDisplay);
|
||||||
final Configuration config2 = container.getConfiguration();
|
final Configuration config2 = container.getConfiguration();
|
||||||
final Rect bounds2 = new Rect(0, 0, 20, 20);
|
final Rect bounds2 = new Rect(0, 0, 20, 20);
|
||||||
@@ -174,7 +191,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
|
|||||||
.setDisplayContent(mDefaultDisplay)
|
.setDisplayContent(mDefaultDisplay)
|
||||||
.setFromClientToken(true)
|
.setFromClientToken(true)
|
||||||
.build();
|
.build();
|
||||||
final DisplayArea da = windowContextCreatedToken.getDisplayArea();
|
final DisplayArea<?> da = windowContextCreatedToken.getDisplayArea();
|
||||||
|
|
||||||
mController.registerWindowContainerListener(mClientToken, windowContextCreatedToken,
|
mController.registerWindowContainerListener(mClientToken, windowContextCreatedToken,
|
||||||
TEST_UID, TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */);
|
TEST_UID, TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */);
|
||||||
@@ -192,11 +209,12 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
|
|||||||
// Let the Display to be created with the DualDisplay policy.
|
// Let the Display to be created with the DualDisplay policy.
|
||||||
final DisplayAreaPolicy.Provider policyProvider =
|
final DisplayAreaPolicy.Provider policyProvider =
|
||||||
new DualDisplayAreaGroupPolicyTest.DualDisplayTestPolicyProvider();
|
new DualDisplayAreaGroupPolicyTest.DualDisplayTestPolicyProvider();
|
||||||
Mockito.doReturn(policyProvider).when(mWm).getDisplayAreaPolicyProvider();
|
doReturn(policyProvider).when(mWm).getDisplayAreaPolicyProvider();
|
||||||
// Create a DisplayContent with dual RootDisplayArea
|
// Create a DisplayContent with dual RootDisplayArea
|
||||||
DualDisplayAreaGroupPolicyTest.DualDisplayContent dualDisplayContent =
|
DualDisplayAreaGroupPolicyTest.DualDisplayContent dualDisplayContent =
|
||||||
new DualDisplayAreaGroupPolicyTest.DualDisplayContent
|
new DualDisplayAreaGroupPolicyTest.DualDisplayContent
|
||||||
.Builder(mAtm, 1000, 1000).build();
|
.Builder(mAtm, 1000, 1000).build();
|
||||||
|
dualDisplayContent.getDisplayInfo().state = STATE_ON;
|
||||||
final DisplayArea.Tokens imeContainer = dualDisplayContent.getImeContainer();
|
final DisplayArea.Tokens imeContainer = dualDisplayContent.getImeContainer();
|
||||||
// Put the ImeContainer to the first sub-RootDisplayArea
|
// Put the ImeContainer to the first sub-RootDisplayArea
|
||||||
dualDisplayContent.mFirstRoot.placeImeContainer(imeContainer);
|
dualDisplayContent.mFirstRoot.placeImeContainer(imeContainer);
|
||||||
@@ -222,7 +240,62 @@ public class WindowContextListenerControllerTests extends WindowTestsBase {
|
|||||||
assertThat(mController.getContainer(mClientToken)).isEqualTo(imeContainer);
|
assertThat(mController.getContainer(mClientToken)).isEqualTo(imeContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestWindowTokenClient extends IWindowToken.Stub {
|
@Test
|
||||||
|
public void testConfigUpdateForSuspendedWindowContext() {
|
||||||
|
final TestWindowTokenClient mockToken = new TestWindowTokenClient();
|
||||||
|
spyOn(mockToken);
|
||||||
|
|
||||||
|
mContainer.getDisplayContent().getDisplayInfo().state = STATE_OFF;
|
||||||
|
|
||||||
|
final Configuration config1 = mContainer.getConfiguration();
|
||||||
|
final Rect bounds1 = new Rect(0, 0, 10, 10);
|
||||||
|
config1.windowConfiguration.setBounds(bounds1);
|
||||||
|
config1.densityDpi = 100;
|
||||||
|
mContainer.onRequestedOverrideConfigurationChanged(config1);
|
||||||
|
|
||||||
|
mController.registerWindowContainerListener(mockToken, mContainer, -1,
|
||||||
|
TYPE_APPLICATION_OVERLAY, null /* options */);
|
||||||
|
|
||||||
|
verify(mockToken, never()).onConfigurationChanged(any(), anyInt());
|
||||||
|
|
||||||
|
// Turn on the display and verify if the client receive the callback
|
||||||
|
Display display = mContainer.getDisplayContent().getDisplay();
|
||||||
|
spyOn(display);
|
||||||
|
Mockito.doAnswer(invocation -> {
|
||||||
|
final DisplayInfo info = mContainer.getDisplayContent().getDisplayInfo();
|
||||||
|
info.state = STATE_ON;
|
||||||
|
((DisplayInfo) invocation.getArgument(0)).copyFrom(info);
|
||||||
|
return null;
|
||||||
|
}).when(display).getDisplayInfo(any(DisplayInfo.class));
|
||||||
|
|
||||||
|
mContainer.getDisplayContent().onDisplayChanged();
|
||||||
|
|
||||||
|
assertThat(mockToken.mConfiguration).isEqualTo(config1);
|
||||||
|
assertThat(mockToken.mDisplayId).isEqualTo(mContainer.getDisplayContent().getDisplayId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReportConfigUpdateForSuspendedWindowProviderService() {
|
||||||
|
final TestWindowTokenClient clientToken = new TestWindowTokenClient();
|
||||||
|
final Bundle options = new Bundle();
|
||||||
|
options.putBoolean(KEY_IS_WINDOW_PROVIDER_SERVICE, true);
|
||||||
|
|
||||||
|
mContainer.getDisplayContent().getDisplayInfo().state = STATE_OFF;
|
||||||
|
|
||||||
|
final Configuration config1 = mContainer.getConfiguration();
|
||||||
|
final Rect bounds1 = new Rect(0, 0, 10, 10);
|
||||||
|
config1.windowConfiguration.setBounds(bounds1);
|
||||||
|
config1.densityDpi = 100;
|
||||||
|
mContainer.onRequestedOverrideConfigurationChanged(config1);
|
||||||
|
|
||||||
|
mController.registerWindowContainerListener(clientToken, mContainer, -1,
|
||||||
|
TYPE_APPLICATION_OVERLAY, options);
|
||||||
|
|
||||||
|
assertThat(clientToken.mConfiguration).isEqualTo(config1);
|
||||||
|
assertThat(clientToken.mDisplayId).isEqualTo(mDisplayContent.mDisplayId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestWindowTokenClient extends IWindowToken.Stub {
|
||||||
private Configuration mConfiguration;
|
private Configuration mConfiguration;
|
||||||
private int mDisplayId;
|
private int mDisplayId;
|
||||||
private boolean mRemoved;
|
private boolean mRemoved;
|
||||||
|
|||||||
Reference in New Issue
Block a user