Merge "Trigger unfold animation without treshold while on keyguard" into tm-qpr-dev am: c3f30502f8

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

Change-Id: Idc2429dd81f74528561cc749ef09d4838f412d0a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Nicolò Mazzucato
2022-12-30 11:34:24 +00:00
committed by Automerger Merge Worker
6 changed files with 169 additions and 4 deletions

View File

@@ -20,6 +20,7 @@ import com.android.keyguard.KeyguardUnfoldTransition
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.shade.NotificationPanelUnfoldAnimationController
import com.android.systemui.statusbar.phone.StatusBarMoveFromCenterAnimationController
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
import com.android.systemui.unfold.util.NaturalRotationUnfoldProgressProvider
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.systemui.util.kotlin.getOrNull
@@ -95,4 +96,6 @@ interface SysUIUnfoldComponent {
fun getUnfoldHapticsPlayer(): UnfoldHapticsPlayer
fun getUnfoldLightRevealOverlayAnimation(): UnfoldLightRevealOverlayAnimation
fun getUnfoldKeyguardVisibilityManager(): UnfoldKeyguardVisibilityManager
}

View File

@@ -0,0 +1,39 @@
package com.android.systemui.unfold
import android.util.Log
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
import com.android.systemui.util.kotlin.getOrNull
import java.util.Optional
import javax.inject.Inject
/**
* Used to set the keyguard visibility state to [UnfoldKeyguardVisibilityManager].
*
* It is not possible to directly inject a sysui class (e.g. [KeyguardStateController]) into
* [DeviceStateProvider], as it can't depend on google sysui directly. So,
* [UnfoldKeyguardVisibilityManager] is provided to clients, that can set the keyguard visibility
* accordingly.
*/
@SysUISingleton
class UnfoldKeyguardVisibilityListener
@Inject
constructor(
keyguardStateController: KeyguardStateController,
unfoldComponent: Optional<SysUIUnfoldComponent>,
) {
private val unfoldKeyguardVisibilityManager =
unfoldComponent.getOrNull()?.getUnfoldKeyguardVisibilityManager()
private val delegate = { keyguardStateController.isVisible }
fun init() {
unfoldKeyguardVisibilityManager?.setKeyguardVisibleDelegate(delegate).also {
Log.d(TAG, "setKeyguardVisibleDelegate set")
}
}
}
private const val TAG = "UnfoldKeyguardVisibilityListener"

View File

@@ -29,6 +29,7 @@ import com.android.systemui.unfold.updates.RotationChangeProvider.RotationListen
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.google.common.truth.Truth.assertThat
@@ -56,6 +57,9 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
@Mock
private lateinit var rotationChangeProvider: RotationChangeProvider
@Mock
private lateinit var unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider
@Captor
private lateinit var rotationListener: ArgumentCaptor<RotationListener>
@@ -87,6 +91,7 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
screenOnStatusProvider,
foldProvider,
activityTypeProvider,
unfoldKeyguardVisibilityProvider,
rotationChangeProvider,
context.mainExecutor,
handler
@@ -379,6 +384,47 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
}
@Test
fun startClosingEvent_whileNotOnKeyguardAndNotOnLauncher_doesNotTriggerBeforeThreshold() {
setKeyguardVisibility(visible = false)
setupForegroundActivityType(isHomeActivity = false)
sendHingeAngleEvent(180)
sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
assertThat(foldUpdates).isEmpty()
}
@Test
fun startClosingEvent_whileKeyguardStateNotAvailable_triggerBeforeThreshold() {
setKeyguardVisibility(visible = null)
sendHingeAngleEvent(180)
sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
}
@Test
fun startClosingEvent_whileonKeyguard_doesTriggerBeforeThreshold() {
setKeyguardVisibility(visible = true)
sendHingeAngleEvent(180)
sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES + 1)
assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
}
@Test
fun startClosingEvent_whileNotOnKeyguard_triggersAfterThreshold() {
setKeyguardVisibility(visible = false)
sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES)
sendHingeAngleEvent(START_CLOSING_ON_APPS_THRESHOLD_DEGREES - 1)
assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
}
@Test
fun screenOff_whileFolded_hingeAngleProviderRemainsOff() {
setFoldState(folded = true)
@@ -445,6 +491,10 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
whenever(activityTypeProvider.isHomeActivity).thenReturn(isHomeActivity)
}
private fun setKeyguardVisibility(visible: Boolean?) {
whenever(unfoldKeyguardVisibilityProvider.isKeyguardVisible).thenReturn(visible)
}
private fun simulateTimeout(waitTime: Long = HALF_OPENED_TIMEOUT_MILLIS) {
val runnableDelay = scheduledRunnableDelay ?: throw Exception("No runnable scheduled.")
if (waitTime >= runnableDelay) {

View File

@@ -28,6 +28,9 @@ import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManager
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityManagerImpl
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
import dagger.Module
import dagger.Provides
import java.util.Optional
@@ -57,7 +60,8 @@ class UnfoldSharedModule {
scaleAwareProviderFactory.wrap(baseProgressProvider).apply {
// Always present callback that logs animation beginning and end.
addCallback(tracingListener)
})
}
)
}
@Provides
@@ -77,4 +81,16 @@ class UnfoldSharedModule {
} else {
EmptyHingeAngleProvider
}
@Provides
@Singleton
fun unfoldKeyguardVisibilityProvider(
impl: UnfoldKeyguardVisibilityManagerImpl
): UnfoldKeyguardVisibilityProvider = impl
@Provides
@Singleton
fun unfoldKeyguardVisibilityManager(
impl: UnfoldKeyguardVisibilityManagerImpl
): UnfoldKeyguardVisibilityManager = impl
}

