Merge changes Ibe1f0387,I2d1ec382 into tm-qpr-dev

* changes:
  Moves quick affordances to data layer.
  Changes quick affordance key to string.
This commit is contained in:
Ale Nijamkin
2022-10-27 01:04:15 +00:00
committed by Android (Google) Code Review
22 changed files with 229 additions and 148 deletions

View File

@@ -8,7 +8,7 @@ credit card, etc.
### Step 1: create a new quick affordance config ### Step 1: create a new quick affordance config
* Create a new class under the [systemui/keyguard/domain/quickaffordance](../../src/com/android/systemui/keyguard/domain/quickaffordance) directory * Create a new class under the [systemui/keyguard/domain/quickaffordance](../../src/com/android/systemui/keyguard/domain/quickaffordance) directory
* Please make sure that the class is injected through the Dagger dependency injection system by using the `@Inject` annotation on its main constructor and the `@SysUISingleton` annotation at class level, to make sure only one instance of the class is ever instantiated * Please make sure that the class is injected through the Dagger dependency injection system by using the `@Inject` annotation on its main constructor and the `@SysUISingleton` annotation at class level, to make sure only one instance of the class is ever instantiated
* Have the class implement the [KeyguardQuickAffordanceConfig](../../src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceConfig.kt) interface, notes: * Have the class implement the [KeyguardQuickAffordanceConfig](../../src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt) interface, notes:
* The `state` Flow property must emit `State.Hidden` when the feature is not enabled! * The `state` Flow property must emit `State.Hidden` when the feature is not enabled!
* It is safe to assume that `onQuickAffordanceClicked` will not be invoked if-and-only-if the previous rule is followed * It is safe to assume that `onQuickAffordanceClicked` will not be invoked if-and-only-if the previous rule is followed
* When implementing `onQuickAffordanceClicked`, the implementation can do something or it can ask the framework to start an activity using an `Intent` provided by the implementation * When implementing `onQuickAffordanceClicked`, the implementation can do something or it can ask the framework to start an activity using an `Intent` provided by the implementation

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.android.systemui.keyguard.data.quickaffordance
/**
* Unique identifier keys for all known built-in quick affordances.
*
* Please ensure uniqueness by never associating more than one class with each key.
*/
object BuiltInKeyguardQuickAffordanceKeys {
// Please keep alphabetical order of const names to simplify future maintenance.
const val HOME_CONTROLS = "home"
const val QR_CODE_SCANNER = "qr_code_scanner"
const val QUICK_ACCESS_WALLET = "wallet"
// Please keep alphabetical order of const names to simplify future maintenance.
}

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@@ -51,6 +51,8 @@ constructor(
private val appContext = context.applicationContext private val appContext = context.applicationContext
override val key: String = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
override val state: Flow<KeyguardQuickAffordanceConfig.State> = override val state: Flow<KeyguardQuickAffordanceConfig.State> =
component.canShowWhileLockedSetting.flatMapLatest { canShowWhileLocked -> component.canShowWhileLockedSetting.flatMapLatest { canShowWhileLocked ->
if (canShowWhileLocked) { if (canShowWhileLocked) {

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import android.content.Intent import android.content.Intent
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
@@ -26,8 +26,18 @@ import kotlinx.coroutines.flow.Flow
/** Defines interface that can act as data source for a single quick affordance model. */ /** Defines interface that can act as data source for a single quick affordance model. */
interface KeyguardQuickAffordanceConfig { interface KeyguardQuickAffordanceConfig {
/** Unique identifier for this quick affordance. It must be globally unique. */
val key: String
/** The observable [State] of the affordance. */
val state: Flow<State> val state: Flow<State>
/**
* Notifies that the affordance was clicked by the user.
*
* @param expandable An [Expandable] to use when animating dialogs or activities
* @return An [OnClickedResult] telling the caller what to do next
*/
fun onQuickAffordanceClicked(expandable: Expandable?): OnClickedResult fun onQuickAffordanceClicked(expandable: Expandable?): OnClickedResult
/** /**

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import com.android.systemui.R import com.android.systemui.R
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
@@ -37,6 +37,8 @@ constructor(
private val controller: QRCodeScannerController, private val controller: QRCodeScannerController,
) : KeyguardQuickAffordanceConfig { ) : KeyguardQuickAffordanceConfig {
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
override val state: Flow<KeyguardQuickAffordanceConfig.State> = conflatedCallbackFlow { override val state: Flow<KeyguardQuickAffordanceConfig.State> = conflatedCallbackFlow {
val callback = val callback =
object : QRCodeScannerController.Callback { object : QRCodeScannerController.Callback {

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.service.quickaccesswallet.GetWalletCardsError import android.service.quickaccesswallet.GetWalletCardsError
@@ -44,6 +44,8 @@ constructor(
private val activityStarter: ActivityStarter, private val activityStarter: ActivityStarter,
) : KeyguardQuickAffordanceConfig { ) : KeyguardQuickAffordanceConfig {
override val key: String = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
override val state: Flow<KeyguardQuickAffordanceConfig.State> = conflatedCallbackFlow { override val state: Flow<KeyguardQuickAffordanceConfig.State> = conflatedCallbackFlow {
val callback = val callback =
object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback { object : QuickAccessWalletClient.OnWalletCardsRetrievedCallback {

View File

@@ -21,15 +21,14 @@ import android.content.Intent
import com.android.internal.widget.LockPatternUtils import com.android.internal.widget.LockPatternUtils
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceRegistry import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceRegistry
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.KeyguardStateController
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.KClass
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart
@@ -70,10 +69,10 @@ constructor(
* @param expandable An optional [Expandable] for the activity- or dialog-launch animation * @param expandable An optional [Expandable] for the activity- or dialog-launch animation
*/ */
fun onQuickAffordanceClicked( fun onQuickAffordanceClicked(
configKey: KClass<out KeyguardQuickAffordanceConfig>, configKey: String,
expandable: Expandable?, expandable: Expandable?,
) { ) {
@Suppress("UNCHECKED_CAST") val config = registry.get(configKey as KClass<Nothing>) @Suppress("UNCHECKED_CAST") val config = registry.get(configKey)
when (val result = config.onQuickAffordanceClicked(expandable)) { when (val result = config.onQuickAffordanceClicked(expandable)) {
is KeyguardQuickAffordanceConfig.OnClickedResult.StartActivity -> is KeyguardQuickAffordanceConfig.OnClickedResult.StartActivity ->
launchQuickAffordance( launchQuickAffordance(
@@ -102,7 +101,7 @@ constructor(
if (index != -1) { if (index != -1) {
val visibleState = states[index] as KeyguardQuickAffordanceConfig.State.Visible val visibleState = states[index] as KeyguardQuickAffordanceConfig.State.Visible
KeyguardQuickAffordanceModel.Visible( KeyguardQuickAffordanceModel.Visible(
configKey = configs[index]::class, configKey = configs[index].key,
icon = visibleState.icon, icon = visibleState.icon,
toggle = visibleState.toggle, toggle = visibleState.toggle,
) )

View File

@@ -18,9 +18,7 @@
package com.android.systemui.keyguard.domain.model package com.android.systemui.keyguard.domain.model
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState
import kotlin.reflect.KClass
/** /**
* Models a "quick affordance" in the keyguard bottom area (for example, a button on the * Models a "quick affordance" in the keyguard bottom area (for example, a button on the
@@ -33,7 +31,7 @@ sealed class KeyguardQuickAffordanceModel {
/** A affordance is visible. */ /** A affordance is visible. */
data class Visible( data class Visible(
/** Identifier for the affordance this is modeling. */ /** Identifier for the affordance this is modeling. */
val configKey: KClass<out KeyguardQuickAffordanceConfig>, val configKey: String,
/** An icon for the affordance. */ /** An icon for the affordance. */
val icon: Icon, val icon: Icon,
/** The toggle state for the affordance. */ /** The toggle state for the affordance. */

View File

@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.domain.quickaffordance
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module

View File

@@ -17,14 +17,17 @@
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.domain.quickaffordance
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition import com.android.systemui.keyguard.data.quickaffordance.HomeControlsKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.QrCodeScannerKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.QuickAccessWalletKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.KClass
/** Central registry of all known quick affordance configs. */ /** Central registry of all known quick affordance configs. */
interface KeyguardQuickAffordanceRegistry<T : KeyguardQuickAffordanceConfig> { interface KeyguardQuickAffordanceRegistry<T : KeyguardQuickAffordanceConfig> {
fun getAll(position: KeyguardQuickAffordancePosition): List<T> fun getAll(position: KeyguardQuickAffordancePosition): List<T>
fun get(configClass: KClass<out T>): T fun get(key: String): T
} }
class KeyguardQuickAffordanceRegistryImpl class KeyguardQuickAffordanceRegistryImpl
@@ -46,8 +49,8 @@ constructor(
qrCodeScanner, qrCodeScanner,
), ),
) )
private val configByClass = private val configByKey =
configsByPosition.values.flatten().associateBy { config -> config::class } configsByPosition.values.flatten().associateBy { config -> config.key }
override fun getAll( override fun getAll(
position: KeyguardQuickAffordancePosition, position: KeyguardQuickAffordancePosition,
@@ -56,8 +59,8 @@ constructor(
} }
override fun get( override fun get(
configClass: KClass<out KeyguardQuickAffordanceConfig> key: String,
): KeyguardQuickAffordanceConfig { ): KeyguardQuickAffordanceConfig {
return configByClass.getValue(configClass) return configByKey.getValue(key)
} }
} }

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package com.android.systemui.keyguard.domain.model package com.android.systemui.keyguard.shared.quickaffordance
/** Enumerates all possible positions for quick affordances that can appear on the lock-screen. */ /** Enumerates all possible positions for quick affordances that can appear on the lock-screen. */
enum class KeyguardQuickAffordancePosition { enum class KeyguardQuickAffordancePosition {

View File

@@ -22,7 +22,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInterac
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow

View File

@@ -18,12 +18,10 @@ package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
import kotlin.reflect.KClass
/** Models the UI state of a keyguard quick affordance button. */ /** Models the UI state of a keyguard quick affordance button. */
data class KeyguardQuickAffordanceViewModel( data class KeyguardQuickAffordanceViewModel(
val configKey: KClass<out KeyguardQuickAffordanceConfig>? = null, val configKey: String? = null,
val isVisible: Boolean = false, val isVisible: Boolean = false,
/** Whether to animate the transition of the quick affordance from invisible to visible. */ /** Whether to animate the transition of the quick affordance from invisible to visible. */
val animateReveal: Boolean = false, val animateReveal: Boolean = false,
@@ -33,7 +31,7 @@ data class KeyguardQuickAffordanceViewModel(
val isActivated: Boolean = false, val isActivated: Boolean = false,
) { ) {
data class OnClickedParameters( data class OnClickedParameters(
val configKey: KClass<out KeyguardQuickAffordanceConfig>, val configKey: String,
val expandable: Expandable?, val expandable: Expandable?,
) )
} }

View File

@@ -15,10 +15,10 @@
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig.OnClickedResult import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnClickedResult
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.yield import kotlinx.coroutines.yield
@@ -29,7 +29,9 @@ import kotlinx.coroutines.yield
* This class is abstract to force tests to provide extensions of it as the system that references * This class is abstract to force tests to provide extensions of it as the system that references
* these configs uses each implementation's class type to refer to them. * these configs uses each implementation's class type to refer to them.
*/ */
abstract class FakeKeyguardQuickAffordanceConfig : KeyguardQuickAffordanceConfig { abstract class FakeKeyguardQuickAffordanceConfig(
override val key: String,
) : KeyguardQuickAffordanceConfig {
var onClickedResult: OnClickedResult = OnClickedResult.Handled var onClickedResult: OnClickedResult = OnClickedResult.Handled

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.R import com.android.systemui.R

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.R import com.android.systemui.R
@@ -23,7 +23,7 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
import com.android.systemui.controls.controller.ControlsController import com.android.systemui.controls.controller.ControlsController
import com.android.systemui.controls.dagger.ControlsComponent import com.android.systemui.controls.dagger.ControlsComponent
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig.OnClickedResult import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnClickedResult
import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import java.util.Optional import java.util.Optional

View File

@@ -1,26 +1,26 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import android.content.Intent import android.content.Intent
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig.OnClickedResult import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.OnClickedResult
import com.android.systemui.qrcodescanner.controller.QRCodeScannerController import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock

View File

@@ -1,21 +1,21 @@
/* /*
* Copyright (C) 2022 The Android Open Source Project * Copyright (C) 2022 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
* *
*/ */
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.data.quickaffordance
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.service.quickaccesswallet.GetWalletCardsResponse import android.service.quickaccesswallet.GetWalletCardsResponse

View File

@@ -25,11 +25,12 @@ import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -211,7 +212,11 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
whenever(expandable.activityLaunchController()).thenReturn(animationController) whenever(expandable.activityLaunchController()).thenReturn(animationController)
homeControls = object : FakeKeyguardQuickAffordanceConfig() {} homeControls =
object :
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
) {}
underTest = underTest =
KeyguardQuickAffordanceInteractor( KeyguardQuickAffordanceInteractor(
keyguardInteractor = KeyguardInteractor(repository = FakeKeyguardRepository()), keyguardInteractor = KeyguardInteractor(repository = FakeKeyguardRepository()),
@@ -224,8 +229,14 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
), ),
KeyguardQuickAffordancePosition.BOTTOM_END to KeyguardQuickAffordancePosition.BOTTOM_END to
listOf( listOf(
object : FakeKeyguardQuickAffordanceConfig() {}, object :
object : FakeKeyguardQuickAffordanceConfig() {}, FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
) {},
object :
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
) {},
), ),
), ),
), ),
@@ -260,7 +271,7 @@ class KeyguardQuickAffordanceInteractorParameterizedTest : SysuiTestCase() {
} }
underTest.onQuickAffordanceClicked( underTest.onQuickAffordanceClicked(
configKey = homeControls::class, configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS,
expandable = expandable, expandable = expandable,
) )

View File

@@ -22,12 +22,13 @@ import com.android.internal.widget.LockPatternUtils
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
@@ -69,9 +70,21 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
repository = FakeKeyguardRepository() repository = FakeKeyguardRepository()
repository.setKeyguardShowing(true) repository.setKeyguardShowing(true)
homeControls = object : FakeKeyguardQuickAffordanceConfig() {} homeControls =
quickAccessWallet = object : FakeKeyguardQuickAffordanceConfig() {} object :
qrCodeScanner = object : FakeKeyguardQuickAffordanceConfig() {} FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
) {}
quickAccessWallet =
object :
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
) {}
qrCodeScanner =
object :
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
) {}
underTest = underTest =
KeyguardQuickAffordanceInteractor( KeyguardQuickAffordanceInteractor(
@@ -99,7 +112,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
@Test @Test
fun `quickAffordance - bottom start affordance is visible`() = runBlockingTest { fun `quickAffordance - bottom start affordance is visible`() = runBlockingTest {
val configKey = homeControls::class val configKey = BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
homeControls.setState( homeControls.setState(
KeyguardQuickAffordanceConfig.State.Visible( KeyguardQuickAffordanceConfig.State.Visible(
icon = ICON, icon = ICON,
@@ -130,7 +143,7 @@ class KeyguardQuickAffordanceInteractorTest : SysuiTestCase() {
@Test @Test
fun `quickAffordance - bottom end affordance is visible`() = runBlockingTest { fun `quickAffordance - bottom end affordance is visible`() = runBlockingTest {
val configKey = quickAccessWallet::class val configKey = BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
quickAccessWallet.setState( quickAccessWallet.setState(
KeyguardQuickAffordanceConfig.State.Visible( KeyguardQuickAffordanceConfig.State.Visible(
icon = ICON, icon = ICON,

View File

@@ -17,8 +17,8 @@
package com.android.systemui.keyguard.domain.quickaffordance package com.android.systemui.keyguard.domain.quickaffordance
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
import kotlin.reflect.KClass import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
/** Fake implementation of [FakeKeyguardQuickAffordanceRegistry], for tests. */ /** Fake implementation of [FakeKeyguardQuickAffordanceRegistry], for tests. */
class FakeKeyguardQuickAffordanceRegistry( class FakeKeyguardQuickAffordanceRegistry(
@@ -33,11 +33,8 @@ class FakeKeyguardQuickAffordanceRegistry(
} }
override fun get( override fun get(
configClass: KClass<out FakeKeyguardQuickAffordanceConfig> key: String,
): FakeKeyguardQuickAffordanceConfig { ): FakeKeyguardQuickAffordanceConfig {
return configsByPosition.values return configsByPosition.values.flatten().associateBy { config -> config.key }.getValue(key)
.flatten()
.associateBy { config -> config::class }
.getValue(configClass)
} }
} }

View File

@@ -23,14 +23,15 @@ import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Expandable import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Icon
import com.android.systemui.doze.util.BurnInHelperWrapper import com.android.systemui.doze.util.BurnInHelperWrapper
import com.android.systemui.keyguard.data.quickaffordance.BuiltInKeyguardQuickAffordanceKeys
import com.android.systemui.keyguard.data.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
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.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardQuickAffordanceInteractor
import com.android.systemui.keyguard.domain.model.KeyguardQuickAffordancePosition
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry import com.android.systemui.keyguard.domain.quickaffordance.FakeKeyguardQuickAffordanceRegistry
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordancePosition
import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState import com.android.systemui.keyguard.shared.quickaffordance.KeyguardQuickAffordanceToggleState
import com.android.systemui.plugins.ActivityStarter import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
@@ -40,7 +41,6 @@ import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
import kotlin.reflect.KClass
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.test.runBlockingTest import kotlinx.coroutines.test.runBlockingTest
@@ -81,9 +81,21 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
whenever(burnInHelperWrapper.burnInOffset(anyInt(), any())) whenever(burnInHelperWrapper.burnInOffset(anyInt(), any()))
.thenReturn(RETURNED_BURN_IN_OFFSET) .thenReturn(RETURNED_BURN_IN_OFFSET)
homeControlsQuickAffordanceConfig = object : FakeKeyguardQuickAffordanceConfig() {} homeControlsQuickAffordanceConfig =
quickAccessWalletAffordanceConfig = object : FakeKeyguardQuickAffordanceConfig() {} object :
qrCodeScannerAffordanceConfig = object : FakeKeyguardQuickAffordanceConfig() {} FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.HOME_CONTROLS
) {}
quickAccessWalletAffordanceConfig =
object :
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QUICK_ACCESS_WALLET
) {}
qrCodeScannerAffordanceConfig =
object :
FakeKeyguardQuickAffordanceConfig(
BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
) {}
registry = registry =
FakeKeyguardQuickAffordanceRegistry( FakeKeyguardQuickAffordanceRegistry(
mapOf( mapOf(
@@ -489,7 +501,7 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
private suspend fun setUpQuickAffordanceModel( private suspend fun setUpQuickAffordanceModel(
position: KeyguardQuickAffordancePosition, position: KeyguardQuickAffordancePosition,
testConfig: TestConfig, testConfig: TestConfig,
): KClass<out FakeKeyguardQuickAffordanceConfig> { ): String {
val config = val config =
when (position) { when (position) {
KeyguardQuickAffordancePosition.BOTTOM_START -> homeControlsQuickAffordanceConfig KeyguardQuickAffordancePosition.BOTTOM_START -> homeControlsQuickAffordanceConfig
@@ -518,13 +530,13 @@ class KeyguardBottomAreaViewModelTest : SysuiTestCase() {
KeyguardQuickAffordanceConfig.State.Hidden KeyguardQuickAffordanceConfig.State.Hidden
} }
config.setState(state) config.setState(state)
return config::class return config.key
} }
private fun assertQuickAffordanceViewModel( private fun assertQuickAffordanceViewModel(
viewModel: KeyguardQuickAffordanceViewModel?, viewModel: KeyguardQuickAffordanceViewModel?,
testConfig: TestConfig, testConfig: TestConfig,
configKey: KClass<out FakeKeyguardQuickAffordanceConfig>, configKey: String,
) { ) {
checkNotNull(viewModel) checkNotNull(viewModel)
assertThat(viewModel.isVisible).isEqualTo(testConfig.isVisible) assertThat(viewModel.isVisible).isEqualTo(testConfig.isVisible)