summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
author Mark Renouf <mrenouf@google.com> 2024-01-12 13:06:21 -0500
committer Mark Renouf <mrenouf@google.com> 2024-01-23 22:14:49 -0500
commit6eaed71f6a9b3a487441c8abb82c2ccb0c714f98 (patch)
treeb877d0fe27c6a860e9cf97005b4df9a3d59acc74 /java
parent561298bef94365950247075723dafdcfe998c745 (diff)
Updates UserRepository users to List<User>
This is a way to provide a stable iteration order to consumers. Bug: 300157408 Bug: 309960444 Test: atest IntentResolver-tests-unit Change-Id: I502b9744e93288bf1682d009c1e2ba03cfc013a9
Diffstat (limited to 'java')
-rw-r--r--java/src/com/android/intentresolver/v2/data/repository/UserRepository.kt62
1 files changed, 31 insertions, 31 deletions
diff --git a/java/src/com/android/intentresolver/v2/data/repository/UserRepository.kt b/java/src/com/android/intentresolver/v2/data/repository/UserRepository.kt
index cbf89fe8..d2011aed 100644
--- a/java/src/com/android/intentresolver/v2/data/repository/UserRepository.kt
+++ b/java/src/com/android/intentresolver/v2/data/repository/UserRepository.kt
@@ -21,7 +21,6 @@ import com.android.intentresolver.inject.Main
import com.android.intentresolver.inject.ProfileParent
import com.android.intentresolver.v2.data.broadcastFlow
import com.android.intentresolver.v2.data.model.User
-import com.android.intentresolver.v2.data.model.User.Role
import com.android.intentresolver.v2.data.repository.UserRepositoryImpl.UserEvent
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
@@ -40,10 +39,10 @@ import kotlinx.coroutines.withContext
interface UserRepository {
/**
- * A [Flow] user profile groups. Each map contains the context user along with all members of
+ * A [Flow] user profile groups. Each list contains the context user along with all members of
* the profile group. This includes the (Full) parent user, if the context user is a profile.
*/
- val users: Flow<Map<Role, User>>
+ val users: Flow<List<User>>
/**
* A [Flow] of availability. Only profile users may become unavailable.
@@ -71,7 +70,7 @@ private const val TAG = "UserRepository"
private data class UserWithState(val user: User, val available: Boolean)
-private typealias UserStateMap = Map<UserHandle, UserWithState>
+private typealias UserStates = List<UserWithState>
/** Tracks and publishes state for the parent user and associated profiles. */
class UserRepositoryImpl
@@ -111,15 +110,16 @@ constructor(
override val cause: Throwable? = null
) : RuntimeException("$message: event=$event", cause)
- private val usersWithState: Flow<UserStateMap> =
+ private val sharingScope = CoroutineScope(scope.coroutineContext + backgroundDispatcher)
+ private val usersWithState: Flow<UserStates> =
userEvents
.onStart { emit(UserEvent(INITIALIZE, profileParent)) }
- .onEach { Log.i("UserDataSource", "userEvent: $it") }
- .runningFold<UserEvent, UserStateMap>(emptyMap()) { users, event ->
+ .onEach { Log.i(TAG, "userEvent: $it") }
+ .runningFold<UserEvent, UserStates>(emptyList()) { users, event ->
try {
// Handle an action by performing some operation, then returning a new map
when (event.action) {
- INITIALIZE -> createNewUserStateMap(profileParent)
+ INITIALIZE -> createNewUserStates(profileParent)
ACTION_PROFILE_ADDED -> handleProfileAdded(event, users)
ACTION_PROFILE_REMOVED -> handleProfileRemoved(event, users)
ACTION_MANAGED_PROFILE_UNAVAILABLE,
@@ -134,19 +134,21 @@ constructor(
} catch (e: UserStateException) {
Log.e(TAG, "An error occurred handling an event: ${e.event}", e)
Log.e(TAG, "Attempting to recover...")
- createNewUserStateMap(profileParent)
+ createNewUserStates(profileParent)
}
}
- .onEach { Log.i("UserDataSource", "userStateMap: $it") }
- .stateIn(scope, SharingStarted.Eagerly, emptyMap())
+ .distinctUntilChanged()
+ .onEach { Log.i(TAG, "userStateList: $it") }
+ .stateIn(sharingScope, SharingStarted.Eagerly, emptyList())
.filterNot { it.isEmpty() }
- override val users: Flow<Map<Role, User>> = usersWithState.map { userStateMap ->
- userStateMap.map { it.value.user }.associateBy { it.role }
- }.distinctUntilChanged()
+ override val users: Flow<List<User>> =
+ usersWithState.map { userStateMap -> userStateMap.map { it.user } }.distinctUntilChanged()
private val availability: Flow<Map<UserHandle, Boolean>> =
- usersWithState.map { map -> map.mapValues { it.value.available } }.distinctUntilChanged()
+ usersWithState
+ .map { list -> list.associateBy { it.user.handle }.mapValues { it.value.available } }
+ .distinctUntilChanged()
override fun isAvailable(user: User): Flow<Boolean> {
return isAvailable(user.handle)
@@ -170,42 +172,40 @@ constructor(
}
}
- private fun handleAvailability(event: UserEvent, current: UserStateMap): UserStateMap {
+ private fun handleAvailability(event: UserEvent, current: UserStates): UserStates {
val userEntry =
- current[event.user]
+ current.firstOrNull { it.user.id == event.user.identifier }
?: throw UserStateException("User was not present in the map", event)
- return current + (event.user to userEntry.copy(available = !event.quietMode))
+ return current + userEntry.copy(available = !event.quietMode)
}
- private fun handleProfileRemoved(event: UserEvent, current: UserStateMap): UserStateMap {
- if (!current.containsKey(event.user)) {
+ private fun handleProfileRemoved(event: UserEvent, current: UserStates): UserStates {
+ if (!current.any { it.user.id == event.user.identifier }) {
throw UserStateException("User was not present in the map", event)
}
- return current.filterKeys { it != event.user }
+ return current.filter { it.user.id != event.user.identifier }
}
- private suspend fun handleProfileAdded(event: UserEvent, current: UserStateMap): UserStateMap {
+ private suspend fun handleProfileAdded(event: UserEvent, current: UserStates): UserStates {
val user =
try {
requireNotNull(readUser(event.user))
} catch (e: Exception) {
throw UserStateException("Failed to read user from UserManager", event, e)
}
- return current + (event.user to UserWithState(user, !event.quietMode))
+ return current + UserWithState(user, !event.quietMode)
}
- private suspend fun createNewUserStateMap(user: UserHandle): UserStateMap {
+ private suspend fun createNewUserStates(user: UserHandle): UserStates {
val profiles = readProfileGroup(user)
- return profiles
- .mapNotNull { userInfo ->
- userInfo.toUser()?.let { user -> UserWithState(user, userInfo.isAvailable()) }
- }
- .associateBy { it.user.handle }
+ return profiles.mapNotNull { userInfo ->
+ userInfo.toUser()?.let { user -> UserWithState(user, userInfo.isAvailable()) }
+ }
}
- private suspend fun readProfileGroup(handle: UserHandle): List<UserInfo> {
+ private suspend fun readProfileGroup(member: UserHandle): List<UserInfo> {
return withContext(backgroundDispatcher) {
- @Suppress("DEPRECATION") userManager.getEnabledProfiles(handle.identifier)
+ @Suppress("DEPRECATION") userManager.getEnabledProfiles(member.identifier)
}
.toList()
}