Merge "Redraw dream overlay when a new dream is connected." into tm-qpr-dev am: eabe3bf0c1

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

Change-Id: Idd25f2e09016a1e6db4a6b30bfaab420403f5cab
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Darrell Shi
2022-10-12 21:31:12 +00:00
committed by Automerger Merge Worker
5 changed files with 180 additions and 85 deletions

View File

@@ -42,8 +42,11 @@ public abstract class DreamOverlayService extends Service {
private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() { private IDreamOverlay mDreamOverlay = new IDreamOverlay.Stub() {
@Override @Override
public void startDream(WindowManager.LayoutParams layoutParams, public void startDream(WindowManager.LayoutParams layoutParams,
IDreamOverlayCallback callback) { IDreamOverlayCallback callback, String dreamComponent,
boolean shouldShowComplications) {
mDreamOverlayCallback = callback; mDreamOverlayCallback = callback;
mDreamComponent = ComponentName.unflattenFromString(dreamComponent);
mShowComplications = shouldShowComplications;
onStartDream(layoutParams); onStartDream(layoutParams);
} }
}; };
@@ -56,10 +59,6 @@ public abstract class DreamOverlayService extends Service {
@Nullable @Nullable
@Override @Override
public final IBinder onBind(@NonNull Intent intent) { public final IBinder onBind(@NonNull Intent intent) {
mShowComplications = intent.getBooleanExtra(DreamService.EXTRA_SHOW_COMPLICATIONS,
DreamService.DEFAULT_SHOW_COMPLICATIONS);
mDreamComponent = intent.getParcelableExtra(DreamService.EXTRA_DREAM_COMPONENT,
ComponentName.class);
return mDreamOverlay.asBinder(); return mDreamOverlay.asBinder();
} }

View File

@@ -213,19 +213,6 @@ public class DreamService extends Service implements Window.Callback {
*/ */
private static final String DREAM_META_DATA_ROOT_TAG = "dream"; private static final String DREAM_META_DATA_ROOT_TAG = "dream";
/**
* Extra containing a boolean for whether to show complications on the overlay.
* @hide
*/
public static final String EXTRA_SHOW_COMPLICATIONS =
"android.service.dreams.SHOW_COMPLICATIONS";
/**
* Extra containing the component name for the active dream.
* @hide
*/
public static final String EXTRA_DREAM_COMPONENT = "android.service.dreams.DREAM_COMPONENT";
/** /**
* The default value for whether to show complications on the overlay. * The default value for whether to show complications on the overlay.
* *
@@ -252,6 +239,9 @@ public class DreamService extends Service implements Window.Callback {
private boolean mDebug = false; private boolean mDebug = false;
private ComponentName mDreamComponent;
private boolean mShouldShowComplications;
private DreamServiceWrapper mDreamServiceWrapper; private DreamServiceWrapper mDreamServiceWrapper;
private Runnable mDispatchAfterOnAttachedToWindow; private Runnable mDispatchAfterOnAttachedToWindow;
@@ -947,6 +937,11 @@ public class DreamService extends Service implements Window.Callback {
@Override @Override
public void onCreate() { public void onCreate() {
if (mDebug) Slog.v(mTag, "onCreate()"); if (mDebug) Slog.v(mTag, "onCreate()");
mDreamComponent = new ComponentName(this, getClass());
mShouldShowComplications = fetchShouldShowComplications(this /*context*/,
fetchServiceInfo(this /*context*/, mDreamComponent));
super.onCreate(); super.onCreate();
} }
@@ -994,14 +989,7 @@ public class DreamService extends Service implements Window.Callback {
// Connect to the overlay service if present. // Connect to the overlay service if present.
if (!mWindowless && overlayComponent != null) { if (!mWindowless && overlayComponent != null) {
final Resources resources = getResources(); final Resources resources = getResources();
final ComponentName dreamService = new ComponentName(this, getClass()); final Intent overlayIntent = new Intent().setComponent(overlayComponent);
final ServiceInfo serviceInfo = fetchServiceInfo(this, dreamService);
final Intent overlayIntent = new Intent()
.setComponent(overlayComponent)
.putExtra(EXTRA_SHOW_COMPLICATIONS,
fetchShouldShowComplications(this, serviceInfo))
.putExtra(EXTRA_DREAM_COMPONENT, dreamService);
mOverlayConnection = new OverlayConnection( mOverlayConnection = new OverlayConnection(
/* context= */ this, /* context= */ this,
@@ -1364,7 +1352,9 @@ public class DreamService extends Service implements Window.Callback {
// parameters once the window has been attached. // parameters once the window has been attached.
mDreamStartOverlayConsumer = overlay -> { mDreamStartOverlayConsumer = overlay -> {
try { try {
overlay.startDream(mWindow.getAttributes(), mOverlayCallback); overlay.startDream(mWindow.getAttributes(), mOverlayCallback,
mDreamComponent.flattenToString(),
mShouldShowComplications);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(mTag, "could not send window attributes:" + e); Log.e(mTag, "could not send window attributes:" + e);
} }

View File

@@ -32,6 +32,10 @@ interface IDreamOverlay {
token of the Dream Activity. token of the Dream Activity.
* @param callback The {@link IDreamOverlayCallback} for requesting actions such as exiting the * @param callback The {@link IDreamOverlayCallback} for requesting actions such as exiting the
* dream. * dream.
* @param dreamComponent The component name of the dream service requesting overlay.
* @param shouldShowComplications Whether the dream overlay should show complications, e.g. clock
* and weather.
*/ */
void startDream(in LayoutParams params, in IDreamOverlayCallback callback); void startDream(in LayoutParams params, in IDreamOverlayCallback callback,
in String dreamComponent, in boolean shouldShowComplications);
} }

View File

@@ -64,29 +64,26 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
private final Executor mExecutor; private final Executor mExecutor;
// A controller for the dream overlay container view (which contains both the status bar and the // A controller for the dream overlay container view (which contains both the status bar and the
// content area). // content area).
private final DreamOverlayContainerViewController mDreamOverlayContainerViewController; private DreamOverlayContainerViewController mDreamOverlayContainerViewController;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Nullable @Nullable
private final ComponentName mLowLightDreamComponent; private final ComponentName mLowLightDreamComponent;
private final UiEventLogger mUiEventLogger; private final UiEventLogger mUiEventLogger;
private final WindowManager mWindowManager;
// A reference to the {@link Window} used to hold the dream overlay. // A reference to the {@link Window} used to hold the dream overlay.
private Window mWindow; private Window mWindow;
// True if the service has been destroyed. // True if a dream has bound to the service and dream overlay service has started.
private boolean mDestroyed; private boolean mStarted = false;
private final Complication.Host mHost = new Complication.Host() { // True if the service has been destroyed.
@Override private boolean mDestroyed = false;
public void requestExitDream() {
mExecutor.execute(DreamOverlayService.this::requestExit); private final DreamOverlayComponent mDreamOverlayComponent;
}
};
private final LifecycleRegistry mLifecycleRegistry; private final LifecycleRegistry mLifecycleRegistry;
private ViewModelStore mViewModelStore = new ViewModelStore();
private DreamOverlayTouchMonitor mDreamOverlayTouchMonitor; private DreamOverlayTouchMonitor mDreamOverlayTouchMonitor;
private final KeyguardUpdateMonitorCallback mKeyguardCallback = private final KeyguardUpdateMonitorCallback mKeyguardCallback =
@@ -103,7 +100,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
} }
}; };
private DreamOverlayStateController mStateController; private final DreamOverlayStateController mStateController;
@VisibleForTesting @VisibleForTesting
public enum DreamOverlayEvent implements UiEventLogger.UiEventEnum { public enum DreamOverlayEvent implements UiEventLogger.UiEventEnum {
@@ -128,6 +125,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
public DreamOverlayService( public DreamOverlayService(
Context context, Context context,
@Main Executor executor, @Main Executor executor,
WindowManager windowManager,
DreamOverlayComponent.Factory dreamOverlayComponentFactory, DreamOverlayComponent.Factory dreamOverlayComponentFactory,
DreamOverlayStateController stateController, DreamOverlayStateController stateController,
KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardUpdateMonitor keyguardUpdateMonitor,
@@ -136,19 +134,19 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
ComponentName lowLightDreamComponent) { ComponentName lowLightDreamComponent) {
mContext = context; mContext = context;
mExecutor = executor; mExecutor = executor;
mWindowManager = windowManager;
mKeyguardUpdateMonitor = keyguardUpdateMonitor; mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLowLightDreamComponent = lowLightDreamComponent; mLowLightDreamComponent = lowLightDreamComponent;
mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback); mKeyguardUpdateMonitor.registerCallback(mKeyguardCallback);
mStateController = stateController; mStateController = stateController;
mUiEventLogger = uiEventLogger; mUiEventLogger = uiEventLogger;
final DreamOverlayComponent component = final ViewModelStore viewModelStore = new ViewModelStore();
dreamOverlayComponentFactory.create(mViewModelStore, mHost); final Complication.Host host =
mDreamOverlayContainerViewController = component.getDreamOverlayContainerViewController(); () -> mExecutor.execute(DreamOverlayService.this::requestExit);
mDreamOverlayComponent = dreamOverlayComponentFactory.create(viewModelStore, host);
mLifecycleRegistry = mDreamOverlayComponent.getLifecycleRegistry();
setCurrentState(Lifecycle.State.CREATED); setCurrentState(Lifecycle.State.CREATED);
mLifecycleRegistry = component.getLifecycleRegistry();
mDreamOverlayTouchMonitor = component.getDreamOverlayTouchMonitor();
mDreamOverlayTouchMonitor.init();
} }
private void setCurrentState(Lifecycle.State state) { private void setCurrentState(Lifecycle.State state) {
@@ -159,34 +157,48 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
public void onDestroy() { public void onDestroy() {
mKeyguardUpdateMonitor.removeCallback(mKeyguardCallback); mKeyguardUpdateMonitor.removeCallback(mKeyguardCallback);
setCurrentState(Lifecycle.State.DESTROYED); setCurrentState(Lifecycle.State.DESTROYED);
final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
if (mWindow != null) { resetCurrentDreamOverlay();
windowManager.removeView(mWindow.getDecorView());
}
mStateController.setOverlayActive(false);
mStateController.setLowLightActive(false);
mDestroyed = true; mDestroyed = true;
super.onDestroy(); super.onDestroy();
} }
@Override @Override
public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) { public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) {
mUiEventLogger.log(DreamOverlayEvent.DREAM_OVERLAY_ENTER_START);
setCurrentState(Lifecycle.State.STARTED); setCurrentState(Lifecycle.State.STARTED);
final ComponentName dreamComponent = getDreamComponent();
mStateController.setLowLightActive(
dreamComponent != null && dreamComponent.equals(mLowLightDreamComponent));
mExecutor.execute(() -> { mExecutor.execute(() -> {
mUiEventLogger.log(DreamOverlayEvent.DREAM_OVERLAY_ENTER_START);
if (mDestroyed) { if (mDestroyed) {
// The task could still be executed after the service has been destroyed. Bail if // The task could still be executed after the service has been destroyed. Bail if
// that is the case. // that is the case.
return; return;
} }
if (mStarted) {
// Reset the current dream overlay before starting a new one. This can happen
// when two dreams overlap (briefly, for a smoother dream transition) and both
// dreams are bound to the dream overlay service.
resetCurrentDreamOverlay();
}
mDreamOverlayContainerViewController =
mDreamOverlayComponent.getDreamOverlayContainerViewController();
mDreamOverlayTouchMonitor = mDreamOverlayComponent.getDreamOverlayTouchMonitor();
mDreamOverlayTouchMonitor.init();
mStateController.setShouldShowComplications(shouldShowComplications()); mStateController.setShouldShowComplications(shouldShowComplications());
addOverlayWindowLocked(layoutParams); addOverlayWindowLocked(layoutParams);
setCurrentState(Lifecycle.State.RESUMED); setCurrentState(Lifecycle.State.RESUMED);
mStateController.setOverlayActive(true); mStateController.setOverlayActive(true);
final ComponentName dreamComponent = getDreamComponent();
mStateController.setLowLightActive(
dreamComponent != null && dreamComponent.equals(mLowLightDreamComponent));
mUiEventLogger.log(DreamOverlayEvent.DREAM_OVERLAY_COMPLETE_START); mUiEventLogger.log(DreamOverlayEvent.DREAM_OVERLAY_COMPLETE_START);
mStarted = true;
}); });
} }
@@ -222,8 +234,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
removeContainerViewFromParent(); removeContainerViewFromParent();
mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView()); mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView());
final WindowManager windowManager = mContext.getSystemService(WindowManager.class); mWindowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
windowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
} }
private void removeContainerViewFromParent() { private void removeContainerViewFromParent() {
@@ -238,4 +249,18 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
Log.w(TAG, "Removing dream overlay container view parent!"); Log.w(TAG, "Removing dream overlay container view parent!");
parentView.removeView(containerView); parentView.removeView(containerView);
} }
private void resetCurrentDreamOverlay() {
if (mStarted && mWindow != null) {
mWindowManager.removeView(mWindow.getDecorView());
}
mStateController.setOverlayActive(false);
mStateController.setLowLightActive(false);
mDreamOverlayContainerViewController = null;
mDreamOverlayTouchMonitor = null;
mStarted = false;
}
} }

