Merge "Revert "Tap to wake up dreaming for lockscreen hosted dream"" into udc-qpr-dev

This commit is contained in:
Fangqiu Su
2023-07-14 22:03:40 +00:00
committed by Android (Google) Code Review
7 changed files with 1 additions and 312 deletions

View File

@@ -70,19 +70,6 @@ constructor(
}
}
/**
* Wakes up the device if dreaming with a screensaver.
*
* @param why a string explaining why we're waking the device for debugging purposes. Should be
* in SCREAMING_SNAKE_CASE.
* @param wakeReason the PowerManager-based reason why we're waking the device.
*/
fun wakeUpIfDreaming(why: String, @PowerManager.WakeReason wakeReason: Int) {
if (statusBarStateController.isDreaming) {
repository.wakeUp(why, wakeReason)
}
}
companion object {
private const val FSI_WAKE_WHY = "full_screen_intent"
}

View File

@@ -1,72 +0,0 @@
/*
* Copyright (C) 2023 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.shade
import android.os.PowerManager
import android.view.GestureDetector
import android.view.MotionEvent
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.FalsingManager.LOW_PENALTY
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
import javax.inject.Inject
/**
* This gestureListener will wake up by tap when the device is dreaming but not dozing, and the
* selected screensaver is hosted in lockscreen. Tap is gated by the falsing manager.
*
* Touches go through the [NotificationShadeWindowViewController].
*/
@CentralSurfacesComponent.CentralSurfacesScope
class LockscreenHostedDreamGestureListener
@Inject
constructor(
private val falsingManager: FalsingManager,
private val powerInteractor: PowerInteractor,
private val statusBarStateController: StatusBarStateController,
private val primaryBouncerInteractor: PrimaryBouncerInteractor,
private val keyguardRepository: KeyguardRepository,
private val shadeLogger: ShadeLogger,
) : GestureDetector.SimpleOnGestureListener() {
private val TAG = this::class.simpleName
override fun onSingleTapUp(e: MotionEvent): Boolean {
if (shouldHandleMotionEvent()) {
if (!falsingManager.isFalseTap(LOW_PENALTY)) {
shadeLogger.d("$TAG#onSingleTapUp tap handled, requesting wakeUpIfDreaming")
powerInteractor.wakeUpIfDreaming(
"DREAMING_SINGLE_TAP",
PowerManager.WAKE_REASON_TAP
)
} else {
shadeLogger.d("$TAG#onSingleTapUp false tap ignored")
}
return true
}
return false
}
private fun shouldHandleMotionEvent(): Boolean {
return keyguardRepository.isActiveDreamLockscreenHosted.value &&
statusBarStateController.state == StatusBarState.KEYGUARD &&
!primaryBouncerInteractor.isBouncerShowing()
}
}

View File

