Fix notes task app user when launching from work profile, COPE & multi-users
1. lock screen quick affordance entry point a. COPE: work profile notes app b. Work Profile: main profile notes app c. no management: main profile notes app 2. tail button entry point a. COPE / work profile: user preference b. no management: main profile notes app 3. other entry point: tracking user Also fix an issue with enabling notes app shortcut entry point caused by not using the right user package manager to manage the notes app shortcut entry point. Test: NoteTaskControllerTest Fix: 290215897 Fix: 290580903 Change-Id: I3cadb0c2333ddaa95688aa394b814e95f9b1f0b3
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user