Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17b05e6b authored by Mark Renouf's avatar Mark Renouf
Browse files

Adds ProfileTypeRepository

The simplest test-friendly path for determining user profile types.

API note:
UserInfo usage should be deprecated by UserProperties but API is not
yet complete enough to determine policy rules in a generic way,
especially for screenshots.

For now, the profile types must be tested and checked for explicitly.

Useage of this class should be limited to screenshots handling.

Bug: 327613051
Test: N/A; this is a facade for UserManager
Flag: None
Change-Id: I97306f07e7a7e990b285c7c57ba871d00df95b63
parent bfce36ed
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.screenshot.data.model

/** The profile type of a user. */
enum class ProfileType {
    /** The user is not a profile. */
    NONE,
    /** Private space user */
    PRIVATE,
    /** Managed (work) profile. */
    WORK,
    /** Cloned apps user */
    CLONE,
    /** Communal profile */
    COMMUNAL,
}
+29 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.screenshot.data.repository

import android.annotation.UserIdInt
import com.android.systemui.screenshot.data.model.ProfileType

/** A facility for checking user profile types. */
fun interface ProfileTypeRepository {
    /**
     * Returns the profile type when [userId] refers to a profile user. If the profile type is
     * unknown or not a profile user, [ProfileType.NONE] is returned.
     */
    suspend fun getProfileType(@UserIdInt userId: Int): ProfileType
}
+58 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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.
 */
@file:SuppressLint("MissingPermission")

package com.android.systemui.screenshot.data.repository

import android.annotation.SuppressLint
import android.annotation.UserIdInt
import android.os.UserManager
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.screenshot.data.model.ProfileType
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext

/** Fetches profile types from [UserManager] as needed, caching results for a given user. */
class ProfileTypeRepositoryImpl
@Inject
constructor(
    private val userManager: UserManager,
    @Background private val background: CoroutineDispatcher
) : ProfileTypeRepository {
    /** Cache to avoid repeated requests to IActivityTaskManager for the same userId */
    private val cache = mutableMapOf<Int, ProfileType>()
    private val mutex = Mutex()

    override suspend fun getProfileType(@UserIdInt userId: Int): ProfileType {
        return mutex.withLock {
            cache[userId]
                ?: withContext(background) {
                        val userType = userManager.getUserInfo(userId).userType
                        when (userType) {
                            UserManager.USER_TYPE_PROFILE_MANAGED -> ProfileType.WORK
                            UserManager.USER_TYPE_PROFILE_PRIVATE -> ProfileType.PRIVATE
                            UserManager.USER_TYPE_PROFILE_CLONE -> ProfileType.CLONE
                            UserManager.USER_TYPE_PROFILE_COMMUNAL -> ProfileType.COMMUNAL
                            else -> ProfileType.NONE
                        }
                    }
                    .also { cache[userId] = it }
        }
    }
}
+16 −7
Original line number Diff line number Diff line
@@ -21,13 +21,21 @@ import com.android.systemui.screenshot.ImageCapture
import com.android.systemui.screenshot.RequestProcessor
import com.android.systemui.screenshot.ScreenshotPolicy
import com.android.systemui.screenshot.ScreenshotRequestProcessor
import com.android.systemui.screenshot.data.repository.ProfileTypeRepository
import com.android.systemui.screenshot.data.repository.ProfileTypeRepositoryImpl
import dagger.Binds
import dagger.Module
import dagger.Provides
import javax.inject.Provider

@Module
object ScreenshotPolicyModule {
interface ScreenshotPolicyModule {

    @Binds
    @SysUISingleton
    fun bindProfileTypeRepository(impl: ProfileTypeRepositoryImpl): ProfileTypeRepository

    companion object {
        @Provides
        @SysUISingleton
        fun bindScreenshotRequestProcessor(
@@ -37,3 +45,4 @@ object ScreenshotPolicyModule {
            return RequestProcessor(imageCapture, policyProvider.get())
        }
    }
}