Loading packages/SystemUI/res/values/config.xml +6 −0 Original line number Diff line number Diff line Loading @@ -506,6 +506,12 @@ icon will be shown. --> <string name="config_screenshotFilesApp" translatable="false"></string> <!-- Recommends a UI mode for the default note-taking app when launched with android.content.Intent#ACTION_CREATE_NOTE 0: No UI recommendation. The note app should use its default mode 1: Recommend a UI optimized for stylus input. --> <integer name="config_preferredNotesMode">1</integer> <!-- The component name of the screenshot editing activity that provides the App Clips flow. The App Clips flow includes taking a screenshot, showing user screenshot cropping activity and finally letting user send the screenshot to the calling notes app. This activity Loading packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +14 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled import com.android.systemui.log.DebugLogger.debugLog import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser Loading Loading @@ -117,7 +118,6 @@ constructor( } else { getUserForHandlingNotesTaking(entryPoint) } activityContext.startActivityAsUser(createNotesRoleHolderSettingsIntent(), user) } Loading Loading @@ -206,9 +206,17 @@ constructor( try { // TODO(b/266686199): We should handle when app not available. For now, we log. debugLog { "onShowNoteTask - start: $info on user#${user.identifier}" } val useStylusMode = when { info.entryPoint == TAIL_BUTTON -> true info.entryPoint == KEYBOARD_SHORTCUT -> false else -> context.resources.getInteger(R.integer.config_preferredNotesMode) == PREFERRED_NOTES_MODE_STYLUS } when (info.launchMode) { is NoteTaskLaunchMode.AppBubble -> { val intent = createNoteTaskIntent(info) val intent = createNoteTaskIntent(info, useStylusMode) val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget) noteTaskBubblesController.showOrHideAppBubble( Loading @@ -229,7 +237,7 @@ constructor( eventLogger.logNoteTaskClosed(info) debugLog { "onShowNoteTask - closed as activity: $info" } } else { val intent = createNoteTaskIntent(info) val intent = createNoteTaskIntent(info, useStylusMode) context.startActivityAsUser(intent, user) eventLogger.logNoteTaskOpened(info) debugLog { "onShowNoteTask - opened as activity: $info" } Loading Loading @@ -393,6 +401,8 @@ constructor( */ const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package" const val PREFERRED_NOTES_MODE_STYLUS = 1 /** Returns notes role holder settings intent. */ fun createNotesRoleHolderSettingsIntent() = Intent(Intent.ACTION_MANAGE_DEFAULT_APP).putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES) Loading @@ -400,13 +410,12 @@ constructor( } /** Creates an [Intent] for [ROLE_NOTES]. */ private fun createNoteTaskIntent(info: NoteTaskInfo): Intent = private fun createNoteTaskIntent(info: NoteTaskInfo, useStylusMode: Boolean): Intent = Intent(Intent.ACTION_CREATE_NOTE).apply { setPackage(info.packageName) // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint // was used to start the note task. val useStylusMode = info.entryPoint != NoteTaskEntryPoint.KEYBOARD_SHORTCUT putExtra(Intent.EXTRA_USE_STYLUS_MODE, useStylusMode) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) Loading packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt +108 −29 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED import android.content.pm.ShortcutManager import android.content.pm.UserInfo import android.content.res.Resources import android.graphics.drawable.Icon import android.os.UserHandle import android.os.UserManager Loading Loading @@ -84,6 +85,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations import org.mockito.kotlin.whenever Loading @@ -106,6 +108,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { @Mock private lateinit var shortcutManager: ShortcutManager @Mock private lateinit var activityManager: ActivityManager @Mock private lateinit var devicePolicyManager: DevicePolicyManager private lateinit var spiedResources: Resources private val userTracker = FakeUserTracker() private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) Loading @@ -130,7 +133,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE) Loading @@ -139,6 +142,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever(activityManager.getRunningTasks(anyInt())).thenReturn(emptyList()) whenever(userManager.isManagedProfile(workUserInfo.id)).thenReturn(true) whenever(context.resources).thenReturn(getContext().resources) spiedResources = spy(context.resources) `when`(context.resources).thenReturn(spiedResources) } private fun createNoteTaskController( Loading @@ -161,7 +167,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { noteTaskBubblesController = FakeNoteTaskBubbleController(context, testDispatcher, Optional.ofNullable(bubbles)), applicationScope = testScope, bgCoroutineContext = testScope.backgroundScope.coroutineContext bgCoroutineContext = testScope.backgroundScope.coroutineContext, ) // region onBubbleExpandChanged Loading Loading @@ -225,11 +231,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { @Test fun onBubbleExpandChanged_notKeyAppBubble_shouldDoNothing() { createNoteTaskController() .onBubbleExpandChanged( isExpanding = true, key = "any other key", ) createNoteTaskController().onBubbleExpandChanged(isExpanding = true, key = "any other key") verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger) } Loading @@ -251,11 +253,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { fun showNoteTaskAsUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() { val user10 = UserHandle.of(/* userId= */ 10) val expectedInfo = NOTE_TASK_INFO.copy( entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10, ) NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) Loading Loading @@ -360,7 +358,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ 10, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) val user10 = UserHandle.of(/* userId= */ 10) Loading @@ -373,10 +371,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController() .showNoteTask( entryPoint = expectedInfo.entryPoint!!, ) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() Loading Loading @@ -456,6 +451,85 @@ internal class NoteTaskControllerTest : SysuiTestCase() { verifyNoMoreInteractions(bubbles) } @Test fun showNoteTask_stylusModePreferred_keyboardShortcut_shouldStartInDefaultUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = KEYBOARD_SHORTCUT, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isFalse() } } @Test fun showNoteTask_stylusModePreferred_quickAffordance_shouldStartInStylusUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isTrue() } } @Test fun showNoteTask_noUIRecommendation_quickAffordance_shouldStartInDefaultUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isFalse() } } @Test fun showNoteTask_noUIRecommendation_tailButton_shouldStartInStylusUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isTrue() } } // endregion // region setNoteTaskShortcutEnabled Loading Loading @@ -543,7 +617,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL) Loading @@ -559,7 +633,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) Loading @@ -575,7 +649,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL) Loading @@ -591,7 +665,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) Loading @@ -604,8 +678,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { // endregion // region showNoteTask, COPE devices @Suppress("ktlint:standard:max-line-length") @Test fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() { // ktlint-disable max-line-length fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() { whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(listOf(mainUserInfo), mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading @@ -629,7 +704,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ mainUserInfo.id, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading Loading @@ -836,12 +911,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ workUserInfo.id, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading @@ -851,12 +927,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ mainUserInfo.id, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading Loading @@ -934,8 +1011,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE) Loading @@ -947,8 +1025,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) createNoteTaskController().startNotesRoleSetting(context, entryPoint = null) Loading Loading
packages/SystemUI/res/values/config.xml +6 −0 Original line number Diff line number Diff line Loading @@ -506,6 +506,12 @@ icon will be shown. --> <string name="config_screenshotFilesApp" translatable="false"></string> <!-- Recommends a UI mode for the default note-taking app when launched with android.content.Intent#ACTION_CREATE_NOTE 0: No UI recommendation. The note app should use its default mode 1: Recommend a UI optimized for stylus input. --> <integer name="config_preferredNotesMode">1</integer> <!-- The component name of the screenshot editing activity that provides the App Clips flow. The App Clips flow includes taking a screenshot, showing user screenshot cropping activity and finally letting user send the screenshot to the calling notes app. This activity Loading
packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +14 −5 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled import com.android.systemui.log.DebugLogger.debugLog import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser Loading Loading @@ -117,7 +118,6 @@ constructor( } else { getUserForHandlingNotesTaking(entryPoint) } activityContext.startActivityAsUser(createNotesRoleHolderSettingsIntent(), user) } Loading Loading @@ -206,9 +206,17 @@ constructor( try { // TODO(b/266686199): We should handle when app not available. For now, we log. debugLog { "onShowNoteTask - start: $info on user#${user.identifier}" } val useStylusMode = when { info.entryPoint == TAIL_BUTTON -> true info.entryPoint == KEYBOARD_SHORTCUT -> false else -> context.resources.getInteger(R.integer.config_preferredNotesMode) == PREFERRED_NOTES_MODE_STYLUS } when (info.launchMode) { is NoteTaskLaunchMode.AppBubble -> { val intent = createNoteTaskIntent(info) val intent = createNoteTaskIntent(info, useStylusMode) val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget) noteTaskBubblesController.showOrHideAppBubble( Loading @@ -229,7 +237,7 @@ constructor( eventLogger.logNoteTaskClosed(info) debugLog { "onShowNoteTask - closed as activity: $info" } } else { val intent = createNoteTaskIntent(info) val intent = createNoteTaskIntent(info, useStylusMode) context.startActivityAsUser(intent, user) eventLogger.logNoteTaskOpened(info) debugLog { "onShowNoteTask - opened as activity: $info" } Loading Loading @@ -393,6 +401,8 @@ constructor( */ const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package" const val PREFERRED_NOTES_MODE_STYLUS = 1 /** Returns notes role holder settings intent. */ fun createNotesRoleHolderSettingsIntent() = Intent(Intent.ACTION_MANAGE_DEFAULT_APP).putExtra(Intent.EXTRA_ROLE_NAME, ROLE_NOTES) Loading @@ -400,13 +410,12 @@ constructor( } /** Creates an [Intent] for [ROLE_NOTES]. */ private fun createNoteTaskIntent(info: NoteTaskInfo): Intent = private fun createNoteTaskIntent(info: NoteTaskInfo, useStylusMode: Boolean): Intent = Intent(Intent.ACTION_CREATE_NOTE).apply { setPackage(info.packageName) // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint // was used to start the note task. val useStylusMode = info.entryPoint != NoteTaskEntryPoint.KEYBOARD_SHORTCUT putExtra(Intent.EXTRA_USE_STYLUS_MODE, useStylusMode) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) Loading
packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt +108 −29 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED import android.content.pm.ShortcutManager import android.content.pm.UserInfo import android.content.res.Resources import android.graphics.drawable.Icon import android.os.UserHandle import android.os.UserManager Loading Loading @@ -84,6 +85,7 @@ import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.Mockito.verifyNoMoreInteractions import org.mockito.Mockito.`when` import org.mockito.MockitoAnnotations import org.mockito.kotlin.whenever Loading @@ -106,6 +108,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { @Mock private lateinit var shortcutManager: ShortcutManager @Mock private lateinit var activityManager: ActivityManager @Mock private lateinit var devicePolicyManager: DevicePolicyManager private lateinit var spiedResources: Resources private val userTracker = FakeUserTracker() private val testDispatcher = UnconfinedTestDispatcher() private val testScope = TestScope(testDispatcher) Loading @@ -130,7 +133,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE) Loading @@ -139,6 +142,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever(activityManager.getRunningTasks(anyInt())).thenReturn(emptyList()) whenever(userManager.isManagedProfile(workUserInfo.id)).thenReturn(true) whenever(context.resources).thenReturn(getContext().resources) spiedResources = spy(context.resources) `when`(context.resources).thenReturn(spiedResources) } private fun createNoteTaskController( Loading @@ -161,7 +167,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { noteTaskBubblesController = FakeNoteTaskBubbleController(context, testDispatcher, Optional.ofNullable(bubbles)), applicationScope = testScope, bgCoroutineContext = testScope.backgroundScope.coroutineContext bgCoroutineContext = testScope.backgroundScope.coroutineContext, ) // region onBubbleExpandChanged Loading Loading @@ -225,11 +231,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { @Test fun onBubbleExpandChanged_notKeyAppBubble_shouldDoNothing() { createNoteTaskController() .onBubbleExpandChanged( isExpanding = true, key = "any other key", ) createNoteTaskController().onBubbleExpandChanged(isExpanding = true, key = "any other key") verifyNoMoreInteractions(bubbles, keyguardManager, userManager, eventLogger) } Loading @@ -251,11 +253,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { fun showNoteTaskAsUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() { val user10 = UserHandle.of(/* userId= */ 10) val expectedInfo = NOTE_TASK_INFO.copy( entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10, ) NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) Loading Loading @@ -360,7 +358,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ 10, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) val user10 = UserHandle.of(/* userId= */ 10) Loading @@ -373,10 +371,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController() .showNoteTask( entryPoint = expectedInfo.entryPoint!!, ) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() Loading Loading @@ -456,6 +451,85 @@ internal class NoteTaskControllerTest : SysuiTestCase() { verifyNoMoreInteractions(bubbles) } @Test fun showNoteTask_stylusModePreferred_keyboardShortcut_shouldStartInDefaultUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = KEYBOARD_SHORTCUT, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isFalse() } } @Test fun showNoteTask_stylusModePreferred_quickAffordance_shouldStartInStylusUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(1) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isTrue() } } @Test fun showNoteTask_noUIRecommendation_quickAffordance_shouldStartInDefaultUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = QUICK_AFFORDANCE, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isFalse() } } @Test fun showNoteTask_noUIRecommendation_tailButton_shouldStartInStylusUIMode() { `when`(spiedResources.getInteger(R.integer.config_preferredNotesMode)).thenReturn(0) val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!) val intentCaptor = argumentCaptor<Intent>() val userCaptor = argumentCaptor<UserHandle>() verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor)) assertThat(intentCaptor.value).run { hasAction(ACTION_CREATE_NOTE) hasPackage(NOTE_TASK_PACKAGE_NAME) extras().bool(EXTRA_USE_STYLUS_MODE).isTrue() } } // endregion // region setNoteTaskShortcutEnabled Loading Loading @@ -543,7 +617,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL) Loading @@ -559,7 +633,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) Loading @@ -575,7 +649,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL) Loading @@ -591,7 +665,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { whenever( devicePolicyManager.getKeyguardDisabledFeatures( /* admin= */ eq(null), /* userHandle= */ anyInt() /* userHandle= */ anyInt(), ) ) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) Loading @@ -604,8 +678,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { // endregion // region showNoteTask, COPE devices @Suppress("ktlint:standard:max-line-length") @Test fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() { // ktlint-disable max-line-length fun showNoteTask_copeDevices_quickAffordanceEntryPoint_managedProfileNotFound_shouldStartBubbleInTheMainProfile() { whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(listOf(mainUserInfo), mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading @@ -629,7 +704,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ mainUserInfo.id, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading Loading @@ -836,12 +911,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ workUserInfo.id, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading @@ -851,12 +927,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { secureSettings.putIntForUser( /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* value= */ mainUserInfo.id, /* userHandle= */ userTracker.userId /* userHandle= */ userTracker.userId, ) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) Loading Loading @@ -934,8 +1011,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length fun startNotesRoleSetting_noManagement_quickAffordance_shouldStartNoteRoleIntentWithCurrentUser() { userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) createNoteTaskController().startNotesRoleSetting(context, QUICK_AFFORDANCE) Loading @@ -947,8 +1025,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(userCaptor.value).isEqualTo(UserHandle.of(mainUserInfo.id)) } @Suppress("ktlint:standard:max-line-length") @Test fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { // ktlint-disable max-line-length fun startNotesRoleSetting_noManagement_nullEntryPoint_shouldStartNoteRoleIntentWithCurrentUser() { userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) createNoteTaskController().startNotesRoleSetting(context, entryPoint = null) Loading