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.devicepolicy.areKeyguardShortcutsDisabled
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.getDefaultRoleHolderAsUser
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].
*
* On company owned personally enabled (COPE) devices, if the given [entryPoint] is in the
* [FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES] list, the default notes app in the work
* profile user will always be launched.
*
* On non managed devices or devices with other management modes, the current [UserHandle] is
* returned.
* 1. tail button entry point: In COPE or work profile devices, the user can select whether the
* work or main profile notes app should be launched in the Settings app. In non-management
* or device owner devices, the user can only select main profile notes app.
* 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
* COPE devices.
* 3. Other entry point: the current user from [UserTracker.userHandle].
*/
fun getUserForHandlingNotesTaking(entryPoint: NoteTaskEntryPoint): UserHandle =
if (
entryPoint in FORCE_WORK_NOTE_APPS_ENTRY_POINTS_ON_COPE_DEVICES &&
devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile
) {
userTracker.userProfiles.firstOrNull { userManager.isManagedProfile(it.id) }?.userHandle
?: userTracker.userHandle
} else {
secureSettings.preferredUser
when {
entryPoint == TAIL_BUTTON -> secureSettings.preferredUser
devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile &&
entryPoint == QUICK_AFFORDANCE -> {
userTracker.userProfiles
.firstOrNull { userManager.isManagedProfile(it.id) }
?.userHandle
?: userTracker.userHandle
}
// On work profile devices, SysUI always run in the main user.
else -> userTracker.userHandle
}
/**
@@ -267,15 +272,7 @@ constructor(
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
}
// 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)
}
val userContext = context.createContextAsUser(user, /* flags= */ 0)
userContext.packageManager.setComponentEnabledSetting(
componentName,
@@ -283,7 +280,7 @@ constructor(
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
get() {
val trackingUserId = userTracker.userHandle.identifier
val userId =
secureSettings.getInt(
Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
userTracker.userHandle.identifier,
secureSettings.getIntForUser(
/* name= */ Settings.Secure.DEFAULT_NOTE_TASK_PROFILE,
/* def= */ trackingUserId,
/* userHandle= */ trackingUserId,
)
return UserHandle.of(userId)
}
@@ -381,16 +380,6 @@ constructor(
* @see com.android.launcher3.icons.IconCache.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()))
.thenReturn(NOTE_TASK_LONG_LABEL)
whenever(context.packageManager).thenReturn(packageManager)
whenever(context.createContextAsUser(any(), any())).thenReturn(context)
whenever(packageManager.getApplicationInfo(any(), any<Int>())).thenReturn(mock())
whenever(packageManager.getApplicationLabel(any())).thenReturn(NOTE_TASK_LONG_LABEL)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(NOTE_TASK_INFO)
@@ -353,7 +354,13 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Test
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)
val user10 = UserHandle.of(/* userId= */ 10)
@@ -615,13 +622,21 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
}
@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)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
createNoteTaskController().showNoteTask(entryPoint = TAIL_BUTTON)
verifyNoteTaskOpenInBubbleInUser(workUserInfo.userHandle)
verifyNoteTaskOpenInBubbleInUser(mainUserInfo.userHandle)
}
@Test
@@ -813,7 +828,15 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
}
@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)
userTracker.set(mainAndWorkProfileUsers, mainAndWorkProfileUsers.indexOf(mainUserInfo))
@@ -822,6 +845,24 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
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
fun getUserForHandlingNotesTaking_cope_appClip_shouldReturnCurrentUser() {
whenever(devicePolicyManager.isOrganizationOwnedDeviceWithManagedProfile).thenReturn(true)