From d43875a34e203f2ee25abfe7dba1f98d5a980d83 Mon Sep 17 00:00:00 2001 From: mrenouf Date: Mon, 20 Nov 2023 10:38:28 -0500 Subject: 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 --- .../v2/data/repository/UserScopedService.kt | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 java/src/com/android/intentresolver/v2/data/repository/UserScopedService.kt 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(context) + * + * fun getStatsForUser( + * user: User, + * from: Long, + * to: Long + * ): UsageStats { + * return usageStats.forUser(user) + * .queryUsageStats(INTERVAL_BEST, from, to) + * } + * ``` + */ +interface UserScopedService { + fun forUser(user: User): T +} + +inline fun userScopedService(context: Context): UserScopedService { + return object : UserScopedService { + private val map = mutableMapOf() + + override fun forUser(user: User): T { + return synchronized(this) { + map.getOrPut(user) { + val userContext = context.createContextAsUser(user.handle, 0) + requireNotNull(userContext.getSystemService()) + } + } + } + } +} -- cgit v1.2.3-59-g8ed1b