Unifies use-cases into interactors.
To reduce memory use and garbage collection pressure, moving from having multiple one-method use-case classes without a dagger scope to having a handful of multi-method interactor classes with a singleton dagger scope. Fix: 241788615 Test: Unit tests. Manually verified bottom area view quick affordances behave as before. Change-Id: I441c31d5643dd7dc19d681261f8ef415ec533e0b
This commit is contained in:
@@ -35,7 +35,7 @@ object ChannelExt {
|
||||
* " - downstream canceled or failed.",
|
||||
* it,
|
||||
* )
|
||||
*}
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
fun <T> SendChannel<T>.trySendWithFailureLogging(
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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.common.domain.model
|
||||
|
||||
import com.android.systemui.common.data.model.Position as DataLayerPosition
|
||||
|
||||
/** Models a two-dimensional position */
|
||||
data class Position(
|
||||
val x: Int,
|
||||
val y: Int,
|
||||
) {
|
||||
companion object {
|
||||
fun DataLayerPosition.toDomainLayer(): Position {
|
||||
return Position(
|
||||
x = x,
|
||||
y = y,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.common.data.model
|
||||
package com.android.systemui.common.shared.model
|
||||
|
||||
/** Models a two-dimensional position */
|
||||
data class Position(
|
||||
@@ -44,7 +44,6 @@ import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.KeyguardViewMediator;
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule;
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceModule;
|
||||
import com.android.systemui.keyguard.domain.usecase.KeyguardUseCaseModule;
|
||||
import com.android.systemui.navigationbar.NavigationModeController;
|
||||
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
@@ -73,7 +72,6 @@ import dagger.Provides;
|
||||
FalsingModule.class,
|
||||
KeyguardQuickAffordanceModule.class,
|
||||
KeyguardRepositoryModule.class,
|
||||
KeyguardUseCaseModule.class,
|
||||
})
|
||||
public class KeyguardModule {
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.android.systemui.keyguard.data.repository
|
||||
|
||||
import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
|
||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||
import com.android.systemui.common.data.model.Position
|
||||
import com.android.systemui.common.shared.model.Position
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.keyguard.domain.interactor
|
||||
|
||||
import com.android.systemui.common.shared.model.Position
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/** Encapsulates business-logic specifically related to the keyguard bottom area. */
|
||||
@SysUISingleton
|
||||
class KeyguardBottomAreaInteractor
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
/** Whether to animate the next doze mode transition. */
|
||||
val animateDozingTransitions: Flow<Boolean> = repository.animateBottomAreaDozingTransitions
|
||||
/** The amount of alpha for the UI components of the bottom area. */
|
||||
val alpha: Flow<Float> = repository.bottomAreaAlpha
|
||||
/** The position of the keyguard clock. */
|
||||
val clockPosition: Flow<Position> = repository.clockPosition
|
||||
|
||||
fun setClockPosition(x: Int, y: Int) {
|
||||
repository.setClockPosition(x, y)
|
||||
}
|
||||
|
||||
fun setAlpha(alpha: Float) {
|
||||
repository.setBottomAreaAlpha(alpha)
|
||||
}
|
||||
|
||||
fun setAnimateDozingTransitions(animate: Boolean) {
|
||||
repository.setAnimateDozingTransitions(animate)
|
||||
}
|
||||
}
|
||||
@@ -15,25 +15,29 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.systemui.keyguard.domain.usecase
|
||||
package com.android.systemui.keyguard.domain.interactor
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/**
|
||||
* Use-case for observing whether the keyguard is currently being shown.
|
||||
*
|
||||
* Note: this is also `true` when the lock-screen is occluded with an `Activity` "above" it in the
|
||||
* z-order (which is not really above the system UI window, but rather - the lock-screen becomes
|
||||
* invisible to reveal the "occluding activity").
|
||||
* Encapsulates business-logic related to the keyguard but not to a more specific part within it.
|
||||
*/
|
||||
class ObserveIsKeyguardShowingUseCase
|
||||
@SysUISingleton
|
||||
class KeyguardInteractor
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(): Flow<Boolean> {
|
||||
return repository.isKeyguardShowing
|
||||
}
|
||||
/**
|
||||
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
|
||||
* all.
|
||||
*/
|
||||
val dozeAmount: Flow<Float> = repository.dozeAmount
|
||||
/** Whether the system is in doze mode. */
|
||||
val isDozing: Flow<Boolean> = repository.isDozing
|
||||
/** Whether the keyguard is showing ot not. */
|
||||
val isKeyguardShowing: Flow<Boolean> = repository.isKeyguardShowing
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.keyguard.domain.interactor
|
||||
|
||||
import android.content.Intent
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceRegistry
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
||||
@SysUISingleton
|
||||
class KeyguardQuickAffordanceInteractor
|
||||
@Inject
|
||||
constructor(
|
||||
private val keyguardInteractor: KeyguardInteractor,
|
||||
private val registry: KeyguardQuickAffordanceRegistry<out KeyguardQuickAffordanceConfig>,
|
||||
private val lockPatternUtils: LockPatternUtils,
|
||||
private val keyguardStateController: KeyguardStateController,
|
||||
private val userTracker: UserTracker,
|
||||
private val activityStarter: ActivityStarter,
|
||||
) {
|
||||
/** Returns an observable for the quick affordance at the given position. */
|
||||
fun quickAffordance(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): Flow<KeyguardQuickAffordanceModel> {
|
||||
return combine(
|
||||
quickAffordanceInternal(position),
|
||||
keyguardInteractor.isDozing,
|
||||
keyguardInteractor.isKeyguardShowing,
|
||||
) { affordance, isDozing, isKeyguardShowing ->
|
||||
if (!isDozing && isKeyguardShowing) {
|
||||
affordance
|
||||
} else {
|
||||
KeyguardQuickAffordanceModel.Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that a quick affordance has been clicked by the user.
|
||||
*
|
||||
* @param configKey The configuration key corresponding to the [KeyguardQuickAffordanceModel] of
|
||||
* the affordance that was clicked
|
||||
* @param animationController An optional controller for the activity-launch animation
|
||||
*/
|
||||
fun onQuickAffordanceClicked(
|
||||
configKey: KClass<out KeyguardQuickAffordanceConfig>,
|
||||
animationController: ActivityLaunchAnimator.Controller?,
|
||||
) {
|
||||
@Suppress("UNCHECKED_CAST") val config = registry.get(configKey as KClass<Nothing>)
|
||||
when (val result = config.onQuickAffordanceClicked(animationController)) {
|
||||
is KeyguardQuickAffordanceConfig.OnClickedResult.StartActivity ->
|
||||
launchQuickAffordance(
|
||||
intent = result.intent,
|
||||
canShowWhileLocked = result.canShowWhileLocked,
|
||||
animationController = animationController
|
||||
)
|
||||
is KeyguardQuickAffordanceConfig.OnClickedResult.Handled -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun quickAffordanceInternal(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): Flow<KeyguardQuickAffordanceModel> {
|
||||
val configs = registry.getAll(position)
|
||||
return combine(configs.map { config -> config.state }) { states ->
|
||||
val index = states.indexOfFirst { it is KeyguardQuickAffordanceConfig.State.Visible }
|
||||
if (index != -1) {
|
||||
val visibleState = states[index] as KeyguardQuickAffordanceConfig.State.Visible
|
||||
KeyguardQuickAffordanceModel.Visible(
|
||||
configKey = configs[index]::class,
|
||||
icon = visibleState.icon,
|
||||
contentDescriptionResourceId = visibleState.contentDescriptionResourceId,
|
||||
)
|
||||
} else {
|
||||
KeyguardQuickAffordanceModel.Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchQuickAffordance(
|
||||
intent: Intent,
|
||||
canShowWhileLocked: Boolean,
|
||||
animationController: ActivityLaunchAnimator.Controller?,
|
||||
) {
|
||||
@LockPatternUtils.StrongAuthTracker.StrongAuthFlags
|
||||
val strongAuthFlags =
|
||||
lockPatternUtils.getStrongAuthForUser(userTracker.userHandle.identifier)
|
||||
val needsToUnlockFirst =
|
||||
when {
|
||||
strongAuthFlags ==
|
||||
LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT -> true
|
||||
!canShowWhileLocked && !keyguardStateController.isUnlocked -> true
|
||||
else -> false
|
||||
}
|
||||
if (needsToUnlockFirst) {
|
||||
activityStarter.postStartActivityDismissingKeyguard(
|
||||
intent,
|
||||
0 /* delay */,
|
||||
animationController
|
||||
)
|
||||
} else {
|
||||
activityStarter.startActivity(
|
||||
intent,
|
||||
true /* dismissShade */,
|
||||
animationController,
|
||||
true /* showOverLockscreenWhenLocked */,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,21 +42,4 @@ sealed class KeyguardQuickAffordanceModel {
|
||||
*/
|
||||
@StringRes val contentDescriptionResourceId: Int,
|
||||
) : KeyguardQuickAffordanceModel()
|
||||
|
||||
companion object {
|
||||
fun from(
|
||||
state: KeyguardQuickAffordanceConfig.State?,
|
||||
configKey: KClass<out KeyguardQuickAffordanceConfig>,
|
||||
): KeyguardQuickAffordanceModel {
|
||||
return when (state) {
|
||||
is KeyguardQuickAffordanceConfig.State.Visible ->
|
||||
Visible(
|
||||
configKey = configKey,
|
||||
icon = state.icon,
|
||||
contentDescriptionResourceId = state.contentDescriptionResourceId,
|
||||
)
|
||||
else -> Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,5 +25,5 @@ interface KeyguardQuickAffordanceModule {
|
||||
@Binds
|
||||
fun keyguardQuickAffordanceRegistry(
|
||||
impl: KeyguardQuickAffordanceRegistryImpl
|
||||
): KeyguardQuickAffordanceRegistry
|
||||
): KeyguardQuickAffordanceRegistry<out KeyguardQuickAffordanceConfig>
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/** Central registry of all known quick affordance configs. */
|
||||
interface KeyguardQuickAffordanceRegistry {
|
||||
fun getAll(position: KeyguardQuickAffordancePosition): List<KeyguardQuickAffordanceConfig>
|
||||
fun get(configClass: KClass<out KeyguardQuickAffordanceConfig>): KeyguardQuickAffordanceConfig
|
||||
interface KeyguardQuickAffordanceRegistry<T : KeyguardQuickAffordanceConfig> {
|
||||
fun getAll(position: KeyguardQuickAffordancePosition): List<T>
|
||||
fun get(configClass: KClass<out T>): T
|
||||
}
|
||||
|
||||
class KeyguardQuickAffordanceRegistryImpl
|
||||
@@ -33,7 +33,7 @@ constructor(
|
||||
homeControls: HomeControlsKeyguardQuickAffordanceConfig,
|
||||
quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
|
||||
qrCodeScanner: QrCodeScannerKeyguardQuickAffordanceConfig,
|
||||
) : KeyguardQuickAffordanceRegistry {
|
||||
) : KeyguardQuickAffordanceRegistry<KeyguardQuickAffordanceConfig> {
|
||||
private val configsByPosition =
|
||||
mapOf(
|
||||
KeyguardQuickAffordancePosition.BOTTOM_START to
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
|
||||
@Module
|
||||
interface KeyguardUseCaseModule {
|
||||
|
||||
@Binds
|
||||
fun launchQuickAffordance(
|
||||
impl: LaunchKeyguardQuickAffordanceUseCaseImpl
|
||||
): LaunchKeyguardQuickAffordanceUseCase
|
||||
|
||||
@Binds
|
||||
fun observeKeyguardQuickAffordance(
|
||||
impl: ObserveKeyguardQuickAffordanceUseCaseImpl
|
||||
): ObserveKeyguardQuickAffordanceUseCase
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import android.content.Intent
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.internal.widget.LockPatternUtils.StrongAuthTracker.StrongAuthFlags
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Defines interface for classes that can launch a quick affordance. */
|
||||
interface LaunchKeyguardQuickAffordanceUseCase {
|
||||
operator fun invoke(
|
||||
intent: Intent,
|
||||
canShowWhileLocked: Boolean,
|
||||
animationController: ActivityLaunchAnimator.Controller?,
|
||||
)
|
||||
}
|
||||
|
||||
/** Real implementation of [LaunchKeyguardQuickAffordanceUseCase] */
|
||||
class LaunchKeyguardQuickAffordanceUseCaseImpl
|
||||
@Inject
|
||||
constructor(
|
||||
private val lockPatternUtils: LockPatternUtils,
|
||||
private val keyguardStateController: KeyguardStateController,
|
||||
private val userTracker: UserTracker,
|
||||
private val activityStarter: ActivityStarter,
|
||||
) : LaunchKeyguardQuickAffordanceUseCase {
|
||||
override operator fun invoke(
|
||||
intent: Intent,
|
||||
canShowWhileLocked: Boolean,
|
||||
animationController: ActivityLaunchAnimator.Controller?,
|
||||
) {
|
||||
@StrongAuthFlags
|
||||
val strongAuthFlags =
|
||||
lockPatternUtils.getStrongAuthForUser(userTracker.userHandle.identifier)
|
||||
val needsToUnlockFirst =
|
||||
when {
|
||||
strongAuthFlags ==
|
||||
LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT -> true
|
||||
!canShowWhileLocked && !keyguardStateController.isUnlocked -> true
|
||||
else -> false
|
||||
}
|
||||
if (needsToUnlockFirst) {
|
||||
activityStarter.postStartActivityDismissingKeyguard(
|
||||
intent,
|
||||
0 /* delay */,
|
||||
animationController
|
||||
)
|
||||
} else {
|
||||
activityStarter.startActivity(
|
||||
intent,
|
||||
true /* dismissShade */,
|
||||
animationController,
|
||||
true /* showOverLockscreenWhenLocked */,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/** Use-case for observing whether doze state transitions should animate the bottom area */
|
||||
class ObserveAnimateBottomAreaTransitionsUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(): Flow<Boolean> {
|
||||
return repository.animateBottomAreaDozingTransitions
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/** Use-case for observing the alpha of the bottom area */
|
||||
class ObserveBottomAreaAlphaUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(): Flow<Float> {
|
||||
return repository.bottomAreaAlpha
|
||||
}
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.common.domain.model.Position
|
||||
import com.android.systemui.common.domain.model.Position.Companion.toDomainLayer
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
/** Use-case for observing the position of the clock. */
|
||||
class ObserveClockPositionUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(): Flow<Position> {
|
||||
return repository.clockPosition.map { it.toDomainLayer() }
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/** Use-case for observing the amount of doze the system is in. */
|
||||
class ObserveDozeAmountUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(): Flow<Float> {
|
||||
return repository.dozeAmount
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
/** Use-case for observing whether we are dozing. */
|
||||
class ObserveIsDozingUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(): Flow<Boolean> {
|
||||
return repository.isDozing
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceRegistry
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
||||
/** Defines interface for use-case for observing the model of a quick affordance in the keyguard. */
|
||||
interface ObserveKeyguardQuickAffordanceUseCase {
|
||||
operator fun invoke(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): Flow<KeyguardQuickAffordanceModel>
|
||||
}
|
||||
|
||||
class ObserveKeyguardQuickAffordanceUseCaseImpl
|
||||
@Inject
|
||||
constructor(
|
||||
private val registry: KeyguardQuickAffordanceRegistry,
|
||||
private val isDozingUseCase: ObserveIsDozingUseCase,
|
||||
private val isKeyguardShowingUseCase: ObserveIsKeyguardShowingUseCase,
|
||||
) : ObserveKeyguardQuickAffordanceUseCase {
|
||||
override fun invoke(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): Flow<KeyguardQuickAffordanceModel> {
|
||||
return combine(
|
||||
affordance(position),
|
||||
isDozingUseCase(),
|
||||
isKeyguardShowingUseCase(),
|
||||
) { affordance, isDozing, isKeyguardShowing ->
|
||||
if (!isDozing && isKeyguardShowing) {
|
||||
affordance
|
||||
} else {
|
||||
KeyguardQuickAffordanceModel.Hidden
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun affordance(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): Flow<KeyguardQuickAffordanceModel> {
|
||||
val configs = registry.getAll(position)
|
||||
return combine(configs.map { config -> config.state }) { states ->
|
||||
val index =
|
||||
states.indexOfFirst { state ->
|
||||
state is KeyguardQuickAffordanceConfig.State.Visible
|
||||
}
|
||||
val visibleState =
|
||||
if (index != -1) {
|
||||
states[index] as KeyguardQuickAffordanceConfig.State.Visible
|
||||
} else {
|
||||
null
|
||||
}
|
||||
KeyguardQuickAffordanceModel.from(visibleState, configs[index]::class)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig.OnClickedResult
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceRegistry
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/** Use-case for handling a click on a keyguard quick affordance (e.g. bottom button). */
|
||||
class OnKeyguardQuickAffordanceClickedUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val registry: KeyguardQuickAffordanceRegistry,
|
||||
private val launchAffordanceUseCase: LaunchKeyguardQuickAffordanceUseCase,
|
||||
) {
|
||||
operator fun invoke(
|
||||
configKey: KClass<*>,
|
||||
animationController: ActivityLaunchAnimator.Controller?,
|
||||
) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val config = registry.get(configKey as KClass<out KeyguardQuickAffordanceConfig>)
|
||||
when (val result = config.onQuickAffordanceClicked(animationController)) {
|
||||
is OnClickedResult.StartActivity ->
|
||||
launchAffordanceUseCase(
|
||||
intent = result.intent,
|
||||
canShowWhileLocked = result.canShowWhileLocked,
|
||||
animationController = animationController
|
||||
)
|
||||
is OnClickedResult.Handled -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Use-case for setting the updated clock position. */
|
||||
class SetClockPositionUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val keyguardRepository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(x: Int, y: Int) {
|
||||
keyguardRepository.setClockPosition(x, y)
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Use-case for setting the alpha that the keyguard bottom area should use */
|
||||
class SetKeyguardBottomAreaAlphaUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(alpha: Float) {
|
||||
repository.setBottomAreaAlpha(alpha)
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Use-case for setting whether the keyguard bottom area should animate the next doze transitions
|
||||
*/
|
||||
class SetKeyguardBottomAreaAnimateDozingTransitionsUseCase
|
||||
@Inject
|
||||
constructor(
|
||||
private val repository: KeyguardRepository,
|
||||
) {
|
||||
operator fun invoke(animate: Boolean) {
|
||||
repository.setAnimateDozingTransitions(animate)
|
||||
}
|
||||
}
|
||||
@@ -17,15 +17,11 @@
|
||||
package com.android.systemui.keyguard.ui.viewmodel
|
||||
|
||||
import com.android.systemui.doze.util.BurnInHelperWrapper
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveAnimateBottomAreaTransitionsUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveBottomAreaAlphaUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveClockPositionUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveDozeAmountUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveIsDozingUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveKeyguardQuickAffordanceUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.OnKeyguardQuickAffordanceClickedUseCase
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -36,13 +32,9 @@ import kotlinx.coroutines.flow.map
|
||||
class KeyguardBottomAreaViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val observeQuickAffordanceUseCase: ObserveKeyguardQuickAffordanceUseCase,
|
||||
private val onQuickAffordanceClickedUseCase: OnKeyguardQuickAffordanceClickedUseCase,
|
||||
observeBottomAreaAlphaUseCase: ObserveBottomAreaAlphaUseCase,
|
||||
observeIsDozingUseCase: ObserveIsDozingUseCase,
|
||||
observeAnimateBottomAreaTransitionsUseCase: ObserveAnimateBottomAreaTransitionsUseCase,
|
||||
private val observeDozeAmountUseCase: ObserveDozeAmountUseCase,
|
||||
observeClockPositionUseCase: ObserveClockPositionUseCase,
|
||||
private val keyguardInteractor: KeyguardInteractor,
|
||||
private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
|
||||
bottomAreaInteractor: KeyguardBottomAreaInteractor,
|
||||
private val burnInHelperWrapper: BurnInHelperWrapper,
|
||||
) {
|
||||
/** An observable for the view-model of the "start button" quick affordance. */
|
||||
@@ -56,12 +48,12 @@ constructor(
|
||||
* animate.
|
||||
*/
|
||||
val animateButtonReveal: Flow<Boolean> =
|
||||
observeAnimateBottomAreaTransitionsUseCase().distinctUntilChanged()
|
||||
bottomAreaInteractor.animateDozingTransitions.distinctUntilChanged()
|
||||
/** An observable for whether the overlay container should be visible. */
|
||||
val isOverlayContainerVisible: Flow<Boolean> =
|
||||
observeIsDozingUseCase().map { !it }.distinctUntilChanged()
|
||||
keyguardInteractor.isDozing.map { !it }.distinctUntilChanged()
|
||||
/** An observable for the alpha level for the entire bottom area. */
|
||||
val alpha: Flow<Float> = observeBottomAreaAlphaUseCase().distinctUntilChanged()
|
||||
val alpha: Flow<Float> = bottomAreaInteractor.alpha.distinctUntilChanged()
|
||||
/** An observable for whether the indication area should be padded. */
|
||||
val isIndicationAreaPadded: Flow<Boolean> =
|
||||
combine(startButton, endButton) { startButtonModel, endButtonModel ->
|
||||
@@ -70,11 +62,11 @@ constructor(
|
||||
.distinctUntilChanged()
|
||||
/** An observable for the x-offset by which the indication area should be translated. */
|
||||
val indicationAreaTranslationX: Flow<Float> =
|
||||
observeClockPositionUseCase().map { it.x.toFloat() }.distinctUntilChanged()
|
||||
bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
|
||||
|
||||
/** Returns an observable for the y-offset by which the indication area should be translated. */
|
||||
fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> {
|
||||
return observeDozeAmountUseCase()
|
||||
return keyguardInteractor.dozeAmount
|
||||
.map { dozeAmount ->
|
||||
dozeAmount *
|
||||
(burnInHelperWrapper.burnInOffset(
|
||||
@@ -88,7 +80,8 @@ constructor(
|
||||
private fun button(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): Flow<KeyguardQuickAffordanceViewModel> {
|
||||
return observeQuickAffordanceUseCase(position)
|
||||
return quickAffordanceInteractor
|
||||
.quickAffordance(position)
|
||||
.map { model -> model.toViewModel() }
|
||||
.distinctUntilChanged()
|
||||
}
|
||||
@@ -102,7 +95,7 @@ constructor(
|
||||
icon = icon,
|
||||
contentDescriptionResourceId = contentDescriptionResourceId,
|
||||
onClicked = { parameters ->
|
||||
onQuickAffordanceClickedUseCase(
|
||||
quickAffordanceInteractor.onQuickAffordanceClicked(
|
||||
configKey = parameters.configKey,
|
||||
animationController = parameters.animationController,
|
||||
)
|
||||
|
||||
@@ -19,18 +19,19 @@ package com.android.systemui.keyguard.ui.viewmodel
|
||||
import androidx.annotation.StringRes
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/** Models the UI state of a keyguard quick affordance button. */
|
||||
data class KeyguardQuickAffordanceViewModel(
|
||||
val configKey: KClass<*>? = null,
|
||||
val configKey: KClass<out KeyguardQuickAffordanceConfig>? = null,
|
||||
val isVisible: Boolean = false,
|
||||
val icon: ContainedDrawable = ContainedDrawable.WithResource(0),
|
||||
@StringRes val contentDescriptionResourceId: Int = 0,
|
||||
val onClicked: (OnClickedParameters) -> Unit = {},
|
||||
) {
|
||||
data class OnClickedParameters(
|
||||
val configKey: KClass<*>,
|
||||
val configKey: KClass<out KeyguardQuickAffordanceConfig>,
|
||||
val animationController: ActivityLaunchAnimator.Controller?,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -127,9 +127,7 @@ import com.android.systemui.flags.Flags;
|
||||
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
|
||||
import com.android.systemui.fragments.FragmentService;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.usecase.SetClockPositionUseCase;
|
||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAlphaUseCase;
|
||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAnimateDozingTransitionsUseCase;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||
import com.android.systemui.media.KeyguardMediaController;
|
||||
import com.android.systemui.media.MediaDataManager;
|
||||
@@ -705,11 +703,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
|
||||
private final CameraGestureHelper mCameraGestureHelper;
|
||||
private final Provider<KeyguardBottomAreaViewModel> mKeyguardBottomAreaViewModelProvider;
|
||||
private final Provider<SetClockPositionUseCase> mSetClockPositionUseCaseProvider;
|
||||
private final Provider<SetKeyguardBottomAreaAlphaUseCase>
|
||||
mSetKeyguardBottomAreaAlphaUseCaseProvider;
|
||||
private final Provider<SetKeyguardBottomAreaAnimateDozingTransitionsUseCase>
|
||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider;
|
||||
private final Provider<KeyguardBottomAreaInteractor> mKeyguardBottomAreaInteractorProvider;
|
||||
|
||||
@Inject
|
||||
public NotificationPanelViewController(NotificationPanelView view,
|
||||
@@ -781,10 +775,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
SystemClock systemClock,
|
||||
CameraGestureHelper cameraGestureHelper,
|
||||
Provider<KeyguardBottomAreaViewModel> keyguardBottomAreaViewModelProvider,
|
||||
Provider<SetClockPositionUseCase> setClockPositionUseCaseProvider,
|
||||
Provider<SetKeyguardBottomAreaAlphaUseCase> setKeyguardBottomAreaAlphaUseCaseProvider,
|
||||
Provider<SetKeyguardBottomAreaAnimateDozingTransitionsUseCase>
|
||||
setKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider) {
|
||||
Provider<KeyguardBottomAreaInteractor> keyguardBottomAreaInteractorProvider) {
|
||||
super(view,
|
||||
falsingManager,
|
||||
dozeLog,
|
||||
@@ -966,10 +957,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
}
|
||||
});
|
||||
mCameraGestureHelper = cameraGestureHelper;
|
||||
mSetClockPositionUseCaseProvider = setClockPositionUseCaseProvider;
|
||||
mSetKeyguardBottomAreaAlphaUseCaseProvider = setKeyguardBottomAreaAlphaUseCaseProvider;
|
||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider =
|
||||
setKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider;
|
||||
mKeyguardBottomAreaInteractorProvider = keyguardBottomAreaInteractorProvider;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -1487,7 +1475,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
mKeyguardStatusViewController.getClockBottom(mStatusBarHeaderHeightKeyguard),
|
||||
mKeyguardStatusViewController.isClockTopAligned());
|
||||
mClockPositionAlgorithm.run(mClockPositionResult);
|
||||
mSetClockPositionUseCaseProvider.get().invoke(
|
||||
mKeyguardBottomAreaInteractorProvider.get().setClockPosition(
|
||||
mClockPositionResult.clockX, mClockPositionResult.clockY);
|
||||
boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
|
||||
boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange;
|
||||
@@ -3261,7 +3249,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction());
|
||||
alpha *= mBottomAreaShadeAlpha;
|
||||
mKeyguardBottomArea.setComponentAlphas(alpha);
|
||||
mSetKeyguardBottomAreaAlphaUseCaseProvider.get().invoke(alpha);
|
||||
mKeyguardBottomAreaInteractorProvider.get().setAlpha(alpha);
|
||||
mLockIconViewController.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@@ -3461,7 +3449,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
|
||||
private void updateDozingVisibilities(boolean animate) {
|
||||
mKeyguardBottomArea.setDozing(mDozing, animate);
|
||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider.get().invoke(animate);
|
||||
mKeyguardBottomAreaInteractorProvider.get().setAnimateDozingTransitions(animate);
|
||||
if (!mDozing && animate) {
|
||||
mKeyguardStatusBarViewController.animateKeyguardStatusBarIn();
|
||||
}
|
||||
@@ -3764,7 +3752,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
||||
mDozing = dozing;
|
||||
mNotificationStackScrollLayoutController.setDozing(mDozing, animate, wakeUpTouchLocation);
|
||||
mKeyguardBottomArea.setDozing(mDozing, animate);
|
||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider.get().invoke(animate);
|
||||
mKeyguardBottomAreaInteractorProvider.get().setAnimateDozingTransitions(animate);
|
||||
mKeyguardStatusBarViewController.setDozing(mDozing);
|
||||
|
||||
if (dozing) {
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package com.android.systemui.keyguard.data.repository
|
||||
|
||||
import com.android.systemui.common.data.model.Position
|
||||
import com.android.systemui.common.shared.model.Position
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.yield
|
||||
|
||||
/** Fake implementation of [KeyguardRepository] */
|
||||
class FakeKeyguardRepository : KeyguardRepository {
|
||||
@@ -56,30 +55,15 @@ class FakeKeyguardRepository : KeyguardRepository {
|
||||
_clockPosition.value = Position(x, y)
|
||||
}
|
||||
|
||||
suspend fun setKeyguardShowing(isShowing: Boolean) {
|
||||
fun setKeyguardShowing(isShowing: Boolean) {
|
||||
_isKeyguardShowing.value = isShowing
|
||||
// Yield to allow the test's collection coroutine to "catch up" and collect this value
|
||||
// before the test continues to the next line.
|
||||
// TODO(b/239834928): once coroutines.test is updated, switch to the approach described in
|
||||
// https://developer.android.com/kotlin/flow/test#continuous-collection and remove this.
|
||||
yield()
|
||||
}
|
||||
|
||||
suspend fun setDozing(isDozing: Boolean) {
|
||||
fun setDozing(isDozing: Boolean) {
|
||||
_isDozing.value = isDozing
|
||||
// Yield to allow the test's collection coroutine to "catch up" and collect this value
|
||||
// before the test continues to the next line.
|
||||
// TODO(b/239834928): once coroutines.test is updated, switch to the approach described in
|
||||
// https://developer.android.com/kotlin/flow/test#continuous-collection and remove this.
|
||||
yield()
|
||||
}
|
||||
|
||||
suspend fun setDozeAmount(dozeAmount: Float) {
|
||||
fun setDozeAmount(dozeAmount: Float) {
|
||||
_dozeAmount.value = dozeAmount
|
||||
// Yield to allow the test's collection coroutine to "catch up" and collect this value
|
||||
// before the test continues to the next line.
|
||||
// TODO(b/239834928): once coroutines.test is updated, switch to the approach described in
|
||||
// https://developer.android.com/kotlin/flow/test#continuous-collection and remove this.
|
||||
yield()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.android.systemui.keyguard.data.repository
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.common.data.model.Position
|
||||
import com.android.systemui.common.shared.model.Position
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
|
||||
@@ -23,18 +23,18 @@ import kotlin.reflect.KClass
|
||||
/** Fake implementation of [FakeKeyguardQuickAffordanceRegistry], for tests. */
|
||||
class FakeKeyguardQuickAffordanceRegistry(
|
||||
private val configsByPosition:
|
||||
Map<KeyguardQuickAffordancePosition, List<KeyguardQuickAffordanceConfig>>,
|
||||
) : KeyguardQuickAffordanceRegistry {
|
||||
Map<KeyguardQuickAffordancePosition, List<FakeKeyguardQuickAffordanceConfig>>,
|
||||
) : KeyguardQuickAffordanceRegistry<FakeKeyguardQuickAffordanceConfig> {
|
||||
|
||||
override fun getAll(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): List<KeyguardQuickAffordanceConfig> {
|
||||
): List<FakeKeyguardQuickAffordanceConfig> {
|
||||
return configsByPosition.getValue(position)
|
||||
}
|
||||
|
||||
override fun get(
|
||||
configClass: KClass<out KeyguardQuickAffordanceConfig>
|
||||
): KeyguardQuickAffordanceConfig {
|
||||
configClass: KClass<out FakeKeyguardQuickAffordanceConfig>
|
||||
): FakeKeyguardQuickAffordanceConfig {
|
||||
return configsByPosition.values
|
||||
.flatten()
|
||||
.associateBy { config -> config::class }
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import android.content.Intent
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
|
||||
/** Fake implementation of [LaunchKeyguardQuickAffordanceUseCase], for tests. */
|
||||
class FakeLaunchKeyguardQuickAffordanceUseCase : LaunchKeyguardQuickAffordanceUseCase {
|
||||
|
||||
data class Invocation(
|
||||
val intent: Intent,
|
||||
val canShowWhileLocked: Boolean,
|
||||
val animationController: ActivityLaunchAnimator.Controller?
|
||||
)
|
||||
|
||||
private val _invocations = mutableListOf<Invocation>()
|
||||
val invocations: List<Invocation> = _invocations
|
||||
|
||||
override fun invoke(
|
||||
intent: Intent,
|
||||
canShowWhileLocked: Boolean,
|
||||
animationController: ActivityLaunchAnimator.Controller?
|
||||
) {
|
||||
_invocations.add(
|
||||
Invocation(
|
||||
intent = intent,
|
||||
canShowWhileLocked = canShowWhileLocked,
|
||||
animationController = animationController,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class FakeObserveKeyguardQuickAffordanceUseCase : ObserveKeyguardQuickAffordanceUseCase {
|
||||
|
||||
private val affordanceByPosition =
|
||||
mutableMapOf<
|
||||
KeyguardQuickAffordancePosition, MutableStateFlow<KeyguardQuickAffordanceModel>>()
|
||||
|
||||
init {
|
||||
KeyguardQuickAffordancePosition.values().forEach { position ->
|
||||
affordanceByPosition[position] = MutableStateFlow(KeyguardQuickAffordanceModel.Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
override fun invoke(
|
||||
position: KeyguardQuickAffordancePosition
|
||||
): Flow<KeyguardQuickAffordanceModel> {
|
||||
return affordanceByPosition[position] ?: error("Flow unexpectedly missing!")
|
||||
}
|
||||
|
||||
fun setModel(position: KeyguardQuickAffordancePosition, model: KeyguardQuickAffordanceModel) {
|
||||
affordanceByPosition[position]?.value = model
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import kotlinx.coroutines.test.runBlockingTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import org.junit.runners.Parameterized.Parameter
|
||||
import org.junit.runners.Parameterized.Parameters
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
import org.mockito.ArgumentMatchers.same
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.verifyZeroInteractions
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(Parameterized::class)
|
||||
class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
|
||||
|
||||
companion object {
|
||||
private val INTENT = Intent("some.intent.action")
|
||||
private val DRAWABLE = mock<ContainedDrawable>()
|
||||
private const val CONTENT_DESCRIPTION_RESOURCE_ID = 1337
|
||||
|
||||
@Parameters(
|
||||
name =
|
||||
"needStrongAuthAfterBoot={0}, canShowWhileLocked={1}," +
|
||||
" keyguardIsUnlocked={2}, needsToUnlockFirst={3}, startActivity={4}"
|
||||
)
|
||||
@JvmStatic
|
||||
fun data() =
|
||||
listOf(
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
/* startActivity= */ true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock private lateinit var userTracker: UserTracker
|
||||
@Mock private lateinit var activityStarter: ActivityStarter
|
||||
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
|
||||
|
||||
private lateinit var underTest: KeyguardQuickAffordanceInteractor
|
||||
|
||||
@JvmField @Parameter(0) var needStrongAuthAfterBoot: Boolean = false
|
||||
@JvmField @Parameter(1) var canShowWhileLocked: Boolean = false
|
||||
@JvmField @Parameter(2) var keyguardIsUnlocked: Boolean = false
|
||||
@JvmField @Parameter(3) var needsToUnlockFirst: Boolean = false
|
||||
@JvmField @Parameter(4) var startActivity: Boolean = false
|
||||
private lateinit var homeControls: FakeKeyguardQuickAffordanceConfig
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
homeControls = object : FakeKeyguardQuickAffordanceConfig() {}
|
||||
underTest =
|
||||
KeyguardQuickAffordanceInteractor(
|
||||
keyguardInteractor = KeyguardInteractor(repository = FakeKeyguardRepository()),
|
||||
registry =
|
||||
FakeKeyguardQuickAffordanceRegistry(
|
||||
mapOf(
|
||||
KeyguardQuickAffordancePosition.BOTTOM_START to
|
||||
listOf(
|
||||
homeControls,
|
||||
),
|
||||
KeyguardQuickAffordancePosition.BOTTOM_END to
|
||||
listOf(
|
||||
object : FakeKeyguardQuickAffordanceConfig() {},
|
||||
object : FakeKeyguardQuickAffordanceConfig() {},
|
||||
),
|
||||
),
|
||||
),
|
||||
lockPatternUtils = lockPatternUtils,
|
||||
keyguardStateController = keyguardStateController,
|
||||
userTracker = userTracker,
|
||||
activityStarter = activityStarter,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onQuickAffordanceClicked() = runBlockingTest {
|
||||
setUpMocks(
|
||||
needStrongAuthAfterBoot = needStrongAuthAfterBoot,
|
||||
keyguardIsUnlocked = keyguardIsUnlocked,
|
||||
)
|
||||
|
||||
homeControls.setState(
|
||||
state =
|
||||
KeyguardQuickAffordanceConfig.State.Visible(
|
||||
icon = DRAWABLE,
|
||||
contentDescriptionResourceId = CONTENT_DESCRIPTION_RESOURCE_ID,
|
||||
)
|
||||
)
|
||||
homeControls.onClickedResult =
|
||||
if (startActivity) {
|
||||
KeyguardQuickAffordanceConfig.OnClickedResult.StartActivity(
|
||||
intent = INTENT,
|
||||
canShowWhileLocked = canShowWhileLocked,
|
||||
)
|
||||
} else {
|
||||
KeyguardQuickAffordanceConfig.OnClickedResult.Handled
|
||||
}
|
||||
|
||||
underTest.onQuickAffordanceClicked(
|
||||
configKey = homeControls::class,
|
||||
animationController = animationController,
|
||||
)
|
||||
|
||||
if (startActivity) {
|
||||
if (needsToUnlockFirst) {
|
||||
verify(activityStarter)
|
||||
.postStartActivityDismissingKeyguard(
|
||||
any(),
|
||||
/* delay= */ eq(0),
|
||||
same(animationController),
|
||||
)
|
||||
} else {
|
||||
verify(activityStarter)
|
||||
.startActivity(
|
||||
any(),
|
||||
/* dismissShade= */ eq(true),
|
||||
same(animationController),
|
||||
/* showOverLockscreenWhenLocked= */ eq(true),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
verifyZeroInteractions(activityStarter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpMocks(
|
||||
needStrongAuthAfterBoot: Boolean = true,
|
||||
keyguardIsUnlocked: Boolean = false,
|
||||
) {
|
||||
whenever(userTracker.userHandle).thenReturn(mock())
|
||||
whenever(lockPatternUtils.getStrongAuthForUser(any()))
|
||||
.thenReturn(
|
||||
if (needStrongAuthAfterBoot) {
|
||||
LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|
||||
} else {
|
||||
LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
|
||||
}
|
||||
)
|
||||
whenever(keyguardStateController.isUnlocked).thenReturn(keyguardIsUnlocked)
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,20 @@
|
||||
package com.android.systemui.keyguard.domain.usecase
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
@@ -34,33 +40,39 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(JUnit4::class)
|
||||
class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var underTest: ObserveKeyguardQuickAffordanceUseCase
|
||||
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock private lateinit var userTracker: UserTracker
|
||||
@Mock private lateinit var activityStarter: ActivityStarter
|
||||
|
||||
private lateinit var underTest: KeyguardQuickAffordanceInteractor
|
||||
|
||||
private lateinit var repository: FakeKeyguardRepository
|
||||
private lateinit var isDozingUseCase: ObserveIsDozingUseCase
|
||||
private lateinit var isKeyguardShowingUseCase: ObserveIsKeyguardShowingUseCase
|
||||
private lateinit var homeControls: FakeKeyguardQuickAffordanceConfig
|
||||
private lateinit var quickAccessWallet: FakeKeyguardQuickAffordanceConfig
|
||||
private lateinit var qrCodeScanner: FakeKeyguardQuickAffordanceConfig
|
||||
|
||||
@Before
|
||||
fun setUp() = runBlockingTest {
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
repository = FakeKeyguardRepository()
|
||||
repository.setKeyguardShowing(true)
|
||||
isDozingUseCase = ObserveIsDozingUseCase(repository)
|
||||
isKeyguardShowingUseCase = ObserveIsKeyguardShowingUseCase(repository)
|
||||
|
||||
homeControls = object : FakeKeyguardQuickAffordanceConfig() {}
|
||||
quickAccessWallet = object : FakeKeyguardQuickAffordanceConfig() {}
|
||||
qrCodeScanner = object : FakeKeyguardQuickAffordanceConfig() {}
|
||||
|
||||
underTest =
|
||||
ObserveKeyguardQuickAffordanceUseCaseImpl(
|
||||
KeyguardQuickAffordanceInteractor(
|
||||
keyguardInteractor = KeyguardInteractor(repository = repository),
|
||||
registry =
|
||||
FakeKeyguardQuickAffordanceRegistry(
|
||||
mapOf(
|
||||
@@ -75,13 +87,15 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
),
|
||||
),
|
||||
),
|
||||
isDozingUseCase = isDozingUseCase,
|
||||
isKeyguardShowingUseCase = isKeyguardShowingUseCase,
|
||||
lockPatternUtils = lockPatternUtils,
|
||||
keyguardStateController = keyguardStateController,
|
||||
userTracker = userTracker,
|
||||
activityStarter = activityStarter,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke - bottom start affordance is visible`() = runBlockingTest {
|
||||
fun `quickAffordance - bottom start affordance is visible`() = runBlockingTest {
|
||||
val configKey = homeControls::class
|
||||
homeControls.setState(
|
||||
KeyguardQuickAffordanceConfig.State.Visible(
|
||||
@@ -92,7 +106,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
underTest
|
||||
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
|
||||
@@ -106,7 +121,7 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke - bottom end affordance is visible`() = runBlockingTest {
|
||||
fun `quickAffordance - bottom end affordance is visible`() = runBlockingTest {
|
||||
val configKey = quickAccessWallet::class
|
||||
quickAccessWallet.setState(
|
||||
KeyguardQuickAffordanceConfig.State.Visible(
|
||||
@@ -117,7 +132,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
underTest
|
||||
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
|
||||
@@ -131,7 +147,7 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke - bottom start affordance hidden while dozing`() = runBlockingTest {
|
||||
fun `quickAffordance - bottom start affordance hidden while dozing`() = runBlockingTest {
|
||||
repository.setDozing(true)
|
||||
homeControls.setState(
|
||||
KeyguardQuickAffordanceConfig.State.Visible(
|
||||
@@ -142,7 +158,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
underTest
|
||||
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
||||
@@ -150,7 +167,7 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invoke - bottom start affordance hidden when lockscreen is not showing`() =
|
||||
fun `quickAffordance - bottom start affordance hidden when lockscreen is not showing`() =
|
||||
runBlockingTest {
|
||||
repository.setKeyguardShowing(false)
|
||||
homeControls.setState(
|
||||
@@ -162,7 +179,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
|
||||
var latest: KeyguardQuickAffordanceModel? = null
|
||||
val job =
|
||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
underTest
|
||||
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||
.onEach { latest = it }
|
||||
.launchIn(this)
|
||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
||||
@@ -1,178 +0,0 @@
|
||||
/*
|
||||
* 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.keyguard.domain.usecase
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import org.junit.runners.Parameterized.Parameter
|
||||
import org.junit.runners.Parameterized.Parameters
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(Parameterized::class)
|
||||
class LaunchKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
||||
|
||||
companion object {
|
||||
private val INTENT = Intent("some.intent.action")
|
||||
|
||||
@Parameters(
|
||||
name =
|
||||
"needStrongAuthAfterBoot={0}, canShowWhileLocked={1}," +
|
||||
" keyguardIsUnlocked={2}, needsToUnlockFirst={3}"
|
||||
)
|
||||
@JvmStatic
|
||||
fun data() =
|
||||
listOf(
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ false,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ false,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ false,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ false,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
),
|
||||
arrayOf(
|
||||
/* needStrongAuthAfterBoot= */ true,
|
||||
/* canShowWhileLocked= */ true,
|
||||
/* keyguardIsUnlocked= */ true,
|
||||
/* needsToUnlockFirst= */ true,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock private lateinit var userTracker: UserTracker
|
||||
@Mock private lateinit var activityStarter: ActivityStarter
|
||||
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
|
||||
|
||||
private lateinit var underTest: LaunchKeyguardQuickAffordanceUseCase
|
||||
|
||||
@JvmField @Parameter(0) var needStrongAuthAfterBoot: Boolean = false
|
||||
@JvmField @Parameter(1) var canShowWhileLocked: Boolean = false
|
||||
@JvmField @Parameter(2) var keyguardIsUnlocked: Boolean = false
|
||||
@JvmField @Parameter(3) var needsToUnlockFirst: Boolean = false
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
underTest =
|
||||
LaunchKeyguardQuickAffordanceUseCaseImpl(
|
||||
lockPatternUtils = lockPatternUtils,
|
||||
keyguardStateController = keyguardStateController,
|
||||
userTracker = userTracker,
|
||||
activityStarter = activityStarter,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invoke() {
|
||||
setUpMocks(
|
||||
needStrongAuthAfterBoot = needStrongAuthAfterBoot,
|
||||
keyguardIsUnlocked = keyguardIsUnlocked,
|
||||
)
|
||||
|
||||
underTest(
|
||||
intent = INTENT,
|
||||
canShowWhileLocked = canShowWhileLocked,
|
||||
animationController = animationController,
|
||||
)
|
||||
|
||||
if (needsToUnlockFirst) {
|
||||
verify(activityStarter)
|
||||
.postStartActivityDismissingKeyguard(
|
||||
INTENT,
|
||||
/* delay= */ 0,
|
||||
animationController,
|
||||
)
|
||||
} else {
|
||||
verify(activityStarter)
|
||||
.startActivity(
|
||||
INTENT,
|
||||
/* dismissShade= */ true,
|
||||
animationController,
|
||||
/* showOverLockscreenWhenLocked= */ true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpMocks(
|
||||
needStrongAuthAfterBoot: Boolean = true,
|
||||
keyguardIsUnlocked: Boolean = false,
|
||||
) {
|
||||
whenever(userTracker.userHandle).thenReturn(mock())
|
||||
whenever(lockPatternUtils.getStrongAuthForUser(any()))
|
||||
.thenReturn(
|
||||
if (needStrongAuthAfterBoot) {
|
||||
LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT
|
||||
} else {
|
||||
LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED
|
||||
}
|
||||
)
|
||||
whenever(keyguardStateController.isUnlocked).thenReturn(keyguardIsUnlocked)
|
||||
}
|
||||
}
|
||||
@@ -18,24 +18,22 @@ package com.android.systemui.keyguard.ui.viewmodel
|
||||
|
||||
import android.content.Intent
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.widget.LockPatternUtils
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||
import com.android.systemui.doze.util.BurnInHelperWrapper
|
||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
|
||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
|
||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||
import com.android.systemui.keyguard.domain.usecase.FakeLaunchKeyguardQuickAffordanceUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.FakeObserveKeyguardQuickAffordanceUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveAnimateBottomAreaTransitionsUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveBottomAreaAlphaUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveClockPositionUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveDozeAmountUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.ObserveIsDozingUseCase
|
||||
import com.android.systemui.keyguard.domain.usecase.OnKeyguardQuickAffordanceClickedUseCase
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
@@ -49,6 +47,8 @@ import org.junit.runner.RunWith
|
||||
import org.junit.runners.JUnit4
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.verifyZeroInteractions
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@@ -58,17 +58,18 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
|
||||
@Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper
|
||||
@Mock private lateinit var lockPatternUtils: LockPatternUtils
|
||||
@Mock private lateinit var keyguardStateController: KeyguardStateController
|
||||
@Mock private lateinit var userTracker: UserTracker
|
||||
@Mock private lateinit var activityStarter: ActivityStarter
|
||||
|
||||
private lateinit var underTest: KeyguardBottomAreaViewModel
|
||||
|
||||
private lateinit var repository: FakeKeyguardRepository
|
||||
private lateinit var registry: FakeKeyguardQuickAffordanceRegistry
|
||||
private lateinit var isDozingUseCase: ObserveIsDozingUseCase
|
||||
private lateinit var launchQuickAffordanceUseCase: FakeLaunchKeyguardQuickAffordanceUseCase
|
||||
private lateinit var homeControlsQuickAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||
private lateinit var quickAccessWalletAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||
private lateinit var qrCodeScannerAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||
private lateinit var observeQuickAffordanceUseCase: FakeObserveKeyguardQuickAffordanceUseCase
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
@@ -94,57 +95,31 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
),
|
||||
)
|
||||
repository = FakeKeyguardRepository()
|
||||
isDozingUseCase =
|
||||
ObserveIsDozingUseCase(
|
||||
repository = repository,
|
||||
)
|
||||
launchQuickAffordanceUseCase = FakeLaunchKeyguardQuickAffordanceUseCase()
|
||||
observeQuickAffordanceUseCase = FakeObserveKeyguardQuickAffordanceUseCase()
|
||||
|
||||
val keyguardInteractor = KeyguardInteractor(repository = repository)
|
||||
whenever(userTracker.userHandle).thenReturn(mock())
|
||||
whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
|
||||
.thenReturn(LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED)
|
||||
underTest =
|
||||
KeyguardBottomAreaViewModel(
|
||||
observeQuickAffordanceUseCase = observeQuickAffordanceUseCase,
|
||||
onQuickAffordanceClickedUseCase =
|
||||
OnKeyguardQuickAffordanceClickedUseCase(
|
||||
registry =
|
||||
FakeKeyguardQuickAffordanceRegistry(
|
||||
mapOf(
|
||||
KeyguardQuickAffordancePosition.BOTTOM_START to
|
||||
listOf(
|
||||
homeControlsQuickAffordanceConfig,
|
||||
),
|
||||
KeyguardQuickAffordancePosition.BOTTOM_END to
|
||||
listOf(
|
||||
quickAccessWalletAffordanceConfig,
|
||||
qrCodeScannerAffordanceConfig,
|
||||
),
|
||||
),
|
||||
),
|
||||
launchAffordanceUseCase = launchQuickAffordanceUseCase,
|
||||
),
|
||||
observeBottomAreaAlphaUseCase =
|
||||
ObserveBottomAreaAlphaUseCase(
|
||||
repository = repository,
|
||||
),
|
||||
observeIsDozingUseCase = isDozingUseCase,
|
||||
observeAnimateBottomAreaTransitionsUseCase =
|
||||
ObserveAnimateBottomAreaTransitionsUseCase(
|
||||
repository = repository,
|
||||
),
|
||||
observeDozeAmountUseCase =
|
||||
ObserveDozeAmountUseCase(
|
||||
repository = repository,
|
||||
),
|
||||
observeClockPositionUseCase =
|
||||
ObserveClockPositionUseCase(
|
||||
repository = repository,
|
||||
keyguardInteractor = keyguardInteractor,
|
||||
quickAffordanceInteractor =
|
||||
KeyguardQuickAffordanceInteractor(
|
||||
keyguardInteractor = keyguardInteractor,
|
||||
registry = registry,
|
||||
lockPatternUtils = lockPatternUtils,
|
||||
keyguardStateController = keyguardStateController,
|
||||
userTracker = userTracker,
|
||||
activityStarter = activityStarter,
|
||||
),
|
||||
bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
|
||||
burnInHelperWrapper = burnInHelperWrapper,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `startButton - present - visible model - starts activity on click`() = runBlockingTest {
|
||||
repository.setKeyguardShowing(true)
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -171,6 +146,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun `endButton - present - visible model - do nothing on click`() = runBlockingTest {
|
||||
repository.setKeyguardShowing(true)
|
||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||
val job = underTest.endButton.onEach { latest = it }.launchIn(this)
|
||||
|
||||
@@ -357,7 +333,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
private suspend fun setUpQuickAffordanceModel(
|
||||
position: KeyguardQuickAffordancePosition,
|
||||
testConfig: TestConfig,
|
||||
): KClass<*> {
|
||||
): KClass<out FakeKeyguardQuickAffordanceConfig> {
|
||||
val config =
|
||||
when (position) {
|
||||
KeyguardQuickAffordancePosition.BOTTOM_START -> homeControlsQuickAffordanceConfig
|
||||
@@ -381,20 +357,13 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
KeyguardQuickAffordanceConfig.State.Hidden
|
||||
}
|
||||
config.setState(state)
|
||||
|
||||
val configKey = config::class
|
||||
observeQuickAffordanceUseCase.setModel(
|
||||
position,
|
||||
KeyguardQuickAffordanceModel.from(state, configKey)
|
||||
)
|
||||
|
||||
return configKey
|
||||
return config::class
|
||||
}
|
||||
|
||||
private fun assertQuickAffordanceViewModel(
|
||||
viewModel: KeyguardQuickAffordanceViewModel?,
|
||||
testConfig: TestConfig,
|
||||
configKey: KClass<*>,
|
||||
configKey: KClass<out FakeKeyguardQuickAffordanceConfig>,
|
||||
) {
|
||||
checkNotNull(viewModel)
|
||||
assertThat(viewModel.isVisible).isEqualTo(testConfig.isVisible)
|
||||
@@ -406,19 +375,11 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
||||
animationController = animationController,
|
||||
)
|
||||
)
|
||||
testConfig.intent?.let { intent ->
|
||||
assertThat(launchQuickAffordanceUseCase.invocations)
|
||||
.isEqualTo(
|
||||
listOf(
|
||||
FakeLaunchKeyguardQuickAffordanceUseCase.Invocation(
|
||||
intent = intent,
|
||||
canShowWhileLocked = testConfig.canShowWhileLocked,
|
||||
animationController = animationController,
|
||||
)
|
||||
)
|
||||
)
|
||||
if (testConfig.intent != null) {
|
||||
assertThat(Mockito.mockingDetails(activityStarter).invocations).hasSize(1)
|
||||
} else {
|
||||
verifyZeroInteractions(activityStarter)
|
||||
}
|
||||
?: run { assertThat(launchQuickAffordanceUseCase.invocations).isEmpty() }
|
||||
} else {
|
||||
assertThat(viewModel.isVisible).isFalse()
|
||||
}
|
||||
|
||||
@@ -98,9 +98,7 @@ import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.fragments.FragmentHostManager;
|
||||
import com.android.systemui.fragments.FragmentService;
|
||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||
import com.android.systemui.keyguard.domain.usecase.SetClockPositionUseCase;
|
||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAlphaUseCase;
|
||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAnimateDozingTransitionsUseCase;
|
||||
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
|
||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||
import com.android.systemui.media.KeyguardMediaController;
|
||||
import com.android.systemui.media.MediaDataManager;
|
||||
@@ -379,10 +377,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private ViewTreeObserver mViewTreeObserver;
|
||||
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
|
||||
@Mock private SetClockPositionUseCase mSetClockPositionUseCase;
|
||||
@Mock private SetKeyguardBottomAreaAlphaUseCase mSetKeyguardBottomAreaAlphaUseCase;
|
||||
@Mock private SetKeyguardBottomAreaAnimateDozingTransitionsUseCase
|
||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCase;
|
||||
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
|
||||
private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
|
||||
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
|
||||
private SysuiStatusBarStateController mStatusBarStateController;
|
||||
@@ -577,9 +572,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
||||
mSystemClock,
|
||||
mock(CameraGestureHelper.class),
|
||||
() -> mKeyguardBottomAreaViewModel,
|
||||
() -> mSetClockPositionUseCase,
|
||||
() -> mSetKeyguardBottomAreaAlphaUseCase,
|
||||
() -> mSetKeyguardBottomAreaAnimateDozingTransitionsUseCase);
|
||||
() -> mKeyguardBottomAreaInteractor);
|
||||
mNotificationPanelViewController.initDependencies(
|
||||
mCentralSurfaces,
|
||||
() -> {},
|
||||
|
||||
Reference in New Issue
Block a user