Merge "Handle invalid dream window in DreamOverlayService." into tm-qpr-dev am: 85243f02b5

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21538455

Change-Id: Id75528773627ef0e6fa8349b1b71478f5066b4e5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Bryce Lee
2023-02-23 03:23:05 +00:00
committed by Automerger Merge Worker
2 changed files with 49 additions and 3 deletions

View File

@@ -195,7 +195,14 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
mDreamOverlayTouchMonitor.init(); mDreamOverlayTouchMonitor.init();
mStateController.setShouldShowComplications(shouldShowComplications()); mStateController.setShouldShowComplications(shouldShowComplications());
addOverlayWindowLocked(layoutParams);
// If we are not able to add the overlay window, reset the overlay.
if (!addOverlayWindowLocked(layoutParams)) {
resetCurrentDreamOverlayLocked();
return;
}
setCurrentStateLocked(Lifecycle.State.RESUMED); setCurrentStateLocked(Lifecycle.State.RESUMED);
mStateController.setOverlayActive(true); mStateController.setOverlayActive(true);
final ComponentName dreamComponent = getDreamComponent(); final ComponentName dreamComponent = getDreamComponent();
@@ -241,7 +248,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
* @param layoutParams The {@link android.view.WindowManager.LayoutParams} which allow inserting * @param layoutParams The {@link android.view.WindowManager.LayoutParams} which allow inserting
* into the dream window. * into the dream window.
*/ */
private void addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) { private boolean addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) {
mWindow = new PhoneWindow(mContext); mWindow = new PhoneWindow(mContext);
// Default to SystemUI name for TalkBack. // Default to SystemUI name for TalkBack.
mWindow.setTitle(""); mWindow.setTitle("");
@@ -266,9 +273,22 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
// risk an IllegalStateException in some cases when setting the container view as the // risk an IllegalStateException in some cases when setting the container view as the
// window's content view and the container view hasn't been properly removed previously). // window's content view and the container view hasn't been properly removed previously).
removeContainerViewFromParentLocked(); removeContainerViewFromParentLocked();
mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView()); mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView());
mWindowManager.addView(mWindow.getDecorView(), mWindow.getAttributes()); // It is possible that a dream's window (and the dream as a whole) is no longer valid by
// the time the overlay service processes the dream. This can happen for example if
// another dream is started immediately after the existing dream begins. In this case, the
// overlay service should identify the situation through the thrown exception and tear down
// the overlay.
try {
mWindowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
return true;
} catch (WindowManager.BadTokenException exception) {
Log.e(TAG, "Dream activity window invalid: " + layoutParams.packageName,
exception);
return false;
}
} }
private void removeContainerViewFromParentLocked() { private void removeContainerViewFromParentLocked() {

View File

@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
@@ -190,6 +191,31 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
verify(mWindowManager).addView(any(), any()); verify(mWindowManager).addView(any(), any());
} }
// Validates that {@link DreamOverlayService} properly handles the case where the dream's
// window is no longer valid by the time start is called.
@Test
public void testInvalidWindowAddStart() throws Exception {
final IDreamOverlayClient client = getClient();
doThrow(new WindowManager.BadTokenException()).when(mWindowManager).addView(any(), any());
// Inform the overlay service of dream starting.
client.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
false /*shouldShowComplication*/);
mMainExecutor.runAllReady();
verify(mWindowManager).addView(any(), any());
verify(mStateController).setOverlayActive(false);
verify(mStateController).setLowLightActive(false);
verify(mStateController).setEntryAnimationsFinished(false);
verify(mStateController, never()).setOverlayActive(true);
verify(mUiEventLogger, never()).log(
DreamOverlayService.DreamOverlayEvent.DREAM_OVERLAY_COMPLETE_START);
verify(mDreamOverlayCallbackController, never()).onStartDream();
}
@Test @Test
public void testDreamOverlayContainerViewControllerInitialized() throws Exception { public void testDreamOverlayContainerViewControllerInitialized() throws Exception {
final IDreamOverlayClient client = getClient(); final IDreamOverlayClient client = getClient();