1 /*
2  * Copyright (C) 2022 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 @file:OptIn(InternalNoteTaskApi::class)
17 
18 package com.android.systemui.notetask
19 
20 import android.app.ActivityManager
21 import android.app.KeyguardManager
22 import android.app.admin.DevicePolicyManager
23 import android.app.role.RoleManager
24 import android.app.role.RoleManager.ROLE_NOTES
25 import android.content.ComponentName
26 import android.content.Context
27 import android.content.Intent
28 import android.content.Intent.ACTION_CREATE_NOTE
29 import android.content.Intent.ACTION_MAIN
30 import android.content.Intent.ACTION_MANAGE_DEFAULT_APP
31 import android.content.Intent.CATEGORY_HOME
32 import android.content.Intent.EXTRA_USE_STYLUS_MODE
33 import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
34 import android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT
35 import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
36 import android.content.pm.PackageManager
37 import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
38 import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED
39 import android.content.pm.ShortcutManager
40 import android.content.pm.UserInfo
41 import android.graphics.drawable.Icon
42 import android.os.UserHandle
43 import android.os.UserManager
44 import android.provider.Settings
45 import androidx.test.ext.truth.content.IntentSubject.assertThat
46 import androidx.test.filters.SmallTest
47 import androidx.test.runner.AndroidJUnit4
48 import com.android.systemui.R
49 import com.android.systemui.SysuiTestCase
50 import com.android.systemui.notetask.NoteTaskController.Companion.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
51 import com.android.systemui.notetask.NoteTaskController.Companion.SHORTCUT_ID
52 import com.android.systemui.notetask.NoteTaskEntryPoint.APP_CLIPS
53 import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT
54 import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
55 import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
56 import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT
57 import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
58 import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
59 import com.android.systemui.settings.FakeUserTracker
60 import com.android.systemui.util.mockito.any
61 import com.android.systemui.util.mockito.argumentCaptor
62 import com.android.systemui.util.mockito.capture
63 import com.android.systemui.util.mockito.eq
64 import com.android.systemui.util.mockito.mock
65 import com.android.systemui.util.mockito.whenever
66 import com.android.systemui.util.mockito.withArgCaptor
67 import com.android.systemui.util.settings.SecureSettings
68 import com.android.wm.shell.bubbles.Bubble
69 import com.android.wm.shell.bubbles.Bubbles
70 import com.google.common.truth.Truth.assertThat
71 import java.util.Optional
72 import kotlin.test.assertNotNull
73 import kotlinx.coroutines.ExperimentalCoroutinesApi
74 import kotlinx.coroutines.test.TestScope
75 import kotlinx.coroutines.test.UnconfinedTestDispatcher
76 import org.junit.Before
77 import org.junit.Test
78 import org.junit.runner.RunWith
79 import org.mockito.ArgumentMatchers.anyInt
80 import org.mockito.Mock
81 import org.mockito.Mockito.atLeastOnce
82 import org.mockito.Mockito.doNothing
83 import org.mockito.Mockito.never
84 import org.mockito.Mockito.spy
85 import org.mockito.Mockito.verify
86 import org.mockito.Mockito.verifyZeroInteractions
87 import org.mockito.MockitoAnnotations
88 
89 /** atest SystemUITests:NoteTaskControllerTest */
90 @OptIn(ExperimentalCoroutinesApi::class)
91 @SmallTest
92 @RunWith(AndroidJUnit4::class)
93 internal class NoteTaskControllerTest : SysuiTestCase() {
94 
95     @Mock private lateinit var context: Context
96     @Mock private lateinit var workProfileContext: Context
97     @Mock private lateinit var packageManager: PackageManager
98     @Mock private lateinit var workProfilePackageManager: PackageManager
99     @Mock private lateinit var resolver: NoteTaskInfoResolver
100     @Mock private lateinit var bubbles: Bubbles
101     @Mock private lateinit var keyguardManager: KeyguardManager
102     @Mock private lateinit var userManager: UserManager
103     @Mock private lateinit var eventLogger: NoteTaskEventLogger
104     @Mock private lateinit var roleManager: RoleManager
105     @Mock private lateinit var shortcutManager: ShortcutManager
106     @Mock private lateinit var activityManager: ActivityManager
107     @Mock private lateinit var devicePolicyManager: DevicePolicyManager
108     @Mock private lateinit var secureSettings: SecureSettings
109     private val userTracker = FakeUserTracker()
110     private val testDispatcher = UnconfinedTestDispatcher()
111     private val testScope = TestScope(testDispatcher)
112 
113     @Before
114     fun setUp() {
115         MockitoAnnotations.initMocks(this)
116 
117         whenever(context.getString(R.string.note_task_button_label))
118             .thenReturn(NOTE_TASK_SHORT_LABEL)
119         whenever(context.getString(eq(R.string.note_task_shortcut_long_label), any()))
120             .thenReturn(NOTE_TASK_LONG_LABEL)
121         whenever(context.packageManager).thenReturn(packageManager)
122         whenever(context.createContextAsUser(any(), any())).thenReturn(context)
123         whenever(packageManager.getApplicationInfo(any(), any<Int>())).thenReturn(mock())
124         whenever(packageManager.getApplicationLabel(any())).thenReturn(NOTE_TASK_LONG_LABEL)
125         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO)
126         whenever(userManager.isUserUnlocked).thenReturn(true)
127         whenever(userManager.isUserUnlocked(any<Int>())).thenReturn(true)
128         whenever(userManager.isUserUnlocked(any<UserHandle>())).thenReturn(true)
129         whenever(
130                 devicePolicyManager.getKeyguardDisabledFeatures(
131                     /* admin= */ eq(null),
132                     /* userHandle= */ anyInt()
133                 )
134             )
135             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE)
136         whenever(roleManager.getRoleHoldersAsUser(ROLE_NOTES, userTracker.userHandle))
137             .thenReturn(listOf(NOTE_TASK_PACKAGE_NAME))
138         whenever(activityManager.getRunningTasks(anyInt())).thenReturn(emptyList())
139         whenever(userManager.isManagedProfile(workUserInfo.id)).thenReturn(true)
140         whenever(context.resources).thenReturn(getContext().resources)
141         whenever(secureSettings.userTracker).thenReturn(userTracker)
142     }
143 
144     private fun createNoteTaskController(
145         isEnabled: Boolean = true,
146         bubbles: Bubbles? = this.bubbles,
147     ): NoteTaskController =
148         NoteTaskController(
149             context = context,
150             resolver = resolver,
151             eventLogger = eventLogger,
152             userManager = userManager,
153             keyguardManager = keyguardManager,
154             isEnabled = isEnabled,
155             devicePolicyManager = devicePolicyManager,
156             userTracker = userTracker,
157             roleManager = roleManager,
158             shortcutManager = shortcutManager,
159             activityManager = activityManager,
160             secureSettings = secureSettings,
161             noteTaskBubblesController =
162                 FakeNoteTaskBubbleController(context, testDispatcher, Optional.ofNullable(bubbles)),
163             applicationScope = testScope,
164         )
165 
166     // region onBubbleExpandChanged
167     @Test
168     fun onBubbleExpandChanged_expanding_logNoteTaskOpened() {
169         val expectedInfo = NOTE_TASK_INFO.copy(isKeyguardLocked = false)
170 
171         createNoteTaskController()
172             .apply { infoReference.set(expectedInfo) }
173             .onBubbleExpandChanged(
174                 isExpanding = true,
175                 key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
176             )
177 
178         verify(eventLogger).logNoteTaskOpened(expectedInfo)
179         verifyZeroInteractions(bubbles, keyguardManager, userManager)
180     }
181 
182     @Test
183     fun onBubbleExpandChanged_collapsing_logNoteTaskClosed() {
184         val expectedInfo = NOTE_TASK_INFO.copy(isKeyguardLocked = false)
185 
186         createNoteTaskController()
187             .apply { infoReference.set(expectedInfo) }
188             .onBubbleExpandChanged(
189                 isExpanding = false,
190                 key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
191             )
192 
193         verify(eventLogger).logNoteTaskClosed(expectedInfo)
194         verifyZeroInteractions(bubbles, keyguardManager, userManager)
195     }
196 
197     @Test
198     fun onBubbleExpandChanged_expandingAndKeyguardLocked_shouldDoNothing() {
199         val expectedInfo = NOTE_TASK_INFO.copy(isKeyguardLocked = true)
200 
201         createNoteTaskController()
202             .apply { infoReference.set(expectedInfo) }
203             .onBubbleExpandChanged(
204                 isExpanding = true,
205                 key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
206             )
207 
208         verifyZeroInteractions(bubbles, keyguardManager, userManager, eventLogger)
209     }
210 
211     @Test
212     fun onBubbleExpandChanged_notExpandingAndKeyguardLocked_shouldDoNothing() {
213         val expectedInfo = NOTE_TASK_INFO.copy(isKeyguardLocked = true)
214 
215         createNoteTaskController()
216             .apply { infoReference.set(expectedInfo) }
217             .onBubbleExpandChanged(
218                 isExpanding = false,
219                 key = Bubble.getAppBubbleKeyForApp(expectedInfo.packageName, expectedInfo.user),
220             )
221 
222         verifyZeroInteractions(bubbles, keyguardManager, userManager, eventLogger)
223     }
224 
225     @Test
226     fun onBubbleExpandChanged_notKeyAppBubble_shouldDoNothing() {
227         createNoteTaskController()
228             .onBubbleExpandChanged(
229                 isExpanding = true,
230                 key = "any other key",
231             )
232 
233         verifyZeroInteractions(bubbles, keyguardManager, userManager, eventLogger)
234     }
235 
236     @Test
237     fun onBubbleExpandChanged_flagDisabled_shouldDoNothing() {
238         createNoteTaskController(isEnabled = false)
239             .onBubbleExpandChanged(
240                 isExpanding = true,
241                 key = Bubble.getAppBubbleKeyForApp(NOTE_TASK_INFO.packageName, NOTE_TASK_INFO.user),
242             )
243 
244         verifyZeroInteractions(bubbles, keyguardManager, userManager, eventLogger)
245     }
246     // endregion
247 
248     // region showNoteTask
249     fun showNoteTaskAsUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() {
250         val user10 = UserHandle.of(/* userId= */ 10)
251         val expectedInfo =
252             NOTE_TASK_INFO.copy(
253                 entryPoint = TAIL_BUTTON,
254                 isKeyguardLocked = true,
255                 user = user10,
256             )
257         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
258         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
259 
260         createNoteTaskController()
261             .showNoteTaskAsUser(entryPoint = expectedInfo.entryPoint!!, user = user10)
262 
263         val intentCaptor = argumentCaptor<Intent>()
264         val userCaptor = argumentCaptor<UserHandle>()
265         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
266         assertThat(intentCaptor.value).run {
267             hasAction(ACTION_CREATE_NOTE)
268             hasPackage(NOTE_TASK_PACKAGE_NAME)
269             hasFlags(FLAG_ACTIVITY_NEW_TASK)
270             hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
271             hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
272             extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
273         }
274         assertThat(userCaptor.value).isEqualTo(user10)
275         verify(eventLogger).logNoteTaskOpened(expectedInfo)
276         verifyZeroInteractions(bubbles)
277     }
278 
279     @Test
280     fun showNoteTask_keyguardIsLocked_notesIsClosed_shouldStartActivityAndLogUiEvent() {
281         val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
282         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
283         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
284 
285         createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
286 
287         val intentCaptor = argumentCaptor<Intent>()
288         val userCaptor = argumentCaptor<UserHandle>()
289         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
290         assertThat(intentCaptor.value).run {
291             hasAction(ACTION_CREATE_NOTE)
292             hasPackage(NOTE_TASK_PACKAGE_NAME)
293             hasFlags(FLAG_ACTIVITY_NEW_TASK)
294             hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
295             hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
296             extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
297         }
298         assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
299         verify(eventLogger).logNoteTaskOpened(expectedInfo)
300         verifyZeroInteractions(bubbles)
301     }
302 
303     @Test
304     fun showNoteTask_keyguardIsLocked_noteIsOpen_shouldCloseActivityAndLogUiEvent() {
305         val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
306         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
307         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
308         whenever(activityManager.getRunningTasks(anyInt()))
309             .thenReturn(listOf(NOTE_RUNNING_TASK_INFO))
310 
311         createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
312 
313         val intentCaptor = argumentCaptor<Intent>()
314         val userCaptor = argumentCaptor<UserHandle>()
315         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
316         assertThat(intentCaptor.value).run {
317             hasAction(ACTION_MAIN)
318             categories().contains(CATEGORY_HOME)
319             hasFlags(FLAG_ACTIVITY_NEW_TASK)
320         }
321         assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
322         verify(eventLogger).logNoteTaskClosed(expectedInfo)
323         verifyZeroInteractions(bubbles)
324     }
325 
326     @Test
327     fun showNoteTask_keyguardIsUnlocked_noteIsClosed_shouldStartBubblesWithoutLoggingUiEvent() {
328         val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = false)
329         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
330         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
331 
332         createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
333 
334         // Context package name used to create bubble icon from drawable resource id
335         verify(context, atLeastOnce()).packageName
336         verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
337         verifyZeroInteractions(eventLogger)
338     }
339 
340     @Test
341     fun showNoteTask_keyguardIsUnlocked_noteIsOpen_shouldStartBubblesWithoutLoggingUiEvent() {
342         val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = false)
343         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
344         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
345         whenever(activityManager.getRunningTasks(anyInt()))
346             .thenReturn(listOf(NOTE_RUNNING_TASK_INFO))
347 
348         createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
349 
350         // Context package name used to create bubble icon from drawable resource id
351         verify(context, atLeastOnce()).packageName
352         verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
353         verifyZeroInteractions(eventLogger)
354     }
355 
356     @Test
357     fun showNoteTask_defaultUserSet_shouldStartActivityWithExpectedUserAndLogUiEvent() {
358         whenever(
359                 secureSettings.getIntForUser(
360                     /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
361                     /* def= */ any(),
362                     /* userHandle= */ any()
363                 )
364             )
365             .thenReturn(10)
366         val user10 = UserHandle.of(/* userId= */ 10)
367 
368         val expectedInfo =
369             NOTE_TASK_INFO.copy(
370                 entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
371                 isKeyguardLocked = true,
372                 user = user10,
373             )
374         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
375         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
376 
377         createNoteTaskController()
378             .showNoteTask(
379                 entryPoint = expectedInfo.entryPoint!!,
380             )
381 
382         val intentCaptor = argumentCaptor<Intent>()
383         val userCaptor = argumentCaptor<UserHandle>()
384         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
385         intentCaptor.value.let { intent ->
386             assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
387             assertThat(intent.`package`).isEqualTo(NOTE_TASK_PACKAGE_NAME)
388             assertThat(intent.flags and FLAG_ACTIVITY_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
389             assertThat(intent.flags and FLAG_ACTIVITY_MULTIPLE_TASK)
390                 .isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK)
391             assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT)
392                 .isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT)
393             assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
394         }
395         assertThat(userCaptor.value).isEqualTo(user10)
396         verify(eventLogger).logNoteTaskOpened(expectedInfo)
397         verifyZeroInteractions(bubbles)
398     }
399 
400     @Test
401     fun showNoteTask_bubblesIsNull_shouldDoNothing() {
402         createNoteTaskController(bubbles = null).showNoteTask(entryPoint = TAIL_BUTTON)
403 
404         verifyZeroInteractions(bubbles, eventLogger)
405     }
406 
407     @Test
408     fun showNoteTask_intentResolverReturnsNull_shouldShowToast() {
409         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(null)
410         val noteTaskController = spy(createNoteTaskController())
411         doNothing().whenever(noteTaskController).showNoDefaultNotesAppToast()
412 
413         noteTaskController.showNoteTask(entryPoint = TAIL_BUTTON)
414 
415         verify(noteTaskController).showNoDefaultNotesAppToast()
416         verifyZeroInteractions(bubbles, eventLogger)
417     }
418 
419     @Test
420     fun showNoteTask_flagDisabled_shouldDoNothing() {
421         createNoteTaskController(isEnabled = false).showNoteTask(entryPoint = TAIL_BUTTON)
422 
423         verifyZeroInteractions(bubbles, eventLogger)
424     }
425 
426     @Test
427     fun showNoteTask_userIsLocked_shouldDoNothing() {
428         whenever(userManager.isUserUnlocked).thenReturn(false)
429 
430         createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
431 
432         verifyZeroInteractions(bubbles, eventLogger)
433     }
434 
435     @Test
436     fun showNoteTask_keyboardShortcut_shouldStartActivity() {
437         val expectedInfo =
438             NOTE_TASK_INFO.copy(entryPoint = KEYBOARD_SHORTCUT, isKeyguardLocked = true)
439         whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
440         whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
441 
442         createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
443 
444         val intentCaptor = argumentCaptor<Intent>()
445         val userCaptor = argumentCaptor<UserHandle>()
446         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
447         assertThat(intentCaptor.value).run {
448             hasAction(ACTION_CREATE_NOTE)
449             hasPackage(NOTE_TASK_PACKAGE_NAME)
450             hasFlags(FLAG_ACTIVITY_NEW_TASK)
451             hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
452             hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
453             extras().bool(EXTRA_USE_STYLUS_MODE).isFalse()
454         }
455         assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
456         verify(eventLogger).logNoteTaskOpened(expectedInfo)
457         verifyZeroInteractions(bubbles)
458     }
459     // endregion
460 
461     // region setNoteTaskShortcutEnabled
462     @Test
463     fun setNoteTaskShortcutEnabled_setTrue() {
464         createNoteTaskController().setNoteTaskShortcutEnabled(value = true, userTracker.userHandle)
465 
466         val argument = argumentCaptor<ComponentName>()
467         verify(context.packageManager)
468             .setComponentEnabledSetting(
469                 argument.capture(),
470                 eq(COMPONENT_ENABLED_STATE_ENABLED),
471                 eq(PackageManager.DONT_KILL_APP),
472             )
473 
474         assertThat(argument.value.className)
475             .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
476     }
477 
478     @Test
479     fun setNoteTaskShortcutEnabled_setFalse() {
480         createNoteTaskController().setNoteTaskShortcutEnabled(value = false, userTracker.userHandle)
481 
482         val argument = argumentCaptor<ComponentName>()
483         verify(context.packageManager)
484             .setComponentEnabledSetting(
485                 argument.capture(),
486                 eq(COMPONENT_ENABLED_STATE_DISABLED),
487                 eq(PackageManager.DONT_KILL_APP),
488             )
489 
490         assertThat(argument.value.className)
491             .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
492     }
493 
494     @Test
495     fun setNoteTaskShortcutEnabled_workProfileUser_setTrue() {
496         whenever(context.createContextAsUser(eq(workUserInfo.userHandle), any()))
497             .thenReturn(workProfileContext)
498         whenever(workProfileContext.packageManager).thenReturn(workProfilePackageManager)
499         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
500 
501         createNoteTaskController().setNoteTaskShortcutEnabled(value = true, workUserInfo.userHandle)
502 
503         val argument = argumentCaptor<ComponentName>()
504         verify(workProfilePackageManager)
505             .setComponentEnabledSetting(
506                 argument.capture(),
507                 eq(COMPONENT_ENABLED_STATE_ENABLED),
508                 eq(PackageManager.DONT_KILL_APP),
509             )
510 
511         assertThat(argument.value.className)
512             .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
513     }
514 
515     @Test
516     fun setNoteTaskShortcutEnabled_workProfileUser_setFalse() {
517         whenever(context.createContextAsUser(eq(workUserInfo.userHandle), any()))
518             .thenReturn(workProfileContext)
519         whenever(workProfileContext.packageManager).thenReturn(workProfilePackageManager)
520         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
521 
522         createNoteTaskController()
523             .setNoteTaskShortcutEnabled(value = false, workUserInfo.userHandle)
524 
525         val argument = argumentCaptor<ComponentName>()
526         verify(workProfilePackageManager)
527             .setComponentEnabledSetting(
528                 argument.capture(),
529                 eq(COMPONENT_ENABLED_STATE_DISABLED),
530                 eq(PackageManager.DONT_KILL_APP),
531             )
532 
533         assertThat(argument.value.className)
534             .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
535     }
536     // endregion
537 
538     // region keyguard policy
539     @Test
540     fun showNoteTask_keyguardLocked_keyguardDisableShortcutsAll_shouldDoNothing() {
541         whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
542         whenever(
543                 devicePolicyManager.getKeyguardDisabledFeatures(
544                     /* admin= */ eq(null),
545                     /* userHandle= */ anyInt()
546                 )
547             )
548             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
549 
550         createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
551 
552         verifyZeroInteractions(bubbles, eventLogger)
553     }
554 
555     @Test
556     fun showNoteTask_keyguardLocked_keyguardDisableFeaturesAll_shouldDoNothing() {
557         whenever(keyguardManager.isKeyguardLocked).thenReturn(true)
558         whenever(
559                 devicePolicyManager.getKeyguardDisabledFeatures(
560                     /* admin= */ eq(null),
561                     /* userHandle= */ anyInt()
562                 )
563             )
564             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
565 
566         createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
567 
568         verifyZeroInteractions(bubbles, eventLogger)
569     }
570 
571     @Test
572     fun showNoteTask_keyguardUnlocked_keyguardDisableShortcutsAll_shouldStartBubble() {
573         whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
574         whenever(
575                 devicePolicyManager.getKeyguardDisabledFeatures(
576                     /* admin= */ eq(null),
577                     /* userHandle= */ anyInt()
578                 )
579             )
580             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
581 
582         createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
583 
584         verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
585     }
586 
587     @Test
588     fun showNoteTask_keyguardUnlocked_keyguardDisableFeaturesAll_shouldStartBubble() {
589         whenever(keyguardManager.isKeyguardLocked).thenReturn(false)
590         whenever(
591                 devicePolicyManager.getKeyguardDisabledFeatures(
592                     /* admin= */ eq(null),
593                     /* userHandle= */ anyInt()
594                 )
595             )
596             .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
597 
598         createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
599 
600         verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
601     }
602     // endregion
603 
604     // region showNoteTask, COPE devices
605     @Test
606     fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() { // ktlint-disable max-line-length
607         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
608         userTracker.set(listOf(mainUserInfo), mainAndWorkProfileUsers.indexOf(mainUserInfo))
609 
610         createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
611 
612         verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
613     }
614 
615     @Test
616     fun showNoteTask_copeDevices_quickAffordanceEntryPoint_shouldStartBubbleInWorkProfile() {
617         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
618         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
619 
620         createNoteTaskController().showNoteTask(entryPoint = QUICK_AFFORDANCE)
621 
622         verifyNoteTaskOpenInBubbleInUser(workUserInfo.userHandle)
623     }
624 
625     @Test
626     fun showNoteTask_copeDevices_tailButtonEntryPoint_shouldStartBubbleInTheUserSelectedUser() {
627         whenever(
628                 secureSettings.getIntForUser(
629                     /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
630                     /* def= */ any(),
631                     /* userHandle= */ any()
632                 )
633             )
634             .thenReturn(mainUserInfo.id)
635         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
636         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
637 
638         createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
639 
640         verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
641     }
642 
643     @Test
644     fun showNoteTask_copeDevices_shortcutsEntryPoint_shouldStartBubbleInTheSelectedUser() {
645         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
646         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
647 
648         createNoteTaskController().showNoteTask(entryPoint = WIDGET_PICKER_SHORTCUT)
649 
650         verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
651     }
652 
653     @Test
654     fun showNoteTask_copeDevices_appClipsEntryPoint_shouldStartBubbleInTheSelectedUser() {
655         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
656         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
657 
658         createNoteTaskController().showNoteTask(entryPoint = APP_CLIPS)
659 
660         verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
661     }
662     // endregion
663 
664     private fun verifyNoteTaskOpenInBubbleInUser(userHandle: UserHandle) {
665         val intentCaptor = argumentCaptor<Intent>()
666         val iconCaptor = argumentCaptor<Icon>()
667         verify(bubbles)
668             .showOrHideAppBubble(capture(intentCaptor), eq(userHandle), capture(iconCaptor))
669         assertThat(intentCaptor.value).run {
670             hasAction(ACTION_CREATE_NOTE)
671             hasPackage(NOTE_TASK_PACKAGE_NAME)
672             hasFlags(FLAG_ACTIVITY_NEW_TASK)
673             extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
674         }
675         iconCaptor.value?.let { icon ->
676             assertNotNull(icon)
677             assertThat(icon.resId).isEqualTo(R.drawable.ic_note_task_shortcut_widget)
678         }
679     }
680 
681     // region onRoleHoldersChanged
682     @Test
683     fun onRoleHoldersChanged_notNotesRole_doNothing() {
684         val user = UserHandle.of(0)
685 
686         createNoteTaskController(isEnabled = true).onRoleHoldersChanged("NOT_NOTES", user)
687 
688         verify(context, never()).startActivityAsUser(any(), any())
689     }
690 
691     @Test
692     fun onRoleHoldersChanged_notesRole_shouldUpdateShortcuts() {
693         val user = userTracker.userHandle
694         val controller = spy(createNoteTaskController())
695         doNothing().whenever(controller).updateNoteTaskAsUser(any())
696 
697         controller.onRoleHoldersChanged(ROLE_NOTES, user)
698 
699         verify(controller).updateNoteTaskAsUser(user)
700     }
701     // endregion
702 
703     // region updateNoteTaskAsUser
704     @Test
705     fun updateNoteTaskAsUser_sameUser_shouldUpdateShortcuts() {
706         val user = UserHandle.CURRENT
707         val controller = spy(createNoteTaskController())
708         doNothing().whenever(controller).updateNoteTaskAsUserInternal(any())
709         whenever(controller.getCurrentRunningUser()).thenReturn(user)
710 
711         controller.updateNoteTaskAsUser(user)
712 
713         verify(controller).updateNoteTaskAsUserInternal(user)
714         verify(context, never()).startServiceAsUser(any(), any())
715     }
716 
717     @Test
718     fun updateNoteTaskAsUser_differentUser_shouldUpdateShortcutsInUserProcess() {
719         val user = UserHandle.CURRENT
720         val controller = spy(createNoteTaskController(isEnabled = true))
721         doNothing().whenever(controller).updateNoteTaskAsUserInternal(any())
722         whenever(controller.getCurrentRunningUser()).thenReturn(UserHandle.SYSTEM)
723 
724         controller.updateNoteTaskAsUser(user)
725 
726         verify(controller, never()).updateNoteTaskAsUserInternal(any())
727         val intent = withArgCaptor { verify(context).startServiceAsUser(capture(), eq(user)) }
728         assertThat(intent).hasComponentClass(NoteTaskControllerUpdateService::class.java)
729     }
730     // endregion
731 
732     // region internalUpdateNoteTaskAsUser
733     @Test
734     fun updateNoteTaskAsUserInternal_withNotesRole_withShortcuts_shouldUpdateShortcuts() {
735         createNoteTaskController(isEnabled = true)
736             .updateNoteTaskAsUserInternal(userTracker.userHandle)
737 
738         val actualComponent = argumentCaptor<ComponentName>()
739         verify(context.packageManager)
740             .setComponentEnabledSetting(
741                 actualComponent.capture(),
742                 eq(COMPONENT_ENABLED_STATE_ENABLED),
743                 eq(PackageManager.DONT_KILL_APP),
744             )
745         assertThat(actualComponent.value.className)
746             .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
747         verify(shortcutManager, never()).disableShortcuts(any())
748         verify(shortcutManager).enableShortcuts(listOf(SHORTCUT_ID))
749         val shortcutInfo = withArgCaptor { verify(shortcutManager).updateShortcuts(capture()) }
750         with(shortcutInfo.first()) {
751             assertThat(id).isEqualTo(SHORTCUT_ID)
752             assertThat(intent).run {
753                 hasComponentClass(LaunchNoteTaskActivity::class.java)
754                 hasAction(ACTION_CREATE_NOTE)
755             }
756             assertThat(shortLabel).isEqualTo(NOTE_TASK_SHORT_LABEL)
757             assertThat(longLabel).isEqualTo(NOTE_TASK_LONG_LABEL)
758             assertThat(isLongLived).isEqualTo(true)
759             assertThat(icon?.resId).isEqualTo(R.drawable.ic_note_task_shortcut_widget)
760             assertThat(extras?.getString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE))
761                 .isEqualTo(NOTE_TASK_PACKAGE_NAME)
762         }
763     }
764 
765     @Test
766     fun updateNoteTaskAsUserInternal_noNotesRole_shouldDisableShortcuts() {
767         whenever(roleManager.getRoleHoldersAsUser(ROLE_NOTES, userTracker.userHandle))
768             .thenReturn(emptyList())
769 
770         createNoteTaskController(isEnabled = true)
771             .updateNoteTaskAsUserInternal(userTracker.userHandle)
772 
773         val argument = argumentCaptor<ComponentName>()
774         verify(context.packageManager)
775             .setComponentEnabledSetting(
776                 argument.capture(),
777                 eq(COMPONENT_ENABLED_STATE_DISABLED),
778                 eq(PackageManager.DONT_KILL_APP),
779             )
780         assertThat(argument.value.className)
781             .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
782         verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
783         verify(shortcutManager, never()).enableShortcuts(any())
784         verify(shortcutManager, never()).updateShortcuts(any())
785     }
786 
787     @Test
788     fun updateNoteTaskAsUserInternal_flagDisabled_shouldDisableShortcuts() {
789         createNoteTaskController(isEnabled = false)
790             .updateNoteTaskAsUserInternal(userTracker.userHandle)
791 
792         val argument = argumentCaptor<ComponentName>()
793         verify(context.packageManager)
794             .setComponentEnabledSetting(
795                 argument.capture(),
796                 eq(COMPONENT_ENABLED_STATE_DISABLED),
797                 eq(PackageManager.DONT_KILL_APP),
798             )
799         assertThat(argument.value.className)
800             .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
801         verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
802         verify(shortcutManager, never()).enableShortcuts(any())
803         verify(shortcutManager, never()).updateShortcuts(any())
804     }
805     // endregion
806 
807     // startregion updateNoteTaskForAllUsers
808     @Test
809     fun updateNoteTaskForAllUsers_shouldRunUpdateForCurrentUserAndProfiles() {
810         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
811         val controller = spy(createNoteTaskController())
812         doNothing().whenever(controller).updateNoteTaskAsUser(any())
813 
814         controller.updateNoteTaskForCurrentUserAndManagedProfiles()
815 
816         verify(controller).updateNoteTaskAsUser(mainUserInfo.userHandle)
817         verify(controller).updateNoteTaskAsUser(workUserInfo.userHandle)
818     }
819     // endregion
820 
821     // region getUserForHandlingNotesTaking
822     @Test
823     fun getUserForHandlingNotesTaking_cope_quickAffordance_shouldReturnWorkProfileUser() {
824         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
825         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
826 
827         val user = createNoteTaskController().getUserForHandlingNotesTaking(QUICK_AFFORDANCE)
828 
829         assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
830     }
831 
832     @Test
833     fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length
834         whenever(
835                 secureSettings.getIntForUser(
836                     /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
837                     /* def= */ any(),
838                     /* userHandle= */ any()
839                 )
840             )
841             .thenReturn(workUserInfo.id)
842         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
843         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
844 
845         val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
846 
847         assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
848     }
849 
850     @Test
851     fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length
852         whenever(
853                 secureSettings.getIntForUser(
854                     /* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
855                     /* def= */ any(),
856                     /* userHandle= */ any()
857                 )
858             )
859             .thenReturn(mainUserInfo.id)
860         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
861         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
862 
863         val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
864 
865         assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
866     }
867 
868     @Test
869     fun getUserForHandlingNotesTaking_cope_appClip_shouldReturnCurrentUser() {
870         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
871         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
872 
873         val user = createNoteTaskController().getUserForHandlingNotesTaking(APP_CLIPS)
874 
875         assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
876     }
877 
878     @Test
879     fun getUserForHandlingNotesTaking_noManagement_quickAffordance_shouldReturnCurrentUser() {
880         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
881 
882         val user = createNoteTaskController().getUserForHandlingNotesTaking(QUICK_AFFORDANCE)
883 
884         assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
885     }
886 
887     @Test
888     fun getUserForHandlingNotesTaking_noManagement_tailButton_shouldReturnCurrentUser() {
889         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
890 
891         val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
892 
893         assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
894     }
895 
896     @Test
897     fun getUserForHandlingNotesTaking_noManagement_appClip_shouldReturnCurrentUser() {
898         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
899 
900         val user = createNoteTaskController().getUserForHandlingNotesTaking(APP_CLIPS)
901 
902         assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
903     }
904     // endregion
905 
906     // startregion startNotesRoleSetting
907     @Test
908     fun startNotesRoleSetting_cope_quickAffordance_shouldStartNoteRoleIntentWithWorkProfileUser() {
909         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
910         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
911 
912         createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE)
913 
914         val intentCaptor = argumentCaptor<Intent>()
915         val userCaptor = argumentCaptor<UserHandle>()
916         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
917         assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
918         assertThat(userCaptor.value).isEqualTo(UserHandle.of(workUserInfo.id))
919     }
920 
921     @Test
922     fun startNotesRoleSetting_cope_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() {
923         whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
924         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
925 
926         createNoteTaskController().startNotesRoleSetting(context, entryPoint = null)
927 
928         val intentCaptor = argumentCaptor<Intent>()
929         val userCaptor = argumentCaptor<UserHandle>()
930         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
931         assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
932         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
933     }
934 
935     @Test
936     fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
937         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
938 
939         createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE)
940 
941         val intentCaptor = argumentCaptor<Intent>()
942         val userCaptor = argumentCaptor<UserHandle>()
943         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
944         assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
945         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
946     }
947 
948     @Test
949     fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length
950         userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
951 
952         createNoteTaskController().startNotesRoleSetting(context, entryPoint = null)
953 
954         val intentCaptor = argumentCaptor<Intent>()
955         val userCaptor = argumentCaptor<UserHandle>()
956         verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
957         assertThat(intentCaptor.value).hasAction(ACTION_MANAGE_DEFAULT_APP)
958         assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id))
959     }
960     // endregion
961 
962     private companion object {
963         const val NOTE_TASK_SHORT_LABEL = "Note-taking"
964         const val NOTE_TASK_LONG_LABEL = "Note-taking, App"
965         const val NOTE_TASK_ACTIVITY_NAME = "NoteTaskActivity"
966         const val NOTE_TASK_PACKAGE_NAME = "com.android.note.app"
967         const val NOTE_TASK_UID = 123456
968 
969         private val NOTE_TASK_INFO =
970             NoteTaskInfo(
971                 packageName = NOTE_TASK_PACKAGE_NAME,
972                 uid = NOTE_TASK_UID,
973                 user = UserHandle.of(0),
974             )
975         private val NOTE_RUNNING_TASK_INFO =
976             ActivityManager.RunningTaskInfo().apply {
977                 topActivity = ComponentName(NOTE_TASK_PACKAGE_NAME, NOTE_TASK_ACTIVITY_NAME)
978             }
979 
980         val mainUserInfo =
981             UserInfo(/* id= */ 0, /* name= */ "primary", /* flags= */ UserInfo.FLAG_MAIN)
982         val workUserInfo =
983             UserInfo(/* id= */ 10, /* name= */ "work", /* flags= */ UserInfo.FLAG_PROFILE)
984         val mainAndWorkProfileUsers = listOf(mainUserInfo, workUserInfo)
985     }
986 }
987