Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85243f02 authored by Bryce Lee's avatar Bryce Lee Committed by Android (Google) Code Review
Browse files

Merge "Handle invalid dream window in DreamOverlayService." into tm-qpr-dev

parents 69ce1098 b0514b19
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -195,7 +195,14 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
            mDreamOverlayTouchMonitor.init();

            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);
            mStateController.setOverlayActive(true);
            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
     *                     into the dream window.
     */
    private void addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) {
    private boolean addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) {
        mWindow = new PhoneWindow(mContext);
        // Default to SystemUI name for TalkBack.
        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
        // window's content view and the container view hasn't been properly removed previously).
        removeContainerViewFromParentLocked();

        mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView());

        // 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() {
+26 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -190,6 +191,31 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
        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
    public void testDreamOverlayContainerViewControllerInitialized() throws Exception {
        final IDreamOverlayClient client = getClient();