1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.photopicker.core.user
17 
18 import androidx.compose.ui.graphics.ImageBitmap
19 
20 /**
21  * Photopicker's Internal representation of a UserProfile, derived from [UserHandle]
22  *
23  * @property identifier unique identifier for this profile.
24  * @property handle the [UserHandle] associated with this profile.
25  * @property profileType the internal type that Photopicker considers this profile
26  * @property disabledReasons a [Set] of [DisabledReason] for why the profile cannot become the
27  *   active profile.
28  * @property enabled if the profile is currently enabled to for use in Photopicker.
29  */
30 data class UserProfile(
31     val identifier: Int,
32     val icon: ImageBitmap? = null,
33     val label: String? = null,
34     val profileType: ProfileType = ProfileType.UNKNOWN,
35     val disabledReasons: Set<DisabledReason> = emptySet(),
36 ) {
37 
38     /** A custom equals operator to not consider the value of the Icon field when it is not null */
equalsnull39     override fun equals(other: Any?): Boolean {
40         if (other !is UserProfile) return false
41         if (icon != null && other.icon == null) return false
42         if (icon == null && other.icon != null) return false
43         return identifier == other.identifier &&
44             label == other.label &&
45             profileType == other.profileType &&
46             disabledReasons == other.disabledReasons
47     }
48 
49     /** A profile is considered enabled if it has no reason to be disabled! :) */
50     val enabled = disabledReasons.isEmpty()
51 
52     // These Profile Types are only needed for devices on pre Android V to map the
53     // appropriate display resources to the type of profile. After Android V these
54     // resources are provided by the [UserManager] and so any other profiles that get
55     // added after Android V will show up as UNKNOWN.
56     enum class ProfileType {
57         PRIMARY, // For parent // base user profiles
58         MANAGED, // For Managed (aka Work) Profiles
59         UNKNOWN, // Default
60     }
61 
62     /**
63      * Why a particular profile cannot be enabled. (For determining specific error messages and
64      * priority of messages)
65      */
66     enum class DisabledReason {
67         CROSS_PROFILE_NOT_ALLOWED,
68         QUIET_MODE,
69     }
70 }
71