diff options
author | 2023-11-20 10:38:28 -0500 | |
---|---|---|
committer | 2023-11-21 17:02:27 +0000 | |
commit | d43875a34e203f2ee25abfe7dba1f98d5a980d83 (patch) | |
tree | 1ed7e54d88a4ca9c910de05ce6146ca0e567b28e | |
parent | 43fe454f23a95ec11f25620975340bf392ddb161 (diff) |
UserScopedService
Provides cached instances of a system service created with the context
of a specified user. This allows more natural interaction with APIs
which do not accept a direct UserId parameter.
Bug: 309960444
Bug: 300157408
Change-Id: Ib0abbd308a197b59c1d9ba37c7ce22d19d4dde9c
-rw-r--r-- | java/src/com/android/intentresolver/v2/data/repository/UserScopedService.kt | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/java/src/com/android/intentresolver/v2/data/repository/UserScopedService.kt b/java/src/com/android/intentresolver/v2/data/repository/UserScopedService.kt new file mode 100644 index 00000000..7ee78d91 --- /dev/null +++ b/java/src/com/android/intentresolver/v2/data/repository/UserScopedService.kt @@ -0,0 +1,46 @@ +package com.android.intentresolver.v2.data.repository + +import android.content.Context +import androidx.core.content.getSystemService +import com.android.intentresolver.v2.data.model.User + +/** + * Provides cached instances of a [system service][Context.getSystemService] created with + * [the context of a specified user][Context.createContextAsUser]. + * + * System services which have only `@UserHandleAware` APIs operate on the user id available from + * [Context.getUser], the context used to retrieve the service. This utility helps adapt a per-user + * API model to work in multi-user manner. + * + * Example usage: + * ``` + * val usageStats = userScopedService<UsageStatsManager>(context) + * + * fun getStatsForUser( + * user: User, + * from: Long, + * to: Long + * ): UsageStats { + * return usageStats.forUser(user) + * .queryUsageStats(INTERVAL_BEST, from, to) + * } + * ``` + */ +interface UserScopedService<T> { + fun forUser(user: User): T +} + +inline fun <reified T> userScopedService(context: Context): UserScopedService<T> { + return object : UserScopedService<T> { + private val map = mutableMapOf<User, T>() + + override fun forUser(user: User): T { + return synchronized(this) { + map.getOrPut(user) { + val userContext = context.createContextAsUser(user.handle, 0) + requireNotNull(userContext.getSystemService()) + } + } + } + } +} |