1 /*
2  * Copyright (C) 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 
17 package com.android.intentresolver
18 
19 import com.android.intentresolver.Flags.FLAG_ENABLE_PRIVATE_PROFILE
20 import com.android.intentresolver.annotation.JavaInterop
21 import com.android.intentresolver.data.repository.FakeUserRepository
22 import com.android.intentresolver.domain.interactor.UserInteractor
23 import com.android.intentresolver.inject.FakeIntentResolverFlags
24 import com.android.intentresolver.shared.model.Profile
25 import com.android.intentresolver.shared.model.User
26 import com.google.common.truth.Truth.assertThat
27 import kotlinx.coroutines.Dispatchers
28 import kotlinx.coroutines.test.runTest
29 import org.junit.Test
30 
31 @OptIn(JavaInterop::class)
32 class ProfileHelperTest {
33 
34     private val personalUser = User(0, User.Role.PERSONAL)
35     private val cloneUser = User(10, User.Role.CLONE)
36 
37     private val personalProfile = Profile(Profile.Type.PERSONAL, personalUser)
38     private val personalWithCloneProfile = Profile(Profile.Type.PERSONAL, personalUser, cloneUser)
39 
40     private val workUser = User(11, User.Role.WORK)
41     private val workProfile = Profile(Profile.Type.WORK, workUser)
42 
43     private val privateUser = User(12, User.Role.PRIVATE)
44     private val privateProfile = Profile(Profile.Type.PRIVATE, privateUser)
45 
46     private val flags =
<lambda>null47         FakeIntentResolverFlags().apply { setFlag(FLAG_ENABLE_PRIVATE_PROFILE, true) }
48 
assertProfilesnull49     private fun assertProfiles(
50         helper: ProfileHelper,
51         personalProfile: Profile,
52         workProfile: Profile? = null,
53         privateProfile: Profile? = null
54     ) {
55         assertThat(helper.personalProfile).isEqualTo(personalProfile)
56         assertThat(helper.personalHandle).isEqualTo(personalProfile.primary.handle)
57 
58         personalProfile.clone?.also {
59             assertThat(helper.cloneUserPresent).isTrue()
60             assertThat(helper.cloneHandle).isEqualTo(it.handle)
61         }
62             ?: {
63                 assertThat(helper.cloneUserPresent).isFalse()
64                 assertThat(helper.cloneHandle).isNull()
65             }
66 
67         workProfile?.also {
68             assertThat(helper.workProfilePresent).isTrue()
69             assertThat(helper.workProfile).isEqualTo(it)
70             assertThat(helper.workHandle).isEqualTo(it.primary.handle)
71         }
72             ?: {
73                 assertThat(helper.workProfilePresent).isFalse()
74                 assertThat(helper.workProfile).isNull()
75                 assertThat(helper.workHandle).isNull()
76             }
77 
78         privateProfile?.also {
79             assertThat(helper.privateProfilePresent).isTrue()
80             assertThat(helper.privateProfile).isEqualTo(it)
81             assertThat(helper.privateHandle).isEqualTo(it.primary.handle)
82         }
83             ?: {
84                 assertThat(helper.privateProfilePresent).isFalse()
85                 assertThat(helper.privateProfile).isNull()
86                 assertThat(helper.privateHandle).isNull()
87             }
88     }
89 
90     @Test
<lambda>null91     fun launchedByPersonal() = runTest {
92         val repository = FakeUserRepository(listOf(personalUser))
93         val interactor = UserInteractor(repository, launchedAs = personalUser.handle)
94 
95         val helper =
96             ProfileHelper(
97                 interactor = interactor,
98                 scope = this,
99                 background = Dispatchers.Unconfined,
100                 flags = flags
101             )
102 
103         assertProfiles(helper, personalProfile)
104 
105         assertThat(helper.isLaunchedAsCloneProfile).isFalse()
106         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.PERSONAL)
107         assertThat(helper.getQueryIntentsHandle(personalUser.handle))
108             .isEqualTo(personalProfile.primary.handle)
109         assertThat(helper.tabOwnerUserHandleForLaunch).isEqualTo(personalProfile.primary.handle)
110     }
111 
112     @Test
<lambda>null113     fun launchedByPersonal_withClone() = runTest {
114         val repository = FakeUserRepository(listOf(personalUser, cloneUser))
115         val interactor = UserInteractor(repository, launchedAs = personalUser.handle)
116 
117         val helper =
118             ProfileHelper(
119                 interactor = interactor,
120                 scope = this,
121                 background = Dispatchers.Unconfined,
122                 flags = flags
123             )
124 
125         assertProfiles(helper, personalWithCloneProfile)
126 
127         assertThat(helper.isLaunchedAsCloneProfile).isFalse()
128         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.PERSONAL)
129         assertThat(helper.getQueryIntentsHandle(personalUser.handle)).isEqualTo(personalUser.handle)
130         assertThat(helper.tabOwnerUserHandleForLaunch).isEqualTo(personalProfile.primary.handle)
131     }
132 
133     @Test
<lambda>null134     fun launchedByClone() = runTest {
135         val repository = FakeUserRepository(listOf(personalUser, cloneUser))
136         val interactor = UserInteractor(repository, launchedAs = cloneUser.handle)
137 
138         val helper =
139             ProfileHelper(
140                 interactor = interactor,
141                 scope = this,
142                 background = Dispatchers.Unconfined,
143                 flags = flags
144             )
145 
146         assertProfiles(helper, personalWithCloneProfile)
147 
148         assertThat(helper.isLaunchedAsCloneProfile).isTrue()
149         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.PERSONAL)
150         assertThat(helper.getQueryIntentsHandle(personalWithCloneProfile.primary.handle))
151             .isEqualTo(personalWithCloneProfile.clone?.handle)
152         assertThat(helper.tabOwnerUserHandleForLaunch)
153             .isEqualTo(personalWithCloneProfile.primary.handle)
154     }
155 
156     @Test
<lambda>null157     fun launchedByPersonal_withWork() = runTest {
158         val repository = FakeUserRepository(listOf(personalUser, workUser))
159         val interactor = UserInteractor(repository, launchedAs = personalUser.handle)
160 
161         val helper =
162             ProfileHelper(
163                 interactor = interactor,
164                 scope = this,
165                 background = Dispatchers.Unconfined,
166                 flags = flags
167             )
168 
169         assertProfiles(helper, personalProfile = personalProfile, workProfile = workProfile)
170 
171         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.PERSONAL)
172         assertThat(helper.isLaunchedAsCloneProfile).isFalse()
173         assertThat(helper.getQueryIntentsHandle(personalUser.handle))
174             .isEqualTo(personalProfile.primary.handle)
175         assertThat(helper.getQueryIntentsHandle(workUser.handle))
176             .isEqualTo(workProfile.primary.handle)
177         assertThat(helper.tabOwnerUserHandleForLaunch).isEqualTo(personalProfile.primary.handle)
178     }
179 
180     @Test
<lambda>null181     fun launchedByWork() = runTest {
182         val repository = FakeUserRepository(listOf(personalUser, workUser))
183         val interactor = UserInteractor(repository, launchedAs = workUser.handle)
184 
185         val helper =
186             ProfileHelper(
187                 interactor = interactor,
188                 scope = this,
189                 background = Dispatchers.Unconfined,
190                 flags = flags
191             )
192 
193         assertProfiles(helper, personalProfile = personalProfile, workProfile = workProfile)
194 
195         assertThat(helper.isLaunchedAsCloneProfile).isFalse()
196         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.WORK)
197         assertThat(helper.getQueryIntentsHandle(personalProfile.primary.handle))
198             .isEqualTo(personalProfile.primary.handle)
199         assertThat(helper.getQueryIntentsHandle(workProfile.primary.handle))
200             .isEqualTo(workProfile.primary.handle)
201         assertThat(helper.tabOwnerUserHandleForLaunch).isEqualTo(workProfile.primary.handle)
202     }
203 
204     @Test
<lambda>null205     fun launchedByPersonal_withPrivate() = runTest {
206         val repository = FakeUserRepository(listOf(personalUser, privateUser))
207         val interactor = UserInteractor(repository, launchedAs = personalUser.handle)
208 
209         val helper =
210             ProfileHelper(
211                 interactor = interactor,
212                 scope = this,
213                 background = Dispatchers.Unconfined,
214                 flags = flags
215             )
216 
217         assertProfiles(helper, personalProfile = personalProfile, privateProfile = privateProfile)
218 
219         assertThat(helper.isLaunchedAsCloneProfile).isFalse()
220         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.PERSONAL)
221         assertThat(helper.getQueryIntentsHandle(personalProfile.primary.handle))
222             .isEqualTo(personalProfile.primary.handle)
223         assertThat(helper.getQueryIntentsHandle(privateProfile.primary.handle))
224             .isEqualTo(privateProfile.primary.handle)
225         assertThat(helper.tabOwnerUserHandleForLaunch).isEqualTo(personalProfile.primary.handle)
226     }
227 
228     @Test
<lambda>null229     fun launchedByPrivate() = runTest {
230         val repository = FakeUserRepository(listOf(personalUser, privateUser))
231         val interactor = UserInteractor(repository, launchedAs = privateUser.handle)
232 
233         val helper =
234             ProfileHelper(
235                 interactor = interactor,
236                 scope = this,
237                 background = Dispatchers.Unconfined,
238                 flags = flags
239             )
240 
241         assertProfiles(helper, personalProfile = personalProfile, privateProfile = privateProfile)
242 
243         assertThat(helper.isLaunchedAsCloneProfile).isFalse()
244         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.PRIVATE)
245         assertThat(helper.getQueryIntentsHandle(personalProfile.primary.handle))
246             .isEqualTo(personalProfile.primary.handle)
247         assertThat(helper.getQueryIntentsHandle(privateProfile.primary.handle))
248             .isEqualTo(privateProfile.primary.handle)
249         assertThat(helper.tabOwnerUserHandleForLaunch).isEqualTo(privateProfile.primary.handle)
250     }
251 
252     @Test
<lambda>null253     fun launchedByPersonal_withPrivate_privateDisabled() = runTest {
254         flags.setFlag(FLAG_ENABLE_PRIVATE_PROFILE, false)
255 
256         val repository = FakeUserRepository(listOf(personalUser, privateUser))
257         val interactor = UserInteractor(repository, launchedAs = personalUser.handle)
258 
259         val helper =
260             ProfileHelper(
261                 interactor = interactor,
262                 scope = this,
263                 background = Dispatchers.Unconfined,
264                 flags = flags
265             )
266 
267         assertProfiles(helper, personalProfile = personalProfile, privateProfile = null)
268 
269         assertThat(helper.isLaunchedAsCloneProfile).isFalse()
270         assertThat(helper.launchedAsProfileType).isEqualTo(Profile.Type.PERSONAL)
271         assertThat(helper.getQueryIntentsHandle(personalProfile.primary.handle))
272             .isEqualTo(personalProfile.primary.handle)
273         assertThat(helper.tabOwnerUserHandleForLaunch).isEqualTo(personalProfile.primary.handle)
274     }
275 }
276