Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b4f8b1a authored by Alejandro Nijamkin's avatar Alejandro Nijamkin
Browse files

Moves quick affordances into domain layer.

After much discussion, it became clear that it would be better to move
quic affordance config definitions out of the data layer and into the
domain layer.

This CL does the following:
1. Moves config definitions to the domain layer
2. Moves the "configs" class to the domain layer and renames it to
   "registry"
3. Eliminates the quick affordance repository from the data layer,
   merging its logic into the observe quick affordance use-case
4. Updates the documentation

Fix: 241681067
Test: Unit tests updated. Manually verified the bottom area quick
affordances still work properly when locked, unlocked, and dozing.
Played with the settings under Display > Lock screen to turn the on and
off.

Change-Id: I4b293eeef02e5546fc834008b096e4a7935657fe
parent 5f7ead34
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -6,16 +6,16 @@ credit card, etc.

## Adding a new Quick Affordance
### Step 1: create a new quick affordance config
* Create a new class under the [systemui/keyguard/data/quickaffordance](../../src/com/android/systemui/keyguard/data/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
* Have the class implement the [KeyguardQuickAffordanceConfig](../../src/com/android/systemui/keyguard/data/quickaffordance/KeyguardQuickAffordanceConfig.kt) interface, notes:
* Have the class implement the [KeyguardQuickAffordanceConfig](../../src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceConfig.kt) interface, notes:
  * 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
  * 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
* Please include a unit test for your new implementation under [the correct directory](../../tests/src/com/android/systemui/keyguard/data/quickaffordance)
* Please include a unit test for your new implementation under [the correct directory](../../tests/src/com/android/systemui/keyguard/domain/quickaffordance)

### Step 2: choose a position and priority
* Add the new class as a dependency in the constructor of [KeyguardQuickAffordanceConfigs](../../src/com/android/systemui/keyguard/data/repository/KeyguardQuickAffordanceConfigs.kt)
* Add the new class as a dependency in the constructor of [KeyguardQuickAffordanceRegistry](../../src/com/android/systemui/keyguard/domain/quickaffordance/KeyguardQuickAffordanceRegistry.kt)
* Place the new class in one of the available positions in the `configsByPosition` property, note:
  * In each position, there is a list. The order matters. The order of that list is the priority order in which the framework considers each config. The first config whose state property returns `State.Visible` determines the button that is shown for that position
  * Please only add to one position. The framework treats each position individually and there is no good way to prevent the same config from making its button appear in more than one position at the same time
+2 −0
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.data.repository.KeyguardRepositoryModule;
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceModule;
import com.android.systemui.keyguard.domain.usecase.KeyguardUseCaseModule;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.statusbar.NotificationShadeDepthController;
@@ -70,6 +71,7 @@ import dagger.Provides;
        KeyguardUserSwitcherComponent.class},
        includes = {
            FalsingModule.class,
            KeyguardQuickAffordanceModule.class,
            KeyguardRepositoryModule.class,
            KeyguardUseCaseModule.class,
        })
+0 −65
Original line number Diff line number Diff line
/*
 * 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.repository

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.data.config.KeyguardQuickAffordanceConfigs
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig.State
import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordanceModel
import com.android.systemui.keyguard.shared.model.KeyguardQuickAffordancePosition
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine

/** Defines interface for classes that encapsulate quick affordance state for the keyguard. */
interface KeyguardQuickAffordanceRepository {
    fun affordance(position: KeyguardQuickAffordancePosition): Flow<KeyguardQuickAffordanceModel>
}

/** Real implementation of [KeyguardQuickAffordanceRepository] */
@SysUISingleton
class KeyguardQuickAffordanceRepositoryImpl
@Inject
constructor(
    private val configs: KeyguardQuickAffordanceConfigs,
) : KeyguardQuickAffordanceRepository {

    /** Returns an observable for the quick affordance model in the given position. */
    override fun affordance(
        position: KeyguardQuickAffordancePosition
    ): Flow<KeyguardQuickAffordanceModel> {
        val configs = configs.getAll(position)
        return combine(configs.map { config -> config.state }) { states ->
            val index = states.indexOfFirst { state -> state is State.Visible }
            val visibleState =
                if (index != -1) {
                    states[index] as State.Visible
                } else {
                    null
                }
            if (visibleState != null) {
                KeyguardQuickAffordanceModel.Visible(
                    configKey = configs[index]::class,
                    icon = visibleState.icon,
                    contentDescriptionResourceId = visibleState.contentDescriptionResourceId,
                )
            } else {
                KeyguardQuickAffordanceModel.Hidden
            }
        }
    }
}
+0 −12
Original line number Diff line number Diff line
@@ -16,22 +16,10 @@

package com.android.systemui.keyguard.data.repository

import com.android.systemui.keyguard.data.config.KeyguardQuickAffordanceConfigs
import com.android.systemui.keyguard.data.config.KeyguardQuickAffordanceConfigsImpl
import dagger.Binds
import dagger.Module

@Module
interface KeyguardRepositoryModule {
    @Binds fun keyguardRepository(impl: KeyguardRepositoryImpl): KeyguardRepository

    @Binds
    fun keyguardQuickAffordanceRepository(
        impl: KeyguardQuickAffordanceRepositoryImpl
    ): KeyguardQuickAffordanceRepository

    @Binds
    fun keyguardQuickAffordanceConfigs(
        impl: KeyguardQuickAffordanceConfigsImpl
    ): KeyguardQuickAffordanceConfigs
}
+19 −3
Original line number Diff line number Diff line
@@ -15,11 +15,11 @@
 *
 */

package com.android.systemui.keyguard.shared.model
package com.android.systemui.keyguard.domain.model

import androidx.annotation.StringRes
import com.android.systemui.containeddrawable.ContainedDrawable
import com.android.systemui.keyguard.data.quickaffordance.KeyguardQuickAffordanceConfig
import com.android.systemui.keyguard.domain.quickaffordance.KeyguardQuickAffordanceConfig
import kotlin.reflect.KClass

/**
@@ -27,7 +27,6 @@ import kotlin.reflect.KClass
 * lock-screen).
 */
sealed class KeyguardQuickAffordanceModel {

    /** No affordance should show up. */
    object Hidden : KeyguardQuickAffordanceModel()

@@ -43,4 +42,21 @@ sealed class KeyguardQuickAffordanceModel {
         */
        @StringRes val contentDescriptionResourceId: Int,
    ) : KeyguardQuickAffordanceModel()

    companion object {
        fun from(
            state: KeyguardQuickAffordanceConfig.State?,
            configKey: KClass<out KeyguardQuickAffordanceConfig>,
        ): KeyguardQuickAffordanceModel {
            return when (state) {
                is KeyguardQuickAffordanceConfig.State.Visible ->
                    Visible(
                        configKey = configKey,
                        icon = state.icon,
                        contentDescriptionResourceId = state.contentDescriptionResourceId,
                    )
                else -> Hidden
            }
        }
    }
}
Loading