From 9b11048e8c1f64244a3c74253a90a0203469aa5f Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Mon, 3 Apr 2023 17:47:50 +0000 Subject: [PATCH] Enable work profile notes app shortcut when notes role is set Test: atest SystemUITests:com.android.systemui.notetask.NoteTaskInitializer atest SystemUITests:com.android.systemui.notetask.NoteTaskControllerTest Bug: 259952057 Change-Id: I88e39d48c34e157b8b22437bbbba235e69876c9b --- .../systemui/notetask/NoteTaskController.kt | 15 ++++- .../systemui/notetask/NoteTaskInitializer.kt | 9 ++- .../notetask/NoteTaskControllerTest.kt | 65 +++++++++++++++---- .../notetask/NoteTaskInitializerTest.kt | 36 +++++++--- 4 files changed, 98 insertions(+), 27 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt index 334c70b217a3c..9513801f0985d 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt @@ -214,7 +214,7 @@ constructor( * If the shortcut entry `android:enabled` is set to `true`, the shortcut will be visible in the * Widget Picker to all users. */ - fun setNoteTaskShortcutEnabled(value: Boolean) { + fun setNoteTaskShortcutEnabled(value: Boolean, user: UserHandle) { val componentName = ComponentName(context, CreateNoteTaskShortcutActivity::class.java) val enabledState = @@ -224,7 +224,16 @@ constructor( PackageManager.COMPONENT_ENABLED_STATE_DISABLED } - context.packageManager.setComponentEnabledSetting( + // If the required user matches the tracking user, the injected context is already a context + // of the required user. Avoid calling #createContextAsUser because creating a context for + // a user takes time. + val userContext = + if (user == userTracker.userHandle) { + context + } else { + context.createContextAsUser(user, /* flags= */ 0) + } + userContext.packageManager.setComponentEnabledSetting( componentName, enabledState, PackageManager.DONT_KILL_APP, @@ -246,7 +255,7 @@ constructor( val packageName = roleManager.getDefaultRoleHolderAsUser(ROLE_NOTES, user) val hasNotesRoleHolder = isEnabled && !packageName.isNullOrEmpty() - setNoteTaskShortcutEnabled(hasNotesRoleHolder) + setNoteTaskShortcutEnabled(hasNotesRoleHolder, user) if (hasNotesRoleHolder) { shortcutManager.enableShortcuts(listOf(SHORTCUT_ID)) diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt index 23ee13b4deac9..7bb615b8d866a 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskInitializer.kt @@ -20,6 +20,7 @@ import android.os.UserHandle import android.view.KeyEvent import androidx.annotation.VisibleForTesting import com.android.systemui.dagger.qualifiers.Background +import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.CommandQueue import com.android.wm.shell.bubbles.Bubbles import java.util.Optional @@ -36,6 +37,7 @@ constructor( private val optionalBubbles: Optional, @Background private val backgroundExecutor: Executor, @NoteTaskEnabledKey private val isEnabled: Boolean, + private val userTracker: UserTracker, ) { @VisibleForTesting @@ -44,8 +46,9 @@ constructor( override fun handleSystemKey(key: KeyEvent) { if (key.keyCode == KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL) { controller.showNoteTask(NoteTaskEntryPoint.TAIL_BUTTON) - } else if (key.keyCode == KeyEvent.KEYCODE_N && key.isMetaPressed && - key.isCtrlPressed) { + } else if ( + key.keyCode == KeyEvent.KEYCODE_N && key.isMetaPressed && key.isCtrlPressed + ) { controller.showNoteTask(NoteTaskEntryPoint.KEYBOARD_SHORTCUT) } } @@ -55,7 +58,7 @@ constructor( // Guard against feature not being enabled or mandatory dependencies aren't available. if (!isEnabled || optionalBubbles.isEmpty) return - controller.setNoteTaskShortcutEnabled(true) + controller.setNoteTaskShortcutEnabled(true, userTracker.userHandle) commandQueue.addCallback(callbacks) roleManager.addOnRoleHoldersChangedListenerAsUser( backgroundExecutor, 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 ba29ca57cefbc..5e7394aee98c0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt @@ -75,7 +75,9 @@ import org.mockito.MockitoAnnotations internal class NoteTaskControllerTest : SysuiTestCase() { @Mock private lateinit var context: Context + @Mock private lateinit var workProfileContext: Context @Mock private lateinit var packageManager: PackageManager + @Mock private lateinit var workProfilePackageManager: PackageManager @Mock private lateinit var resolver: NoteTaskInfoResolver @Mock private lateinit var bubbles: Bubbles @Mock private lateinit var keyguardManager: KeyguardManager @@ -373,17 +375,17 @@ internal class NoteTaskControllerTest : SysuiTestCase() { @Test fun showNoteTask_keyboardShortcut_shouldStartActivity() { val expectedInfo = - NOTE_TASK_INFO.copy( - entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT, - isKeyguardLocked = true, - ) + NOTE_TASK_INFO.copy( + entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT, + isKeyguardLocked = true, + ) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(resolver.resolveInfo(any(), any())).thenReturn(expectedInfo) createNoteTaskController() - .showNoteTask( - entryPoint = expectedInfo.entryPoint!!, - ) + .showNoteTask( + entryPoint = expectedInfo.entryPoint!!, + ) val intentCaptor = argumentCaptor() val userCaptor = argumentCaptor() @@ -393,9 +395,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(intent.`package`).isEqualTo(NOTE_TASK_PACKAGE_NAME) assertThat(intent.flags and FLAG_ACTIVITY_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK) assertThat(intent.flags and FLAG_ACTIVITY_MULTIPLE_TASK) - .isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK) + .isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK) assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT) - .isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT) + .isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT) assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, true)).isFalse() } assertThat(userCaptor.value).isEqualTo(userTracker.userHandle) @@ -407,7 +409,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { // region setNoteTaskShortcutEnabled @Test fun setNoteTaskShortcutEnabled_setTrue() { - createNoteTaskController().setNoteTaskShortcutEnabled(value = true) + createNoteTaskController().setNoteTaskShortcutEnabled(value = true, userTracker.userHandle) val argument = argumentCaptor() verify(context.packageManager) @@ -422,7 +424,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() { @Test fun setNoteTaskShortcutEnabled_setFalse() { - createNoteTaskController().setNoteTaskShortcutEnabled(value = false) + createNoteTaskController().setNoteTaskShortcutEnabled(value = false, userTracker.userHandle) val argument = argumentCaptor() verify(context.packageManager) @@ -434,6 +436,47 @@ internal class NoteTaskControllerTest : SysuiTestCase() { assertThat(argument.value.className) .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name) } + + @Test + fun setNoteTaskShortcutEnabled_workProfileUser_setTrue() { + whenever(context.createContextAsUser(eq(workUserInfo.userHandle), any())) + .thenReturn(workProfileContext) + whenever(workProfileContext.packageManager).thenReturn(workProfilePackageManager) + userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) + + createNoteTaskController().setNoteTaskShortcutEnabled(value = true, workUserInfo.userHandle) + + val argument = argumentCaptor() + verify(workProfilePackageManager) + .setComponentEnabledSetting( + argument.capture(), + eq(COMPONENT_ENABLED_STATE_ENABLED), + eq(PackageManager.DONT_KILL_APP), + ) + assertThat(argument.value.className) + .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name) + } + + @Test + fun setNoteTaskShortcutEnabled_workProfileUser_setFalse() { + whenever(context.createContextAsUser(eq(workUserInfo.userHandle), any())) + .thenReturn(workProfileContext) + whenever(workProfileContext.packageManager).thenReturn(workProfilePackageManager) + userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) + + createNoteTaskController() + .setNoteTaskShortcutEnabled(value = false, workUserInfo.userHandle) + + val argument = argumentCaptor() + verify(workProfilePackageManager) + .setComponentEnabledSetting( + argument.capture(), + eq(COMPONENT_ENABLED_STATE_DISABLED), + eq(PackageManager.DONT_KILL_APP), + ) + assertThat(argument.value.className) + .isEqualTo(CreateNoteTaskShortcutActivity::class.java.name) + } // endregion // region keyguard policy diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt index ec4daee72cf8e..28ed9d22a41bc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskInitializerTest.kt @@ -20,9 +20,11 @@ import android.test.suitebuilder.annotation.SmallTest import android.view.KeyEvent import androidx.test.runner.AndroidJUnit4 import com.android.systemui.SysuiTestCase +import com.android.systemui.settings.FakeUserTracker import com.android.systemui.statusbar.CommandQueue import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any +import com.android.systemui.util.mockito.eq import com.android.systemui.util.time.FakeSystemClock import com.android.wm.shell.bubbles.Bubbles import java.util.Optional @@ -46,6 +48,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { @Mock lateinit var roleManager: RoleManager private val clock = FakeSystemClock() private val executor = FakeExecutor(clock) + private val userTracker = FakeUserTracker() @Before fun setUp() { @@ -63,6 +66,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { isEnabled = isEnabled, roleManager = roleManager, backgroundExecutor = executor, + userTracker = userTracker, ) } @@ -71,7 +75,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { fun initialize() { createNoteTaskInitializer().initialize() - verify(controller).setNoteTaskShortcutEnabled(true) + verify(controller).setNoteTaskShortcutEnabled(eq(true), eq(userTracker.userHandle)) verify(commandQueue).addCallback(any()) verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), any(), any()) } @@ -80,7 +84,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { fun initialize_flagDisabled() { createNoteTaskInitializer(isEnabled = false).initialize() - verify(controller, never()).setNoteTaskShortcutEnabled(any()) + verify(controller, never()).setNoteTaskShortcutEnabled(any(), any()) verify(commandQueue, never()).addCallback(any()) verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any()) } @@ -89,7 +93,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { fun initialize_bubblesNotPresent() { createNoteTaskInitializer(bubbles = null).initialize() - verify(controller, never()).setNoteTaskShortcutEnabled(any()) + verify(controller, never()).setNoteTaskShortcutEnabled(any(), any()) verify(commandQueue, never()).addCallback(any()) verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any()) } @@ -98,24 +102,36 @@ internal class NoteTaskInitializerTest : SysuiTestCase() { // region handleSystemKey @Test fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() { - createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, - KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL)) + createNoteTaskInitializer() + .callbacks + .handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL)) verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON) } @Test fun handleSystemKey_receiveKeyboardShortcut_shouldShowNoteTask() { - createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent(0, 0, KeyEvent.ACTION_DOWN, - KeyEvent.KEYCODE_N, 0, KeyEvent.META_META_ON or KeyEvent.META_CTRL_ON)) + createNoteTaskInitializer() + .callbacks + .handleSystemKey( + KeyEvent( + 0, + 0, + KeyEvent.ACTION_DOWN, + KeyEvent.KEYCODE_N, + 0, + KeyEvent.META_META_ON or KeyEvent.META_CTRL_ON + ) + ) verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT) } - + @Test fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() { - createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, - KeyEvent.KEYCODE_UNKNOWN)) + createNoteTaskInitializer() + .callbacks + .handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_UNKNOWN)) verifyZeroInteractions(controller) }