Merge "Keyguard - Migrate indication area" into udc-qpr-dev

This commit is contained in:
Matt Pietal
2023-05-30 15:06:27 +00:00
committed by Android (Google) Code Review
36 changed files with 842 additions and 339 deletions

View File

@@ -23,7 +23,7 @@
android:outlineProvider="none" > android:outlineProvider="none" >
<LinearLayout <LinearLayout
android:id="@+id/keyguard_indication_area" android:id="@id/keyguard_indication_area"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom" android:layout_marginBottom="@dimen/keyguard_indication_margin_bottom"
@@ -31,7 +31,7 @@
android:orientation="vertical"> android:orientation="vertical">
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
android:id="@+id/keyguard_indication_text" android:id="@id/keyguard_indication_text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
@@ -41,13 +41,12 @@
android:accessibilityLiveRegion="polite"/> android:accessibilityLiveRegion="polite"/>
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView <com.android.systemui.statusbar.phone.KeyguardIndicationTextView
android:id="@+id/keyguard_indication_text_bottom" android:id="@id/keyguard_indication_text_bottom"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
android:minHeight="48dp" android:minHeight="@dimen/keyguard_indication_text_min_height"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_centerHorizontal="true"
android:paddingStart="@dimen/keyguard_indication_text_padding" android:paddingStart="@dimen/keyguard_indication_text_padding"
android:paddingEnd="@dimen/keyguard_indication_text_padding" android:paddingEnd="@dimen/keyguard_indication_text_padding"
android:textAppearance="@style/TextAppearance.Keyguard.BottomArea" android:textAppearance="@style/TextAppearance.Keyguard.BottomArea"

View File

@@ -70,6 +70,12 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:visibility="invisible" /> android:visibility="invisible" />
<!-- Root for all keyguard content. It was previously located within the shade. -->
<com.android.systemui.keyguard.ui.view.KeyguardRootView
android:id="@id/keyguard_root_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<include layout="@layout/brightness_mirror_container" /> <include layout="@layout/brightness_mirror_container" />
<com.android.systemui.scrim.ScrimView <com.android.systemui.scrim.ScrimView

View File

@@ -275,6 +275,9 @@
<!-- The padding at start and end of indication text shown on AOD --> <!-- The padding at start and end of indication text shown on AOD -->
<dimen name="keyguard_indication_text_padding">16dp</dimen> <dimen name="keyguard_indication_text_padding">16dp</dimen>
<!-- The min height on the indication text shown on AOD -->
<dimen name="keyguard_indication_text_min_height">48dp</dimen>
<!-- Shadows under the clock, date and other keyguard text fields --> <!-- Shadows under the clock, date and other keyguard text fields -->
<dimen name="keyguard_shadow_radius">5</dimen> <dimen name="keyguard_shadow_radius">5</dimen>

View File

@@ -206,5 +206,9 @@
<!-- keyboard backlight indicator--> <!-- keyboard backlight indicator-->
<item type="id" name="backlight_icon" /> <item type="id" name="backlight_icon" />
</resources>
<item type="id" name="keyguard_root_view" />
<item type="id" name="keyguard_indication_area" />
<item type="id" name="keyguard_indication_text" />
<item type="id" name="keyguard_indication_text_bottom" />
</resources>

View File

@@ -34,6 +34,7 @@ import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.keyboard.KeyboardUI import com.android.systemui.keyboard.KeyboardUI
import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable
import com.android.systemui.keyguard.KeyguardViewMediator import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.KeyguardViewConfigurator
import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable import com.android.systemui.keyguard.data.quickaffordance.MuteQuickAffordanceCoreStartable
import com.android.systemui.log.SessionTracker import com.android.systemui.log.SessionTracker
import com.android.systemui.media.RingtonePlayer import com.android.systemui.media.RingtonePlayer
@@ -295,4 +296,9 @@ abstract class SystemUICoreStartableModule {
@IntoMap @IntoMap
@ClassKey(AssistantAttentionMonitor::class) @ClassKey(AssistantAttentionMonitor::class)
abstract fun bindAssistantAttentionMonitor(sysui: AssistantAttentionMonitor): CoreStartable abstract fun bindAssistantAttentionMonitor(sysui: AssistantAttentionMonitor): CoreStartable
@Binds
@IntoMap
@ClassKey(KeyguardViewConfigurator::class)
abstract fun bindKeyguardViewConfigurator(impl: KeyguardViewConfigurator): CoreStartable
} }

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.keyguard
import android.view.View
import android.view.ViewGroup
import com.android.systemui.CoreStartable
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
import com.android.systemui.shade.NotificationShadeWindowView
import com.android.systemui.statusbar.KeyguardIndicationController
import javax.inject.Inject
import kotlinx.coroutines.DisposableHandle
/** Binds keyguard views on startup, and also exposes methods to allow rebinding if views change */
@SysUISingleton
class KeyguardViewConfigurator
@Inject
constructor(
private val keyguardRootView: KeyguardRootView,
private val keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel,
private val notificationShadeWindowView: NotificationShadeWindowView,
private val featureFlags: FeatureFlags,
private val indicationController: KeyguardIndicationController,
) : CoreStartable {
private var indicationAreaHandle: DisposableHandle? = null
override fun start() {
bindIndicationArea(
notificationShadeWindowView.requireViewById(R.id.notification_panel) as ViewGroup
)
}
fun bindIndicationArea(legacyParent: ViewGroup) {
indicationAreaHandle?.dispose()
// At startup, 2 views with the ID `R.id.keyguard_indication_area` will be available.
// Disable one of them
if (featureFlags.isEnabled(Flags.MIGRATE_INDICATION_AREA)) {
legacyParent.requireViewById<View>(R.id.keyguard_indication_area).let {
legacyParent.removeView(it)
}
} else {
keyguardRootView.findViewById<View?>(R.id.keyguard_indication_area)?.let {
keyguardRootView.removeView(it)
}
}
indicationAreaHandle =
KeyguardIndicationAreaBinder.bind(
notificationShadeWindowView,
keyguardIndicationAreaViewModel,
indicationController
)
}
}

View File

