Add ability to show a low-light clock when dozing.

This change introduces the hooks in SystemUI to show a low-light clock
while dozing. The default is to use the AOD clock instead.

Test: atest NotificationShadeWindowViewControllerTest
Bug: 217755348
Change-Id: I621eddeaf4e0e5da263e1bee0595cec60bc236a9
This commit is contained in:
Will
2022-02-04 17:25:44 -08:00
parent b32e148d59
commit ff7e671a89
6 changed files with 128 additions and 3 deletions

View File

@@ -42,6 +42,7 @@ import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FlagsModule;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.log.dagger.LogModule;
import com.android.systemui.lowlightclock.LowLightClockController;
import com.android.systemui.model.SysUiState;
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -86,6 +87,7 @@ import com.android.systemui.util.time.SystemClockImpl;
import com.android.systemui.wallet.dagger.WalletModule;
import com.android.systemui.wmshell.BubblesManager;
import com.android.wm.shell.bubbles.Bubbles;
import com.android.wm.shell.dagger.DynamicOverride;
import java.util.Optional;
import java.util.concurrent.Executor;
@@ -214,4 +216,19 @@ public abstract class SystemUIModule {
groupManager, entryManager, notifCollection, notifPipeline, sysUiState,
notifPipelineFlags, dumpManager, sysuiMainExecutor));
}
@BindsOptionalOf
@DynamicOverride
abstract LowLightClockController optionalLowLightClockController();
@SysUISingleton
@Provides
static Optional<LowLightClockController> provideLowLightClockController(
@DynamicOverride Optional<LowLightClockController> optionalController) {
if (optionalController.isPresent() && optionalController.get().isLowLightClockEnabled()) {
return optionalController;
} else {
return Optional.empty();
}
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2022 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.lowlightclock;
import android.view.ViewGroup;
/**
* A controller responsible for attaching and showing an optional low-light clock while dozing.
*/
public interface LowLightClockController {
/**
* Returns {@code true} if the low-light clock is enabled.
*/
boolean isLowLightClockEnabled();
/**
* Attach the low light-clock to the given parent {@link ViewGroup}.
* @param parent The parent {@link ViewGroup} to which the low-light clock view should be
* attached.
*/
void attachLowLightClockView(ViewGroup parent);
/**
* Show or hide the low-light clock.
* @param show Whether to show the low-light clock.
* @return {@code true} if the low-light clock was shown.
*/
boolean showLowLightClock(boolean show);
/**
* An opportunity to perform burn-in prevention.
*/
void dozeTimeTick();
}

View File

@@ -214,6 +214,7 @@ public final class DozeServiceHost implements DozeHost {
}
mStatusBarStateController.setIsDozing(dozing);
mNotificationShadeWindowViewController.setDozing(dozing);
}
@Override
@@ -294,6 +295,7 @@ public final class DozeServiceHost implements DozeHost {
public void dozeTimeTick() {
mNotificationPanel.dozeTimeTick();
mAuthController.dozeTimeTick();
mNotificationShadeWindowViewController.dozeTimeTick();
if (mAmbientIndicationContainer instanceof DozeReceiver) {
((DozeReceiver) mAmbientIndicationContainer).dozeTimeTick();
}

View File

@@ -36,6 +36,7 @@ import com.android.keyguard.LockIconViewController;
import com.android.systemui.R;
import com.android.systemui.classifier.FalsingCollector;
import com.android.systemui.dock.DockManager;
import com.android.systemui.lowlightclock.LowLightClockController;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -49,6 +50,7 @@ import com.android.systemui.tuner.TunerService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Optional;
import javax.inject.Inject;
@@ -84,6 +86,7 @@ public class NotificationShadeWindowViewController {
private final DockManager mDockManager;
private final NotificationPanelViewController mNotificationPanelViewController;
private final PanelExpansionStateManager mPanelExpansionStateManager;
private final Optional<LowLightClockController> mLowLightClockController;
private boolean mIsTrackingBarGesture = false;
@@ -101,7 +104,8 @@ public class NotificationShadeWindowViewController {
NotificationStackScrollLayoutController notificationStackScrollLayoutController,
StatusBarKeyguardViewManager statusBarKeyguardViewManager,
StatusBarWindowStateController statusBarWindowStateController,
LockIconViewController lockIconViewController) {
LockIconViewController lockIconViewController,
Optional<LowLightClockController> lowLightClockController) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
mTunerService = tunerService;
@@ -115,6 +119,7 @@ public class NotificationShadeWindowViewController {
mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
mStatusBarWindowStateController = statusBarWindowStateController;
mLockIconViewController = lockIconViewController;
mLowLightClockController = lowLightClockController;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -171,6 +176,8 @@ public class NotificationShadeWindowViewController {
};
mGestureDetector = new GestureDetector(mView.getContext(), gestureListener);
mLowLightClockController.ifPresent(controller -> controller.attachLowLightClockView(mView));
mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
@Override
public Boolean handleDispatchTouchEvent(MotionEvent ev) {
@@ -450,6 +457,21 @@ public class NotificationShadeWindowViewController {
mNotificationShadeWindowController = controller;
}
/**
* Tell the controller that dozing has begun or ended.
* @param dozing True if dozing has begun.
*/
public void setDozing(boolean dozing) {
mLowLightClockController.ifPresent(controller -> controller.showLowLightClock(dozing));
}
/**
* Tell the controller to perform burn-in prevention.
*/
public void dozeTimeTick() {
mLowLightClockController.ifPresent(LowLightClockController::dozeTimeTick);
}
@VisibleForTesting
void setDragDownHelper(DragDownHelper dragDownHelper) {
mDragDownHelper = dragDownHelper;

View File

@@ -24,6 +24,7 @@ import com.android.keyguard.LockIconViewController
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollectorFake
import com.android.systemui.dock.DockManager
import com.android.systemui.lowlightclock.LowLightClockController
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.NotificationShadeDepthController
import com.android.systemui.statusbar.NotificationShadeWindowController
@@ -38,11 +39,13 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.anyFloat
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import java.util.Optional
import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidTestingRunner::class)
@@ -79,6 +82,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
private lateinit var mLockIconViewController: LockIconViewController
@Mock
private lateinit var mPhoneStatusBarViewController: PhoneStatusBarViewController
@Mock
private lateinit var mLowLightClockController: LowLightClockController
private lateinit var mInteractionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
private lateinit var mInteractionEventHandler: InteractionEventHandler
@@ -101,7 +106,8 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
stackScrollLayoutController,
mStatusBarKeyguardViewManager,
mStatusBarWindowStateController,
mLockIconViewController
mLockIconViewController,
Optional.of(mLowLightClockController)
)
mController.setupExpandedStatusBar()
mController.setService(mStatusBar, mNotificationShadeWindowController)
@@ -235,6 +241,31 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
verify(mPhoneStatusBarViewController).sendTouchToView(nextEvent)
assertThat(returnVal).isTrue()
}
@Test
fun testLowLightClockAttachedWhenExpandedStatusBarSetup() {
verify(mLowLightClockController).attachLowLightClockView(ArgumentMatchers.any())
}
@Test
fun testLowLightClockShownWhenDozing() {
mController.setDozing(true)
verify(mLowLightClockController).showLowLightClock(true)
}
@Test
fun testLowLightClockDozeTimeTickCalled() {
mController.dozeTimeTick()
verify(mLowLightClockController).dozeTimeTick()
}
@Test
fun testLowLightClockHiddenWhenNotDozing() {
mController.setDozing(true)
verify(mLowLightClockController).showLowLightClock(true)
mController.setDozing(false)
verify(mLowLightClockController).showLowLightClock(false)
}
}
private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)

View File

@@ -37,6 +37,7 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.dock.DockManager;
import com.android.systemui.lowlightclock.LowLightClockController;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -56,6 +57,8 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper(setAsMainLooper = true)
@SmallTest
@@ -79,6 +82,7 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
@Mock private StatusBarWindowStateController mStatusBarWindowStateController;
@Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
@Mock private LockIconViewController mLockIconViewController;
@Mock private LowLightClockController mLowLightClockController;
@Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
mInteractionEventHandlerCaptor;
@@ -110,7 +114,8 @@ public class NotificationShadeWindowViewTest extends SysuiTestCase {
mNotificationStackScrollLayoutController,
mStatusBarKeyguardViewManager,
mStatusBarWindowStateController,
mLockIconViewController);
mLockIconViewController,
Optional.of(mLowLightClockController));
mController.setupExpandedStatusBar();
mController.setService(mStatusBar, mNotificationShadeWindowController);
mController.setDragDownHelper(mDragDownHelper);