View File

@@ -31,6 +31,7 @@ import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.util.CurrentActivityTypeProvider
import com.android.systemui.unfold.util.UnfoldKeyguardVisibilityProvider
import java.util.concurrent.Executor
import javax.inject.Inject
@@ -42,6 +43,7 @@ constructor(
private val screenStatusProvider: ScreenStatusProvider,
private val foldProvider: FoldProvider,
private val activityTypeProvider: CurrentActivityTypeProvider,
private val unfoldKeyguardVisibilityProvider: UnfoldKeyguardVisibilityProvider,
private val rotationChangeProvider: RotationChangeProvider,
@UnfoldMain private val mainExecutor: Executor,
@UnfoldMain private val handler: Handler
@@ -152,12 +154,13 @@ constructor(
*/
private fun getClosingThreshold(): Int? {
val isHomeActivity = activityTypeProvider.isHomeActivity ?: return null
val isKeyguardVisible = unfoldKeyguardVisibilityProvider.isKeyguardVisible == true
if (DEBUG) {
Log.d(TAG, "isHomeActivity=$isHomeActivity")
Log.d(TAG, "isHomeActivity=$isHomeActivity, isOnKeyguard=$isKeyguardVisible")
}
return if (isHomeActivity) {
return if (isHomeActivity || isKeyguardVisible) {
null
} else {
START_CLOSING_ON_APPS_THRESHOLD_DEGREES
@@ -257,7 +260,7 @@ fun @receiver:FoldUpdate Int.name() =
}
private const val TAG = "DeviceFoldProvider"
private const val DEBUG = false
private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
/** Threshold after which we consider the device fully unfolded. */
@VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f

View File

@@ -0,0 +1,54 @@
/*
* 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.unfold.util
import java.lang.ref.WeakReference
import javax.inject.Inject
import javax.inject.Singleton
interface UnfoldKeyguardVisibilityProvider {
/**
* True when the keyguard is visible.
*
* Might be [null] when it is not known.
*/
val isKeyguardVisible: Boolean?
}
/** Used to notify keyguard visibility. */
interface UnfoldKeyguardVisibilityManager {
/** Sets the delegate. [delegate] should return true when the keyguard is visible. */
fun setKeyguardVisibleDelegate(delegate: () -> Boolean)
}
/**
* Keeps a [WeakReference] for the keyguard visibility provider.
*
* It is a weak reference because this is in the global scope, while the delegate might be set from
* another subcomponent (that might have shorter lifespan).
*/
@Singleton
class UnfoldKeyguardVisibilityManagerImpl @Inject constructor() :
UnfoldKeyguardVisibilityProvider, UnfoldKeyguardVisibilityManager {
private var delegatedProvider: WeakReference<() -> Boolean?>? = null
override fun setKeyguardVisibleDelegate(delegate: () -> Boolean) {
delegatedProvider = WeakReference(delegate)
}
override val isKeyguardVisible: Boolean?
get() = delegatedProvider?.get()?.invoke()
}