@@ -21,6 +21,7 @@ import android.app.StatusBarManager
import android.graphics.Point import android.graphics.Point
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.ui.data.repository.ConfigurationRepository
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
@@ -59,6 +60,7 @@ constructor(
private val commandQueue: CommandQueue, private val commandQueue: CommandQueue,
featureFlags: FeatureFlags, featureFlags: FeatureFlags,
bouncerRepository: KeyguardBouncerRepository, bouncerRepository: KeyguardBouncerRepository,
configurationRepository: ConfigurationRepository,
) { ) {
/** /**
* The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at * The amount of doze the system is in, where `1.0` is fully dozing and `0.0` is not dozing at
@@ -172,6 +174,9 @@ constructor(
/** The approximate location on the screen of the face unlock sensor, if one is available. */ /** The approximate location on the screen of the face unlock sensor, if one is available. */
val faceSensorLocation: Flow<Point?> = repository.faceSensorLocation val faceSensorLocation: Flow<Point?> = repository.faceSensorLocation
/** Notifies when a new configuration is set */
val configurationChange: Flow<Unit> = configurationRepository.onAnyConfigurationChange
fun dozeTransitionTo(vararg states: DozeStateModel): Flow<DozeTransitionModel> { fun dozeTransitionTo(vararg states: DozeStateModel): Flow<DozeTransitionModel> {
return dozeTransitionModel.filter { states.contains(it.to) } return dozeTransitionModel.filter { states.contains(it.to) }
} }

View File

@@ -21,12 +21,10 @@ import android.content.Intent
import android.graphics.Rect import android.graphics.Rect
import android.graphics.drawable.Animatable2 import android.graphics.drawable.Animatable2
import android.util.Size import android.util.Size
import android.util.TypedValue
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.ViewPropertyAnimator import android.view.ViewPropertyAnimator
import android.widget.ImageView import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
@@ -108,14 +106,10 @@ object KeyguardBottomAreaViewBinder {
activityStarter: ActivityStarter?, activityStarter: ActivityStarter?,
messageDisplayer: (Int) -> Unit, messageDisplayer: (Int) -> Unit,
): Binding { ): Binding {
val indicationArea: View = view.requireViewById(R.id.keyguard_indication_area)
val ambientIndicationArea: View? = view.findViewById(R.id.ambient_indication_container) val ambientIndicationArea: View? = view.findViewById(R.id.ambient_indication_container)
val startButton: ImageView = view.requireViewById(R.id.start_button) val startButton: ImageView = view.requireViewById(R.id.start_button)
val endButton: ImageView = view.requireViewById(R.id.end_button) val endButton: ImageView = view.requireViewById(R.id.end_button)
val overlayContainer: View = view.requireViewById(R.id.overlay_container) val overlayContainer: View = view.requireViewById(R.id.overlay_container)
val indicationText: TextView = view.requireViewById(R.id.keyguard_indication_text)
val indicationTextBottom: TextView =
view.requireViewById(R.id.keyguard_indication_text_bottom)
val settingsMenu: LaunchableLinearLayout = val settingsMenu: LaunchableLinearLayout =
view.requireViewById(R.id.keyguard_settings_button) view.requireViewById(R.id.keyguard_settings_button)
@@ -183,7 +177,6 @@ object KeyguardBottomAreaViewBinder {
} }
ambientIndicationArea?.alpha = alpha ambientIndicationArea?.alpha = alpha
indicationArea.alpha = alpha
} }
} }
@@ -205,27 +198,10 @@ object KeyguardBottomAreaViewBinder {
launch { launch {
viewModel.indicationAreaTranslationX.collect { translationX -> viewModel.indicationAreaTranslationX.collect { translationX ->
indicationArea.translationX = translationX
ambientIndicationArea?.translationX = translationX ambientIndicationArea?.translationX = translationX
} }
} }
launch {
combine(
viewModel.isIndicationAreaPadded,
configurationBasedDimensions.map { it.indicationAreaPaddingPx },
) { isPadded, paddingIfPaddedPx ->
if (isPadded) {
paddingIfPaddedPx
} else {
0
}
}
.collect { paddingPx ->
indicationArea.setPadding(paddingPx, 0, paddingPx, 0)
}
}
launch { launch {
configurationBasedDimensions configurationBasedDimensions
.map { it.defaultBurnInPreventionYOffsetPx } .map { it.defaultBurnInPreventionYOffsetPx }
@@ -233,22 +209,12 @@ object KeyguardBottomAreaViewBinder {
viewModel.indicationAreaTranslationY(defaultBurnInOffsetY) viewModel.indicationAreaTranslationY(defaultBurnInOffsetY)
} }
.collect { translationY -> .collect { translationY ->
indicationArea.translationY = translationY
ambientIndicationArea?.translationY = translationY ambientIndicationArea?.translationY = translationY
} }
} }
launch { launch {
configurationBasedDimensions.collect { dimensions -> configurationBasedDimensions.collect { dimensions ->
indicationText.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
dimensions.indicationTextSizePx.toFloat(),
)
indicationTextBottom.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
dimensions.indicationTextSizePx.toFloat(),
)
startButton.updateLayoutParams<ViewGroup.LayoutParams> { startButton.updateLayoutParams<ViewGroup.LayoutParams> {
width = dimensions.buttonSizePx.width width = dimensions.buttonSizePx.width
height = dimensions.buttonSizePx.height height = dimensions.buttonSizePx.height
@@ -305,7 +271,7 @@ object KeyguardBottomAreaViewBinder {
return object : Binding { return object : Binding {
override fun getIndicationAreaAnimators(): List<ViewPropertyAnimator> { override fun getIndicationAreaAnimators(): List<ViewPropertyAnimator> {
return listOf(indicationArea, ambientIndicationArea).mapNotNull { it?.animate() } return listOf(ambientIndicationArea).mapNotNull { it?.animate() }
} }
override fun onConfigurationChanged() { override fun onConfigurationChanged() {
@@ -517,12 +483,6 @@ object KeyguardBottomAreaViewBinder {
return ConfigurationBasedDimensions( return ConfigurationBasedDimensions(
defaultBurnInPreventionYOffsetPx = defaultBurnInPreventionYOffsetPx =
view.resources.getDimensionPixelOffset(R.dimen.default_burn_in_prevention_offset), view.resources.getDimensionPixelOffset(R.dimen.default_burn_in_prevention_offset),
indicationAreaPaddingPx =
view.resources.getDimensionPixelOffset(R.dimen.keyguard_indication_area_padding),
indicationTextSizePx =
view.resources.getDimensionPixelSize(
com.android.internal.R.dimen.text_size_small_material,
),
buttonSizePx = buttonSizePx =
Size( Size(
view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width), view.resources.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
@@ -552,8 +512,6 @@ object KeyguardBottomAreaViewBinder {
private data class ConfigurationBasedDimensions( private data class ConfigurationBasedDimensions(
val defaultBurnInPreventionYOffsetPx: Int, val defaultBurnInPreventionYOffsetPx: Int,
val indicationAreaPaddingPx: Int,
val indicationTextSizePx: Int,
val buttonSizePx: Size, val buttonSizePx: Size,
) )
} }

View File

@@ -0,0 +1,153 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.keyguard.ui.binder
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.R
import com.android.systemui.keyguard.ui.viewmodel.KeyguardIndicationAreaViewModel
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.KeyguardIndicationController
import kotlinx.coroutines.DisposableHandle
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
/**
* Binds a keyguard indication area view to its view-model.
*
* To use this properly, users should maintain a one-to-one relationship between the [View] and the
* view-binding, binding each view only once. It is okay and expected for the same instance of the
* view-model to be reused for multiple view/view-binder bindings.
*/
@OptIn(ExperimentalCoroutinesApi::class)
object KeyguardIndicationAreaBinder {
/** Binds the view to the view-model, continuing to update the former based on the latter. */
@JvmStatic
fun bind(
view: ViewGroup,
viewModel: KeyguardIndicationAreaViewModel,
indicationController: KeyguardIndicationController,
): DisposableHandle {
val indicationArea: ViewGroup = view.requireViewById(R.id.keyguard_indication_area)
indicationController.setIndicationArea(indicationArea)
val indicationText: TextView = indicationArea.requireViewById(R.id.keyguard_indication_text)
val indicationTextBottom: TextView =
indicationArea.requireViewById(R.id.keyguard_indication_text_bottom)
view.clipChildren = false
view.clipToPadding = false
val configurationBasedDimensions = MutableStateFlow(loadFromResources(view))
val disposableHandle =
view.repeatWhenAttached {
repeatOnLifecycle(Lifecycle.State.STARTED) {
launch {
viewModel.alpha.collect { alpha ->
view.importantForAccessibility =
if (alpha == 0f) {
View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
} else {
View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
}
indicationArea.alpha = alpha
}
}
launch {
viewModel.indicationAreaTranslationX.collect { translationX ->
indicationArea.translationX = translationX
}
}
launch {
combine(
viewModel.isIndicationAreaPadded,
configurationBasedDimensions.map { it.indicationAreaPaddingPx },
) { isPadded, paddingIfPaddedPx ->
if (isPadded) {
paddingIfPaddedPx
} else {
0
}
}
.collect { paddingPx ->
indicationArea.setPadding(paddingPx, 0, paddingPx, 0)
}
}
launch {
configurationBasedDimensions
.map { it.defaultBurnInPreventionYOffsetPx }
.flatMapLatest { defaultBurnInOffsetY ->
viewModel.indicationAreaTranslationY(defaultBurnInOffsetY)
}
.collect { translationY -> indicationArea.translationY = translationY }
}
launch {
configurationBasedDimensions.collect { dimensions ->
indicationText.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
dimensions.indicationTextSizePx.toFloat(),
)
indicationTextBottom.setTextSize(
TypedValue.COMPLEX_UNIT_PX,
dimensions.indicationTextSizePx.toFloat(),
)
}
}
launch {
viewModel.configurationChange.collect {
configurationBasedDimensions.value = loadFromResources(view)
}
}
}
}
return disposableHandle
}
private fun loadFromResources(view: View): ConfigurationBasedDimensions {
return ConfigurationBasedDimensions(
defaultBurnInPreventionYOffsetPx =
view.resources.getDimensionPixelOffset(R.dimen.default_burn_in_prevention_offset),
indicationAreaPaddingPx =
view.resources.getDimensionPixelOffset(R.dimen.keyguard_indication_area_padding),
indicationTextSizePx =
view.resources.getDimensionPixelSize(
com.android.internal.R.dimen.text_size_small_material,
),
)
}
private data class ConfigurationBasedDimensions(
val defaultBurnInPreventionYOffsetPx: Int,
val indicationAreaPaddingPx: Int,
val indicationTextSizePx: Int,
)
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.keyguard.ui.view
import android.content.Context
import android.text.TextUtils
import android.util.AttributeSet
import android.view.Gravity
import android.view.View
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.LinearLayout
import com.android.systemui.R
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView
class KeyguardIndicationArea(
context: Context,
private val attrs: AttributeSet?,
) :
LinearLayout(
context,
attrs,
) {
init {
setId(R.id.keyguard_indication_area)
orientation = LinearLayout.VERTICAL
addView(indicationTopRow(), LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
addView(
indicationBottomRow(),
LinearLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).apply {
gravity = Gravity.CENTER_HORIZONTAL
}
)
}
private fun indicationTopRow(): KeyguardIndicationTextView {
return KeyguardIndicationTextView(context, attrs).apply {
id = R.id.keyguard_indication_text
gravity = Gravity.CENTER
accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE
setTextAppearance(R.style.TextAppearance_Keyguard_BottomArea)
val padding = R.dimen.keyguard_indication_text_padding.dp()
setPaddingRelative(padding, 0, padding, 0)
}
}
private fun indicationBottomRow(): KeyguardIndicationTextView {
return KeyguardIndicationTextView(context, attrs).apply {
id = R.id.keyguard_indication_text_bottom
gravity = Gravity.CENTER
accessibilityLiveRegion = View.ACCESSIBILITY_LIVE_REGION_POLITE
setTextAppearance(R.style.TextAppearance_Keyguard_BottomArea)
setEllipsize(TextUtils.TruncateAt.END)
setAlpha(0.8f)
setMinHeight(R.dimen.keyguard_indication_text_min_height.dp())
setMaxLines(2)
setVisibility(View.GONE)
val padding = R.dimen.keyguard_indication_text_padding.dp()
setPaddingRelative(padding, 0, padding, 0)
}
}
private fun Int.dp(): Int {
return context.resources.getDimensionPixelSize(this)
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.keyguard.ui.view
import android.content.Context
import android.util.AttributeSet
import android.view.Gravity
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout
import com.android.systemui.R
/** Provides a container for all keyguard ui content. */
class KeyguardRootView(
context: Context,
private val attrs: AttributeSet?,
) :
FrameLayout(
context,
attrs,
) {
init {
addIndicationTextArea()
}
private fun addIndicationTextArea() {
val view = KeyguardIndicationArea(context, attrs)
addView(
view,
FrameLayout.LayoutParams(
MATCH_PARENT,
WRAP_CONTENT,
)
.apply {
gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
bottomMargin = R.dimen.keyguard_indication_margin_bottom.dp()
}
)
}
private fun Int.dp(): Int {
return context.resources.getDimensionPixelSize(this)
}
}

View File

@@ -57,7 +57,7 @@ constructor(
* in the wallpaper picker application. This should _always_ be `false` for the real lock screen * in the wallpaper picker application. This should _always_ be `false` for the real lock screen
* experience. * experience.
*/ */
private val previewMode = MutableStateFlow(PreviewMode()) val previewMode = MutableStateFlow(PreviewMode())
/** /**
* ID of the slot that's currently selected in the preview that renders exclusively in the * ID of the slot that's currently selected in the preview that renders exclusively in the
@@ -101,12 +101,6 @@ constructor(
bottomAreaInteractor.alpha.distinctUntilChanged() bottomAreaInteractor.alpha.distinctUntilChanged()
} }
} }
/** An observable for whether the indication area should be padded. */
val isIndicationAreaPadded: Flow<Boolean> =
combine(startButton, endButton) { startButtonModel, endButtonModel ->
startButtonModel.isVisible || endButtonModel.isVisible
}
.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> =
bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged() bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
/** View-model for the keyguard indication area view */
@OptIn(ExperimentalCoroutinesApi::class)
class KeyguardIndicationAreaViewModel
@Inject
constructor(
private val keyguardInteractor: KeyguardInteractor,
private val bottomAreaInteractor: KeyguardBottomAreaInteractor,
private val keyguardBottomAreaViewModel: KeyguardBottomAreaViewModel,
private val burnInHelperWrapper: BurnInHelperWrapper,
) {
/** Notifies when a new configuration is set */
val configurationChange: Flow<Unit> = keyguardInteractor.configurationChange
/** An observable for the alpha level for the entire bottom area. */
val alpha: Flow<Float> = keyguardBottomAreaViewModel.alpha
/** An observable for whether the indication area should be padded. */
val isIndicationAreaPadded: Flow<Boolean> =
combine(keyguardBottomAreaViewModel.startButton, keyguardBottomAreaViewModel.endButton) {
startButtonModel,
endButtonModel ->
startButtonModel.isVisible || endButtonModel.isVisible
}
.distinctUntilChanged()
/** An observable for the x-offset by which the indication area should be translated. */
val indicationAreaTranslationX: Flow<Float> =
bottomAreaInteractor.clockPosition.map { it.x.toFloat() }.distinctUntilChanged()
/** Returns an observable for the y-offset by which the indication area should be translated. */
fun indicationAreaTranslationY(defaultBurnInOffset: Int): Flow<Float> {
return keyguardInteractor.dozeAmount
.map { dozeAmount ->
dozeAmount *
(burnInHelperWrapper.burnInOffset(
/* amplitude = */ defaultBurnInOffset * 2,
/* xAxis= */ false,
) - defaultBurnInOffset)
}
.distinctUntilChanged()
}
}

View File

@@ -125,6 +125,7 @@ import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags; import com.android.systemui.flags.Flags;
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.KeyguardViewConfigurator;
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
@@ -598,6 +599,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private final KeyguardTransitionInteractor mKeyguardTransitionInteractor; private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
private final KeyguardInteractor mKeyguardInteractor; private final KeyguardInteractor mKeyguardInteractor;
private final KeyguardViewConfigurator mKeyguardViewConfigurator;
private final @Nullable MultiShadeInteractor mMultiShadeInteractor; private final @Nullable MultiShadeInteractor mMultiShadeInteractor;
private final CoroutineDispatcher mMainDispatcher; private final CoroutineDispatcher mMainDispatcher;
private boolean mIsAnyMultiShadeExpanded; private boolean mIsAnyMultiShadeExpanded;
@@ -740,6 +742,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
KeyguardLongPressViewModel keyguardLongPressViewModel, KeyguardLongPressViewModel keyguardLongPressViewModel,
KeyguardInteractor keyguardInteractor, KeyguardInteractor keyguardInteractor,
ActivityStarter activityStarter, ActivityStarter activityStarter,
KeyguardViewConfigurator keyguardViewConfigurator,
KeyguardFaceAuthInteractor keyguardFaceAuthInteractor) { KeyguardFaceAuthInteractor keyguardFaceAuthInteractor) {
mInteractionJankMonitor = interactionJankMonitor; mInteractionJankMonitor = interactionJankMonitor;
keyguardStateController.addCallback(new KeyguardStateController.Callback() { keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@@ -762,6 +765,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mLockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel; mLockscreenToOccludedTransitionViewModel = lockscreenToOccludedTransitionViewModel;
mKeyguardTransitionInteractor = keyguardTransitionInteractor; mKeyguardTransitionInteractor = keyguardTransitionInteractor;
mKeyguardInteractor = keyguardInteractor; mKeyguardInteractor = keyguardInteractor;
mKeyguardViewConfigurator = keyguardViewConfigurator;
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override @Override
public void onViewAttachedToWindow(View v) { public void onViewAttachedToWindow(View v) {
@@ -1319,7 +1323,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardBottomArea.initFrom(oldBottomArea); mKeyguardBottomArea.initFrom(oldBottomArea);
mView.addView(mKeyguardBottomArea, index); mView.addView(mKeyguardBottomArea, index);
initBottomArea(); initBottomArea();
mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea);
mStatusBarStateListener.onDozeAmountChanged(mStatusBarStateController.getDozeAmount(), mStatusBarStateListener.onDozeAmountChanged(mStatusBarStateController.getDozeAmount(),
mStatusBarStateController.getInterpolatedDozeAmount()); mStatusBarStateController.getInterpolatedDozeAmount());
@@ -1361,6 +1364,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardIndicationController.showTransientIndication(stringResourceId), mKeyguardIndicationController.showTransientIndication(stringResourceId),
mVibratorHelper, mVibratorHelper,
mActivityStarter); mActivityStarter);
// Rebind (for now), as a new bottom area and indication area may have been created
mKeyguardViewConfigurator.bindIndicationArea(mKeyguardBottomArea);
} }
@VisibleForTesting @VisibleForTesting
@@ -1398,7 +1404,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
private void setKeyguardBottomArea(KeyguardBottomAreaView keyguardBottomArea) { private void setKeyguardBottomArea(KeyguardBottomAreaView keyguardBottomArea) {
mKeyguardBottomArea = keyguardBottomArea; mKeyguardBottomArea = keyguardBottomArea;
mKeyguardIndicationController.setIndicationArea(mKeyguardBottomArea);
} }
void setOpenCloseListener(OpenCloseListener openCloseListener) { void setOpenCloseListener(OpenCloseListener openCloseListener) {
@@ -3023,12 +3028,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump
mKeyguardStatusViewController.setStatusAccessibilityImportance(mode); mKeyguardStatusViewController.setStatusAccessibilityImportance(mode);
} }
//TODO(b/254875405): this should be removed.
@Override
public KeyguardBottomAreaView getKeyguardBottomAreaView() {
return mKeyguardBottomArea;
}
@Override @Override
public void applyLaunchAnimationProgress(float linearProgress) { public void applyLaunchAnimationProgress(float linearProgress) {
boolean hideIcons = LaunchAnimator.getProgress(ActivityLaunchAnimator.TIMINGS, boolean hideIcons = LaunchAnimator.getProgress(ActivityLaunchAnimator.TIMINGS,

View File

@@ -32,6 +32,7 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.ui.view.KeyguardRootView
import com.android.systemui.privacy.OngoingPrivacyChip import com.android.systemui.privacy.OngoingPrivacyChip
import com.android.systemui.scene.ui.view.WindowRootView import com.android.systemui.scene.ui.view.WindowRootView
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
@@ -71,9 +72,9 @@ abstract class ShadeModule {
layoutInflater.inflate(R.layout.scene_window_root, null) layoutInflater.inflate(R.layout.scene_window_root, null)
} else { } else {
layoutInflater.inflate(R.layout.super_notification_shade, null) layoutInflater.inflate(R.layout.super_notification_shade, null)
} as WindowRootView? ?: throw IllegalStateException( }
"Window root view could not be properly inflated" as WindowRootView?
) ?: throw IllegalStateException("Window root view could not be properly inflated")
} }
@Provides @Provides
@@ -89,9 +90,7 @@ abstract class ShadeModule {
return root.findViewById(R.id.legacy_window_root) return root.findViewById(R.id.legacy_window_root)
} }
return root as NotificationShadeWindowView? return root as NotificationShadeWindowView?
?: throw IllegalStateException( ?: throw IllegalStateException("root view not a NotificationShadeWindowView")
"root view not a NotificationShadeWindowView"
)
} }
// TODO(b/277762009): Only allow this view's controller to inject the view. See above. // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
@@ -120,6 +119,14 @@ abstract class ShadeModule {
return notificationShadeWindowView.findViewById(R.id.light_reveal_scrim) return notificationShadeWindowView.findViewById(R.id.light_reveal_scrim)
} }
@Provides
@SysUISingleton
fun providesKeyguardRootView(
notificationShadeWindowView: NotificationShadeWindowView,
): KeyguardRootView {
return notificationShadeWindowView.findViewById(R.id.keyguard_root_view)
}
// TODO(b/277762009): Only allow this view's controller to inject the view. See above. // TODO(b/277762009): Only allow this view's controller to inject the view. See above.
@Provides @Provides
@SysUISingleton @SysUISingleton

View File

@@ -21,7 +21,6 @@ import com.android.systemui.statusbar.RemoteInputController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController import com.android.systemui.statusbar.phone.HeadsUpAppearanceController
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView
import com.android.systemui.statusbar.phone.KeyguardStatusBarView import com.android.systemui.statusbar.phone.KeyguardStatusBarView
import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController
import java.util.function.Consumer import java.util.function.Consumer
@@ -120,13 +119,6 @@ interface ShadeViewController {
/** Returns the StatusBarState. */ /** Returns the StatusBarState. */
val barState: Int val barState: Int
/**
* Returns the bottom part of the keyguard, which contains quick affordances.
*
* TODO(b/275550429): this should be removed.
*/
val keyguardBottomAreaView: KeyguardBottomAreaView?
/** Returns the NSSL controller. */ /** Returns the NSSL controller. */
val notificationStackScrollLayoutController: NotificationStackScrollLayoutController val notificationStackScrollLayoutController: NotificationStackScrollLayoutController

View File

@@ -40,7 +40,6 @@ import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.shade.QuickSettingsController; import com.android.systemui.shade.QuickSettingsController;
import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationMediaManager;
@@ -86,7 +85,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
private final HeadsUpManagerPhone mHeadsUpManager; private final HeadsUpManagerPhone mHeadsUpManager;
private final AboveShelfObserver mAboveShelfObserver; private final AboveShelfObserver mAboveShelfObserver;
private final DozeScrimController mDozeScrimController; private final DozeScrimController mDozeScrimController;
private final KeyguardIndicationController mKeyguardIndicationController;
private final CentralSurfaces mCentralSurfaces; private final CentralSurfaces mCentralSurfaces;
private final LockscreenShadeTransitionController mShadeTransitionController; private final LockscreenShadeTransitionController mShadeTransitionController;
private final CommandQueue mCommandQueue; private final CommandQueue mCommandQueue;
@@ -115,7 +113,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
NotificationShadeWindowController notificationShadeWindowController, NotificationShadeWindowController notificationShadeWindowController,
DynamicPrivacyController dynamicPrivacyController, DynamicPrivacyController dynamicPrivacyController,
KeyguardStateController keyguardStateController, KeyguardStateController keyguardStateController,
KeyguardIndicationController keyguardIndicationController,
CentralSurfaces centralSurfaces, CentralSurfaces centralSurfaces,
LockscreenShadeTransitionController shadeTransitionController, LockscreenShadeTransitionController shadeTransitionController,
CommandQueue commandQueue, CommandQueue commandQueue,
@@ -137,7 +134,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
mQsController = quickSettingsController; mQsController = quickSettingsController;
mHeadsUpManager = headsUp; mHeadsUpManager = headsUp;
mDynamicPrivacyController = dynamicPrivacyController; mDynamicPrivacyController = dynamicPrivacyController;
mKeyguardIndicationController = keyguardIndicationController;
// TODO: use KeyguardStateController#isOccluded to remove this dependency // TODO: use KeyguardStateController#isOccluded to remove this dependency
mCentralSurfaces = centralSurfaces; mCentralSurfaces = centralSurfaces;
mShadeTransitionController = shadeTransitionController; mShadeTransitionController = shadeTransitionController;
@@ -173,7 +169,6 @@ class StatusBarNotificationPresenter implements NotificationPresenter,
mNotificationPanel.getShadeNotificationPresenter().createRemoteInputDelegate()); mNotificationPanel.getShadeNotificationPresenter().createRemoteInputDelegate());
initController.addPostInitTask(() -> { initController.addPostInitTask(() -> {
mKeyguardIndicationController.init();
mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied); mNotifShadeEventSource.setShadeEmptiedCallback(this::maybeClosePanelForShadeEmptied);
mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse); mNotifShadeEventSource.setNotifRemovedByUserCallback(this::maybeEndAmbientPulse);
notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor); notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);

View File

@@ -62,6 +62,7 @@ import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit import org.mockito.junit.MockitoJUnit
import java.util.TimeZone import java.util.TimeZone
import java.util.concurrent.Executor import java.util.concurrent.Executor
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import org.mockito.Mockito.`when` as whenever import org.mockito.Mockito.`when` as whenever
@RunWith(AndroidTestingRunner::class) @RunWith(AndroidTestingRunner::class)
@@ -117,6 +118,7 @@ class ClockEventControllerTest : SysuiTestCase() {
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags, featureFlags = featureFlags,
bouncerRepository = bouncerRepository, bouncerRepository = bouncerRepository,
configurationRepository = FakeConfigurationRepository(),
), ),
KeyguardTransitionInteractor(repository = transitionRepository), KeyguardTransitionInteractor(repository = transitionRepository),
broadcastDispatcher, broadcastDispatcher,

View File

@@ -18,6 +18,7 @@ package com.android.keyguard;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1; import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
import static com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@@ -42,15 +43,12 @@ import com.android.systemui.biometrics.AuthController;
import com.android.systemui.biometrics.AuthRippleController; import com.android.systemui.biometrics.AuthRippleController;
import com.android.systemui.doze.util.BurnInHelperKt; import com.android.systemui.doze.util.BurnInHelperKt;
import com.android.systemui.dump.DumpManager; import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.FakeFeatureFlags;
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository; import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.VibratorHelper; import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.statusbar.policy.ConfigurationController;
@@ -91,10 +89,9 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
protected @Mock ConfigurationController mConfigurationController; protected @Mock ConfigurationController mConfigurationController;
protected @Mock VibratorHelper mVibrator; protected @Mock VibratorHelper mVibrator;
protected @Mock AuthRippleController mAuthRippleController; protected @Mock AuthRippleController mAuthRippleController;
protected @Mock FeatureFlags mFeatureFlags;
protected @Mock KeyguardTransitionRepository mTransitionRepository; protected @Mock KeyguardTransitionRepository mTransitionRepository;
protected @Mock CommandQueue mCommandQueue;
protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock()); protected FakeExecutor mDelayableExecutor = new FakeExecutor(new FakeSystemClock());
protected FakeFeatureFlags mFeatureFlags;
protected LockIconViewController mUnderTest; protected LockIconViewController mUnderTest;
@@ -144,6 +141,8 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
when(mStatusBarStateController.isDozing()).thenReturn(false); when(mStatusBarStateController.isDozing()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD);
mFeatureFlags = new FakeFeatureFlags();
mFeatureFlags.set(FACE_AUTH_REFACTOR, false);
mUnderTest = new LockIconViewController( mUnderTest = new LockIconViewController(
mLockIconView, mLockIconView,
mStatusBarStateController, mStatusBarStateController,
@@ -160,12 +159,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
mAuthRippleController, mAuthRippleController,
mResources, mResources,
new KeyguardTransitionInteractor(mTransitionRepository), new KeyguardTransitionInteractor(mTransitionRepository),
new KeyguardInteractor( KeyguardInteractorFactory.create(mFeatureFlags).getKeyguardInteractor(),
new FakeKeyguardRepository(),
mCommandQueue,
mFeatureFlags,
new FakeKeyguardBouncerRepository()
),
mFeatureFlags mFeatureFlags
); );
} }
@@ -226,7 +220,7 @@ public class LockIconViewControllerBaseTest extends SysuiTestCase {
} }
protected void init(boolean useMigrationFlag) { protected void init(boolean useMigrationFlag) {
when(mFeatureFlags.isEnabled(DOZING_MIGRATION_1)).thenReturn(useMigrationFlag); mFeatureFlags.set(DOZING_MIGRATION_1, useMigrationFlag);
mUnderTest.init(); mUnderTest.init();
verify(mLockIconView, atLeast(1)).addOnAttachStateChangeListener(mAttachCaptor.capture()); verify(mLockIconView, atLeast(1)).addOnAttachStateChangeListener(mAttachCaptor.capture());

View File

@@ -34,6 +34,7 @@ import com.android.systemui.R
import com.android.systemui.SystemUIAppComponentFactoryBase import com.android.systemui.SystemUIAppComponentFactoryBase
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.DialogLaunchAnimator import com.android.systemui.animation.DialogLaunchAnimator
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.dock.DockManagerFake import com.android.systemui.dock.DockManagerFake
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
@@ -185,6 +186,7 @@ class CustomizationProviderTest : SysuiTestCase() {
commandQueue = commandQueue, commandQueue = commandQueue,
featureFlags = featureFlags, featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(), bouncerRepository = FakeKeyguardBouncerRepository(),
configurationRepository = FakeConfigurationRepository(),
), ),
registry = mock(), registry = mock(),
lockPatternUtils = lockPatternUtils, lockPatternUtils = lockPatternUtils,

View File

@@ -7,11 +7,9 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.shared.model.TransitionStep
@@ -60,13 +58,12 @@ class ResourceTrimmerTest : SysuiTestCase() {
keyguardRepository.setDozeAmount(0f) keyguardRepository.setDozeAmount(0f)
keyguardRepository.setKeyguardGoingAway(false) keyguardRepository.setKeyguardGoingAway(false)
val keyguardInteractor = val withDeps =
KeyguardInteractor( KeyguardInteractorFactory.create(
keyguardRepository, repository = keyguardRepository,
FakeCommandQueue(), featureFlags = featureFlags,
featureFlags,
FakeKeyguardBouncerRepository()
) )
val keyguardInteractor = withDeps.keyguardInteractor
resourceTrimmer = resourceTrimmer =
ResourceTrimmer( ResourceTrimmer(
keyguardInteractor, keyguardInteractor,

View File

@@ -47,6 +47,7 @@ import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.AuthenticationStatus import com.android.systemui.keyguard.shared.model.AuthenticationStatus
import com.android.systemui.keyguard.shared.model.DetectionStatus import com.android.systemui.keyguard.shared.model.DetectionStatus
@@ -159,17 +160,16 @@ class DeviceEntryFaceAuthRepositoryTest : SysuiTestCase() {
biometricSettingsRepository = FakeBiometricSettingsRepository() biometricSettingsRepository = FakeBiometricSettingsRepository()
deviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository() deviceEntryFingerprintAuthRepository = FakeDeviceEntryFingerprintAuthRepository()
trustRepository = FakeTrustRepository() trustRepository = FakeTrustRepository()
keyguardRepository = FakeKeyguardRepository()
bouncerRepository = FakeKeyguardBouncerRepository()
featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) } featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
fakeCommandQueue = FakeCommandQueue() val withDeps =
keyguardInteractor = KeyguardInteractorFactory.create(
KeyguardInteractor( featureFlags = featureFlags,
keyguardRepository,
fakeCommandQueue,
featureFlags,
bouncerRepository
) )
keyguardInteractor = withDeps.keyguardInteractor
keyguardRepository = withDeps.repository
bouncerRepository = withDeps.bouncerRepository
fakeCommandQueue = withDeps.commandQueue
alternateBouncerInteractor = alternateBouncerInteractor =
AlternateBouncerInteractor( AlternateBouncerInteractor(
bouncerRepository = bouncerRepository, bouncerRepository = bouncerRepository,

View File

@@ -22,6 +22,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.RoboPilotTest import com.android.systemui.RoboPilotTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
@@ -50,6 +51,7 @@ class KeyguardInteractorTest : SysuiTestCase() {
private lateinit var underTest: KeyguardInteractor private lateinit var underTest: KeyguardInteractor
private lateinit var repository: FakeKeyguardRepository private lateinit var repository: FakeKeyguardRepository
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
private lateinit var configurationRepository: FakeConfigurationRepository
@Before @Before
fun setUp() { fun setUp() {
@@ -59,12 +61,14 @@ class KeyguardInteractorTest : SysuiTestCase() {
testScope = TestScope() testScope = TestScope()
repository = FakeKeyguardRepository() repository = FakeKeyguardRepository()
bouncerRepository = FakeKeyguardBouncerRepository() bouncerRepository = FakeKeyguardBouncerRepository()
configurationRepository = FakeConfigurationRepository()
underTest = underTest =
KeyguardInteractor( KeyguardInteractor(
repository, repository,
commandQueue, commandQueue,
featureFlags, featureFlags,
bouncerRepository, bouncerRepository,
configurationRepository,
) )
} }

View File

@@ -38,8 +38,6 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
@@ -48,7 +46,6 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.FakeUserTracker import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any
@@ -225,7 +222,6 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
@Mock private lateinit var animationController: ActivityLaunchAnimator.Controller @Mock private lateinit var animationController: ActivityLaunchAnimator.Controller
@Mock private lateinit var expandable: Expandable @Mock private lateinit var expandable: Expandable
@Mock private lateinit var launchAnimator: DialogLaunchAnimator @Mock private lateinit var launchAnimator: DialogLaunchAnimator
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var devicePolicyManager: DevicePolicyManager @Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger @Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
@@ -309,12 +305,10 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
underTest = underTest =
KeyguardQuickAffordanceInteractor( KeyguardQuickAffordanceInteractor(
keyguardInteractor = keyguardInteractor =
KeyguardInteractor( KeyguardInteractorFactory.create(
repository = FakeKeyguardRepository(), featureFlags = featureFlags,
commandQueue = commandQueue, )
featureFlags = featureFlags, .keyguardInteractor,
bouncerRepository = FakeKeyguardBouncerRepository(),
),
registry = registry =
FakeKeyguardQuickAffordanceRegistry( FakeKeyguardQuickAffordanceRegistry(
mapOf( mapOf(
@@ -368,11 +362,11 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled KeyguardQuickAffordanceConfig.OnTriggeredResult.Handled
} }
underTest.onQuickAffordanceTriggered( underTest.onQuickAffordanceTriggered(
configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS, configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
expandable = expandable, expandable = expandable,
slotId = "", slotId = "",
) )
if (startActivity) { if (startActivity) {
if (needsToUnlockFirst) { if (needsToUnlockFirst) {

View File

@@ -40,7 +40,6 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
@@ -53,7 +52,6 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences import com.android.systemui.util.FakeSharedPreferences
import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock
@@ -84,7 +82,6 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
@Mock private lateinit var userTracker: UserTracker @Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var launchAnimator: DialogLaunchAnimator @Mock private lateinit var launchAnimator: DialogLaunchAnimator
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var devicePolicyManager: DevicePolicyManager @Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger @Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
@@ -168,15 +165,14 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
set(Flags.FACE_AUTH_REFACTOR, true) set(Flags.FACE_AUTH_REFACTOR, true)
} }
val withDeps =
KeyguardInteractorFactory.create(
featureFlags = featureFlags,
repository = repository,
)
underTest = underTest =
KeyguardQuickAffordanceInteractor( KeyguardQuickAffordanceInteractor(
keyguardInteractor = keyguardInteractor = withDeps.keyguardInteractor,
KeyguardInteractor(
repository = repository,
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
),
registry = registry =
FakeKeyguardQuickAffordanceRegistry( FakeKeyguardQuickAffordanceRegistry(
mapOf( mapOf(

View File

@@ -21,7 +21,6 @@ import com.android.keyguard.KeyguardSecurityModel
import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN import com.android.keyguard.KeyguardSecurityModel.SecurityMode.PIN
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
@@ -39,7 +38,6 @@ import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.keyguard.shared.model.WakefulnessState import com.android.systemui.keyguard.shared.model.WakefulnessState
import com.android.systemui.shade.data.repository.FakeShadeRepository import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.mockito.withArgCaptor import com.android.systemui.util.mockito.withArgCaptor
@@ -74,10 +72,10 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
private lateinit var bouncerRepository: FakeKeyguardBouncerRepository private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
private lateinit var shadeRepository: ShadeRepository private lateinit var shadeRepository: ShadeRepository
private lateinit var transitionRepository: FakeKeyguardTransitionRepository private lateinit var transitionRepository: FakeKeyguardTransitionRepository
private lateinit var featureFlags: FakeFeatureFlags
// Used to verify transition requests for test output // Used to verify transition requests for test output
@Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository @Mock private lateinit var mockTransitionRepository: KeyguardTransitionRepository
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel @Mock private lateinit var keyguardSecurityModel: KeyguardSecurityModel
private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor private lateinit var fromLockscreenTransitionInteractor: FromLockscreenTransitionInteractor
@@ -103,11 +101,11 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
whenever(keyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(PIN) whenever(keyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(PIN)
val featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) } featureFlags = FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, true) }
fromLockscreenTransitionInteractor = fromLockscreenTransitionInteractor =
FromLockscreenTransitionInteractor( FromLockscreenTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
shadeRepository = shadeRepository, shadeRepository = shadeRepository,
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
@@ -117,7 +115,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromDreamingTransitionInteractor = fromDreamingTransitionInteractor =
FromDreamingTransitionInteractor( FromDreamingTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -126,7 +124,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromAodTransitionInteractor = fromAodTransitionInteractor =
FromAodTransitionInteractor( FromAodTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -135,7 +133,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromGoneTransitionInteractor = fromGoneTransitionInteractor =
FromGoneTransitionInteractor( FromGoneTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -144,7 +142,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromDozingTransitionInteractor = fromDozingTransitionInteractor =
FromDozingTransitionInteractor( FromDozingTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -153,7 +151,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromOccludedTransitionInteractor = fromOccludedTransitionInteractor =
FromOccludedTransitionInteractor( FromOccludedTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -162,7 +160,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromAlternateBouncerTransitionInteractor = fromAlternateBouncerTransitionInteractor =
FromAlternateBouncerTransitionInteractor( FromAlternateBouncerTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
) )
@@ -171,7 +169,7 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
fromPrimaryBouncerTransitionInteractor = fromPrimaryBouncerTransitionInteractor =
FromPrimaryBouncerTransitionInteractor( FromPrimaryBouncerTransitionInteractor(
scope = testScope, scope = testScope,
keyguardInteractor = createKeyguardInteractor(featureFlags), keyguardInteractor = createKeyguardInteractor(),
keyguardTransitionRepository = mockTransitionRepository, keyguardTransitionRepository = mockTransitionRepository,
keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository), keyguardTransitionInteractor = KeyguardTransitionInteractor(transitionRepository),
keyguardSecurityModel = keyguardSecurityModel, keyguardSecurityModel = keyguardSecurityModel,
@@ -882,13 +880,13 @@ class KeyguardTransitionScenariosTest : SysuiTestCase() {
WakeSleepReason.OTHER WakeSleepReason.OTHER
) )
private fun createKeyguardInteractor(featureFlags: FeatureFlags): KeyguardInteractor { private fun createKeyguardInteractor(): KeyguardInteractor {
return KeyguardInteractor( return KeyguardInteractorFactory.create(
keyguardRepository, featureFlags = featureFlags,
commandQueue, repository = keyguardRepository,
featureFlags, bouncerRepository = bouncerRepository,
bouncerRepository, )
) .keyguardInteractor
} }
private suspend fun TestScope.runTransition(from: KeyguardState, to: KeyguardState) { private suspend fun TestScope.runTransition(from: KeyguardState, to: KeyguardState) {

View File

@@ -39,12 +39,11 @@ import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanc
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLegacySettingSyncer
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceLocalUserSelectionManager
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceRemoteUserSelectionManager
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository import com.android.systemui.keyguard.data.repository.KeyguardQuickAffordanceRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardLongPressInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -56,7 +55,6 @@ import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserFileManager import com.android.systemui.settings.UserFileManager
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper import com.android.systemui.statusbar.policy.AccessibilityManagerWrapper
import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.FakeSharedPreferences import com.android.systemui.util.FakeSharedPreferences
@@ -95,7 +93,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
@Mock private lateinit var userTracker: UserTracker @Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var activityStarter: ActivityStarter
@Mock private lateinit var launchAnimator: DialogLaunchAnimator @Mock private lateinit var launchAnimator: DialogLaunchAnimator
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var devicePolicyManager: DevicePolicyManager @Mock private lateinit var devicePolicyManager: DevicePolicyManager
@Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger @Mock private lateinit var logger: KeyguardQuickAffordancesMetricsLogger
@Mock private lateinit var broadcastDispatcher: BroadcastDispatcher @Mock private lateinit var broadcastDispatcher: BroadcastDispatcher
@@ -140,7 +137,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
), ),
), ),
) )
repository = FakeKeyguardRepository()
val featureFlags = val featureFlags =
FakeFeatureFlags().apply { FakeFeatureFlags().apply {
set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false) set(Flags.CUSTOMIZABLE_LOCK_SCREEN_QUICK_AFFORDANCES, false)
@@ -149,13 +145,10 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, false) set(Flags.LOCK_SCREEN_LONG_PRESS_DIRECT_TO_WPP, false)
} }
val keyguardInteractor = val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags)
KeyguardInteractor( val keyguardInteractor = withDeps.keyguardInteractor
repository = repository, repository = withDeps.repository
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
)
whenever(userTracker.userHandle).thenReturn(mock()) whenever(userTracker.userHandle).thenReturn(mock())
whenever(userTracker.userId).thenReturn(10) whenever(userTracker.userId).thenReturn(10)
whenever(lockPatternUtils.getStrongAuthForUser(anyInt())) whenever(lockPatternUtils.getStrongAuthForUser(anyInt()))
@@ -549,91 +542,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
assertThat(value()).isEqualTo(1f) assertThat(value()).isEqualTo(1f)
} }
@Test
fun isIndicationAreaPadded() =
testScope.runTest {
repository.setKeyguardShowing(true)
val value = collectLastValue(underTest.isIndicationAreaPadded)
assertThat(value()).isFalse()
setUpQuickAffordanceModel(
position = KeyguardQuickAffordancePosition.BOTTOM_START,
testConfig =
TestConfig(
isVisible = true,
isClickable = true,
icon = mock(),
canShowWhileLocked = true,
slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(),
)
)
assertThat(value()).isTrue()
setUpQuickAffordanceModel(
position = KeyguardQuickAffordancePosition.BOTTOM_END,
testConfig =
TestConfig(
isVisible = true,
isClickable = true,
icon = mock(),
canShowWhileLocked = false,
slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(),
)
)
assertThat(value()).isTrue()
setUpQuickAffordanceModel(
position = KeyguardQuickAffordancePosition.BOTTOM_START,
testConfig =
TestConfig(
isVisible = false,
slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId(),
)
)
assertThat(value()).isTrue()
setUpQuickAffordanceModel(
position = KeyguardQuickAffordancePosition.BOTTOM_END,
testConfig =
TestConfig(
isVisible = false,
slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId(),
)
)
assertThat(value()).isFalse()
}
@Test
fun indicationAreaTranslationX() =
testScope.runTest {
val value = collectLastValue(underTest.indicationAreaTranslationX)
assertThat(value()).isEqualTo(0f)
repository.setClockPosition(100, 100)
assertThat(value()).isEqualTo(100f)
repository.setClockPosition(200, 100)
assertThat(value()).isEqualTo(200f)
repository.setClockPosition(200, 200)
assertThat(value()).isEqualTo(200f)
repository.setClockPosition(300, 100)
assertThat(value()).isEqualTo(300f)
}
@Test
fun indicationAreaTranslationY() =
testScope.runTest {
val value =
collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
// Negative 0 - apparently there's a difference in floating point arithmetic - FML
assertThat(value()).isEqualTo(-0f)
val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
assertThat(value()).isEqualTo(expected1)
val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
assertThat(value()).isEqualTo(expected2)
val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
assertThat(value()).isEqualTo(expected3)
val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
assertThat(value()).isEqualTo(expected4)
}
@Test @Test
fun isClickable_trueWhenAlphaAtThreshold() = fun isClickable_trueWhenAlphaAtThreshold() =
testScope.runTest { testScope.runTest {
@@ -757,11 +665,6 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
) )
} }
private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
repository.setDozeAmount(dozeAmount)
return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET)
}
private suspend fun setUpQuickAffordanceModel( private suspend fun setUpQuickAffordanceModel(
position: KeyguardQuickAffordancePosition, position: KeyguardQuickAffordancePosition,
testConfig: TestConfig, testConfig: TestConfig,

View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.keyguard.ui.viewmodel
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(JUnit4::class)
class KeyguardIndicationAreaViewModelTest : SysuiTestCase() {
@Mock private lateinit var burnInHelperWrapper: BurnInHelperWrapper
private lateinit var underTest: KeyguardIndicationAreaViewModel
private lateinit var repository: FakeKeyguardRepository
private val startButtonFlow =
MutableStateFlow<KeyguardQuickAffordanceViewModel>(
KeyguardQuickAffordanceViewModel(
slotId = KeyguardQuickAffordancePosition.BOTTOM_START.toSlotId()
)
)
private val endButtonFlow =
MutableStateFlow<KeyguardQuickAffordanceViewModel>(
KeyguardQuickAffordanceViewModel(
slotId = KeyguardQuickAffordancePosition.BOTTOM_END.toSlotId()
)
)
private val alphaFlow = MutableStateFlow<Float>(1f)
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
whenever(burnInHelperWrapper.burnInOffset(anyInt(), any()))
.thenReturn(RETURNED_BURN_IN_OFFSET)
val withDeps = KeyguardInteractorFactory.create()
val keyguardInteractor = withDeps.keyguardInteractor
repository = withDeps.repository
val bottomAreaViewModel: KeyguardBottomAreaViewModel = mock()
whenever(bottomAreaViewModel.startButton).thenReturn(startButtonFlow)
whenever(bottomAreaViewModel.endButton).thenReturn(endButtonFlow)
whenever(bottomAreaViewModel.alpha).thenReturn(alphaFlow)
underTest =
KeyguardIndicationAreaViewModel(
keyguardInteractor = keyguardInteractor,
bottomAreaInteractor = KeyguardBottomAreaInteractor(repository = repository),
keyguardBottomAreaViewModel = bottomAreaViewModel,
burnInHelperWrapper = burnInHelperWrapper,
)
}
@Test
fun alpha() = runTest {
val value = collectLastValue(underTest.alpha)
assertThat(value()).isEqualTo(1f)
alphaFlow.value = 0.1f
assertThat(value()).isEqualTo(0.1f)
alphaFlow.value = 0.5f
assertThat(value()).isEqualTo(0.5f)
alphaFlow.value = 0.2f
assertThat(value()).isEqualTo(0.2f)
alphaFlow.value = 0f
assertThat(value()).isEqualTo(0f)
}
@Test
fun isIndicationAreaPadded() = runTest {
repository.setKeyguardShowing(true)
val value = collectLastValue(underTest.isIndicationAreaPadded)
assertThat(value()).isFalse()
startButtonFlow.value = startButtonFlow.value.copy(isVisible = true)
assertThat(value()).isTrue()
endButtonFlow.value = endButtonFlow.value.copy(isVisible = true)
assertThat(value()).isTrue()
startButtonFlow.value = startButtonFlow.value.copy(isVisible = false)
assertThat(value()).isTrue()
endButtonFlow.value = endButtonFlow.value.copy(isVisible = false)
assertThat(value()).isFalse()
}
@Test
fun indicationAreaTranslationX() = runTest {
val value = collectLastValue(underTest.indicationAreaTranslationX)
assertThat(value()).isEqualTo(0f)
repository.setClockPosition(100, 100)
assertThat(value()).isEqualTo(100f)
repository.setClockPosition(200, 100)
assertThat(value()).isEqualTo(200f)
repository.setClockPosition(200, 200)
assertThat(value()).isEqualTo(200f)
repository.setClockPosition(300, 100)
assertThat(value()).isEqualTo(300f)
}
@Test
fun indicationAreaTranslationY() = runTest {
val value = collectLastValue(underTest.indicationAreaTranslationY(DEFAULT_BURN_IN_OFFSET))
// Negative 0 - apparently there's a difference in floating point arithmetic - FML
assertThat(value()).isEqualTo(-0f)
val expected1 = setDozeAmountAndCalculateExpectedTranslationY(0.1f)
assertThat(value()).isEqualTo(expected1)
val expected2 = setDozeAmountAndCalculateExpectedTranslationY(0.2f)
assertThat(value()).isEqualTo(expected2)
val expected3 = setDozeAmountAndCalculateExpectedTranslationY(0.5f)
assertThat(value()).isEqualTo(expected3)
val expected4 = setDozeAmountAndCalculateExpectedTranslationY(1f)
assertThat(value()).isEqualTo(expected4)
}
private fun setDozeAmountAndCalculateExpectedTranslationY(dozeAmount: Float): Float {
repository.setDozeAmount(dozeAmount)
return dozeAmount * (RETURNED_BURN_IN_OFFSET - DEFAULT_BURN_IN_OFFSET)
}
companion object {
private const val DEFAULT_BURN_IN_OFFSET = 5
private const val RETURNED_BURN_IN_OFFSET = 3
}
}

View File

@@ -89,12 +89,13 @@ 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.data.repository.FakeKeyguardBouncerRepository; import com.android.systemui.keyguard.KeyguardViewConfigurator;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor; import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardFaceAuthInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel;
import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.GoneToDreamingTransitionViewModel;
@@ -253,6 +254,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
@Mock protected UserManager mUserManager; @Mock protected UserManager mUserManager;
@Mock protected UiEventLogger mUiEventLogger; @Mock protected UiEventLogger mUiEventLogger;
@Mock protected LockIconViewController mLockIconViewController; @Mock protected LockIconViewController mLockIconViewController;
@Mock protected KeyguardViewConfigurator mKeyguardViewConfigurator;
@Mock protected KeyguardMediaController mKeyguardMediaController; @Mock protected KeyguardMediaController mKeyguardMediaController;
@Mock protected NavigationModeController mNavigationModeController; @Mock protected NavigationModeController mNavigationModeController;
@Mock protected NavigationBarController mNavigationBarController; @Mock protected NavigationBarController mNavigationBarController;
@@ -342,8 +344,8 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mMainDispatcher = getMainDispatcher(); mMainDispatcher = getMainDispatcher();
mKeyguardBottomAreaInteractor = new KeyguardBottomAreaInteractor( mKeyguardBottomAreaInteractor = new KeyguardBottomAreaInteractor(
new FakeKeyguardRepository()); new FakeKeyguardRepository());
mKeyguardInteractor = new KeyguardInteractor(new FakeKeyguardRepository(), mCommandQueue,
mFeatureFlags, new FakeKeyguardBouncerRepository()); mKeyguardInteractor = KeyguardInteractorFactory.create().getKeyguardInteractor();
SystemClock systemClock = new FakeSystemClock(); SystemClock systemClock = new FakeSystemClock();
mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager, mStatusBarStateController = new StatusBarStateControllerImpl(mUiEventLogger, mDumpManager,
mInteractionJankMonitor, mShadeExpansionStateManager); mInteractionJankMonitor, mShadeExpansionStateManager);
@@ -611,6 +613,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase {
mKeyuardLongPressViewModel, mKeyuardLongPressViewModel,
mKeyguardInteractor, mKeyguardInteractor,
mActivityStarter, mActivityStarter,
mKeyguardViewConfigurator,
mKeyguardFaceAuthInteractor); mKeyguardFaceAuthInteractor);
mNotificationPanelViewController.initDependencies( mNotificationPanelViewController.initDependencies(
mCentralSurfaces, mCentralSurfaces,

View File

@@ -44,7 +44,6 @@ import com.android.systemui.shade.ShadeController;
import com.android.systemui.shade.ShadeNotificationPresenter; import com.android.systemui.shade.ShadeNotificationPresenter;
import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.ShadeViewController;
import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController; import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager; import com.android.systemui.statusbar.NotificationMediaManager;
@@ -122,7 +121,6 @@ public class StatusBarNotificationPresenterTest extends SysuiTestCase {
mock(NotificationShadeWindowController.class), mock(NotificationShadeWindowController.class),
mock(DynamicPrivacyController.class), mock(DynamicPrivacyController.class),
mKeyguardStateController, mKeyguardStateController,
mock(KeyguardIndicationController.class),
mCentralSurfaces, mCentralSurfaces,
mock(LockscreenShadeTransitionController.class), mock(LockscreenShadeTransitionController.class),
mCommandQueue, mCommandQueue,

View File

@@ -28,12 +28,10 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.keyguard.WakefulnessLifecycle import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
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.KeyguardInteractorFactory
import com.android.systemui.shade.ShadeFoldAnimator import com.android.systemui.shade.ShadeFoldAnimator
import com.android.systemui.shade.ShadeViewController import com.android.systemui.shade.ShadeViewController
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.LightRevealScrim import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.statusbar.phone.CentralSurfaces import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.unfold.util.FoldableDeviceStates import com.android.systemui.unfold.util.FoldableDeviceStates
@@ -80,8 +78,6 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
@Mock lateinit var viewTreeObserver: ViewTreeObserver @Mock lateinit var viewTreeObserver: ViewTreeObserver
@Mock private lateinit var commandQueue: CommandQueue
@Mock lateinit var shadeFoldAnimator: ShadeFoldAnimator @Mock lateinit var shadeFoldAnimator: ShadeFoldAnimator
@Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener> @Captor private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
@@ -111,15 +107,10 @@ class FoldAodAnimationControllerTest : SysuiTestCase() {
onActionStarted.run() onActionStarted.run()
} }
keyguardRepository = FakeKeyguardRepository()
val featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) } val featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
val keyguardInteractor = val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags)
KeyguardInteractor( val keyguardInteractor = withDeps.keyguardInteractor
repository = keyguardRepository, keyguardRepository = withDeps.repository
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
)
// Needs to be run on the main thread // Needs to be run on the main thread
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {

View File

@@ -39,12 +39,10 @@ import com.android.systemui.common.shared.model.Text
import com.android.systemui.coroutines.collectLastValue import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
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.KeyguardInteractorFactory
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.qs.user.UserSwitchDialogController import com.android.systemui.qs.user.UserSwitchDialogController
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -97,7 +95,6 @@ class UserInteractorTest : SysuiTestCase() {
@Mock private lateinit var dialogShower: UserSwitchDialogController.DialogShower @Mock private lateinit var dialogShower: UserSwitchDialogController.DialogShower
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver @Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver @Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private lateinit var underTest: UserInteractor private lateinit var underTest: UserInteractor
@@ -126,8 +123,9 @@ class UserInteractorTest : SysuiTestCase() {
set(Flags.FULL_SCREEN_USER_SWITCHER, false) set(Flags.FULL_SCREEN_USER_SWITCHER, false)
set(Flags.FACE_AUTH_REFACTOR, true) set(Flags.FACE_AUTH_REFACTOR, true)
} }
val reply = KeyguardInteractorFactory.create(featureFlags = featureFlags)
keyguardRepository = reply.repository
userRepository = FakeUserRepository() userRepository = FakeUserRepository()
keyguardRepository = FakeKeyguardRepository()
telephonyRepository = FakeTelephonyRepository() telephonyRepository = FakeTelephonyRepository()
val testDispatcher = StandardTestDispatcher() val testDispatcher = StandardTestDispatcher()
testScope = TestScope(testDispatcher) testScope = TestScope(testDispatcher)
@@ -142,13 +140,7 @@ class UserInteractorTest : SysuiTestCase() {
applicationContext = context, applicationContext = context,
repository = userRepository, repository = userRepository,
activityStarter = activityStarter, activityStarter = activityStarter,
keyguardInteractor = keyguardInteractor = reply.keyguardInteractor,
KeyguardInteractor(
repository = keyguardRepository,
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
),
manager = manager, manager = manager,
headlessSystemUserMode = headlessSystemUserMode, headlessSystemUserMode = headlessSystemUserMode,
applicationScope = testScope.backgroundScope, applicationScope = testScope.backgroundScope,

View File

@@ -32,11 +32,8 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -80,13 +77,11 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
@Mock private lateinit var uiEventLogger: UiEventLogger @Mock private lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver @Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver @Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private lateinit var underTest: StatusBarUserChipViewModel private lateinit var underTest: StatusBarUserChipViewModel
private val userRepository = FakeUserRepository() private val userRepository = FakeUserRepository()
private val keyguardRepository = FakeKeyguardRepository()
private lateinit var guestUserInteractor: GuestUserInteractor private lateinit var guestUserInteractor: GuestUserInteractor
private lateinit var refreshUsersScheduler: RefreshUsersScheduler private lateinit var refreshUsersScheduler: RefreshUsersScheduler
@@ -250,12 +245,8 @@ class StatusBarUserChipViewModelTest : SysuiTestCase() {
repository = userRepository, repository = userRepository,
activityStarter = activityStarter, activityStarter = activityStarter,
keyguardInteractor = keyguardInteractor =
KeyguardInteractor( KeyguardInteractorFactory.create(featureFlags = featureFlags)
repository = keyguardRepository, .keyguardInteractor,
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = FakeKeyguardBouncerRepository(),
),
featureFlags = featureFlags, featureFlags = featureFlags,
manager = manager, manager = manager,
headlessSystemUserMode = headlessSystemUserMode, headlessSystemUserMode = headlessSystemUserMode,

View File

@@ -30,11 +30,9 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.Text
import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
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.KeyguardInteractorFactory
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.policy.DeviceProvisionedController import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.telephony.data.repository.FakeTelephonyRepository import com.android.systemui.telephony.data.repository.FakeTelephonyRepository
import com.android.systemui.telephony.domain.interactor.TelephonyInteractor import com.android.systemui.telephony.domain.interactor.TelephonyInteractor
@@ -79,7 +77,6 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
@Mock private lateinit var uiEventLogger: UiEventLogger @Mock private lateinit var uiEventLogger: UiEventLogger
@Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver @Mock private lateinit var resumeSessionReceiver: GuestResumeSessionReceiver
@Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver @Mock private lateinit var resetOrExitSessionReceiver: GuestResetOrExitSessionReceiver
@Mock private lateinit var commandQueue: CommandQueue
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
private lateinit var underTest: UserSwitcherViewModel private lateinit var underTest: UserSwitcherViewModel
@@ -112,7 +109,6 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
) )
} }
keyguardRepository = FakeKeyguardRepository()
val refreshUsersScheduler = val refreshUsersScheduler =
RefreshUsersScheduler( RefreshUsersScheduler(
applicationScope = testScope.backgroundScope, applicationScope = testScope.backgroundScope,
@@ -140,38 +136,35 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
set(Flags.FULL_SCREEN_USER_SWITCHER, false) set(Flags.FULL_SCREEN_USER_SWITCHER, false)
set(Flags.FACE_AUTH_REFACTOR, true) set(Flags.FACE_AUTH_REFACTOR, true)
} }
val reply = KeyguardInteractorFactory.create(featureFlags = featureFlags)
keyguardRepository = reply.repository
underTest = underTest =
UserSwitcherViewModel( UserSwitcherViewModel(
userInteractor = userInteractor =
UserInteractor( UserInteractor(
applicationContext = context, applicationContext = context,
repository = userRepository, repository = userRepository,
activityStarter = activityStarter, activityStarter = activityStarter,
keyguardInteractor = keyguardInteractor = reply.keyguardInteractor,
KeyguardInteractor( featureFlags = featureFlags,
repository = keyguardRepository, manager = manager,
commandQueue = commandQueue, headlessSystemUserMode = headlessSystemUserMode,
featureFlags = featureFlags, applicationScope = testScope.backgroundScope,
bouncerRepository = FakeKeyguardBouncerRepository(), telephonyInteractor =
), TelephonyInteractor(
featureFlags = featureFlags, repository = FakeTelephonyRepository(),
manager = manager, ),
headlessSystemUserMode = headlessSystemUserMode, broadcastDispatcher = fakeBroadcastDispatcher,
applicationScope = testScope.backgroundScope, keyguardUpdateMonitor = keyguardUpdateMonitor,
telephonyInteractor = backgroundDispatcher = testDispatcher,
TelephonyInteractor( activityManager = activityManager,
repository = FakeTelephonyRepository(), refreshUsersScheduler = refreshUsersScheduler,
), guestUserInteractor = guestUserInteractor,
broadcastDispatcher = fakeBroadcastDispatcher, uiEventLogger = uiEventLogger,
keyguardUpdateMonitor = keyguardUpdateMonitor, ),
backgroundDispatcher = testDispatcher, guestUserInteractor = guestUserInteractor,
activityManager = activityManager, )
refreshUsersScheduler = refreshUsersScheduler,
guestUserInteractor = guestUserInteractor,
uiEventLogger = uiEventLogger,
),
guestUserInteractor = guestUserInteractor,
)
} }
@Test @Test
@@ -323,7 +316,7 @@ class UserSwitcherViewModelTest : SysuiTestCase() {
setUsers(count = 2) setUsers(count = 2)
val isFinishRequested = mutableListOf<Boolean>() val isFinishRequested = mutableListOf<Boolean>()
val job = val job =
launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) } launch(testDispatcher) { underTest.isFinishRequested.toList(isFinishRequested) }
assertThat(isFinishRequested.last()).isFalse() assertThat(isFinishRequested.last()).isFalse()
underTest.onCancelButtonClicked() underTest.onCancelButtonClicked()

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.keyguard.domain.interactor
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
/**
* Simply put, I got tired of adding a constructor argument and then having to tweak dozens of
* files. This should alleviate some of the burden by providing defaults for testing.
*/
object KeyguardInteractorFactory {
@JvmOverloads
@JvmStatic
fun create(
featureFlags: FakeFeatureFlags = createFakeFeatureFlags(),
repository: FakeKeyguardRepository = FakeKeyguardRepository(),
commandQueue: FakeCommandQueue = FakeCommandQueue(),
bouncerRepository: FakeKeyguardBouncerRepository = FakeKeyguardBouncerRepository(),
configurationRepository: FakeConfigurationRepository = FakeConfigurationRepository(),
): WithDependencies {
return WithDependencies(
repository = repository,
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = bouncerRepository,
configurationRepository = configurationRepository,
KeyguardInteractor(
repository = repository,
commandQueue = commandQueue,
featureFlags = featureFlags,
bouncerRepository = bouncerRepository,
configurationRepository = configurationRepository,
)
)
}
/** Provide defaults, otherwise tests will throw an error */
fun createFakeFeatureFlags(): FakeFeatureFlags {
return FakeFeatureFlags().apply { set(Flags.FACE_AUTH_REFACTOR, false) }
}
data class WithDependencies(
val repository: FakeKeyguardRepository,
val commandQueue: FakeCommandQueue,
val featureFlags: FakeFeatureFlags,
val bouncerRepository: FakeKeyguardBouncerRepository,
val configurationRepository: FakeConfigurationRepository,
val keyguardInteractor: KeyguardInteractor,
)
}