Merge "Fix notes task app user when launching from work profile, COPE & multi-users" into udc-qpr-dev

This commit is contained in:
Steven Ng
2023-07-25 12:55:38 +00:00
committed by Android (Google) Code Review
2 changed files with 72 additions and 42 deletions

View File

@@ -41,6 +41,8 @@ import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.log.DebugLogger.debugLog import com.android.systemui.log.DebugLogger.debugLog
import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
@@ -121,23 +123,26 @@ constructor(
/** /**
* Returns the [UserHandle] of an android user that should handle the notes taking [entryPoint]. * Returns the [UserHandle] of an android user that should handle the notes taking [entryPoint].
* * 1. tail button entry point: In COPE or work profile devices, the user can select whether the
* On company owned personally enabled (COPE) devices, if the given [entryPoint] is in the * work or main profile notes app should be launched in the Settings app. In non-management
* [FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES] list, the default notes app in the work * or device owner devices, the user can only select main profile notes app.
* profile user will always be launched. * 2. lock screen quick affordance: since there is no user setting, the main profile notes app
* * is used as default for work profile devices while the work profile notes app is used for
* On non managed devices or devices with other management modes, the current [UserHandle] is * COPE devices.
* returned. * 3. Other entry point: the current user from [UserTracker.userHandle].
*/ */
fun getUserForHandlingNotesTaking(entryPoint: NoteTaskEntryPoint): UserHandle = fun getUserForHandlingNotesTaking(entryPoint: NoteTaskEntryPoint): UserHandle =
if ( when {
entryPoint in FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES && entryPoint == TAIL_BUTTON -> secureSettings.preferredUser
devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile &&
) { entryPoint == QUICK_AFFORDANCE -> {
userTracker.userProfiles.firstOrNull { userManager.isManagedProfile(it.id) }?.userHandle userTracker.userProfiles
.firstOrNull { userManager.isManagedProfile(it.id) }
?.userHandle
?: userTracker.userHandle ?: userTracker.userHandle
} else { }
secureSettings.preferredUser // On work profile devices, SysUI always run in the main user.
else -> userTracker.userHandle
} }
/** /**
@@ -267,15 +272,7 @@ constructor(
PackageManager.COMPONENT_ENABLED_STATE_DISABLED PackageManager.COMPONENT_ENABLED_STATE_DISABLED
} }
// If the required user matches the tracking user, the injected context is already a context val userContext = context.createContextAsUser(user, /* flags= */ 0)
// 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( userContext.packageManager.setComponentEnabledSetting(
componentName, componentName,
@@ -283,7 +280,7 @@ constructor(
PackageManager.DONT_KILL_APP, PackageManager.DONT_KILL_APP,
) )
debugLog { "setNoteTaskShortcutEnabled - completed: $isEnabled" } debugLog { "setNoteTaskShortcutEnabled for user $user- completed: $enabledState" }
} }
/** /**
@@ -359,10 +356,12 @@ constructor(
private val SecureSettings.preferredUser: UserHandle private val SecureSettings.preferredUser: UserHandle
get() { get() {
val trackingUserId = userTracker.userHandle.identifier
val userId = val userId =
secureSettings.getInt( secureSettings.getIntForUser(
Settings.Secure.DEFAULT_NOTE_TASK_PROFILE, /* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
userTracker.userHandle.identifier, /* def= */ trackingUserId,
/* userHandle= */ trackingUserId,
) )
return UserHandle.of(userId) return UserHandle.of(userId)
} }
@@ -381,16 +380,6 @@ constructor(
* @see com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE * @see com.android.launcher3.icons.IconCache.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
*/ */
const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package" const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = "extra_shortcut_badge_override_package"
/**
* A list of entry points which should be redirected to the work profile default notes app
* on company owned personally enabled (COPE) devices.
*
* Entry points in this list don't let users / admin to select the work or personal default
* notes app to be launched.
*/
val FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES =
listOf(NoteTaskEntryPoint.TAIL_BUTTON, NoteTaskEntryPoint.QUICK_AFFORDANCE)
} }
} }

View File

@@ -118,6 +118,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
whenever(context.getString(eq(R.string.note_task_shortcut_long_label), any())) whenever(context.getString(eq(R.string.note_task_shortcut_long_label), any()))
.thenReturn(NOTE_TASK_LONG_LABEL) .thenReturn(NOTE_TASK_LONG_LABEL)
whenever(context.packageManager).thenReturn(packageManager) whenever(context.packageManager).thenReturn(packageManager)
whenever(context.createContextAsUser(any(), any())).thenReturn(context)
whenever(packageManager.getApplicationInfo(any(), any<Int>())).thenReturn(mock()) whenever(packageManager.getApplicationInfo(any(), any<Int>())).thenReturn(mock())
whenever(packageManager.getApplicationLabel(any())).thenReturn(NOTE_TASK_LONG_LABEL) whenever(packageManager.getApplicationLabel(any())).thenReturn(NOTE_TASK_LONG_LABEL)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO)
@@ -353,7 +354,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Test @Test
fun showNoteTask_defaultUserSet_shouldStartActivityWithExpectedUserAndLogUiEvent() { fun showNoteTask_defaultUserSet_shouldStartActivityWithExpectedUserAndLogUiEvent() {
whenever(secureSettings.getInt(eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE), any())) whenever(
secureSettings.getIntForUser(
/* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
/* def= */ any(),
/* userHandle= */ any()
)
)
.thenReturn(10) .thenReturn(10)
val user10 = UserHandle.of(/* userId= */ 10) val user10 = UserHandle.of(/* userId= */ 10)
@@ -615,13 +622,21 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
} }
@Test @Test
fun showNoteTask_copeDevices_tailButtonEntryPoint_shouldStartBubbleInWorkProfile() { fun showNoteTask_copeDevices_tailButtonEntryPoint_shouldStartBubbleInTheUserSelectedUser() {
whenever(
secureSettings.getIntForUser(
/* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
/* def= */ any(),
/* userHandle= */ any()
)
)
.thenReturn(mainUserInfo.id)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON) createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
verifyNoteTaskOpenInBubbleInUser(workUserInfo.userHandle) verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
} }
@Test @Test
@@ -813,7 +828,15 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
} }
@Test @Test
fun getUserForHandlingNotesTaking_cope_tailButton_shouldReturnWorkProfileUser() { fun getUserForHandlingNotesTaking_cope_userSelectedWorkProfile_tailButton_shouldReturnWorkProfileUser() { // ktlint-disable max-line-length
whenever(
secureSettings.getIntForUser(
/* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
/* def= */ any(),
/* userHandle= */ any()
)
)
.thenReturn(workUserInfo.id)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo)) userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -822,6 +845,24 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id)) assertThat(user).isEqualTo(UserHandle.of(workUserInfo.id))
} }
@Test
fun getUserForHandlingNotesTaking_cope_userSelectedMainProfile_tailButton_shouldReturnMainProfileUser() { // ktlint-disable max-line-length
whenever(
secureSettings.getIntForUser(
/* name= */ eq(Settings.Secure.DEFAULT_NOTE_TASK_PROFILE),
/* def= */ any(),
/* userHandle= */ any()
)
)
.thenReturn(mainUserInfo.id)
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
val user = createNoteTaskController().getUserForHandlingNotesTaking(TAIL_BUTTON)
assertThat(user).isEqualTo(UserHandle.of(mainUserInfo.id))
}
@Test @Test
fun getUserForHandlingNotesTaking_cope_appClip_shouldReturnCurrentUser() { fun getUserForHandlingNotesTaking_cope_appClip_shouldReturnCurrentUser() {
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true) whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)