Merge "Enable work profile notes app shortcut when notes role is set" into udc-dev
This commit is contained in:
@@ -214,7 +214,7 @@ constructor(
|
|||||||
* If the shortcut entry `android:enabled` is set to `true`, the shortcut will be visible in the
|
* If the shortcut entry `android:enabled` is set to `true`, the shortcut will be visible in the
|
||||||
* Widget Picker to all users.
|
* Widget Picker to all users.
|
||||||
*/
|
*/
|
||||||
fun setNoteTaskShortcutEnabled(value: Boolean) {
|
fun setNoteTaskShortcutEnabled(value: Boolean, user: UserHandle) {
|
||||||
val componentName = ComponentName(context, CreateNoteTaskShortcutActivity::class.java)
|
val componentName = ComponentName(context, CreateNoteTaskShortcutActivity::class.java)
|
||||||
|
|
||||||
val enabledState =
|
val enabledState =
|
||||||
@@ -224,7 +224,16 @@ constructor(
|
|||||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|
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,
|
componentName,
|
||||||
enabledState,
|
enabledState,
|
||||||
PackageManager.DONT_KILL_APP,
|
PackageManager.DONT_KILL_APP,
|
||||||
@@ -246,7 +255,7 @@ constructor(
|
|||||||
val packageName = roleManager.getDefaultRoleHolderAsUser(ROLE_NOTES, user)
|
val packageName = roleManager.getDefaultRoleHolderAsUser(ROLE_NOTES, user)
|
||||||
val hasNotesRoleHolder = isEnabled && !packageName.isNullOrEmpty()
|
val hasNotesRoleHolder = isEnabled && !packageName.isNullOrEmpty()
|
||||||
|
|
||||||
setNoteTaskShortcutEnabled(hasNotesRoleHolder)
|
setNoteTaskShortcutEnabled(hasNotesRoleHolder, user)
|
||||||
|
|
||||||
if (hasNotesRoleHolder) {
|
if (hasNotesRoleHolder) {
|
||||||
shortcutManager.enableShortcuts(listOf(SHORTCUT_ID))
|
shortcutManager.enableShortcuts(listOf(SHORTCUT_ID))
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.os.UserHandle
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import androidx.annotation.VisibleForTesting
|
import androidx.annotation.VisibleForTesting
|
||||||
import com.android.systemui.dagger.qualifiers.Background
|
import com.android.systemui.dagger.qualifiers.Background
|
||||||
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.statusbar.CommandQueue
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.wm.shell.bubbles.Bubbles
|
import com.android.wm.shell.bubbles.Bubbles
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
@@ -36,6 +37,7 @@ constructor(
|
|||||||
private val optionalBubbles: Optional<Bubbles>,
|
private val optionalBubbles: Optional<Bubbles>,
|
||||||
@Background private val backgroundExecutor: Executor,
|
@Background private val backgroundExecutor: Executor,
|
||||||
@NoteTaskEnabledKey private val isEnabled: Boolean,
|
@NoteTaskEnabledKey private val isEnabled: Boolean,
|
||||||
|
private val userTracker: UserTracker,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -44,8 +46,9 @@ constructor(
|
|||||||
override fun handleSystemKey(key: KeyEvent) {
|
override fun handleSystemKey(key: KeyEvent) {
|
||||||
if (key.keyCode == KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL) {
|
if (key.keyCode == KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL) {
|
||||||
controller.showNoteTask(NoteTaskEntryPoint.TAIL_BUTTON)
|
controller.showNoteTask(NoteTaskEntryPoint.TAIL_BUTTON)
|
||||||
} else if (key.keyCode == KeyEvent.KEYCODE_N && key.isMetaPressed &&
|
} else if (
|
||||||
key.isCtrlPressed) {
|
key.keyCode == KeyEvent.KEYCODE_N && key.isMetaPressed && key.isCtrlPressed
|
||||||
|
) {
|
||||||
controller.showNoteTask(NoteTaskEntryPoint.KEYBOARD_SHORTCUT)
|
controller.showNoteTask(NoteTaskEntryPoint.KEYBOARD_SHORTCUT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,7 +58,7 @@ constructor(
|
|||||||
// Guard against feature not being enabled or mandatory dependencies aren't available.
|
// Guard against feature not being enabled or mandatory dependencies aren't available.
|
||||||
if (!isEnabled || optionalBubbles.isEmpty) return
|
if (!isEnabled || optionalBubbles.isEmpty) return
|
||||||
|
|
||||||
controller.setNoteTaskShortcutEnabled(true)
|
controller.setNoteTaskShortcutEnabled(true, userTracker.userHandle)
|
||||||
commandQueue.addCallback(callbacks)
|
commandQueue.addCallback(callbacks)
|
||||||
roleManager.addOnRoleHoldersChangedListenerAsUser(
|
roleManager.addOnRoleHoldersChangedListenerAsUser(
|
||||||
backgroundExecutor,
|
backgroundExecutor,
|
||||||
|
|||||||
@@ -75,7 +75,9 @@ import org.mockito.MockitoAnnotations
|
|||||||
internal class NoteTaskControllerTest : SysuiTestCase() {
|
internal class NoteTaskControllerTest : SysuiTestCase() {
|
||||||
|
|
||||||
@Mock private lateinit var context: Context
|
@Mock private lateinit var context: Context
|
||||||
|
@Mock private lateinit var workProfileContext: Context
|
||||||
@Mock private lateinit var packageManager: PackageManager
|
@Mock private lateinit var packageManager: PackageManager
|
||||||
|
@Mock private lateinit var workProfilePackageManager: PackageManager
|
||||||
@Mock private lateinit var resolver: NoteTaskInfoResolver
|
@Mock private lateinit var resolver: NoteTaskInfoResolver
|
||||||
@Mock private lateinit var bubbles: Bubbles
|
@Mock private lateinit var bubbles: Bubbles
|
||||||
@Mock private lateinit var keyguardManager: KeyguardManager
|
@Mock private lateinit var keyguardManager: KeyguardManager
|
||||||
@@ -373,17 +375,17 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun showNoteTask_keyboardShortcut_shouldStartActivity() {
|
fun showNoteTask_keyboardShortcut_shouldStartActivity() {
|
||||||
val expectedInfo =
|
val expectedInfo =
|
||||||
NOTE_TASK_INFO.copy(
|
NOTE_TASK_INFO.copy(
|
||||||
entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT,
|
entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT,
|
||||||
isKeyguardLocked = true,
|
isKeyguardLocked = true,
|
||||||
)
|
)
|
||||||
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
|
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
|
||||||
whenever(resolver.resolveInfo(any(), any())).thenReturn(expectedInfo)
|
whenever(resolver.resolveInfo(any(), any())).thenReturn(expectedInfo)
|
||||||
|
|
||||||
createNoteTaskController()
|
createNoteTaskController()
|
||||||
.showNoteTask(
|
.showNoteTask(
|
||||||
entryPoint = expectedInfo.entryPoint!!,
|
entryPoint = expectedInfo.entryPoint!!,
|
||||||
)
|
)
|
||||||
|
|
||||||
val intentCaptor = argumentCaptor<Intent>()
|
val intentCaptor = argumentCaptor<Intent>()
|
||||||
val userCaptor = argumentCaptor<UserHandle>()
|
val userCaptor = argumentCaptor<UserHandle>()
|
||||||
@@ -393,9 +395,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
|||||||
assertThat(intent.`package`).isEqualTo(NOTE_TASK_PACKAGE_NAME)
|
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_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
|
||||||
assertThat(intent.flags and FLAG_ACTIVITY_MULTIPLE_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)
|
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(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, true)).isFalse()
|
||||||
}
|
}
|
||||||
assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
|
assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
|
||||||
@@ -407,7 +409,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
|||||||
// region setNoteTaskShortcutEnabled
|
// region setNoteTaskShortcutEnabled
|
||||||
@Test
|
@Test
|
||||||
fun setNoteTaskShortcutEnabled_setTrue() {
|
fun setNoteTaskShortcutEnabled_setTrue() {
|
||||||
createNoteTaskController().setNoteTaskShortcutEnabled(value = true)
|
createNoteTaskController().setNoteTaskShortcutEnabled(value = true, userTracker.userHandle)
|
||||||
|
|
||||||
val argument = argumentCaptor<ComponentName>()
|
val argument = argumentCaptor<ComponentName>()
|
||||||
verify(context.packageManager)
|
verify(context.packageManager)
|
||||||
@@ -422,7 +424,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun setNoteTaskShortcutEnabled_setFalse() {
|
fun setNoteTaskShortcutEnabled_setFalse() {
|
||||||
createNoteTaskController().setNoteTaskShortcutEnabled(value = false)
|
createNoteTaskController().setNoteTaskShortcutEnabled(value = false, userTracker.userHandle)
|
||||||
|
|
||||||
val argument = argumentCaptor<ComponentName>()
|
val argument = argumentCaptor<ComponentName>()
|
||||||
verify(context.packageManager)
|
verify(context.packageManager)
|
||||||
@@ -434,6 +436,47 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
|
|||||||
assertThat(argument.value.className)
|
assertThat(argument.value.className)
|
||||||
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
|
.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<ComponentName>()
|
||||||
|
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<ComponentName>()
|
||||||
|
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
|
// endregion
|
||||||
|
|
||||||
// region keyguard policy
|
// region keyguard policy
|
||||||
|
|||||||
@@ -20,9 +20,11 @@ import android.test.suitebuilder.annotation.SmallTest
|
|||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import androidx.test.runner.AndroidJUnit4
|
import androidx.test.runner.AndroidJUnit4
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.settings.FakeUserTracker
|
||||||
import com.android.systemui.statusbar.CommandQueue
|
import com.android.systemui.statusbar.CommandQueue
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor
|
import com.android.systemui.util.concurrency.FakeExecutor
|
||||||
import com.android.systemui.util.mockito.any
|
import com.android.systemui.util.mockito.any
|
||||||
|
import com.android.systemui.util.mockito.eq
|
||||||
import com.android.systemui.util.time.FakeSystemClock
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
import com.android.wm.shell.bubbles.Bubbles
|
import com.android.wm.shell.bubbles.Bubbles
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
@@ -46,6 +48,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() {
|
|||||||
@Mock lateinit var roleManager: RoleManager
|
@Mock lateinit var roleManager: RoleManager
|
||||||
private val clock = FakeSystemClock()
|
private val clock = FakeSystemClock()
|
||||||
private val executor = FakeExecutor(clock)
|
private val executor = FakeExecutor(clock)
|
||||||
|
private val userTracker = FakeUserTracker()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
@@ -63,6 +66,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() {
|
|||||||
isEnabled = isEnabled,
|
isEnabled = isEnabled,
|
||||||
roleManager = roleManager,
|
roleManager = roleManager,
|
||||||
backgroundExecutor = executor,
|
backgroundExecutor = executor,
|
||||||
|
userTracker = userTracker,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +75,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() {
|
|||||||
fun initialize() {
|
fun initialize() {
|
||||||
createNoteTaskInitializer().initialize()
|
createNoteTaskInitializer().initialize()
|
||||||
|
|
||||||
verify(controller).setNoteTaskShortcutEnabled(true)
|
verify(controller).setNoteTaskShortcutEnabled(eq(true), eq(userTracker.userHandle))
|
||||||
verify(commandQueue).addCallback(any())
|
verify(commandQueue).addCallback(any())
|
||||||
verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
|
verify(roleManager).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
|
||||||
}
|
}
|
||||||
@@ -80,7 +84,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() {
|
|||||||
fun initialize_flagDisabled() {
|
fun initialize_flagDisabled() {
|
||||||
createNoteTaskInitializer(isEnabled = false).initialize()
|
createNoteTaskInitializer(isEnabled = false).initialize()
|
||||||
|
|
||||||
verify(controller, never()).setNoteTaskShortcutEnabled(any())
|
verify(controller, never()).setNoteTaskShortcutEnabled(any(), any())
|
||||||
verify(commandQueue, never()).addCallback(any())
|
verify(commandQueue, never()).addCallback(any())
|
||||||
verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
|
verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
|
||||||
}
|
}
|
||||||
@@ -89,7 +93,7 @@ internal class NoteTaskInitializerTest : SysuiTestCase() {
|
|||||||
fun initialize_bubblesNotPresent() {
|
fun initialize_bubblesNotPresent() {
|
||||||
createNoteTaskInitializer(bubbles = null).initialize()
|
createNoteTaskInitializer(bubbles = null).initialize()
|
||||||
|
|
||||||
verify(controller, never()).setNoteTaskShortcutEnabled(any())
|
verify(controller, never()).setNoteTaskShortcutEnabled(any(), any())
|
||||||
verify(commandQueue, never()).addCallback(any())
|
verify(commandQueue, never()).addCallback(any())
|
||||||
verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
|
verify(roleManager, never()).addOnRoleHoldersChangedListenerAsUser(any(), any(), any())
|
||||||
}
|
}
|
||||||
@@ -98,24 +102,36 @@ internal class NoteTaskInitializerTest : SysuiTestCase() {
|
|||||||
// region handleSystemKey
|
// region handleSystemKey
|
||||||
@Test
|
@Test
|
||||||
fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() {
|
fun handleSystemKey_receiveValidSystemKey_shouldShowNoteTask() {
|
||||||
createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN,
|
createNoteTaskInitializer()
|
||||||
KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL))
|
.callbacks
|
||||||
|
.handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_STYLUS_BUTTON_TAIL))
|
||||||
|
|
||||||
verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON)
|
verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.TAIL_BUTTON)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun handleSystemKey_receiveKeyboardShortcut_shouldShowNoteTask() {
|
fun handleSystemKey_receiveKeyboardShortcut_shouldShowNoteTask() {
|
||||||
createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
|
createNoteTaskInitializer()
|
||||||
KeyEvent.KEYCODE_N, 0, KeyEvent.META_META_ON or KeyEvent.META_CTRL_ON))
|
.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)
|
verify(controller).showNoteTask(entryPoint = NoteTaskEntryPoint.KEYBOARD_SHORTCUT)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() {
|
fun handleSystemKey_receiveInvalidSystemKey_shouldDoNothing() {
|
||||||
createNoteTaskInitializer().callbacks.handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN,
|
createNoteTaskInitializer()
|
||||||
KeyEvent.KEYCODE_UNKNOWN))
|
.callbacks
|
||||||
|
.handleSystemKey(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_UNKNOWN))
|
||||||
|
|
||||||
verifyZeroInteractions(controller)
|
verifyZeroInteractions(controller)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user