Add a AutoAddInteractor am: bd1e439025
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/23727545 Change-Id: I923d2d011e20eb570e543193eea80d57c16ed1da Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -161,7 +161,9 @@ public class QSTileHost implements QSHost, Tunable, PluginListener<QSFactory>, P
|
||||
// finishes before creating any tiles.
|
||||
tunerService.addTunable(this, TILES_SETTING);
|
||||
// AutoTileManager can modify mTiles so make sure mTiles has already been initialized.
|
||||
mAutoTiles = autoTiles.get();
|
||||
if (!mFeatureFlags.isEnabled(Flags.QS_PIPELINE_AUTO_ADD)) {
|
||||
mAutoTiles = autoTiles.get();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* 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.qs.pipeline.dagger
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/** A [LogBuffer] for the QS pipeline to track auto-added tiles */
|
||||
@Qualifier @MustBeDocumented @Retention(AnnotationRetention.RUNTIME) annotation class QSAutoAddLog
|
||||
@@ -16,13 +16,40 @@
|
||||
|
||||
package com.android.systemui.qs.pipeline.dagger
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.LogBufferFactory
|
||||
import com.android.systemui.qs.pipeline.data.repository.AutoAddRepository
|
||||
import com.android.systemui.qs.pipeline.data.repository.AutoAddSettingRepository
|
||||
import com.android.systemui.qs.pipeline.domain.model.AutoAddable
|
||||
import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.multibindings.Multibinds
|
||||
|
||||
@Module
|
||||
@Module(
|
||||
includes =
|
||||
[
|
||||
BaseAutoAddableModule::class,
|
||||
]
|
||||
)
|
||||
abstract class QSAutoAddModule {
|
||||
|
||||
@Binds abstract fun bindAutoAddRepository(impl: AutoAddSettingRepository): AutoAddRepository
|
||||
|
||||
@Multibinds abstract fun providesAutoAddableSet(): Set<AutoAddable>
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Provides a logging buffer for all logs related to the new Quick Settings pipeline to log
|
||||
* auto added tiles.
|
||||
*/
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@QSAutoAddLog
|
||||
fun provideQSAutoAddLogBuffer(factory: LogBufferFactory): LogBuffer {
|
||||
return factory.create(QSPipelineLogger.AUTO_ADD_TAG, maxSize = 100, systrace = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,5 +19,5 @@ import java.lang.annotation.Retention
|
||||
import java.lang.annotation.RetentionPolicy
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/** A {@link LogBuffer} for the new QS Pipeline for logging changes to the set of current tiles. */
|
||||
/** A [LogBuffer] for the new QS Pipeline for logging changes to the set of current tiles. */
|
||||
@Qualifier @MustBeDocumented @Retention(RetentionPolicy.RUNTIME) annotation class QSTileListLog
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.qs.pipeline.domain.interactor
|
||||
|
||||
import com.android.systemui.Dumpable
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.qs.pipeline.data.repository.AutoAddRepository
|
||||
import com.android.systemui.qs.pipeline.domain.model.AutoAddSignal
|
||||
import com.android.systemui.qs.pipeline.domain.model.AutoAddTracking
|
||||
import com.android.systemui.qs.pipeline.domain.model.AutoAddable
|
||||
import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
|
||||
import com.android.systemui.util.asIndenting
|
||||
import com.android.systemui.util.indentIfPossible
|
||||
import java.io.PrintWriter
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import kotlinx.coroutines.flow.filterIsInstance
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Collects the signals coming from all registered [AutoAddable] and adds/removes tiles accordingly.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class AutoAddInteractor
|
||||
@Inject
|
||||
constructor(
|
||||
private val autoAddables: Set<@JvmSuppressWildcards AutoAddable>,
|
||||
private val repository: AutoAddRepository,
|
||||
private val dumpManager: DumpManager,
|
||||
private val qsPipelineLogger: QSPipelineLogger,
|
||||
@Application private val scope: CoroutineScope,
|
||||
) : Dumpable {
|
||||
|
||||
private val initialized = AtomicBoolean(false)
|
||||
|
||||
/** Start collection of signals following the user from [currentTilesInteractor]. */
|
||||
fun init(currentTilesInteractor: CurrentTilesInteractor) {
|
||||
if (!initialized.compareAndSet(false, true)) {
|
||||
return
|
||||
}
|
||||
|
||||
dumpManager.registerNormalDumpable(TAG, this)
|
||||
|
||||
scope.launch {
|
||||
currentTilesInteractor.userId.collectLatest { userId ->
|
||||
coroutineScope {
|
||||
val previouslyAdded = repository.autoAddedTiles(userId).stateIn(this)
|
||||
|
||||
autoAddables
|
||||
.map { addable ->
|
||||
val autoAddSignal = addable.autoAddSignal(userId)
|
||||
when (val lifecycle = addable.autoAddTracking) {
|
||||
is AutoAddTracking.Always -> autoAddSignal
|
||||
is AutoAddTracking.Disabled -> emptyFlow()
|
||||
is AutoAddTracking.IfNotAdded -> {
|
||||
if (lifecycle.spec !in previouslyAdded.value) {
|
||||
autoAddSignal.filterIsInstance<AutoAddSignal.Add>().take(1)
|
||||
} else {
|
||||
emptyFlow()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.merge()
|
||||
.collect { signal ->
|
||||
when (signal) {
|
||||
is AutoAddSignal.Add -> {
|
||||
if (signal.spec !in previouslyAdded.value) {
|
||||
currentTilesInteractor.addTile(signal.spec, signal.position)
|
||||
qsPipelineLogger.logTileAutoAdded(
|
||||
userId,
|
||||
signal.spec,
|
||||
signal.position
|
||||
)
|
||||
repository.markTileAdded(userId, signal.spec)
|
||||
}
|
||||
}
|
||||
is AutoAddSignal.Remove -> {
|
||||
currentTilesInteractor.removeTiles(setOf(signal.spec))
|
||||
qsPipelineLogger.logTileAutoRemoved(userId, signal.spec)
|
||||
repository.unmarkTileAdded(userId, signal.spec)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun dump(pw: PrintWriter, args: Array<out String>) {
|
||||
with(pw.asIndenting()) {
|
||||
println("AutoAddables:")
|
||||
indentIfPossible { autoAddables.forEach { println(it.description) } }
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "AutoAddInteractor"
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,7 @@ interface CurrentTilesInteractor : ProtoDumpable {
|
||||
class CurrentTilesInteractorImpl
|
||||
@Inject
|
||||
constructor(
|
||||
autoAddInteractor: AutoAddInteractor,
|
||||
private val tileSpecRepository: TileSpecRepository,
|
||||
private val installedTilesComponentRepository: InstalledTilesComponentRepository,
|
||||
private val userRepository: UserRepository,
|
||||
@@ -172,6 +173,10 @@ constructor(
|
||||
if (featureFlags.isEnabled(Flags.QS_PIPELINE_NEW_HOST)) {
|
||||
startTileCollection()
|
||||
}
|
||||
|
||||
if (featureFlags.isEnabled(Flags.QS_PIPELINE_AUTO_ADD)) {
|
||||
autoAddInteractor.init(this)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.qs.pipeline.shared.logging
|
||||
import android.annotation.UserIdInt
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.LogLevel
|
||||
import com.android.systemui.qs.pipeline.dagger.QSAutoAddLog
|
||||
import com.android.systemui.qs.pipeline.dagger.QSTileListLog
|
||||
import com.android.systemui.qs.pipeline.shared.TileSpec
|
||||
import javax.inject.Inject
|
||||
@@ -32,10 +33,12 @@ class QSPipelineLogger
|
||||
@Inject
|
||||
constructor(
|
||||
@QSTileListLog private val tileListLogBuffer: LogBuffer,
|
||||
@QSAutoAddLog private val tileAutoAddLogBuffer: LogBuffer,
|
||||
) {
|
||||
|
||||
companion object {
|
||||
const val TILE_LIST_TAG = "QSTileListLog"
|
||||
const val AUTO_ADD_TAG = "QSAutoAddableLog"
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -136,6 +139,31 @@ constructor(
|
||||
)
|
||||
}
|
||||
|
||||
fun logTileAutoAdded(userId: Int, spec: TileSpec, position: Int) {
|
||||
tileAutoAddLogBuffer.log(
|
||||
AUTO_ADD_TAG,
|
||||
LogLevel.DEBUG,
|
||||
{
|
||||
int1 = userId
|
||||
int2 = position
|
||||
str1 = spec.toString()
|
||||
},
|
||||
{ "Tile $str1 auto added for user $int1 at position $int2" }
|
||||
)
|
||||
}
|
||||
|
||||
fun logTileAutoRemoved(userId: Int, spec: TileSpec) {
|
||||
tileAutoAddLogBuffer.log(
|
||||
AUTO_ADD_TAG,
|
||||
LogLevel.DEBUG,
|
||||
{
|
||||
int1 = userId
|
||||
str1 = spec.toString()
|
||||
},
|
||||
{ "Tile $str1 auto removed for user $int1" }
|
||||
)
|
||||
}
|
||||
|
||||
/** Reasons for destroying an existing tile. */
|
||||
enum class TileDestroyedReason(val readable: String) {
|
||||
TILE_REMOVED("Tile removed from current set"),
|
||||
|
||||
@@ -140,6 +140,7 @@ public class QSTileHostTest extends SysuiTestCase {
|
||||
mFeatureFlags = new FakeFeatureFlags();
|
||||
|
||||
mFeatureFlags.set(Flags.QS_PIPELINE_NEW_HOST, false);
|
||||
mFeatureFlags.set(Flags.QS_PIPELINE_AUTO_ADD, false);
|
||||
|
||||
mMainExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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.qs.pipeline.domain.interactor
|
||||
|
||||
import android.testing.AndroidTestingRunner
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.qs.pipeline.data.repository.FakeAutoAddRepository
|
||||
import com.android.systemui.qs.pipeline.domain.autoaddable.FakeAutoAddable
|
||||
import com.android.systemui.qs.pipeline.domain.model.AutoAddTracking
|
||||
import com.android.systemui.qs.pipeline.domain.model.AutoAddable
|
||||
import com.android.systemui.qs.pipeline.shared.TileSpec
|
||||
import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
|
||||
import com.android.systemui.util.mockito.any
|
||||
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.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.inOrder
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class AutoAddInteractorTest : SysuiTestCase() {
|
||||
private val testScope = TestScope()
|
||||
|
||||
private val autoAddRepository = FakeAutoAddRepository()
|
||||
|
||||
@Mock private lateinit var dumpManager: DumpManager
|
||||
@Mock private lateinit var currentTilesInteractor: CurrentTilesInteractor
|
||||
@Mock private lateinit var logger: QSPipelineLogger
|
||||
private lateinit var underTest: AutoAddInteractor
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
whenever(currentTilesInteractor.userId).thenReturn(MutableStateFlow(USER))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddable_alwaysTrack_addSignal_tileAddedAndMarked() =
|
||||
testScope.runTest {
|
||||
val fakeAutoAddable = FakeAutoAddable(SPEC, AutoAddTracking.Always)
|
||||
val autoAddedTiles by collectLastValue(autoAddRepository.autoAddedTiles(USER))
|
||||
|
||||
underTest = createInteractor(setOf(fakeAutoAddable))
|
||||
|
||||
val position = 3
|
||||
fakeAutoAddable.sendAddSignal(USER, position)
|
||||
runCurrent()
|
||||
|
||||
verify(currentTilesInteractor).addTile(SPEC, position)
|
||||
assertThat(autoAddedTiles).contains(SPEC)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddable_alwaysTrack_addThenRemoveSignal_tileAddedAndRemoved() =
|
||||
testScope.runTest {
|
||||
val fakeAutoAddable = FakeAutoAddable(SPEC, AutoAddTracking.Always)
|
||||
val autoAddedTiles by collectLastValue(autoAddRepository.autoAddedTiles(USER))
|
||||
|
||||
underTest = createInteractor(setOf(fakeAutoAddable))
|
||||
|
||||
val position = 3
|
||||
fakeAutoAddable.sendAddSignal(USER, position)
|
||||
runCurrent()
|
||||
fakeAutoAddable.sendRemoveSignal(USER)
|
||||
runCurrent()
|
||||
|
||||
val inOrder = inOrder(currentTilesInteractor)
|
||||
inOrder.verify(currentTilesInteractor).addTile(SPEC, position)
|
||||
inOrder.verify(currentTilesInteractor).removeTiles(setOf(SPEC))
|
||||
assertThat(autoAddedTiles).doesNotContain(SPEC)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddable_alwaysTrack_addSignalWhenAddedPreviously_noop() =
|
||||
testScope.runTest {
|
||||
val fakeAutoAddable = FakeAutoAddable(SPEC, AutoAddTracking.Always)
|
||||
autoAddRepository.markTileAdded(USER, SPEC)
|
||||
runCurrent()
|
||||
|
||||
underTest = createInteractor(setOf(fakeAutoAddable))
|
||||
|
||||
val position = 3
|
||||
fakeAutoAddable.sendAddSignal(USER, position)
|
||||
runCurrent()
|
||||
|
||||
verify(currentTilesInteractor, never()).addTile(SPEC, position)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddable_disabled_noInteractionsWithCurrentTilesInteractor() =
|
||||
testScope.runTest {
|
||||
val fakeAutoAddable = FakeAutoAddable(SPEC, AutoAddTracking.Disabled)
|
||||
val autoAddedTiles by collectLastValue(autoAddRepository.autoAddedTiles(USER))
|
||||
|
||||
underTest = createInteractor(setOf(fakeAutoAddable))
|
||||
|
||||
val position = 3
|
||||
fakeAutoAddable.sendAddSignal(USER, position)
|
||||
runCurrent()
|
||||
fakeAutoAddable.sendRemoveSignal(USER)
|
||||
runCurrent()
|
||||
|
||||
verify(currentTilesInteractor, never()).addTile(any(), anyInt())
|
||||
verify(currentTilesInteractor, never()).removeTiles(any())
|
||||
assertThat(autoAddedTiles).doesNotContain(SPEC)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddable_trackIfNotAdded_removeSignal_noop() =
|
||||
testScope.runTest {
|
||||
val fakeAutoAddable = FakeAutoAddable(SPEC, AutoAddTracking.IfNotAdded(SPEC))
|
||||
runCurrent()
|
||||
|
||||
underTest = createInteractor(setOf(fakeAutoAddable))
|
||||
|
||||
fakeAutoAddable.sendRemoveSignal(USER)
|
||||
runCurrent()
|
||||
|
||||
verify(currentTilesInteractor, never()).addTile(any(), anyInt())
|
||||
verify(currentTilesInteractor, never()).removeTiles(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddable_trackIfNotAdded_addSignalWhenPreviouslyAdded_noop() =
|
||||
testScope.runTest {
|
||||
val fakeAutoAddable = FakeAutoAddable(SPEC, AutoAddTracking.IfNotAdded(SPEC))
|
||||
autoAddRepository.markTileAdded(USER, SPEC)
|
||||
runCurrent()
|
||||
|
||||
underTest = createInteractor(setOf(fakeAutoAddable))
|
||||
|
||||
fakeAutoAddable.sendAddSignal(USER)
|
||||
runCurrent()
|
||||
|
||||
verify(currentTilesInteractor, never()).addTile(any(), anyInt())
|
||||
verify(currentTilesInteractor, never()).removeTiles(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddable_trackIfNotAdded_addSignal_addedAndMarked() =
|
||||
testScope.runTest {
|
||||
val fakeAutoAddable = FakeAutoAddable(SPEC, AutoAddTracking.IfNotAdded(SPEC))
|
||||
val autoAddedTiles by collectLastValue(autoAddRepository.autoAddedTiles(USER))
|
||||
|
||||
underTest = createInteractor(setOf(fakeAutoAddable))
|
||||
|
||||
val position = 3
|
||||
fakeAutoAddable.sendAddSignal(USER, position)
|
||||
runCurrent()
|
||||
|
||||
verify(currentTilesInteractor).addTile(SPEC, position)
|
||||
assertThat(autoAddedTiles).contains(SPEC)
|
||||
}
|
||||
|
||||
private fun createInteractor(autoAddables: Set<AutoAddable>): AutoAddInteractor {
|
||||
return AutoAddInteractor(
|
||||
autoAddables,
|
||||
autoAddRepository,
|
||||
dumpManager,
|
||||
logger,
|
||||
testScope.backgroundScope
|
||||
)
|
||||
.apply { init(currentTilesInteractor) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val SPEC = TileSpec.create("spec")
|
||||
private val USER = 10
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,8 @@ class CurrentTilesInteractorImplTest : SysuiTestCase() {
|
||||
|
||||
@Mock private lateinit var customTileStatePersister: CustomTileStatePersister
|
||||
|
||||
@Mock private lateinit var autoAddInteractor: AutoAddInteractor
|
||||
|
||||
@Mock private lateinit var userTracker: UserTracker
|
||||
|
||||
@Mock private lateinit var logger: QSPipelineLogger
|
||||
@@ -100,6 +102,7 @@ class CurrentTilesInteractorImplTest : SysuiTestCase() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
|
||||
featureFlags.set(Flags.QS_PIPELINE_NEW_HOST, true)
|
||||
featureFlags.set(Flags.QS_PIPELINE_AUTO_ADD, true)
|
||||
|
||||
userRepository.setUserInfos(listOf(USER_INFO_0, USER_INFO_1))
|
||||
|
||||
@@ -107,6 +110,7 @@ class CurrentTilesInteractorImplTest : SysuiTestCase() {
|
||||
|
||||
underTest =
|
||||
CurrentTilesInteractorImpl(
|
||||
autoAddInteractor = autoAddInteractor,
|
||||
tileSpecRepository = tileSpecRepository,
|
||||
installedTilesComponentRepository = installedTilesPackageRepository,
|
||||
userRepository = userRepository,
|
||||
@@ -647,6 +651,11 @@ class CurrentTilesInteractorImplTest : SysuiTestCase() {
|
||||
assertThat(tiles!![1].spec).isEqualTo(CUSTOM_TILE_SPEC)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun autoAddInteractor_initted() {
|
||||
verify(autoAddInteractor).init(underTest)
|
||||
}
|
||||
|
||||
private fun QSTile.State.fillIn(state: Int, label: CharSequence, secondaryLabel: CharSequence) {
|
||||
this.state = state
|
||||
this.label = label
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.qs.pipeline.data.repository
|
||||
|
||||
import com.android.systemui.qs.pipeline.shared.TileSpec
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
class FakeAutoAddRepository : AutoAddRepository {
|
||||
|
||||
private val autoAddedTilesPerUser = mutableMapOf<Int, MutableStateFlow<Set<TileSpec>>>()
|
||||
|
||||
override fun autoAddedTiles(userId: Int): Flow<Set<TileSpec>> {
|
||||
return getFlow(userId)
|
||||
}
|
||||
|
||||
override suspend fun markTileAdded(userId: Int, spec: TileSpec) {
|
||||
if (spec == TileSpec.Invalid) return
|
||||
with(getFlow(userId)) { value = value.toMutableSet().apply { add(spec) } }
|
||||
}
|
||||
|
||||
override suspend fun unmarkTileAdded(userId: Int, spec: TileSpec) {
|
||||
with(getFlow(userId)) { value = value.toMutableSet().apply { remove(spec) } }
|
||||
}
|
||||
|
||||
private fun getFlow(userId: Int): MutableStateFlow<Set<TileSpec>> =
|
||||
autoAddedTilesPerUser.getOrPut(userId) { MutableStateFlow(emptySet()) }
|
||||
}
|
||||
Reference in New Issue
Block a user