Loading packages/SystemUI/src/com/android/systemui/common/data/datastore/DataStoreWrapperFactory.kt +12 −8 Original line number Diff line number Diff line Loading @@ -20,29 +20,33 @@ import android.annotation.UserIdInt import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.emptyPreferences import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.settings.UserFileManager import javax.inject.Inject import kotlinx.coroutines.CoroutineScope interface DataStoreWrapperFactory { fun create(dataStoreFileName: String, @UserIdInt userId: Int): DataStoreWrapper fun create( dataStoreFileName: String, @UserIdInt userId: Int, scope: CoroutineScope, ): DataStoreWrapper } class DataStoreWrapperFactoryImpl @Inject constructor( @Background private val backgroundScope: CoroutineScope, private val userFileManager: UserFileManager, ) : DataStoreWrapperFactory { constructor(private val userFileManager: UserFileManager) : DataStoreWrapperFactory { override fun create(dataStoreFileName: String, userId: Int): DataStoreWrapper { override fun create( dataStoreFileName: String, userId: Int, scope: CoroutineScope, ): DataStoreWrapper { return DataStoreWrapperImpl( dataStore = PreferenceDataStoreFactory.create( corruptionHandler = ReplaceFileCorruptionHandler(produceNewData = { emptyPreferences() }), scope = backgroundScope, scope = scope, ) { userFileManager.getFile(dataStoreFileName, userId) } Loading packages/SystemUI/src/com/android/systemui/scene/data/repository/DualShadeEducationRepository.kt +28 −21 Original line number Diff line number Diff line Loading @@ -32,10 +32,10 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.scene.data.model.DualShadeEducationImpressionModel import com.android.systemui.scene.shared.model.DualShadeEducationElement import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext Loading @@ -44,7 +44,6 @@ class DualShadeEducationRepository @Inject constructor( @Background private val backgroundScope: CoroutineScope, @Background private val backgroundDispatcher: CoroutineDispatcher, private val dataStoreWrapperFactory: DataStoreWrapperFactory, ) { Loading @@ -67,25 +66,34 @@ constructor( get() = _elementBounds private var dataStore: DataStoreWrapper? = null private var hydrationJob: Job? = null private var dataStoreJob: Job? = null /** * Keeps the repository data up-to-date for the user identified by [selectedUserId]; runs until * cancelled by the caller. */ suspend fun activateFor(@UserIdInt selectedUserId: Int) { dataStoreJob?.cancelAndJoin() val dataStoreScope = CoroutineScope( context = backgroundScope.coroutineContext + Job(backgroundScope.coroutineContext[Job]) ) dataStoreJob = dataStoreScope.coroutineContext[Job] val newDataStore = dataStoreWrapperFactory.create( dataStoreFileName = DATA_STORE_FILE_NAME, userId = selectedUserId, scope = dataStoreScope, ) dataStore = newDataStore coroutineScope { hydrationJob?.cancel() hydrationJob = launch(backgroundDispatcher) { dataStoreScope.launch { repeatWhenPrefsChange(newDataStore) { prefs -> if (!isActive) { return@repeatWhenPrefsChange } impressions = DualShadeEducationImpressionModel( everShownNotificationsShade = Loading @@ -100,7 +108,6 @@ constructor( } } } } suspend fun setEverShownNotificationsShade(value: Boolean) { persist(Keys.EverShownNotificationsShade, value) Loading packages/SystemUI/tests/utils/src/com/android/systemui/common/data/datastore/DataStoreWrapperKosmos.kt +6 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,17 @@ package com.android.systemui.common.data.datastore import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import kotlinx.coroutines.CoroutineScope val Kosmos.dataStoreWrapperFactory by Fixture { object : DataStoreWrapperFactory { private val cache = mutableMapOf<Int, DataStoreWrapper>() override fun create(dataStoreFileName: String, userId: Int): DataStoreWrapper { override fun create( dataStoreFileName: String, userId: Int, scope: CoroutineScope, ): DataStoreWrapper { return cache.getOrPut(userId) { FakeDataStoreWrapperImpl() } } } Loading packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/DualShadeEducationRepositoryKosmos.kt +0 −2 Original line number Diff line number Diff line Loading @@ -20,12 +20,10 @@ import com.android.systemui.common.data.datastore.dataStoreWrapperFactory import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.testDispatcher val Kosmos.dualShadeEducationRepository by Fixture { DualShadeEducationRepository( backgroundScope = backgroundScope, backgroundDispatcher = testDispatcher, dataStoreWrapperFactory = dataStoreWrapperFactory, ) } Loading
packages/SystemUI/src/com/android/systemui/common/data/datastore/DataStoreWrapperFactory.kt +12 −8 Original line number Diff line number Diff line Loading @@ -20,29 +20,33 @@ import android.annotation.UserIdInt import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler import androidx.datastore.preferences.core.PreferenceDataStoreFactory import androidx.datastore.preferences.core.emptyPreferences import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.settings.UserFileManager import javax.inject.Inject import kotlinx.coroutines.CoroutineScope interface DataStoreWrapperFactory { fun create(dataStoreFileName: String, @UserIdInt userId: Int): DataStoreWrapper fun create( dataStoreFileName: String, @UserIdInt userId: Int, scope: CoroutineScope, ): DataStoreWrapper } class DataStoreWrapperFactoryImpl @Inject constructor( @Background private val backgroundScope: CoroutineScope, private val userFileManager: UserFileManager, ) : DataStoreWrapperFactory { constructor(private val userFileManager: UserFileManager) : DataStoreWrapperFactory { override fun create(dataStoreFileName: String, userId: Int): DataStoreWrapper { override fun create( dataStoreFileName: String, userId: Int, scope: CoroutineScope, ): DataStoreWrapper { return DataStoreWrapperImpl( dataStore = PreferenceDataStoreFactory.create( corruptionHandler = ReplaceFileCorruptionHandler(produceNewData = { emptyPreferences() }), scope = backgroundScope, scope = scope, ) { userFileManager.getFile(dataStoreFileName, userId) } Loading
packages/SystemUI/src/com/android/systemui/scene/data/repository/DualShadeEducationRepository.kt +28 −21 Original line number Diff line number Diff line Loading @@ -32,10 +32,10 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.scene.data.model.DualShadeEducationImpressionModel import com.android.systemui.scene.shared.model.DualShadeEducationElement import javax.inject.Inject import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.cancelAndJoin import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext Loading @@ -44,7 +44,6 @@ class DualShadeEducationRepository @Inject constructor( @Background private val backgroundScope: CoroutineScope, @Background private val backgroundDispatcher: CoroutineDispatcher, private val dataStoreWrapperFactory: DataStoreWrapperFactory, ) { Loading @@ -67,25 +66,34 @@ constructor( get() = _elementBounds private var dataStore: DataStoreWrapper? = null private var hydrationJob: Job? = null private var dataStoreJob: Job? = null /** * Keeps the repository data up-to-date for the user identified by [selectedUserId]; runs until * cancelled by the caller. */ suspend fun activateFor(@UserIdInt selectedUserId: Int) { dataStoreJob?.cancelAndJoin() val dataStoreScope = CoroutineScope( context = backgroundScope.coroutineContext + Job(backgroundScope.coroutineContext[Job]) ) dataStoreJob = dataStoreScope.coroutineContext[Job] val newDataStore = dataStoreWrapperFactory.create( dataStoreFileName = DATA_STORE_FILE_NAME, userId = selectedUserId, scope = dataStoreScope, ) dataStore = newDataStore coroutineScope { hydrationJob?.cancel() hydrationJob = launch(backgroundDispatcher) { dataStoreScope.launch { repeatWhenPrefsChange(newDataStore) { prefs -> if (!isActive) { return@repeatWhenPrefsChange } impressions = DualShadeEducationImpressionModel( everShownNotificationsShade = Loading @@ -100,7 +108,6 @@ constructor( } } } } suspend fun setEverShownNotificationsShade(value: Boolean) { persist(Keys.EverShownNotificationsShade, value) Loading
packages/SystemUI/tests/utils/src/com/android/systemui/common/data/datastore/DataStoreWrapperKosmos.kt +6 −1 Original line number Diff line number Diff line Loading @@ -18,12 +18,17 @@ package com.android.systemui.common.data.datastore import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import kotlinx.coroutines.CoroutineScope val Kosmos.dataStoreWrapperFactory by Fixture { object : DataStoreWrapperFactory { private val cache = mutableMapOf<Int, DataStoreWrapper>() override fun create(dataStoreFileName: String, userId: Int): DataStoreWrapper { override fun create( dataStoreFileName: String, userId: Int, scope: CoroutineScope, ): DataStoreWrapper { return cache.getOrPut(userId) { FakeDataStoreWrapperImpl() } } } Loading
packages/SystemUI/tests/utils/src/com/android/systemui/scene/data/repository/DualShadeEducationRepositoryKosmos.kt +0 −2 Original line number Diff line number Diff line Loading @@ -20,12 +20,10 @@ import com.android.systemui.common.data.datastore.dataStoreWrapperFactory import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture import com.android.systemui.kosmos.backgroundScope import com.android.systemui.kosmos.testDispatcher val Kosmos.dualShadeEducationRepository by Fixture { DualShadeEducationRepository( backgroundScope = backgroundScope, backgroundDispatcher = testDispatcher, dataStoreWrapperFactory = dataStoreWrapperFactory, ) }