@@ -16,7 +16,6 @@
package com.android.systemui.shade;
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
import static com.android.systemui.flags.Flags.TRACKPAD_GESTURE_COMMON;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
@@ -103,12 +102,9 @@ public class NotificationShadeWindowViewController {
private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
private final AmbientState mAmbientState;
private final PulsingGestureListener mPulsingGestureListener;
private final LockscreenHostedDreamGestureListener mLockscreenHostedDreamGestureListener;
private final NotificationInsetsController mNotificationInsetsController;
private final boolean mIsTrackpadCommonEnabled;
private final FeatureFlags mFeatureFlags;
private GestureDetector mPulsingWakeupGestureHandler;
private GestureDetector mDreamingWakeupGestureHandler;
private View mBrightnessMirror;
private boolean mTouchActive;
private boolean mTouchCancelled;
@@ -160,7 +156,6 @@ public class NotificationShadeWindowViewController {
NotificationInsetsController notificationInsetsController,
AmbientState ambientState,
PulsingGestureListener pulsingGestureListener,
LockscreenHostedDreamGestureListener lockscreenHostedDreamGestureListener,
KeyguardBouncerViewModel keyguardBouncerViewModel,
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
@@ -192,10 +187,8 @@ public class NotificationShadeWindowViewController {
mKeyguardUnlockAnimationController = keyguardUnlockAnimationController;
mAmbientState = ambientState;
mPulsingGestureListener = pulsingGestureListener;
mLockscreenHostedDreamGestureListener = lockscreenHostedDreamGestureListener;
mNotificationInsetsController = notificationInsetsController;
mIsTrackpadCommonEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_COMMON);
mFeatureFlags = featureFlags;
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -244,10 +237,7 @@ public class NotificationShadeWindowViewController {
mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller);
mPulsingWakeupGestureHandler = new GestureDetector(mView.getContext(),
mPulsingGestureListener);
if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) {
mDreamingWakeupGestureHandler = new GestureDetector(mView.getContext(),
mLockscreenHostedDreamGestureListener);
}
mView.setLayoutInsetsController(mNotificationInsetsController);
mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() {
@Override
@@ -301,10 +291,6 @@ public class NotificationShadeWindowViewController {
mFalsingCollector.onTouchEvent(ev);
mPulsingWakeupGestureHandler.onTouchEvent(ev);
if (mDreamingWakeupGestureHandler != null
&& mDreamingWakeupGestureHandler.onTouchEvent(ev)) {
return true;
}
if (mStatusBarKeyguardViewManager.dispatchTouchEvent(ev)) {
return true;
}

View File

@@ -182,21 +182,6 @@ class PowerInteractorTest : SysuiTestCase() {
assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_APPLICATION)
}
@Test
fun wakeUpIfDreaming_notDozing() =
runBlocking(IMMEDIATE) {
// GIVEN device is dreaming and not dozing
whenever(statusBarStateController.isDozing).thenReturn(false)
whenever(statusBarStateController.isDreaming).thenReturn(true)
// WHEN wakeUpIfDreaming is called
underTest.wakeUpIfDreaming("testReason", PowerManager.WAKE_REASON_GESTURE)
// THEN device is waken up
assertThat(repository.lastWakeWhy).isEqualTo("testReason")
assertThat(repository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_GESTURE)
}
companion object {
private val IMMEDIATE = Dispatchers.Main.immediate
}

View File

@@ -1,189 +0,0 @@
/*
* Copyright (C) 2023 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.shade
import android.os.PowerManager
import android.testing.AndroidTestingRunner
import android.view.MotionEvent
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.power.data.repository.FakePowerRepository
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.ScreenOffAnimationController
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@SmallTest
@OptIn(ExperimentalCoroutinesApi::class)
@RunWith(AndroidTestingRunner::class)
class LockscreenHostedDreamGestureListenerTest : SysuiTestCase() {
@Mock private lateinit var falsingManager: FalsingManager
@Mock private lateinit var falsingCollector: FalsingCollector
@Mock private lateinit var statusBarStateController: StatusBarStateController
@Mock private lateinit var shadeLogger: ShadeLogger
@Mock private lateinit var screenOffAnimationController: ScreenOffAnimationController
@Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor
private val testDispatcher = UnconfinedTestDispatcher()
private val testScope = TestScope(testDispatcher)
private lateinit var powerRepository: FakePowerRepository
private lateinit var keyguardRepository: FakeKeyguardRepository
private lateinit var underTest: LockscreenHostedDreamGestureListener
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
powerRepository = FakePowerRepository()
keyguardRepository = FakeKeyguardRepository()
underTest =
LockscreenHostedDreamGestureListener(
falsingManager,
PowerInteractor(
powerRepository,
keyguardRepository,
falsingCollector,
screenOffAnimationController,
statusBarStateController,
),
statusBarStateController,
primaryBouncerInteractor,
keyguardRepository,
shadeLogger,
)
whenever(statusBarStateController.state).thenReturn(StatusBarState.KEYGUARD)
whenever(primaryBouncerInteractor.isBouncerShowing()).thenReturn(false)
}
@Test
fun testGestureDetector_onSingleTap_whileDreaming() =
testScope.runTest {
// GIVEN device dreaming and the dream is hosted in lockscreen
whenever(statusBarStateController.isDreaming).thenReturn(true)
keyguardRepository.setIsActiveDreamLockscreenHosted(true)
testScope.runCurrent()
// GIVEN the falsing manager does NOT think the tap is a false tap
whenever(falsingManager.isFalseTap(ArgumentMatchers.anyInt())).thenReturn(false)
// WHEN there's a tap
underTest.onSingleTapUp(upEv)
// THEN wake up device if dreaming
Truth.assertThat(powerRepository.lastWakeWhy).isNotNull()
Truth.assertThat(powerRepository.lastWakeReason).isEqualTo(PowerManager.WAKE_REASON_TAP)
}
@Test
fun testGestureDetector_onSingleTap_notOnKeyguard() =
testScope.runTest {
// GIVEN device dreaming and the dream is hosted in lockscreen
whenever(statusBarStateController.isDreaming).thenReturn(true)
keyguardRepository.setIsActiveDreamLockscreenHosted(true)
testScope.runCurrent()
// GIVEN shade is open
whenever(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
// GIVEN the falsing manager does NOT think the tap is a false tap
whenever(falsingManager.isFalseTap(ArgumentMatchers.anyInt())).thenReturn(false)
// WHEN there's a tap
underTest.onSingleTapUp(upEv)
// THEN the falsing manager never gets a call
verify(falsingManager, never()).isFalseTap(ArgumentMatchers.anyInt())
}
@Test
fun testGestureDetector_onSingleTap_bouncerShown() =
testScope.runTest {
// GIVEN device dreaming and the dream is hosted in lockscreen
whenever(statusBarStateController.isDreaming).thenReturn(true)
keyguardRepository.setIsActiveDreamLockscreenHosted(true)
testScope.runCurrent()
// GIVEN bouncer is expanded
whenever(primaryBouncerInteractor.isBouncerShowing()).thenReturn(true)
// GIVEN the falsing manager does NOT think the tap is a false tap
whenever(falsingManager.isFalseTap(ArgumentMatchers.anyInt())).thenReturn(false)
// WHEN there's a tap
underTest.onSingleTapUp(upEv)
// THEN the falsing manager never gets a call
verify(falsingManager, never()).isFalseTap(ArgumentMatchers.anyInt())
}
@Test
fun testGestureDetector_onSingleTap_falsing() =
testScope.runTest {
// GIVEN device dreaming and the dream is hosted in lockscreen
whenever(statusBarStateController.isDreaming).thenReturn(true)
keyguardRepository.setIsActiveDreamLockscreenHosted(true)
testScope.runCurrent()
// GIVEN the falsing manager thinks the tap is a false tap
whenever(falsingManager.isFalseTap(ArgumentMatchers.anyInt())).thenReturn(true)
// WHEN there's a tap
underTest.onSingleTapUp(upEv)
// THEN the device doesn't wake up
Truth.assertThat(powerRepository.lastWakeWhy).isNull()
Truth.assertThat(powerRepository.lastWakeReason).isNull()
}
@Test
fun testSingleTap_notDreaming_noFalsingCheck() =
testScope.runTest {
// GIVEN device not dreaming with lockscreen hosted dream
whenever(statusBarStateController.isDreaming).thenReturn(false)
keyguardRepository.setIsActiveDreamLockscreenHosted(false)
testScope.runCurrent()
// WHEN there's a tap
underTest.onSingleTapUp(upEv)
// THEN the falsing manager never gets a call
verify(falsingManager, never()).isFalseTap(ArgumentMatchers.anyInt())
}
}
private val upEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)

View File

@@ -111,8 +111,6 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
@Mock private lateinit var lockIconViewController: LockIconViewController
@Mock private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
@Mock private lateinit var pulsingGestureListener: PulsingGestureListener
@Mock
private lateinit var mLockscreenHostedDreamGestureListener: LockscreenHostedDreamGestureListener
@Mock private lateinit var notificationInsetsController: NotificationInsetsController
@Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
@@ -149,7 +147,6 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
featureFlags.set(Flags.DUAL_SHADE, false)
featureFlags.set(Flags.SPLIT_SHADE_SUBPIXEL_OPTIMIZATION, true)
featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
featureFlags.set(Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false)
val inputProxy = MultiShadeInputProxy()
testScope = TestScope()
@@ -186,7 +183,6 @@ class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
notificationInsetsController,
ambientState,
pulsingGestureListener,
mLockscreenHostedDreamGestureListener,
keyguardBouncerViewModel,
keyguardBouncerComponentFactory,
mock(KeyguardMessageAreaController.Factory::class.java),

View File

@@ -113,8 +113,6 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
@Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
@Mock private lateinit var ambientState: AmbientState
@Mock private lateinit var pulsingGestureListener: PulsingGestureListener
@Mock
private lateinit var mLockscreenHostedDreamGestureListener: LockscreenHostedDreamGestureListener
@Mock private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel
@Mock private lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
@Mock private lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
@@ -163,7 +161,6 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
featureFlags.set(Flags.DUAL_SHADE, false)
featureFlags.set(Flags.SPLIT_SHADE_SUBPIXEL_OPTIMIZATION, true)
featureFlags.set(Flags.REVAMPED_BOUNCER_MESSAGES, true)
featureFlags.set(Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED, false)
val inputProxy = MultiShadeInputProxy()
testScope = TestScope()
val multiShadeInteractor =
@@ -199,7 +196,6 @@ class NotificationShadeWindowViewTest : SysuiTestCase() {
notificationInsetsController,
ambientState,
pulsingGestureListener,
mLockscreenHostedDreamGestureListener,
keyguardBouncerViewModel,
keyguardBouncerComponentFactory,
Mockito.mock(KeyguardMessageAreaController.Factory::class.java),