Use current user to launch note task am: a606c18684

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/21674799

Change-Id: I210deecdcc58ceeccfd8f79518dadaa52df97139
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Marcello Galhardo
2023-03-07 14:27:22 +00:00
committed by Automerger Merge Worker
5 changed files with 57 additions and 62 deletions

View File

@@ -22,6 +22,9 @@ import android.content.ActivityNotFoundException
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.os.UserManager import android.os.UserManager
@@ -54,8 +57,8 @@ constructor(
private val resolver: NoteTaskInfoResolver, private val resolver: NoteTaskInfoResolver,
private val eventLogger: NoteTaskEventLogger, private val eventLogger: NoteTaskEventLogger,
private val optionalBubbles: Optional<Bubbles>, private val optionalBubbles: Optional<Bubbles>,
private val optionalUserManager: Optional<UserManager>, private val userManager: UserManager,
private val optionalKeyguardManager: Optional<KeyguardManager>, private val keyguardManager: KeyguardManager,
@NoteTaskEnabledKey private val isEnabled: Boolean, @NoteTaskEnabledKey private val isEnabled: Boolean,
private val devicePolicyManager: DevicePolicyManager, private val devicePolicyManager: DevicePolicyManager,
private val userTracker: UserTracker, private val userTracker: UserTracker,
@@ -106,8 +109,6 @@ constructor(
if (!isEnabled) return if (!isEnabled) return
val bubbles = optionalBubbles.getOrNull() ?: return val bubbles = optionalBubbles.getOrNull() ?: return
val userManager = optionalUserManager.getOrNull() ?: return
val keyguardManager = optionalKeyguardManager.getOrNull() ?: return
// TODO(b/249954038): We should handle direct boot (isUserUnlocked). For now, we do nothing. // TODO(b/249954038): We should handle direct boot (isUserUnlocked). For now, we do nothing.
if (!userManager.isUserUnlocked) return if (!userManager.isUserUnlocked) return
@@ -140,12 +141,13 @@ constructor(
logDebug { "onShowNoteTask - start: $info" } logDebug { "onShowNoteTask - start: $info" }
when (info.launchMode) { when (info.launchMode) {
is NoteTaskLaunchMode.AppBubble -> { is NoteTaskLaunchMode.AppBubble -> {
// TODO(b/267634412, b/268351693): Should use `showOrHideAppBubbleAsUser`
bubbles.showOrHideAppBubble(intent) bubbles.showOrHideAppBubble(intent)
// App bubble logging happens on `onBubbleExpandChanged`. // App bubble logging happens on `onBubbleExpandChanged`.
logDebug { "onShowNoteTask - opened as app bubble: $info" } logDebug { "onShowNoteTask - opened as app bubble: $info" }
} }
is NoteTaskLaunchMode.Activity -> { is NoteTaskLaunchMode.Activity -> {
context.startActivity(intent) context.startActivityAsUser(intent, userTracker.userHandle)
eventLogger.logNoteTaskOpened(info) eventLogger.logNoteTaskOpened(info)
logDebug { "onShowNoteTask - opened as activity: $info" } logDebug { "onShowNoteTask - opened as activity: $info" }
} }
@@ -198,12 +200,21 @@ constructor(
} }
private fun createNoteIntent(info: NoteTaskInfo): Intent = private fun createNoteIntent(info: NoteTaskInfo): Intent =
Intent(NoteTaskController.ACTION_CREATE_NOTE) Intent(NoteTaskController.ACTION_CREATE_NOTE).apply {
.setPackage(info.packageName) setPackage(info.packageName)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
// EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint // EXTRA_USE_STYLUS_MODE does not mean a stylus is in-use, but a stylus entrypoint
// was used to start it. // was used to start it.
.putExtra(NoteTaskController.INTENT_EXTRA_USE_STYLUS_MODE, true) putExtra(NoteTaskController.INTENT_EXTRA_USE_STYLUS_MODE, true)
addFlags(FLAG_ACTIVITY_NEW_TASK)
// We should ensure the note experience can be open both as a full screen (lock screen)
// and inside the app bubble (contextual). These additional flags will do that.
if (info.launchMode == NoteTaskLaunchMode.Activity) {
addFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
addFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
}
}
private inline fun logDebug(message: () -> String) { private inline fun logDebug(message: () -> String) {
if (Build.IS_DEBUGGABLE) { if (Build.IS_DEBUGGABLE) {

View File

@@ -17,19 +17,19 @@
package com.android.systemui.notetask package com.android.systemui.notetask
import android.app.role.RoleManager import android.app.role.RoleManager
import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.content.pm.PackageManager.ApplicationInfoFlags import android.content.pm.PackageManager.ApplicationInfoFlags
import android.os.UserHandle import android.os.UserHandle
import android.util.Log import android.util.Log
import com.android.systemui.settings.UserTracker
import javax.inject.Inject import javax.inject.Inject
class NoteTaskInfoResolver class NoteTaskInfoResolver
@Inject @Inject
constructor( constructor(
private val context: Context,
private val roleManager: RoleManager, private val roleManager: RoleManager,
private val packageManager: PackageManager, private val packageManager: PackageManager,
private val userTracker: UserTracker,
) { ) {
fun resolveInfo( fun resolveInfo(
@@ -38,7 +38,7 @@ constructor(
isKeyguardLocked: Boolean = false, isKeyguardLocked: Boolean = false,
): NoteTaskInfo? { ): NoteTaskInfo? {
// TODO(b/267634412): Select UserHandle depending on where the user initiated note-taking. // TODO(b/267634412): Select UserHandle depending on where the user initiated note-taking.
val user = context.user val user = userTracker.userHandle
val packageName = val packageName =
roleManager.getRoleHoldersAsUser(RoleManager.ROLE_NOTES, user).firstOrNull() roleManager.getRoleHoldersAsUser(RoleManager.ROLE_NOTES, user).firstOrNull()

View File

@@ -17,11 +17,7 @@
package com.android.systemui.notetask package com.android.systemui.notetask
import android.app.Activity import android.app.Activity
import android.app.KeyguardManager
import android.app.role.RoleManager import android.app.role.RoleManager
import android.content.Context
import android.os.UserManager
import androidx.core.content.getSystemService
import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags import com.android.systemui.flags.Flags
import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceModule import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceModule
@@ -32,7 +28,6 @@ import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.multibindings.ClassKey import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap import dagger.multibindings.IntoMap
import java.util.Optional
/** Compose all dependencies required by Note Task feature. */ /** Compose all dependencies required by Note Task feature. */
@Module(includes = [NoteTaskQuickAffordanceModule::class]) @Module(includes = [NoteTaskQuickAffordanceModule::class])
@@ -55,15 +50,5 @@ interface NoteTaskModule {
val isFeatureEnabled = featureFlags.isEnabled(Flags.NOTE_TASKS) val isFeatureEnabled = featureFlags.isEnabled(Flags.NOTE_TASKS)
return isRoleAvailable && isFeatureEnabled return isRoleAvailable && isFeatureEnabled
} }
@Provides
fun provideOptionalKeyguardManager(context: Context): Optional<KeyguardManager> {
return Optional.ofNullable(context.getSystemService())
}
@Provides
fun provideOptionalUserManager(context: Context): Optional<UserManager> {
return Optional.ofNullable(context.getSystemService())
}
} }
} }

View File

@@ -20,12 +20,17 @@ import android.app.admin.DevicePolicyManager
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.UserHandle
import android.os.UserManager import android.os.UserManager
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4 import androidx.test.runner.AndroidJUnit4
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.settings.FakeUserTracker
import com.android.systemui.settings.UserTracker import com.android.systemui.settings.UserTracker
import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.argumentCaptor
@@ -57,8 +62,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Mock lateinit var keyguardManager: KeyguardManager @Mock lateinit var keyguardManager: KeyguardManager
@Mock lateinit var userManager: UserManager @Mock lateinit var userManager: UserManager
@Mock lateinit var eventLogger: NoteTaskEventLogger @Mock lateinit var eventLogger: NoteTaskEventLogger
@Mock private lateinit var userTracker: UserTracker
@Mock private lateinit var devicePolicyManager: DevicePolicyManager @Mock private lateinit var devicePolicyManager: DevicePolicyManager
private val userTracker: UserTracker = FakeUserTracker()
private val noteTaskInfo = NoteTaskInfo(packageName = NOTES_PACKAGE_NAME, uid = NOTES_UID) private val noteTaskInfo = NoteTaskInfo(packageName = NOTES_PACKAGE_NAME, uid = NOTES_UID)
@@ -81,16 +86,14 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
private fun createNoteTaskController( private fun createNoteTaskController(
isEnabled: Boolean = true, isEnabled: Boolean = true,
bubbles: Bubbles? = this.bubbles, bubbles: Bubbles? = this.bubbles,
keyguardManager: KeyguardManager? = this.keyguardManager,
userManager: UserManager? = this.userManager,
): NoteTaskController = ): NoteTaskController =
NoteTaskController( NoteTaskController(
context = context, context = context,
resolver = resolver, resolver = resolver,
eventLogger = eventLogger, eventLogger = eventLogger,
optionalBubbles = Optional.ofNullable(bubbles), optionalBubbles = Optional.ofNullable(bubbles),
optionalUserManager = Optional.ofNullable(userManager), userManager = userManager,
optionalKeyguardManager = Optional.ofNullable(keyguardManager), keyguardManager = keyguardManager,
isEnabled = isEnabled, isEnabled = isEnabled,
devicePolicyManager = devicePolicyManager, devicePolicyManager = devicePolicyManager,
userTracker = userTracker, userTracker = userTracker,
@@ -225,13 +228,19 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
) )
val intentCaptor = argumentCaptor<Intent>() val intentCaptor = argumentCaptor<Intent>()
verify(context).startActivity(capture(intentCaptor)) val userCaptor = argumentCaptor<UserHandle>()
verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
intentCaptor.value.let { intent -> intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE) assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
assertThat(intent.flags).isEqualTo(Intent.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)
.isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK)
assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT)
.isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT)
assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue() assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
} }
assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
verify(eventLogger).logNoteTaskOpened(expectedInfo) verify(eventLogger).logNoteTaskOpened(expectedInfo)
verifyZeroInteractions(bubbles) verifyZeroInteractions(bubbles)
} }
@@ -259,7 +268,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
intentCaptor.value.let { intent -> intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE) assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) assertThat(intent.flags).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue() assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
} }
verifyZeroInteractions(eventLogger) verifyZeroInteractions(eventLogger)
@@ -283,13 +292,22 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
) )
val intentCaptor = argumentCaptor<Intent>() val intentCaptor = argumentCaptor<Intent>()
verify(context).startActivity(capture(intentCaptor)) val userCaptor = argumentCaptor<UserHandle>()
verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
(intentCaptor.value.flags and FLAG_ACTIVITY_NEW_TASK) == FLAG_ACTIVITY_NEW_TASK
intentCaptor.value.let { intent -> intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE) assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
assertThat(intent.flags).isEqualTo(Intent.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)
.isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK)
assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT)
.isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT)
assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue() assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
} }
assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
verify(eventLogger).logNoteTaskOpened(expectedInfo) verify(eventLogger).logNoteTaskOpened(expectedInfo)
verifyZeroInteractions(bubbles) verifyZeroInteractions(bubbles)
} }
@@ -305,28 +323,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
verifyZeroInteractions(context, bubbles, eventLogger) verifyZeroInteractions(context, bubbles, eventLogger)
} }
@Test
fun showNoteTask_keyguardManagerIsNull_shouldDoNothing() {
createNoteTaskController(keyguardManager = null)
.showNoteTask(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
)
verifyZeroInteractions(context, bubbles, eventLogger)
}
@Test
fun showNoteTask_userManagerIsNull_shouldDoNothing() {
createNoteTaskController(userManager = null)
.showNoteTask(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
)
verifyZeroInteractions(context, bubbles, eventLogger)
}
@Test @Test
fun showNoteTask_intentResolverReturnsNull_shouldDoNothing() { fun showNoteTask_intentResolverReturnsNull_shouldDoNothing() {
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(null) whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(null)
@@ -460,7 +456,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
intentCaptor.value.let { intent -> intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE) assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) assertThat(intent.flags).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue() assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
} }
} }
@@ -487,7 +483,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
intentCaptor.value.let { intent -> intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE) assertThat(intent.action).isEqualTo(NoteTaskController.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME) assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK) assertThat(intent.flags).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue() assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
} }
} }

View File

@@ -22,6 +22,8 @@ import android.content.pm.PackageManager
import android.test.suitebuilder.annotation.SmallTest import android.test.suitebuilder.annotation.SmallTest
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.settings.UserTracker
import com.android.systemui.util.mockito.eq import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
@@ -44,13 +46,14 @@ internal class NoteTaskInfoResolverTest : SysuiTestCase() {
@Mock lateinit var packageManager: PackageManager @Mock lateinit var packageManager: PackageManager
@Mock lateinit var roleManager: RoleManager @Mock lateinit var roleManager: RoleManager
private val userTracker: UserTracker = FakeUserTracker()
private lateinit var underTest: NoteTaskInfoResolver private lateinit var underTest: NoteTaskInfoResolver
@Before @Before
fun setUp() { fun setUp() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
underTest = NoteTaskInfoResolver(context, roleManager, packageManager) underTest = NoteTaskInfoResolver(roleManager, packageManager, userTracker)
} }
@Test @Test