Merge "Fix ANR due to `updateShortcuts` called in the main thread" into main
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index 0842fe0..ea8eb36 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -321,7 +321,7 @@
         // When switched to a secondary user, the sysUI is still running in the main user, we will
         // need to update the shortcut in the secondary user.
         if (user == getCurrentRunningUser()) {
-            updateNoteTaskAsUserInternal(user)
+            launchUpdateNoteTaskAsUser(user)
         } else {
             // TODO(b/278729185): Replace fire and forget service with a bounded service.
             val intent = NoteTaskControllerUpdateService.createIntent(context)
@@ -330,23 +330,25 @@
     }
 
     @InternalNoteTaskApi
-    fun updateNoteTaskAsUserInternal(user: UserHandle) {
-        if (!userManager.isUserUnlocked(user)) {
-            debugLog { "updateNoteTaskAsUserInternal call but user locked: user=$user" }
-            return
-        }
+    fun launchUpdateNoteTaskAsUser(user: UserHandle) {
+        applicationScope.launch {
+            if (!userManager.isUserUnlocked(user)) {
+                debugLog { "updateNoteTaskAsUserInternal call but user locked: user=$user" }
+                return@launch
+            }
 
-        val packageName = roleManager.getDefaultRoleHolderAsUser(ROLE_NOTES, user)
-        val hasNotesRoleHolder = isEnabled && !packageName.isNullOrEmpty()
+            val packageName = roleManager.getDefaultRoleHolderAsUser(ROLE_NOTES, user)
+            val hasNotesRoleHolder = isEnabled && !packageName.isNullOrEmpty()
 
-        setNoteTaskShortcutEnabled(hasNotesRoleHolder, user)
+            setNoteTaskShortcutEnabled(hasNotesRoleHolder, user)
 
-        if (hasNotesRoleHolder) {
-            shortcutManager.enableShortcuts(listOf(SHORTCUT_ID))
-            val updatedShortcut = roleManager.createNoteShortcutInfoAsUser(context, user)
-            shortcutManager.updateShortcuts(listOf(updatedShortcut))
-        } else {
-            shortcutManager.disableShortcuts(listOf(SHORTCUT_ID))
+            if (hasNotesRoleHolder) {
+                shortcutManager.enableShortcuts(listOf(SHORTCUT_ID))
+                val updatedShortcut = roleManager.createNoteShortcutInfoAsUser(context, user)
+                shortcutManager.updateShortcuts(listOf(updatedShortcut))
+            } else {
+                shortcutManager.disableShortcuts(listOf(SHORTCUT_ID))
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskControllerUpdateService.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskControllerUpdateService.kt
index 3e352af..486fde1 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskControllerUpdateService.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskControllerUpdateService.kt
@@ -44,7 +44,7 @@
     override fun onCreate() {
         super.onCreate()
         // TODO(b/278729185): Replace fire and forget service with a bounded service.
-        controller.updateNoteTaskAsUserInternal(user)
+        controller.launchUpdateNoteTaskAsUser(user)
         stopSelf()
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 1536c17..b50032f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -73,6 +73,7 @@
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runCurrent
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -705,12 +706,12 @@
     fun updateNoteTaskAsUser_sameUser_shouldUpdateShortcuts() {
         val user = UserHandle.CURRENT
         val controller = spy(createNoteTaskController())
-        doNothing().whenever(controller).updateNoteTaskAsUserInternal(any())
+        doNothing().whenever(controller).launchUpdateNoteTaskAsUser(any())
         whenever(controller.getCurrentRunningUser()).thenReturn(user)
 
         controller.updateNoteTaskAsUser(user)
 
-        verify(controller).updateNoteTaskAsUserInternal(user)
+        verify(controller).launchUpdateNoteTaskAsUser(user)
         verify(context, never()).startServiceAsUser(any(), any())
     }
 
@@ -718,12 +719,12 @@
     fun updateNoteTaskAsUser_differentUser_shouldUpdateShortcutsInUserProcess() {
         val user = UserHandle.CURRENT
         val controller = spy(createNoteTaskController(isEnabled = true))
-        doNothing().whenever(controller).updateNoteTaskAsUserInternal(any())
+        doNothing().whenever(controller).launchUpdateNoteTaskAsUser(any())
         whenever(controller.getCurrentRunningUser()).thenReturn(UserHandle.SYSTEM)
 
         controller.updateNoteTaskAsUser(user)
 
-        verify(controller, never()).updateNoteTaskAsUserInternal(any())
+        verify(controller, never()).launchUpdateNoteTaskAsUser(any())
         val intent = withArgCaptor { verify(context).startServiceAsUser(capture(), eq(user)) }
         assertThat(intent).hasComponentClass(NoteTaskControllerUpdateService::class.java)
     }
@@ -733,7 +734,8 @@
     @Test
     fun updateNoteTaskAsUserInternal_withNotesRole_withShortcuts_shouldUpdateShortcuts() {
         createNoteTaskController(isEnabled = true)
-            .updateNoteTaskAsUserInternal(userTracker.userHandle)
+            .launchUpdateNoteTaskAsUser(userTracker.userHandle)
+        testScope.runCurrent()
 
         val actualComponent = argumentCaptor<ComponentName>()
         verify(context.packageManager)
@@ -768,7 +770,8 @@
             .thenReturn(emptyList())
 
         createNoteTaskController(isEnabled = true)
-            .updateNoteTaskAsUserInternal(userTracker.userHandle)
+            .launchUpdateNoteTaskAsUser(userTracker.userHandle)
+        testScope.runCurrent()
 
         val argument = argumentCaptor<ComponentName>()
         verify(context.packageManager)
@@ -787,7 +790,8 @@
     @Test
     fun updateNoteTaskAsUserInternal_flagDisabled_shouldDisableShortcuts() {
         createNoteTaskController(isEnabled = false)
-            .updateNoteTaskAsUserInternal(userTracker.userHandle)
+            .launchUpdateNoteTaskAsUser(userTracker.userHandle)
+        testScope.runCurrent()
 
         val argument = argumentCaptor<ComponentName>()
         verify(context.packageManager)