summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/layout/dream_overlay_container.xml4
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java126
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java123
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java132
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java120
8 files changed, 355 insertions, 172 deletions
diff --git a/packages/SystemUI/res/layout/dream_overlay_container.xml b/packages/SystemUI/res/layout/dream_overlay_container.xml
index b611ffa6d84e..4929f502fef0 100644
--- a/packages/SystemUI/res/layout/dream_overlay_container.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_container.xml
@@ -32,8 +32,8 @@
android:id="@+id/dream_overlay_status_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/dream_overlay_status_bar_height"
- android:layout_marginEnd="@dimen/dream_overlay_status_bar_margin"
- android:layout_marginStart="@dimen/dream_overlay_status_bar_margin"
+ android:paddingEnd="@dimen/dream_overlay_status_bar_margin"
+ android:paddingStart="@dimen/dream_overlay_status_bar_margin"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index b7f25e81046c..c6640aa8083c 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1309,4 +1309,7 @@
<dimen name="dream_overlay_status_bar_height">80dp</dimen>
<dimen name="dream_overlay_status_bar_margin">40dp</dimen>
<dimen name="dream_overlay_status_icon_margin">8dp</dimen>
+ <!-- Height of the area at the top of the dream overlay to allow dragging down the notifications
+ shade. -->
+ <dimen name="dream_overlay_notifications_drag_area_height">100dp</dimen>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
new file mode 100644
index 000000000000..572bb4467c97
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams;
+
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.R;
+import com.android.systemui.dreams.dagger.DreamOverlayComponent;
+import com.android.systemui.dreams.dagger.DreamOverlayModule;
+import com.android.systemui.util.ViewController;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+/**
+ * View controller for {@link DreamOverlayContainerView}.
+ */
+@DreamOverlayComponent.DreamOverlayScope
+public class DreamOverlayContainerViewController extends ViewController<DreamOverlayContainerView> {
+ // The height of the area at the top of the dream overlay to allow dragging down the
+ // notifications shade.
+ private final int mDreamOverlayNotificationsDragAreaHeight;
+ private final DreamOverlayStatusBarViewController mStatusBarViewController;
+
+ // The dream overlay's content view, which is located below the status bar (in z-order) and is
+ // the space into which widgets are placed.
+ private final ViewGroup mDreamOverlayContentView;
+
+ // A hook into the internal inset calculation where we declare the overlays as the only
+ // touchable regions.
+ private final ViewTreeObserver.OnComputeInternalInsetsListener
+ mOnComputeInternalInsetsListener =
+ new ViewTreeObserver.OnComputeInternalInsetsListener() {
+ @Override
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
+ inoutInfo.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ final Region region = new Region();
+ final Rect rect = new Rect();
+ final int childCount = mDreamOverlayContentView.getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = mDreamOverlayContentView.getChildAt(i);
+ if (child.getGlobalVisibleRect(rect)) {
+ region.op(rect, Region.Op.UNION);
+ }
+ }
+
+ // Add the notifications drag area to the tap region (otherwise the
+ // notifications shade can't be dragged down).
+ if (mDreamOverlayContentView.getGlobalVisibleRect(rect)) {
+ rect.bottom = rect.top + mDreamOverlayNotificationsDragAreaHeight;
+ region.op(rect, Region.Op.UNION);
+ }
+
+ inoutInfo.touchableRegion.set(region);
+ }
+ };
+
+ @Inject
+ public DreamOverlayContainerViewController(
+ DreamOverlayContainerView containerView,
+ @Named(DreamOverlayModule.DREAM_OVERLAY_CONTENT_VIEW) ViewGroup contentView,
+ DreamOverlayStatusBarViewController statusBarViewController) {
+ super(containerView);
+ mDreamOverlayContentView = contentView;
+ mStatusBarViewController = statusBarViewController;
+ mDreamOverlayNotificationsDragAreaHeight =
+ mView.getResources().getDimensionPixelSize(
+ R.dimen.dream_overlay_notifications_drag_area_height);
+ }
+
+ @Override
+ protected void onInit() {
+ mStatusBarViewController.init();
+ }
+
+ @Override
+ protected void onViewAttached() {
+ mView.getViewTreeObserver()
+ .addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
+ }
+
+ @Override
+ protected void onViewDetached() {
+ mView.getViewTreeObserver()
+ .removeOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
+ }
+
+ void addOverlay(View overlayView, ConstraintLayout.LayoutParams layoutParams) {
+ mDreamOverlayContentView.addView(overlayView, layoutParams);
+ }
+
+ View getContainerView() {
+ return mView;
+ }
+
+ void removeAllOverlays() {
+ mDreamOverlayContentView.removeAllViews();
+ }
+
+ @VisibleForTesting
+ int getDreamOverlayNotificationsDragAreaHeight() {
+ return mDreamOverlayNotificationsDragAreaHeight;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
index 7c2bb4bcf4f3..a53120f15a14 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayService.java
@@ -17,13 +17,8 @@
package com.android.systemui.dreams;
import android.content.Context;
-import android.graphics.Rect;
-import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
@@ -54,12 +49,12 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
private final Executor mExecutor;
// The state controller informs the service of updates to the complications present.
private final DreamOverlayStateController mStateController;
- // The component used to resolve dream overlay dependencies.
- private final DreamOverlayComponent mDreamOverlayComponent;
+ // A controller for the dream overlay container view (which contains both the status bar and the
+ // content area).
+ private final DreamOverlayContainerViewController mDreamOverlayContainerViewController;
- // The dream overlay's content view, which is located below the status bar (in z-order) and is
- // the space into which widgets are placed.
- private ViewGroup mDreamOverlayContentView;
+ // A reference to the {@link Window} used to hold the dream overlay.
+ private Window mWindow;
private final DreamOverlayStateController.Callback mOverlayStateCallback =
new DreamOverlayStateController.Callback() {
@@ -69,47 +64,6 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
}
};
- // The service listens to view changes in order to declare that input occurring in areas outside
- // the overlay should be passed through to the dream underneath.
- private final View.OnAttachStateChangeListener mRootViewAttachListener =
- new View.OnAttachStateChangeListener() {
- @Override
- public void onViewAttachedToWindow(View v) {
- v.getViewTreeObserver()
- .addOnComputeInternalInsetsListener(mOnComputeInternalInsetsListener);
- }
-
- @Override
- public void onViewDetachedFromWindow(View v) {
- v.getViewTreeObserver()
- .removeOnComputeInternalInsetsListener(
- mOnComputeInternalInsetsListener);
- }
- };
-
- // A hook into the internal inset calculation where we declare the complications as the only
- // touchable regions.
- private final ViewTreeObserver.OnComputeInternalInsetsListener
- mOnComputeInternalInsetsListener =
- new ViewTreeObserver.OnComputeInternalInsetsListener() {
- @Override
- public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {
- if (mDreamOverlayContentView != null) {
- inoutInfo.setTouchableInsets(
- ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
- final Region region = new Region();
- for (int i = 0; i < mDreamOverlayContentView.getChildCount(); i++) {
- View child = mDreamOverlayContentView.getChildAt(i);
- final Rect rect = new Rect();
- child.getGlobalVisibleRect(rect);
- region.op(rect, Region.Op.UNION);
- }
-
- inoutInfo.touchableRegion.set(region);
- }
- }
- };
-
@Inject
public DreamOverlayService(
Context context,
@@ -119,23 +73,29 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
mContext = context;
mExecutor = executor;
mStateController = overlayStateController;
- mDreamOverlayComponent = dreamOverlayComponentFactory.create();
+ mDreamOverlayContainerViewController =
+ dreamOverlayComponentFactory.create().getDreamOverlayContainerViewController();
mStateController.addCallback(mOverlayStateCallback);
}
@Override
+ public void onDestroy() {
+ final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
+ windowManager.removeView(mWindow.getDecorView());
+ mStateController.removeCallback(mOverlayStateCallback);
+ super.onDestroy();
+ }
+
+ @Override
public void onStartDream(@NonNull WindowManager.LayoutParams layoutParams) {
mExecutor.execute(() -> addOverlayWindowLocked(layoutParams));
}
private void reloadComplicationsLocked() {
- if (mDreamOverlayContentView == null) {
- return;
- }
- mDreamOverlayContentView.removeAllViews();
- for (ComplicationProvider complicationProvider : mStateController.getComplications()) {
- addComplication(complicationProvider);
+ mDreamOverlayContainerViewController.removeAllOverlays();
+ for (ComplicationProvider overlayProvider : mStateController.getComplications()) {
+ addComplication(overlayProvider);
}
}
@@ -147,32 +107,28 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
* into the dream window.
*/
private void addOverlayWindowLocked(WindowManager.LayoutParams layoutParams) {
- final PhoneWindow window = new PhoneWindow(mContext);
- window.setAttributes(layoutParams);
- window.setWindowManager(null, layoutParams.token, "DreamOverlay", true);
+ mWindow = new PhoneWindow(mContext);
+ mWindow.setAttributes(layoutParams);
+ mWindow.setWindowManager(null, layoutParams.token, "DreamOverlay", true);
- window.setBackgroundDrawable(new ColorDrawable(0));
+ mWindow.setBackgroundDrawable(new ColorDrawable(0));
- window.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
- window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
- window.requestFeature(Window.FEATURE_NO_TITLE);
+ mWindow.clearFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
+ mWindow.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
+ mWindow.requestFeature(Window.FEATURE_NO_TITLE);
// Hide all insets when the dream is showing
- window.getDecorView().getWindowInsetsController().hide(WindowInsets.Type.systemBars());
- window.setDecorFitsSystemWindows(false);
+ mWindow.getDecorView().getWindowInsetsController().hide(WindowInsets.Type.systemBars());
+ mWindow.setDecorFitsSystemWindows(false);
if (DEBUG) {
Log.d(TAG, "adding overlay window to dream");
}
- window.setContentView(mDreamOverlayComponent.getDreamOverlayContainerView());
-
- mDreamOverlayContentView = mDreamOverlayComponent.getDreamOverlayContentView();
- mDreamOverlayContentView.addOnAttachStateChangeListener(mRootViewAttachListener);
-
- mDreamOverlayComponent.getDreamOverlayStatusBarViewController().init();
+ mDreamOverlayContainerViewController.init();
+ mWindow.setContentView(mDreamOverlayContainerViewController.getContainerView());
final WindowManager windowManager = mContext.getSystemService(WindowManager.class);
- windowManager.addView(window.getDecorView(), window.getAttributes());
+ windowManager.addView(mWindow.getDecorView(), mWindow.getAttributes());
mExecutor.execute(this::reloadComplicationsLocked);
}
@@ -181,25 +137,12 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ
provider.onCreateComplication(mContext,
(view, layoutParams) -> {
// Always move UI related work to the main thread.
- mExecutor.execute(() -> {
- if (mDreamOverlayContentView == null) {
- return;
- }
-
- mDreamOverlayContentView.addView(view, layoutParams);
- });
+ mExecutor.execute(() -> mDreamOverlayContainerViewController
+ .addOverlay(view, layoutParams));
},
() -> {
// The Callback is set on the main thread.
- mExecutor.execute(() -> {
- requestExit();
- });
+ mExecutor.execute(this::requestExit);
});
}
-
- @Override
- public void onDestroy() {
- mStateController.removeCallback(mOverlayStateCallback);
- super.onDestroy();
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
index a3a446a0dbca..c90332bb9f31 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayComponent.java
@@ -18,10 +18,7 @@ package com.android.systemui.dreams.dagger;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
-import android.view.ViewGroup;
-
-import com.android.systemui.dreams.DreamOverlayContainerView;
-import com.android.systemui.dreams.DreamOverlayStatusBarViewController;
+import com.android.systemui.dreams.DreamOverlayContainerViewController;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
@@ -48,15 +45,7 @@ public interface DreamOverlayComponent {
@Scope
@interface DreamOverlayScope {}
- /** Builds a {@link DreamOverlayContainerView} */
- @DreamOverlayScope
- DreamOverlayContainerView getDreamOverlayContainerView();
-
- /** Builds a content view for dream overlays */
- @DreamOverlayScope
- ViewGroup getDreamOverlayContentView();
-
- /** Builds a {@link DreamOverlayStatusBarViewController}. */
+ /** Builds a {@link DreamOverlayContainerViewController}. */
@DreamOverlayScope
- DreamOverlayStatusBarViewController getDreamOverlayStatusBarViewController();
+ DreamOverlayContainerViewController getDreamOverlayContainerViewController();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
index d0a8fad9b1e5..5b588a9d9023 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamOverlayModule.java
@@ -44,6 +44,7 @@ public abstract class DreamOverlayModule {
private static final String DREAM_OVERLAY_BATTERY_VIEW = "dream_overlay_battery_view";
public static final String DREAM_OVERLAY_BATTERY_CONTROLLER =
"dream_overlay_battery_controller";
+ public static final String DREAM_OVERLAY_CONTENT_VIEW = "dream_overlay_content_view";
/** */
@Provides
@@ -58,6 +59,7 @@ public abstract class DreamOverlayModule {
/** */
@Provides
@DreamOverlayComponent.DreamOverlayScope
+ @Named(DREAM_OVERLAY_CONTENT_VIEW)
public static ViewGroup providesDreamOverlayContentView(DreamOverlayContainerView view) {
return Preconditions.checkNotNull(view.findViewById(R.id.dream_overlay_content),
"R.id.dream_overlay_content must not be null");
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
new file mode 100644
index 000000000000..cf53ccffcdb0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.dreams;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.res.Resources;
+import android.testing.AndroidTestingRunner;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+
+import androidx.constraintlayout.widget.ConstraintLayout;
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
+ private static final int DREAM_OVERLAY_NOTIFICATIONS_DRAG_AREA_HEIGHT = 100;
+
+ @Mock
+ Resources mResources;
+
+ @Mock
+ ViewTreeObserver mViewTreeObserver;
+
+ @Mock
+ DreamOverlayStatusBarViewController mDreamOverlayStatusBarViewController;
+
+ @Mock
+ DreamOverlayContainerView mDreamOverlayContainerView;
+
+ @Mock
+ ViewGroup mDreamOverlayContentView;
+
+ DreamOverlayContainerViewController mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+
+ when(mResources.getDimensionPixelSize(
+ R.dimen.dream_overlay_notifications_drag_area_height)).thenReturn(
+ DREAM_OVERLAY_NOTIFICATIONS_DRAG_AREA_HEIGHT);
+ when(mDreamOverlayContainerView.getResources()).thenReturn(mResources);
+ when(mDreamOverlayContainerView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
+
+ mController = new DreamOverlayContainerViewController(
+ mDreamOverlayContainerView, mDreamOverlayContentView,
+ mDreamOverlayStatusBarViewController);
+ }
+
+ @Test
+ public void testDreamOverlayStatusBarViewControllerInitialized() {
+ mController.init();
+ verify(mDreamOverlayStatusBarViewController).init();
+ }
+
+ @Test
+ public void testSetsDreamOverlayNotificationsDragAreaHeight() {
+ assertEquals(
+ mController.getDreamOverlayNotificationsDragAreaHeight(),
+ DREAM_OVERLAY_NOTIFICATIONS_DRAG_AREA_HEIGHT);
+ }
+
+ @Test
+ public void testAddOverlayAddsOverlayToContentView() {
+ View overlay = new View(getContext());
+ ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(100, 100);
+ mController.addOverlay(overlay, layoutParams);
+ verify(mDreamOverlayContentView).addView(overlay, layoutParams);
+ }
+
+ @Test
+ public void testRemoveAllOverlaysRemovesOverlaysFromContentView() {
+ mController.removeAllOverlays();
+ verify(mDreamOverlayContentView).removeAllViews();
+ }
+
+ @Test
+ public void testOnViewAttachedRegistersComputeInsetsListener() {
+ mController.onViewAttached();
+ verify(mViewTreeObserver).addOnComputeInternalInsetsListener(any());
+ }
+
+ @Test
+ public void testOnViewDetachedUnregistersComputeInsetsListener() {
+ mController.onViewDetached();
+ verify(mViewTreeObserver).removeOnComputeInternalInsetsListener(any());
+ }
+
+ @Test
+ public void testComputeInsetsListenerReturnsRegion() {
+ final ArgumentCaptor<ViewTreeObserver.OnComputeInternalInsetsListener>
+ computeInsetsListenerCapture =
+ ArgumentCaptor.forClass(ViewTreeObserver.OnComputeInternalInsetsListener.class);
+ mController.onViewAttached();
+ verify(mViewTreeObserver).addOnComputeInternalInsetsListener(
+ computeInsetsListenerCapture.capture());
+ final ViewTreeObserver.InternalInsetsInfo info = new ViewTreeObserver.InternalInsetsInfo();
+ computeInsetsListenerCapture.getValue().onComputeInternalInsets(info);
+ assertNotNull(info.touchableRegion);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
index 5fa710f284b4..8cd8e4d7382d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayServiceTest.java
@@ -17,7 +17,6 @@
package com.android.systemui.dreams;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -55,8 +54,8 @@ import java.util.Arrays;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class DreamOverlayServiceTest extends SysuiTestCase {
- private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
- private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
+ private final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
+ private final FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
@Rule
public final LeakCheckedTest.SysuiLeakCheck mLeakCheck = new LeakCheckedTest.SysuiLeakCheck();
@@ -80,51 +79,55 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
DreamOverlayStateController mDreamOverlayStateController;
@Mock
- DreamOverlayComponent.Factory mDreamOverlayStatusBarViewComponentFactory;
+ DreamOverlayComponent.Factory mDreamOverlayComponentFactory;
@Mock
DreamOverlayComponent mDreamOverlayComponent;
@Mock
- DreamOverlayStatusBarViewController mDreamOverlayStatusBarViewController;
-
- @Mock
DreamOverlayContainerView mDreamOverlayContainerView;
@Mock
- ViewGroup mDreamOverlayContentView;
+ DreamOverlayContainerViewController mDreamOverlayContainerViewController;
+
+ DreamOverlayService mService;
@Before
- public void setup() {
+ public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
mContext.addMockSystemService(WindowManager.class, mWindowManager);
- when(mDreamOverlayComponent.getDreamOverlayContentView())
- .thenReturn(mDreamOverlayContentView);
- when(mDreamOverlayComponent.getDreamOverlayContainerView())
- .thenReturn(mDreamOverlayContainerView);
- when(mDreamOverlayComponent.getDreamOverlayStatusBarViewController())
- .thenReturn(mDreamOverlayStatusBarViewController);
- when(mDreamOverlayStatusBarViewComponentFactory.create())
+ when(mDreamOverlayComponent.getDreamOverlayContainerViewController())
+ .thenReturn(mDreamOverlayContainerViewController);
+ when(mDreamOverlayComponentFactory.create())
.thenReturn(mDreamOverlayComponent);
+ when(mDreamOverlayContainerViewController.getContainerView())
+ .thenReturn(mDreamOverlayContainerView);
- }
-
- @Test
- public void testInteraction() throws Exception {
- final DreamOverlayService service = new DreamOverlayService(mContext, mMainExecutor,
- mDreamOverlayStateController, mDreamOverlayStatusBarViewComponentFactory);
- final IBinder proxy = service.onBind(new Intent());
+ mService = new DreamOverlayService(mContext, mMainExecutor,
+ mDreamOverlayStateController, mDreamOverlayComponentFactory);
+ final IBinder proxy = mService.onBind(new Intent());
final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
- clearInvocations(mWindowManager);
// Inform the overlay service of dream starting.
overlay.startDream(mWindowParams, mDreamOverlayCallback);
mMainExecutor.runAllReady();
+ }
+
+ @Test
+ public void testOverlayContainerViewAddedToWindow() {
verify(mWindowManager).addView(any(), any());
+ }
+ @Test
+ public void testDreamOverlayContainerViewControllerInitialized() {
+ verify(mDreamOverlayContainerViewController).init();
+ }
+
+ @Test
+ public void testAddingOverlayToDream() throws Exception {
// Add overlay.
- service.addComplication(mProvider);
+ mService.addComplication(mProvider);
mMainExecutor.runAllReady();
final ArgumentCaptor<ComplicationHost.CreationCallback> creationCallbackCapture =
@@ -139,9 +142,26 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
// Inform service of overlay view creation.
final View view = new View(mContext);
- creationCallbackCapture.getValue().onCreated(view, new ConstraintLayout.LayoutParams(
+ final ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
- ));
+ );
+ creationCallbackCapture.getValue().onCreated(view, lp);
+ mMainExecutor.runAllReady();
+
+ // Verify that DreamOverlayContainerViewController is asked to add an overlay for the view.
+ verify(mDreamOverlayContainerViewController).addOverlay(view, lp);
+ }
+
+ @Test
+ public void testDreamOverlayExit() throws Exception {
+ // Add overlay.
+ mService.addComplication(mProvider);
+ mMainExecutor.runAllReady();
+
+ // Capture interaction callback from overlay creation.
+ final ArgumentCaptor<ComplicationHost.InteractionCallback> interactionCallbackCapture =
+ ArgumentCaptor.forClass(ComplicationHost.InteractionCallback.class);
+ verify(mProvider).onCreateComplication(any(), any(), interactionCallbackCapture.capture());
// Ask service to exit.
interactionCallbackCapture.getValue().onExit();
@@ -152,17 +172,7 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
}
@Test
- public void testListening() throws Exception {
- final DreamOverlayService service = new DreamOverlayService(mContext, mMainExecutor,
- mDreamOverlayStateController, mDreamOverlayStatusBarViewComponentFactory);
-
- final IBinder proxy = service.onBind(new Intent());
- final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
-
- // Inform the overlay service of dream starting.
- overlay.startDream(mWindowParams, mDreamOverlayCallback);
- mMainExecutor.runAllReady();
-
+ public void testListenerRegisteredWithDreamOverlayStateController() {
// Verify overlay service registered as listener with DreamOverlayStateController
// and inform callback of addition.
final ArgumentCaptor<DreamOverlayStateController.Callback> callbackCapture =
@@ -178,33 +188,11 @@ public class DreamOverlayServiceTest extends SysuiTestCase {
}
@Test
- public void testDreamOverlayStatusBarViewControllerInitialized() throws Exception {
- final DreamOverlayService service = new DreamOverlayService(mContext, mMainExecutor,
- mDreamOverlayStateController, mDreamOverlayStatusBarViewComponentFactory);
-
- final IBinder proxy = service.onBind(new Intent());
- final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
-
- // Inform the overlay service of dream starting.
- overlay.startDream(mWindowParams, mDreamOverlayCallback);
- mMainExecutor.runAllReady();
-
- verify(mDreamOverlayStatusBarViewController).init();
- }
-
- @Test
- public void testRootViewAttachListenerIsAddedToDreamOverlayContentView() throws Exception {
- final DreamOverlayService service = new DreamOverlayService(mContext, mMainExecutor,
- mDreamOverlayStateController, mDreamOverlayStatusBarViewComponentFactory);
-
- final IBinder proxy = service.onBind(new Intent());
- final IDreamOverlay overlay = IDreamOverlay.Stub.asInterface(proxy);
-
- // Inform the overlay service of dream starting.
- overlay.startDream(mWindowParams, mDreamOverlayCallback);
- mMainExecutor.runAllReady();
-
- verify(mDreamOverlayContentView).addOnAttachStateChangeListener(
- any(View.OnAttachStateChangeListener.class));
+ public void testOnDestroyRemovesOverlayStateCallback() {
+ final ArgumentCaptor<DreamOverlayStateController.Callback> callbackCapture =
+ ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
+ verify(mDreamOverlayStateController).addCallback(callbackCapture.capture());
+ mService.onDestroy();
+ verify(mDreamOverlayStateController).removeCallback(callbackCapture.getValue());
}
}