View File

@@ -19,6 +19,7 @@ package com.android.systemui.dreams;
import static com.google.common.truth.Truth.assertThat; 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.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -27,10 +28,10 @@ import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamOverlay; import android.service.dreams.IDreamOverlay;
import android.service.dreams.IDreamOverlayCallback; import android.service.dreams.IDreamOverlayCallback;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.WindowManagerImpl; import android.view.WindowManagerImpl;
@@ -53,6 +54,8 @@ import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@@ -61,6 +64,7 @@ import org.mockito.MockitoAnnotations;
public class DreamOverlayServiceTest extends SysuiTestCase { public class DreamOverlayServiceTest extends SysuiTestCase {
private static final ComponentName LOW_LIGHT_COMPONENT = new ComponentName("package", private static final ComponentName LOW_LIGHT_COMPONENT = new ComponentName("package",
"lowlight"); "lowlight");
private static final String DREAM_COMPONENT = "package/dream";
private final FakeSystemClock mFakeSystemClock = new FakeSystemClock(); private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
private final FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock); private final FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
@@ -108,12 +112,14 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
@Mock @Mock
UiEventLogger mUiEventLogger; UiEventLogger mUiEventLogger;
@Captor
ArgumentCaptor<View> mViewCaptor;
DreamOverlayService mService; DreamOverlayService mService;
@Before @Before
public void setup() { public void setup() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext.addMockSystemService(WindowManager.class, mWindowManager);
when(mDreamOverlayComponent.getDreamOverlayContainerViewController()) when(mDreamOverlayComponent.getDreamOverlayContainerViewController())
.thenReturn(mDreamOverlayContainerViewController); .thenReturn(mDreamOverlayContainerViewController);
@@ -129,7 +135,7 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
when(mDreamOverlayContainerViewController.getContainerView()) when(mDreamOverlayContainerViewController.getContainerView())
.thenReturn(mDreamOverlayContainerView); .thenReturn(mDreamOverlayContainerView);
mService = new DreamOverlayService(mContext, mMainExecutor, mService = new DreamOverlayService(mContext, mMainExecutor, mWindowManager,
mDreamOverlayComponentFactory, mDreamOverlayComponentFactory,
mStateController, mStateController,
mKeyguardUpdateMonitor, mKeyguardUpdateMonitor,
@@ -143,7 +149,8 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
// Inform the overlay service of dream starting. // Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback); overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
false /*shouldShowComplication*/);
mMainExecutor.runAllReady(); mMainExecutor.runAllReady();
verify(mUiEventLogger).log(DreamOverlayService.DreamOverlayEvent.DREAM_OVERLAY_ENTER_START); verify(mUiEventLogger).log(DreamOverlayService.DreamOverlayEvent.DREAM_OVERLAY_ENTER_START);
@@ -157,7 +164,8 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
// Inform the overlay service of dream starting. // Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback); overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
false /*shouldShowComplication*/);
mMainExecutor.runAllReady(); mMainExecutor.runAllReady();
verify(mWindowManager).addView(any(), any()); verify(mWindowManager).addView(any(), any());
@@ -169,7 +177,8 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
// Inform the overlay service of dream starting. // Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback); overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
false /*shouldShowComplication*/);
mMainExecutor.runAllReady(); mMainExecutor.runAllReady();
verify(mDreamOverlayContainerViewController).init(); verify(mDreamOverlayContainerViewController).init();
@@ -186,49 +195,76 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
// Inform the overlay service of dream starting. // Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback); overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
false /*shouldShowComplication*/);
mMainExecutor.runAllReady(); mMainExecutor.runAllReady();
verify(mDreamOverlayContainerViewParent).removeView(mDreamOverlayContainerView); verify(mDreamOverlayContainerViewParent).removeView(mDreamOverlayContainerView);
} }
@Test @Test
public void testShouldShowComplicationsFalseByDefault() { public void testShouldShowComplicationsSetByStartDream() throws RemoteException {
mService.onBind(new Intent()); final IBinder proxy = mService.onBind(new Intent());
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
assertThat(mService.shouldShowComplications()).isFalse(); // Inform the overlay service of dream starting.
} overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
true /*shouldShowComplication*/);
@Test
public void testShouldShowComplicationsSetByIntentExtra() {
final Intent intent = new Intent();
intent.putExtra(DreamService.EXTRA_SHOW_COMPLICATIONS, true);
mService.onBind(intent);
assertThat(mService.shouldShowComplications()).isTrue(); assertThat(mService.shouldShowComplications()).isTrue();
} }
@Test @Test
public void testLowLightSetByIntentExtra() throws RemoteException { public void testLowLightSetByStartDream() throws RemoteException {
final Intent intent = new Intent(); final IBinder proxy = mService.onBind(new Intent());
intent.putExtra(DreamService.EXTRA_DREAM_COMPONENT, LOW_LIGHT_COMPONENT);
final IBinder proxy = mService.onBind(intent);
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
assertThat(mService.getDreamComponent()).isEqualTo(LOW_LIGHT_COMPONENT);
// Inform the overlay service of dream starting. // Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback); overlay.startDream(mWindowParams, mDreamOverlayCallback,
LOW_LIGHT_COMPONENT.flattenToString(), false /*shouldShowComplication*/);
mMainExecutor.runAllReady(); mMainExecutor.runAllReady();
assertThat(mService.getDreamComponent()).isEqualTo(LOW_LIGHT_COMPONENT);
verify(mStateController).setLowLightActive(true); verify(mStateController).setLowLightActive(true);
} }
@Test @Test
public void testDestroy() { public void testDestroy() throws RemoteException {
final IBinder proxy = mService.onBind(new Intent());
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
// Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback,
LOW_LIGHT_COMPONENT.flattenToString(), false /*shouldShowComplication*/);
mMainExecutor.runAllReady();
// Verify view added.
verify(mWindowManager).addView(mViewCaptor.capture(), any());
// Service destroyed.
mService.onDestroy(); mService.onDestroy();
mMainExecutor.runAllReady(); mMainExecutor.runAllReady();
// Verify view removed.
verify(mWindowManager).removeView(mViewCaptor.getValue());
// Verify state correctly set.
verify(mKeyguardUpdateMonitor).removeCallback(any());
verify(mLifecycleRegistry).setCurrentState(Lifecycle.State.DESTROYED);
verify(mStateController).setOverlayActive(false);
verify(mStateController).setLowLightActive(false);
}
@Test
public void testDoNotRemoveViewOnDestroyIfOverlayNotStarted() {
// Service destroyed without ever starting dream.
mService.onDestroy();
mMainExecutor.runAllReady();
// Verify no view is removed.
verify(mWindowManager, never()).removeView(any());
// Verify state still correctly set.
verify(mKeyguardUpdateMonitor).removeCallback(any()); verify(mKeyguardUpdateMonitor).removeCallback(any());
verify(mLifecycleRegistry).setCurrentState(Lifecycle.State.DESTROYED); verify(mLifecycleRegistry).setCurrentState(Lifecycle.State.DESTROYED);
verify(mStateController).setOverlayActive(false); verify(mStateController).setOverlayActive(false);
@@ -245,7 +281,8 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy); final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
// Inform the overlay service of dream starting. // Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback); overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
false /*shouldShowComplication*/);
// Destroy the service. // Destroy the service.
mService.onDestroy(); mService.onDestroy();
@@ -255,4 +292,44 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
verify(mWindowManager, never()).addView(any(), any()); verify(mWindowManager, never()).addView(any(), any());
} }
@Test
public void testResetCurrentOverlayWhenConnectedToNewDream() throws RemoteException {
final IBinder proxy = mService.onBind(new Intent());
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
// Inform the overlay service of dream starting. Do not show dream complications.
overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
false /*shouldShowComplication*/);
mMainExecutor.runAllReady();
// Verify that a new window is added.
verify(mWindowManager).addView(mViewCaptor.capture(), any());
final View windowDecorView = mViewCaptor.getValue();
// Assert that the overlay is not showing complications.
assertThat(mService.shouldShowComplications()).isFalse();
clearInvocations(mDreamOverlayComponent);
clearInvocations(mWindowManager);
// New dream starting with dream complications showing. Note that when a new dream is
// binding to the dream overlay service, it receives the same instance of IBinder as the
// first one.
overlay.startDream(mWindowParams, mDreamOverlayCallback, DREAM_COMPONENT,
true /*shouldShowComplication*/);
mMainExecutor.runAllReady();
// Assert that the overlay is showing complications.
assertThat(mService.shouldShowComplications()).isTrue();
// Verify that the old overlay window has been removed, and a new one created.
verify(mWindowManager).removeView(windowDecorView);
verify(mWindowManager).addView(any(), any());
// Verify that new instances of overlay container view controller and overlay touch monitor
// are created.
verify(mDreamOverlayComponent).getDreamOverlayContainerViewController();
verify(mDreamOverlayComponent).getDreamOverlayTouchMonitor();
}
} }