Merge "Unifies use-cases into interactors." into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
1f1e80526c
@@ -35,7 +35,7 @@ object ChannelExt {
|
|||||||
* " - downstream canceled or failed.",
|
* " - downstream canceled or failed.",
|
||||||
* it,
|
* it,
|
||||||
* )
|
* )
|
||||||
*}
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
fun <T> SendChannel<T>.trySendWithFailureLogging(
|
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.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.android.systemui.common.data.model
|
package com.android.systemui.common.shared.model
|
||||||
|
|
||||||
/** Models a two-dimensional position */
|
/** Models a two-dimensional position */
|
||||||
data class 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.KeyguardViewMediator;
|
||||||
import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule;
|
import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule;
|
||||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceModule;
|
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.navigationbar.NavigationModeController;
|
||||||
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||||
@@ -73,7 +72,6 @@ import dagger.Provides;
|
|||||||
FalsingModule.class,
|
FalsingModule.class,
|
||||||
KeyguardQuickAffordanceModule.class,
|
KeyguardQuickAffordanceModule.class,
|
||||||
KeyguardRepositoryModule.class,
|
KeyguardRepositoryModule.class,
|
||||||
KeyguardUseCaseModule.class,
|
|
||||||
})
|
})
|
||||||
public class KeyguardModule {
|
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.ChannelExt.trySendWithFailureLogging
|
||||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
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.dagger.SysUISingleton
|
||||||
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
import com.android.systemui.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
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 com.android.systemui.keyguard.data.repository.KeyguardRepository
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use-case for observing whether the keyguard is currently being shown.
|
* Encapsulates business-logic related to the keyguard but not to a more specific part within it.
|
||||||
*
|
|
||||||
* 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").
|
|
||||||
*/
|
*/
|
||||||
class ObserveIsKeyguardShowingUseCase
|
@SysUISingleton
|
||||||
|
class KeyguardInteractor
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
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,
|
@StringRes val contentDescriptionResourceId: Int,
|
||||||
) : KeyguardQuickAffordanceModel()
|
) : 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
|
@Binds
|
||||||
fun keyguardQuickAffordanceRegistry(
|
fun keyguardQuickAffordanceRegistry(
|
||||||
impl: KeyguardQuickAffordanceRegistryImpl
|
impl: KeyguardQuickAffordanceRegistryImpl
|
||||||
): KeyguardQuickAffordanceRegistry
|
): KeyguardQuickAffordanceRegistry<out KeyguardQuickAffordanceConfig>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import javax.inject.Inject
|
|||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/** Central registry of all known quick affordance configs. */
|
/** Central registry of all known quick affordance configs. */
|
||||||
interface KeyguardQuickAffordanceRegistry {
|
interface KeyguardQuickAffordanceRegistry<T : KeyguardQuickAffordanceConfig> {
|
||||||
fun getAll(position: KeyguardQuickAffordancePosition): List<KeyguardQuickAffordanceConfig>
|
fun getAll(position: KeyguardQuickAffordancePosition): List<T>
|
||||||
fun get(configClass: KClass<out KeyguardQuickAffordanceConfig>): KeyguardQuickAffordanceConfig
|
fun get(configClass: KClass<out T>): T
|
||||||
}
|
}
|
||||||
|
|
||||||
class KeyguardQuickAffordanceRegistryImpl
|
class KeyguardQuickAffordanceRegistryImpl
|
||||||
@@ -33,7 +33,7 @@ constructor(
|
|||||||
homeControls: HomeControlsKeyguardQuickAffordanceConfig,
|
homeControls: HomeControlsKeyguardQuickAffordanceConfig,
|
||||||
quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
|
quickAccessWallet: QuickAccessWalletKeyguardQuickAffordanceConfig,
|
||||||
qrCodeScanner: QrCodeScannerKeyguardQuickAffordanceConfig,
|
qrCodeScanner: QrCodeScannerKeyguardQuickAffordanceConfig,
|
||||||
) : KeyguardQuickAffordanceRegistry {
|
) : KeyguardQuickAffordanceRegistry<KeyguardQuickAffordanceConfig> {
|
||||||
private val configsByPosition =
|
private val configsByPosition =
|
||||||
mapOf(
|
mapOf(
|
||||||
KeyguardQuickAffordancePosition.BOTTOM_START to
|
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
|
package com.android.systemui.keyguard.ui.viewmodel
|
||||||
|
|
||||||
import com.android.systemui.doze.util.BurnInHelperWrapper
|
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.KeyguardQuickAffordanceModel
|
||||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
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 javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
@@ -36,13 +32,9 @@ import kotlinx.coroutines.flow.map
|
|||||||
class KeyguardBottomAreaViewModel
|
class KeyguardBottomAreaViewModel
|
||||||
@Inject
|
@Inject
|
||||||
constructor(
|
constructor(
|
||||||
private val observeQuickAffordanceUseCase: ObserveKeyguardQuickAffordanceUseCase,
|
private val keyguardInteractor: KeyguardInteractor,
|
||||||
private val onQuickAffordanceClickedUseCase: OnKeyguardQuickAffordanceClickedUseCase,
|
private val quickAffordanceInteractor: KeyguardQuickAffordanceInteractor,
|
||||||
observeBottomAreaAlphaUseCase: ObserveBottomAreaAlphaUseCase,
|
bottomAreaInteractor: KeyguardBottomAreaInteractor,
|
||||||
observeIsDozingUseCase: ObserveIsDozingUseCase,
|
|
||||||
observeAnimateBottomAreaTransitionsUseCase: ObserveAnimateBottomAreaTransitionsUseCase,
|
|
||||||
private val observeDozeAmountUseCase: ObserveDozeAmountUseCase,
|
|
||||||
observeClockPositionUseCase: ObserveClockPositionUseCase,
|
|
||||||
private val burnInHelperWrapper: BurnInHelperWrapper,
|
private val burnInHelperWrapper: BurnInHelperWrapper,
|
||||||
) {
|
) {
|
||||||
/** An observable for the view-model of the "start button" quick affordance. */
|
/** An observable for the view-model of the "start button" quick affordance. */
|
||||||
@@ -56,12 +48,12 @@ constructor(
|
|||||||
* animate.
|
* animate.
|
||||||
*/
|
*/
|
||||||
val animateButtonReveal: Flow<Boolean> =
|
val animateButtonReveal: Flow<Boolean> =
|
||||||
observeAnimateBottomAreaTransitionsUseCase().distinctUntilChanged()
|
bottomAreaInteractor.animateDozingTransitions.distinctUntilChanged()
|
||||||
/** An observable for whether the overlay container should be visible. */
|
/** An observable for whether the overlay container should be visible. */
|
||||||
val isOverlayContainerVisible: Flow<Boolean> =
|
val isOverlayContainerVisible: Flow<Boolean> =
|
||||||
observeIsDozingUseCase().map { !it }.distinctUntilChanged()
|
keyguardInteractor.isDozing.map { !it }.distinctUntilChanged()
|
||||||
/** An observable for the alpha level for the entire bottom area. */
|
/** 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. */
|
/** An observable for whether the indication area should be padded. */
|
||||||
val isIndicationAreaPadded: Flow<Boolean> =
|
val isIndicationAreaPadded: Flow<Boolean> =
|
||||||
combine(startButton, endButton) { startButtonModel, endButtonModel ->
|
combine(startButton, endButton) { startButtonModel, endButtonModel ->
|
||||||
@@ -70,11 +62,11 @@ constructor(
|
|||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
/** An observable for the x-offset by which the indication area should be translated. */
|
/** An observable for the x-offset by which the indication area should be translated. */
|
||||||
val indicationAreaTranslationX: Flow<Float> =
|
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. */
|
/** Returns an observable for the y-offset by which the indication area should be translated. */
|
||||||
fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> {
|
fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> {
|
||||||
return observeDozeAmountUseCase()
|
return keyguardInteractor.dozeAmount
|
||||||
.map { dozeAmount ->
|
.map { dozeAmount ->
|
||||||
dozeAmount *
|
dozeAmount *
|
||||||
(burnInHelperWrapper.burnInOffset(
|
(burnInHelperWrapper.burnInOffset(
|
||||||
@@ -88,7 +80,8 @@ constructor(
|
|||||||
private fun button(
|
private fun button(
|
||||||
position: KeyguardQuickAffordancePosition
|
position: KeyguardQuickAffordancePosition
|
||||||
): Flow<KeyguardQuickAffordanceViewModel> {
|
): Flow<KeyguardQuickAffordanceViewModel> {
|
||||||
return observeQuickAffordanceUseCase(position)
|
return quickAffordanceInteractor
|
||||||
|
.quickAffordance(position)
|
||||||
.map { model -> model.toViewModel() }
|
.map { model -> model.toViewModel() }
|
||||||
.distinctUntilChanged()
|
.distinctUntilChanged()
|
||||||
}
|
}
|
||||||
@@ -102,7 +95,7 @@ constructor(
|
|||||||
icon = icon,
|
icon = icon,
|
||||||
contentDescriptionResourceId = contentDescriptionResourceId,
|
contentDescriptionResourceId = contentDescriptionResourceId,
|
||||||
onClicked = { parameters ->
|
onClicked = { parameters ->
|
||||||
onQuickAffordanceClickedUseCase(
|
quickAffordanceInteractor.onQuickAffordanceClicked(
|
||||||
configKey = parameters.configKey,
|
configKey = parameters.configKey,
|
||||||
animationController = parameters.animationController,
|
animationController = parameters.animationController,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -19,18 +19,19 @@ package com.android.systemui.keyguard.ui.viewmodel
|
|||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||||
|
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/** Models the UI state of a keyguard quick affordance button. */
|
/** Models the UI state of a keyguard quick affordance button. */
|
||||||
data class KeyguardQuickAffordanceViewModel(
|
data class KeyguardQuickAffordanceViewModel(
|
||||||
val configKey: KClass<*>? = null,
|
val configKey: KClass<out KeyguardQuickAffordanceConfig>? = null,
|
||||||
val isVisible: Boolean = false,
|
val isVisible: Boolean = false,
|
||||||
val icon: ContainedDrawable = ContainedDrawable.WithResource(0),
|
val icon: ContainedDrawable = ContainedDrawable.WithResource(0),
|
||||||
@StringRes val contentDescriptionResourceId: Int = 0,
|
@StringRes val contentDescriptionResourceId: Int = 0,
|
||||||
val onClicked: (OnClickedParameters) -> Unit = {},
|
val onClicked: (OnClickedParameters) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
data class OnClickedParameters(
|
data class OnClickedParameters(
|
||||||
val configKey: KClass<*>,
|
val configKey: KClass<out KeyguardQuickAffordanceConfig>,
|
||||||
val animationController: ActivityLaunchAnimator.Controller?,
|
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.FragmentHostManager.FragmentListener;
|
||||||
import com.android.systemui.fragments.FragmentService;
|
import com.android.systemui.fragments.FragmentService;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.keyguard.domain.usecase.SetClockPositionUseCase;
|
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
|
||||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAlphaUseCase;
|
|
||||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAnimateDozingTransitionsUseCase;
|
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||||
import com.android.systemui.media.KeyguardMediaController;
|
import com.android.systemui.media.KeyguardMediaController;
|
||||||
import com.android.systemui.media.MediaDataManager;
|
import com.android.systemui.media.MediaDataManager;
|
||||||
@@ -705,11 +703,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
|
|
||||||
private final CameraGestureHelper mCameraGestureHelper;
|
private final CameraGestureHelper mCameraGestureHelper;
|
||||||
private final Provider<KeyguardBottomAreaViewModel> mKeyguardBottomAreaViewModelProvider;
|
private final Provider<KeyguardBottomAreaViewModel> mKeyguardBottomAreaViewModelProvider;
|
||||||
private final Provider<SetClockPositionUseCase> mSetClockPositionUseCaseProvider;
|
private final Provider<KeyguardBottomAreaInteractor> mKeyguardBottomAreaInteractorProvider;
|
||||||
private final Provider<SetKeyguardBottomAreaAlphaUseCase>
|
|
||||||
mSetKeyguardBottomAreaAlphaUseCaseProvider;
|
|
||||||
private final Provider<SetKeyguardBottomAreaAnimateDozingTransitionsUseCase>
|
|
||||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public NotificationPanelViewController(NotificationPanelView view,
|
public NotificationPanelViewController(NotificationPanelView view,
|
||||||
@@ -781,10 +775,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
SystemClock systemClock,
|
SystemClock systemClock,
|
||||||
CameraGestureHelper cameraGestureHelper,
|
CameraGestureHelper cameraGestureHelper,
|
||||||
Provider<KeyguardBottomAreaViewModel> keyguardBottomAreaViewModelProvider,
|
Provider<KeyguardBottomAreaViewModel> keyguardBottomAreaViewModelProvider,
|
||||||
Provider<SetClockPositionUseCase> setClockPositionUseCaseProvider,
|
Provider<KeyguardBottomAreaInteractor> keyguardBottomAreaInteractorProvider) {
|
||||||
Provider<SetKeyguardBottomAreaAlphaUseCase> setKeyguardBottomAreaAlphaUseCaseProvider,
|
|
||||||
Provider<SetKeyguardBottomAreaAnimateDozingTransitionsUseCase>
|
|
||||||
setKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider) {
|
|
||||||
super(view,
|
super(view,
|
||||||
falsingManager,
|
falsingManager,
|
||||||
dozeLog,
|
dozeLog,
|
||||||
@@ -966,10 +957,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
mCameraGestureHelper = cameraGestureHelper;
|
mCameraGestureHelper = cameraGestureHelper;
|
||||||
mSetClockPositionUseCaseProvider = setClockPositionUseCaseProvider;
|
mKeyguardBottomAreaInteractorProvider = keyguardBottomAreaInteractorProvider;
|
||||||
mSetKeyguardBottomAreaAlphaUseCaseProvider = setKeyguardBottomAreaAlphaUseCaseProvider;
|
|
||||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider =
|
|
||||||
setKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -1487,7 +1475,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
mKeyguardStatusViewController.getClockBottom(mStatusBarHeaderHeightKeyguard),
|
mKeyguardStatusViewController.getClockBottom(mStatusBarHeaderHeightKeyguard),
|
||||||
mKeyguardStatusViewController.isClockTopAligned());
|
mKeyguardStatusViewController.isClockTopAligned());
|
||||||
mClockPositionAlgorithm.run(mClockPositionResult);
|
mClockPositionAlgorithm.run(mClockPositionResult);
|
||||||
mSetClockPositionUseCaseProvider.get().invoke(
|
mKeyguardBottomAreaInteractorProvider.get().setClockPosition(
|
||||||
mClockPositionResult.clockX, mClockPositionResult.clockY);
|
mClockPositionResult.clockX, mClockPositionResult.clockY);
|
||||||
boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
|
boolean animate = mNotificationStackScrollLayoutController.isAddOrRemoveAnimationPending();
|
||||||
boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange;
|
boolean animateClock = (animate || mAnimateNextPositionUpdate) && shouldAnimateClockChange;
|
||||||
@@ -3261,7 +3249,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction());
|
float alpha = Math.min(expansionAlpha, 1 - computeQsExpansionFraction());
|
||||||
alpha *= mBottomAreaShadeAlpha;
|
alpha *= mBottomAreaShadeAlpha;
|
||||||
mKeyguardBottomArea.setComponentAlphas(alpha);
|
mKeyguardBottomArea.setComponentAlphas(alpha);
|
||||||
mSetKeyguardBottomAreaAlphaUseCaseProvider.get().invoke(alpha);
|
mKeyguardBottomAreaInteractorProvider.get().setAlpha(alpha);
|
||||||
mLockIconViewController.setAlpha(alpha);
|
mLockIconViewController.setAlpha(alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3461,7 +3449,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
|
|
||||||
private void updateDozingVisibilities(boolean animate) {
|
private void updateDozingVisibilities(boolean animate) {
|
||||||
mKeyguardBottomArea.setDozing(mDozing, animate);
|
mKeyguardBottomArea.setDozing(mDozing, animate);
|
||||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider.get().invoke(animate);
|
mKeyguardBottomAreaInteractorProvider.get().setAnimateDozingTransitions(animate);
|
||||||
if (!mDozing && animate) {
|
if (!mDozing && animate) {
|
||||||
mKeyguardStatusBarViewController.animateKeyguardStatusBarIn();
|
mKeyguardStatusBarViewController.animateKeyguardStatusBarIn();
|
||||||
}
|
}
|
||||||
@@ -3764,7 +3752,7 @@ public final class NotificationPanelViewController extends PanelViewController {
|
|||||||
mDozing = dozing;
|
mDozing = dozing;
|
||||||
mNotificationStackScrollLayoutController.setDozing(mDozing, animate, wakeUpTouchLocation);
|
mNotificationStackScrollLayoutController.setDozing(mDozing, animate, wakeUpTouchLocation);
|
||||||
mKeyguardBottomArea.setDozing(mDozing, animate);
|
mKeyguardBottomArea.setDozing(mDozing, animate);
|
||||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCaseProvider.get().invoke(animate);
|
mKeyguardBottomAreaInteractorProvider.get().setAnimateDozingTransitions(animate);
|
||||||
mKeyguardStatusBarViewController.setDozing(mDozing);
|
mKeyguardStatusBarViewController.setDozing(mDozing);
|
||||||
|
|
||||||
if (dozing) {
|
if (dozing) {
|
||||||
|
|||||||
@@ -16,11 +16,10 @@
|
|||||||
|
|
||||||
package com.android.systemui.keyguard.data.repository
|
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.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.yield
|
|
||||||
|
|
||||||
/** Fake implementation of [KeyguardRepository] */
|
/** Fake implementation of [KeyguardRepository] */
|
||||||
class FakeKeyguardRepository : KeyguardRepository {
|
class FakeKeyguardRepository : KeyguardRepository {
|
||||||
@@ -56,30 +55,15 @@ class FakeKeyguardRepository : KeyguardRepository {
|
|||||||
_clockPosition.value = Position(x, y)
|
_clockPosition.value = Position(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun setKeyguardShowing(isShowing: Boolean) {
|
fun setKeyguardShowing(isShowing: Boolean) {
|
||||||
_isKeyguardShowing.value = isShowing
|
_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
|
_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
|
_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 androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
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.plugins.statusbar.StatusBarStateController
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
import com.android.systemui.util.mockito.argumentCaptor
|
import com.android.systemui.util.mockito.argumentCaptor
|
||||||
|
|||||||
@@ -23,18 +23,18 @@ import kotlin.reflect.KClass
|
|||||||
/** Fake implementation of [FakeKeyguardQuickAffordanceRegistry], for tests. */
|
/** Fake implementation of [FakeKeyguardQuickAffordanceRegistry], for tests. */
|
||||||
class FakeKeyguardQuickAffordanceRegistry(
|
class FakeKeyguardQuickAffordanceRegistry(
|
||||||
private val configsByPosition:
|
private val configsByPosition:
|
||||||
Map<KeyguardQuickAffordancePosition, List<KeyguardQuickAffordanceConfig>>,
|
Map<KeyguardQuickAffordancePosition, List<FakeKeyguardQuickAffordanceConfig>>,
|
||||||
) : KeyguardQuickAffordanceRegistry {
|
) : KeyguardQuickAffordanceRegistry<FakeKeyguardQuickAffordanceConfig> {
|
||||||
|
|
||||||
override fun getAll(
|
override fun getAll(
|
||||||
position: KeyguardQuickAffordancePosition
|
position: KeyguardQuickAffordancePosition
|
||||||
): List<KeyguardQuickAffordanceConfig> {
|
): List<FakeKeyguardQuickAffordanceConfig> {
|
||||||
return configsByPosition.getValue(position)
|
return configsByPosition.getValue(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get(
|
override fun get(
|
||||||
configClass: KClass<out KeyguardQuickAffordanceConfig>
|
configClass: KClass<out FakeKeyguardQuickAffordanceConfig>
|
||||||
): KeyguardQuickAffordanceConfig {
|
): FakeKeyguardQuickAffordanceConfig {
|
||||||
return configsByPosition.values
|
return configsByPosition.values
|
||||||
.flatten()
|
.flatten()
|
||||||
.associateBy { config -> config::class }
|
.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
|
package com.android.systemui.keyguard.domain.usecase
|
||||||
|
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.internal.widget.LockPatternUtils
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
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.KeyguardQuickAffordanceModel
|
||||||
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
|
||||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
|
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
|
||||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
|
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
|
||||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
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.android.systemui.util.mockito.mock
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
@@ -34,33 +40,39 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.junit.runners.JUnit4
|
import org.junit.runners.JUnit4
|
||||||
|
import org.mockito.Mock
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(JUnit4::class)
|
@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 repository: FakeKeyguardRepository
|
||||||
private lateinit var isDozingUseCase: ObserveIsDozingUseCase
|
|
||||||
private lateinit var isKeyguardShowingUseCase: ObserveIsKeyguardShowingUseCase
|
|
||||||
private lateinit var homeControls: FakeKeyguardQuickAffordanceConfig
|
private lateinit var homeControls: FakeKeyguardQuickAffordanceConfig
|
||||||
private lateinit var quickAccessWallet: FakeKeyguardQuickAffordanceConfig
|
private lateinit var quickAccessWallet: FakeKeyguardQuickAffordanceConfig
|
||||||
private lateinit var qrCodeScanner: FakeKeyguardQuickAffordanceConfig
|
private lateinit var qrCodeScanner: FakeKeyguardQuickAffordanceConfig
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() = runBlockingTest {
|
fun setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this)
|
||||||
|
|
||||||
repository = FakeKeyguardRepository()
|
repository = FakeKeyguardRepository()
|
||||||
repository.setKeyguardShowing(true)
|
repository.setKeyguardShowing(true)
|
||||||
isDozingUseCase = ObserveIsDozingUseCase(repository)
|
|
||||||
isKeyguardShowingUseCase = ObserveIsKeyguardShowingUseCase(repository)
|
|
||||||
|
|
||||||
homeControls = object : FakeKeyguardQuickAffordanceConfig() {}
|
homeControls = object : FakeKeyguardQuickAffordanceConfig() {}
|
||||||
quickAccessWallet = object : FakeKeyguardQuickAffordanceConfig() {}
|
quickAccessWallet = object : FakeKeyguardQuickAffordanceConfig() {}
|
||||||
qrCodeScanner = object : FakeKeyguardQuickAffordanceConfig() {}
|
qrCodeScanner = object : FakeKeyguardQuickAffordanceConfig() {}
|
||||||
|
|
||||||
underTest =
|
underTest =
|
||||||
ObserveKeyguardQuickAffordanceUseCaseImpl(
|
KeyguardQuickAffordanceInteractor(
|
||||||
|
keyguardInteractor = KeyguardInteractor(repository = repository),
|
||||||
registry =
|
registry =
|
||||||
FakeKeyguardQuickAffordanceRegistry(
|
FakeKeyguardQuickAffordanceRegistry(
|
||||||
mapOf(
|
mapOf(
|
||||||
@@ -75,13 +87,15 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
isDozingUseCase = isDozingUseCase,
|
lockPatternUtils = lockPatternUtils,
|
||||||
isKeyguardShowingUseCase = isKeyguardShowingUseCase,
|
keyguardStateController = keyguardStateController,
|
||||||
|
userTracker = userTracker,
|
||||||
|
activityStarter = activityStarter,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `invoke - bottom start affordance is visible`() = runBlockingTest {
|
fun `quickAffordance - bottom start affordance is visible`() = runBlockingTest {
|
||||||
val configKey = homeControls::class
|
val configKey = homeControls::class
|
||||||
homeControls.setState(
|
homeControls.setState(
|
||||||
KeyguardQuickAffordanceConfig.State.Visible(
|
KeyguardQuickAffordanceConfig.State.Visible(
|
||||||
@@ -92,7 +106,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
|
|
||||||
var latest: KeyguardQuickAffordanceModel? = null
|
var latest: KeyguardQuickAffordanceModel? = null
|
||||||
val job =
|
val job =
|
||||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
underTest
|
||||||
|
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||||
.onEach { latest = it }
|
.onEach { latest = it }
|
||||||
.launchIn(this)
|
.launchIn(this)
|
||||||
|
|
||||||
@@ -106,7 +121,7 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `invoke - bottom end affordance is visible`() = runBlockingTest {
|
fun `quickAffordance - bottom end affordance is visible`() = runBlockingTest {
|
||||||
val configKey = quickAccessWallet::class
|
val configKey = quickAccessWallet::class
|
||||||
quickAccessWallet.setState(
|
quickAccessWallet.setState(
|
||||||
KeyguardQuickAffordanceConfig.State.Visible(
|
KeyguardQuickAffordanceConfig.State.Visible(
|
||||||
@@ -117,7 +132,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
|
|
||||||
var latest: KeyguardQuickAffordanceModel? = null
|
var latest: KeyguardQuickAffordanceModel? = null
|
||||||
val job =
|
val job =
|
||||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_END)
|
underTest
|
||||||
|
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_END)
|
||||||
.onEach { latest = it }
|
.onEach { latest = it }
|
||||||
.launchIn(this)
|
.launchIn(this)
|
||||||
|
|
||||||
@@ -131,7 +147,7 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `invoke - bottom start affordance hidden while dozing`() = runBlockingTest {
|
fun `quickAffordance - bottom start affordance hidden while dozing`() = runBlockingTest {
|
||||||
repository.setDozing(true)
|
repository.setDozing(true)
|
||||||
homeControls.setState(
|
homeControls.setState(
|
||||||
KeyguardQuickAffordanceConfig.State.Visible(
|
KeyguardQuickAffordanceConfig.State.Visible(
|
||||||
@@ -142,7 +158,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
|
|
||||||
var latest: KeyguardQuickAffordanceModel? = null
|
var latest: KeyguardQuickAffordanceModel? = null
|
||||||
val job =
|
val job =
|
||||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
underTest
|
||||||
|
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||||
.onEach { latest = it }
|
.onEach { latest = it }
|
||||||
.launchIn(this)
|
.launchIn(this)
|
||||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
||||||
@@ -150,7 +167,7 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `invoke - bottom start affordance hidden when lockscreen is not showing`() =
|
fun `quickAffordance - bottom start affordance hidden when lockscreen is not showing`() =
|
||||||
runBlockingTest {
|
runBlockingTest {
|
||||||
repository.setKeyguardShowing(false)
|
repository.setKeyguardShowing(false)
|
||||||
homeControls.setState(
|
homeControls.setState(
|
||||||
@@ -162,7 +179,8 @@ class ObserveKeyguardQuickAffordanceUseCaseImplTest : SysuiTestCase() {
|
|||||||
|
|
||||||
var latest: KeyguardQuickAffordanceModel? = null
|
var latest: KeyguardQuickAffordanceModel? = null
|
||||||
val job =
|
val job =
|
||||||
underTest(KeyguardQuickAffordancePosition.BOTTOM_START)
|
underTest
|
||||||
|
.quickAffordance(KeyguardQuickAffordancePosition.BOTTOM_START)
|
||||||
.onEach { latest = it }
|
.onEach { latest = it }
|
||||||
.launchIn(this)
|
.launchIn(this)
|
||||||
assertThat(latest).isEqualTo(KeyguardQuickAffordanceModel.Hidden)
|
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 android.content.Intent
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.internal.widget.LockPatternUtils
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.animation.ActivityLaunchAnimator
|
import com.android.systemui.animation.ActivityLaunchAnimator
|
||||||
import com.android.systemui.containeddrawable.ContainedDrawable
|
import com.android.systemui.containeddrawable.ContainedDrawable
|
||||||
import com.android.systemui.doze.util.BurnInHelperWrapper
|
import com.android.systemui.doze.util.BurnInHelperWrapper
|
||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
|
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.model.KeyguardQuickAffordancePosition
|
||||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
|
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
|
||||||
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
|
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
|
||||||
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
|
||||||
import com.android.systemui.keyguard.domain.usecase.FakeLaunchKeyguardQuickAffordanceUseCase
|
import com.android.systemui.plugins.ActivityStarter
|
||||||
import com.android.systemui.keyguard.domain.usecase.FakeObserveKeyguardQuickAffordanceUseCase
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.keyguard.domain.usecase.ObserveAnimateBottomAreaTransitionsUseCase
|
import com.android.systemui.statusbar.policy.KeyguardStateController
|
||||||
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.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
import com.android.systemui.util.mockito.mock
|
import com.android.systemui.util.mockito.mock
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
@@ -49,6 +47,8 @@ import org.junit.runner.RunWith
|
|||||||
import org.junit.runners.JUnit4
|
import org.junit.runners.JUnit4
|
||||||
import org.mockito.ArgumentMatchers.anyInt
|
import org.mockito.ArgumentMatchers.anyInt
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito
|
||||||
|
import org.mockito.Mockito.verifyZeroInteractions
|
||||||
import org.mockito.Mockito.`when` as whenever
|
import org.mockito.Mockito.`when` as whenever
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
@@ -58,17 +58,18 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
|
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
|
||||||
@Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper
|
@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 underTest: KeyguardBottomAreaViewModel
|
||||||
|
|
||||||
private lateinit var repository: FakeKeyguardRepository
|
private lateinit var repository: FakeKeyguardRepository
|
||||||
private lateinit var registry: FakeKeyguardQuickAffordanceRegistry
|
private lateinit var registry: FakeKeyguardQuickAffordanceRegistry
|
||||||
private lateinit var isDozingUseCase: ObserveIsDozingUseCase
|
|
||||||
private lateinit var launchQuickAffordanceUseCase: FakeLaunchKeyguardQuickAffordanceUseCase
|
|
||||||
private lateinit var homeControlsQuickAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
private lateinit var homeControlsQuickAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||||
private lateinit var quickAccessWalletAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
private lateinit var quickAccessWalletAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||||
private lateinit var qrCodeScannerAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
private lateinit var qrCodeScannerAffordanceConfig: FakeKeyguardQuickAffordanceConfig
|
||||||
private lateinit var observeQuickAffordanceUseCase: FakeObserveKeyguardQuickAffordanceUseCase
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
@@ -94,57 +95,31 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
repository = FakeKeyguardRepository()
|
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 =
|
underTest =
|
||||||
KeyguardBottomAreaViewModel(
|
KeyguardBottomAreaViewModel(
|
||||||
observeQuickAffordanceUseCase = observeQuickAffordanceUseCase,
|
keyguardInteractor = keyguardInteractor,
|
||||||
onQuickAffordanceClickedUseCase =
|
quickAffordanceInteractor =
|
||||||
OnKeyguardQuickAffordanceClickedUseCase(
|
KeyguardQuickAffordanceInteractor(
|
||||||
registry =
|
keyguardInteractor = keyguardInteractor,
|
||||||
FakeKeyguardQuickAffordanceRegistry(
|
registry = registry,
|
||||||
mapOf(
|
lockPatternUtils = lockPatternUtils,
|
||||||
KeyguardQuickAffordancePosition.BOTTOM_START to
|
keyguardStateController = keyguardStateController,
|
||||||
listOf(
|
userTracker = userTracker,
|
||||||
homeControlsQuickAffordanceConfig,
|
activityStarter = activityStarter,
|
||||||
),
|
|
||||||
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,
|
|
||||||
),
|
),
|
||||||
|
bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
|
||||||
burnInHelperWrapper = burnInHelperWrapper,
|
burnInHelperWrapper = burnInHelperWrapper,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `startButton - present - visible model - starts activity on click`() = runBlockingTest {
|
fun `startButton - present - visible model - starts activity on click`() = runBlockingTest {
|
||||||
|
repository.setKeyguardShowing(true)
|
||||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||||
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
val job = underTest.startButton.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
@@ -171,6 +146,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `endButton - present - visible model - do nothing on click`() = runBlockingTest {
|
fun `endButton - present - visible model - do nothing on click`() = runBlockingTest {
|
||||||
|
repository.setKeyguardShowing(true)
|
||||||
var latest: KeyguardQuickAffordanceViewModel? = null
|
var latest: KeyguardQuickAffordanceViewModel? = null
|
||||||
val job = underTest.endButton.onEach { latest = it }.launchIn(this)
|
val job = underTest.endButton.onEach { latest = it }.launchIn(this)
|
||||||
|
|
||||||
@@ -357,7 +333,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
private suspend fun setUpQuickAffordanceModel(
|
private suspend fun setUpQuickAffordanceModel(
|
||||||
position: KeyguardQuickAffordancePosition,
|
position: KeyguardQuickAffordancePosition,
|
||||||
testConfig: TestConfig,
|
testConfig: TestConfig,
|
||||||
): KClass<*> {
|
): KClass<out FakeKeyguardQuickAffordanceConfig> {
|
||||||
val config =
|
val config =
|
||||||
when (position) {
|
when (position) {
|
||||||
KeyguardQuickAffordancePosition.BOTTOM_START -> homeControlsQuickAffordanceConfig
|
KeyguardQuickAffordancePosition.BOTTOM_START -> homeControlsQuickAffordanceConfig
|
||||||
@@ -381,20 +357,13 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
KeyguardQuickAffordanceConfig.State.Hidden
|
KeyguardQuickAffordanceConfig.State.Hidden
|
||||||
}
|
}
|
||||||
config.setState(state)
|
config.setState(state)
|
||||||
|
return config::class
|
||||||
val configKey = config::class
|
|
||||||
observeQuickAffordanceUseCase.setModel(
|
|
||||||
position,
|
|
||||||
KeyguardQuickAffordanceModel.from(state, configKey)
|
|
||||||
)
|
|
||||||
|
|
||||||
return configKey
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assertQuickAffordanceViewModel(
|
private fun assertQuickAffordanceViewModel(
|
||||||
viewModel: KeyguardQuickAffordanceViewModel?,
|
viewModel: KeyguardQuickAffordanceViewModel?,
|
||||||
testConfig: TestConfig,
|
testConfig: TestConfig,
|
||||||
configKey: KClass<*>,
|
configKey: KClass<out FakeKeyguardQuickAffordanceConfig>,
|
||||||
) {
|
) {
|
||||||
checkNotNull(viewModel)
|
checkNotNull(viewModel)
|
||||||
assertThat(viewModel.isVisible).isEqualTo(testConfig.isVisible)
|
assertThat(viewModel.isVisible).isEqualTo(testConfig.isVisible)
|
||||||
@@ -406,19 +375,11 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
|
|||||||
animationController = animationController,
|
animationController = animationController,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
testConfig.intent?.let { intent ->
|
if (testConfig.intent != null) {
|
||||||
assertThat(launchQuickAffordanceUseCase.invocations)
|
assertThat(Mockito.mockingDetails(activityStarter).invocations).hasSize(1)
|
||||||
.isEqualTo(
|
} else {
|
||||||
listOf(
|
verifyZeroInteractions(activityStarter)
|
||||||
FakeLaunchKeyguardQuickAffordanceUseCase.Invocation(
|
|
||||||
intent = intent,
|
|
||||||
canShowWhileLocked = testConfig.canShowWhileLocked,
|
|
||||||
animationController = animationController,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
?: run { assertThat(launchQuickAffordanceUseCase.invocations).isEmpty() }
|
|
||||||
} else {
|
} else {
|
||||||
assertThat(viewModel.isVisible).isFalse()
|
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.FragmentHostManager;
|
||||||
import com.android.systemui.fragments.FragmentService;
|
import com.android.systemui.fragments.FragmentService;
|
||||||
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
|
||||||
import com.android.systemui.keyguard.domain.usecase.SetClockPositionUseCase;
|
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
|
||||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAlphaUseCase;
|
|
||||||
import com.android.systemui.keyguard.domain.usecase.SetKeyguardBottomAreaAnimateDozingTransitionsUseCase;
|
|
||||||
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
|
||||||
import com.android.systemui.media.KeyguardMediaController;
|
import com.android.systemui.media.KeyguardMediaController;
|
||||||
import com.android.systemui.media.MediaDataManager;
|
import com.android.systemui.media.MediaDataManager;
|
||||||
@@ -379,10 +377,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
@Mock
|
@Mock
|
||||||
private ViewTreeObserver mViewTreeObserver;
|
private ViewTreeObserver mViewTreeObserver;
|
||||||
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
|
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
|
||||||
@Mock private SetClockPositionUseCase mSetClockPositionUseCase;
|
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
|
||||||
@Mock private SetKeyguardBottomAreaAlphaUseCase mSetKeyguardBottomAreaAlphaUseCase;
|
|
||||||
@Mock private SetKeyguardBottomAreaAnimateDozingTransitionsUseCase
|
|
||||||
mSetKeyguardBottomAreaAnimateDozingTransitionsUseCase;
|
|
||||||
private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
|
private NotificationPanelViewController.PanelEventsEmitter mPanelEventsEmitter;
|
||||||
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
|
private Optional<SysUIUnfoldComponent> mSysUIUnfoldComponent = Optional.empty();
|
||||||
private SysuiStatusBarStateController mStatusBarStateController;
|
private SysuiStatusBarStateController mStatusBarStateController;
|
||||||
@@ -577,9 +572,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
|
|||||||
mSystemClock,
|
mSystemClock,
|
||||||
mock(CameraGestureHelper.class),
|
mock(CameraGestureHelper.class),
|
||||||
() -> mKeyguardBottomAreaViewModel,
|
() -> mKeyguardBottomAreaViewModel,
|
||||||
() -> mSetClockPositionUseCase,
|
() -> mKeyguardBottomAreaInteractor);
|
||||||
() -> mSetKeyguardBottomAreaAlphaUseCase,
|
|
||||||
() -> mSetKeyguardBottomAreaAnimateDozingTransitionsUseCase);
|
|
||||||
mNotificationPanelViewController.initDependencies(
|
mNotificationPanelViewController.initDependencies(
|
||||||
mCentralSurfaces,
|
mCentralSurfaces,
|
||||||
() -> {},
|
() -> {},
|
||||||
|
|||||||
Reference in New Issue
Block a user