diff options
| author | 2023-10-26 12:50:55 +0100 | |
|---|---|---|
| committer | 2023-11-02 18:23:42 +0000 | |
| commit | a75bd28537a27e5cb1097b5de8f695332c625726 (patch) | |
| tree | a8b3893528d1f6d736b2f0782d8568a7468c1722 | |
| parent | 930a7c70e84deed6b56ae1adfa6e5bd5ef1aa7c2 (diff) | |
Add package updates repository
Bug: 301055700
Test: atest CustomTilePackagesRepositoryTest
Flag: LEGACY QS_PIPELINE_NEW_TILES DISABLED
Change-Id: Ia8ec87fa8323b50c1214dae95c0a38f7ef0ba689
5 files changed, 244 insertions, 1 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt new file mode 100644 index 000000000000..6d7d88fbfa79 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt @@ -0,0 +1,61 @@ +/* + * 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.tiles.impl.custom.data.repository + +import android.os.UserHandle +import com.android.systemui.common.coroutine.ConflatedCallbackFlow +import com.android.systemui.qs.external.TileServiceManager +import com.android.systemui.qs.pipeline.shared.TileSpec +import com.android.systemui.qs.tiles.impl.custom.di.bound.CustomTileBoundScope +import com.android.systemui.qs.tiles.impl.custom.di.bound.CustomTileUser +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.shareIn + +interface CustomTilePackageUpdatesRepository { + + val packageChanges: Flow<Unit> +} + +@CustomTileBoundScope +class CustomTilePackageUpdatesRepositoryImpl +@Inject +constructor( + tileSpec: TileSpec.CustomTileSpec, + @CustomTileUser user: UserHandle, + serviceManager: TileServiceManager, + defaultsRepository: CustomTileDefaultsRepository, + @CustomTileBoundScope boundScope: CoroutineScope, +) : CustomTilePackageUpdatesRepository { + + override val packageChanges: Flow<Unit> = + ConflatedCallbackFlow.conflatedCallbackFlow { + serviceManager.setTileChangeListener { changedComponentName -> + if (changedComponentName == tileSpec.componentName) { + trySend(Unit) + } + } + + awaitClose { serviceManager.setTileChangeListener(null) } + } + .onEach { defaultsRepository.requestNewDefaults(user, tileSpec.componentName, true) } + .shareIn(boundScope, SharingStarted.WhileSubscribed()) +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/bound/CustomTileBoundComponent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/bound/CustomTileBoundComponent.kt index e33b3e917629..d382d2063f06 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/bound/CustomTileBoundComponent.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/bound/CustomTileBoundComponent.kt @@ -23,7 +23,7 @@ import kotlinx.coroutines.CoroutineScope /** @see CustomTileBoundScope */ @CustomTileBoundScope -@Subcomponent +@Subcomponent(modules = [CustomTileBoundModule::class]) interface CustomTileBoundComponent { @Subcomponent.Builder diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/bound/CustomTileBoundModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/bound/CustomTileBoundModule.kt new file mode 100644 index 000000000000..889424a8e8d3 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/bound/CustomTileBoundModule.kt @@ -0,0 +1,31 @@ +/* + * 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.tiles.impl.custom.di.bound + +import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository +import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepositoryImpl +import dagger.Binds +import dagger.Module + +@Module +interface CustomTileBoundModule { + + @Binds + fun bindCustomTilePackageUpdatesRepository( + impl: CustomTilePackageUpdatesRepositoryImpl + ): CustomTilePackageUpdatesRepository +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt new file mode 100644 index 000000000000..4a221134ce67 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt @@ -0,0 +1,119 @@ +/* + * 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.tiles.impl.custom + +import android.content.ComponentName +import android.os.UserHandle +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.qs.external.TileLifecycleManager +import com.android.systemui.qs.external.TileServiceManager +import com.android.systemui.qs.pipeline.shared.TileSpec +import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository +import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepositoryImpl +import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileDefaultsRepository +import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileDefaultsRepository.DefaultsRequest +import com.android.systemui.util.mockito.capture +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.test.StandardTestDispatcher +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.ArgumentCaptor +import org.mockito.Captor +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@OptIn(ExperimentalCoroutinesApi::class) +@SmallTest +@RunWith(AndroidJUnit4::class) +class CustomTilePackageUpdatesRepositoryTest : SysuiTestCase() { + + @Mock private lateinit var tileServiceManager: TileServiceManager + + @Captor + private lateinit var listenerCaptor: ArgumentCaptor<TileLifecycleManager.TileChangeListener> + + private val defaultsRepository = FakeCustomTileDefaultsRepository() + private val testDispatcher = StandardTestDispatcher() + private val testScope = TestScope(testDispatcher) + + private lateinit var underTest: CustomTilePackageUpdatesRepository + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + underTest = + CustomTilePackageUpdatesRepositoryImpl( + TileSpec.create(COMPONENT_1), + USER, + tileServiceManager, + defaultsRepository, + testScope.backgroundScope, + ) + } + + @Test + fun packageChangesUpdatesDefaults() = + testScope.runTest { + val events = mutableListOf<Unit>() + underTest.packageChanges.onEach { events.add(it) }.launchIn(backgroundScope) + runCurrent() + verify(tileServiceManager).setTileChangeListener(capture(listenerCaptor)) + + emitPackageChange() + runCurrent() + + assertThat(events).hasSize(1) + assertThat(defaultsRepository.defaultsRequests).isNotEmpty() + assertThat(defaultsRepository.defaultsRequests.last()) + .isEqualTo(DefaultsRequest(USER, COMPONENT_1, true)) + } + + @Test + fun packageChangesEmittedOnlyForTheTile() = + testScope.runTest { + val events = mutableListOf<Unit>() + underTest.packageChanges.onEach { events.add(it) }.launchIn(backgroundScope) + runCurrent() + verify(tileServiceManager).setTileChangeListener(capture(listenerCaptor)) + + emitPackageChange(COMPONENT_2) + runCurrent() + + assertThat(events).isEmpty() + } + + private fun emitPackageChange(componentName: ComponentName = COMPONENT_1) { + listenerCaptor.value.onTileChanged(componentName) + } + + private companion object { + val USER = UserHandle(0) + val COMPONENT_1 = ComponentName("pkg.test.1", "cls.test") + val COMPONENT_2 = ComponentName("pkg.test.2", "cls.test") + } +} diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTilePackageUpdatesRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTilePackageUpdatesRepository.kt new file mode 100644 index 000000000000..8f972f52729f --- /dev/null +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTilePackageUpdatesRepository.kt @@ -0,0 +1,32 @@ +/* + * 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.tiles.impl.custom.data.repository + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow + +class FakeCustomTilePackageUpdatesRepository : CustomTilePackageUpdatesRepository { + + private val mutablePackageChanges = MutableSharedFlow<Unit>() + + override val packageChanges: Flow<Unit> + get() = mutablePackageChanges + + suspend fun emitPackageChange() { + mutablePackageChanges.emit(Unit) + } +} |