Merge "Note task does not support split-screen" into udc-dev

This commit is contained in:
Marcello Galhardo
2023-03-09 10:25:44 +00:00
committed by Android (Google) Code Review
7 changed files with 29 additions and 159 deletions

View File

@@ -967,6 +967,7 @@
android:enabled="false" android:enabled="false"
android:exported="true" android:exported="true"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:resizeableActivity="false"
android:theme="@android:style/Theme.NoDisplay" android:theme="@android:style/Theme.NoDisplay"
android:label="@string/note_task_button_label" android:label="@string/note_task_button_label"
android:icon="@drawable/ic_note_task_shortcut_widget"> android:icon="@drawable/ic_note_task_shortcut_widget">
@@ -981,6 +982,7 @@
android:name=".notetask.shortcut.LaunchNoteTaskActivity" android:name=".notetask.shortcut.LaunchNoteTaskActivity"
android:exported="true" android:exported="true"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:resizeableActivity="false"
android:theme="@android:style/Theme.NoDisplay" /> android:theme="@android:style/Theme.NoDisplay" />
<!-- endregion --> <!-- endregion -->

View File

@@ -89,22 +89,16 @@ constructor(
/** /**
* Shows a note task. How the task is shown will depend on when the method is invoked. * Shows a note task. How the task is shown will depend on when the method is invoked.
* *
* If in multi-window mode, notes will open as a full screen experience. That is particularly
* important for Large screen devices. These devices may support a taskbar that let users to
* drag and drop a shortcut into multi-window mode, and notes should comply with this behaviour.
*
* If the keyguard is locked, notes will open as a full screen experience. A locked device has * If the keyguard is locked, notes will open as a full screen experience. A locked device has
* no contextual information which let us use the whole screen space available. * no contextual information which let us use the whole screen space available.
* *
* If not in multi-window or the keyguard is unlocked, notes will open as a bubble OR it will be * If the keyguard is unlocked, notes will open as a bubble OR it will be collapsed if the notes
* collapsed if the notes bubble is already opened. * bubble is already opened.
* *
* That will let users open other apps in full screen, and take contextual notes. * That will let users open other apps in full screen, and take contextual notes.
*/ */
@JvmOverloads
fun showNoteTask( fun showNoteTask(
entryPoint: NoteTaskEntryPoint, entryPoint: NoteTaskEntryPoint,
isInMultiWindowMode: Boolean = false,
) { ) {
if (!isEnabled) return if (!isEnabled) return
@@ -125,13 +119,7 @@ constructor(
return return
} }
val info = val info = resolver.resolveInfo(entryPoint, isKeyguardLocked) ?: return
resolver.resolveInfo(
entryPoint = entryPoint,
isInMultiWindowMode = isInMultiWindowMode,
isKeyguardLocked = isKeyguardLocked,
)
?: return
infoReference.set(info) infoReference.set(info)

View File

@@ -20,12 +20,11 @@ data class NoteTaskInfo(
val packageName: String, val packageName: String,
val uid: Int, val uid: Int,
val entryPoint: NoteTaskEntryPoint? = null, val entryPoint: NoteTaskEntryPoint? = null,
val isInMultiWindowMode: Boolean = false,
val isKeyguardLocked: Boolean = false, val isKeyguardLocked: Boolean = false,
) { ) {
val launchMode: NoteTaskLaunchMode = val launchMode: NoteTaskLaunchMode =
if (isInMultiWindowMode || isKeyguardLocked) { if (isKeyguardLocked) {
NoteTaskLaunchMode.Activity NoteTaskLaunchMode.Activity
} else { } else {
NoteTaskLaunchMode.AppBubble NoteTaskLaunchMode.AppBubble

View File

@@ -34,7 +34,6 @@ constructor(
fun resolveInfo( fun resolveInfo(
entryPoint: NoteTaskEntryPoint? = null, entryPoint: NoteTaskEntryPoint? = null,
isInMultiWindowMode: Boolean = false,
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.
@@ -48,7 +47,6 @@ constructor(
packageName = packageName, packageName = packageName,
uid = packageManager.getUidOf(packageName, user), uid = packageManager.getUidOf(packageName, user),
entryPoint = entryPoint, entryPoint = entryPoint,
isInMultiWindowMode = isInMultiWindowMode,
isKeyguardLocked = isKeyguardLocked, isKeyguardLocked = isKeyguardLocked,
) )
} }

View File

@@ -28,17 +28,12 @@ import javax.inject.Inject
class LaunchNoteTaskActivity class LaunchNoteTaskActivity
@Inject @Inject
constructor( constructor(
private val noteTaskController: NoteTaskController, private val controller: NoteTaskController,
) : ComponentActivity() { ) : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
controller.showNoteTask(entryPoint = NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT)
noteTaskController.showNoteTask(
entryPoint = NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT,
isInMultiWindowMode = isInMultiWindowMode,
)
finish() finish()
} }

View File

@@ -72,7 +72,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
MockitoAnnotations.initMocks(this) MockitoAnnotations.initMocks(this)
whenever(context.packageManager).thenReturn(packageManager) whenever(context.packageManager).thenReturn(packageManager)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(noteTaskInfo) whenever(resolver.resolveInfo(any(), any())).thenReturn(noteTaskInfo)
whenever(userManager.isUserUnlocked).thenReturn(true) whenever(userManager.isUserUnlocked).thenReturn(true)
whenever( whenever(
devicePolicyManager.getKeyguardDisabledFeatures( devicePolicyManager.getKeyguardDisabledFeatures(
@@ -102,7 +102,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
// region onBubbleExpandChanged // region onBubbleExpandChanged
@Test @Test
fun onBubbleExpandChanged_expanding_logNoteTaskOpened() { fun onBubbleExpandChanged_expanding_logNoteTaskOpened() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = false, isInMultiWindowMode = false) val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = false)
createNoteTaskController() createNoteTaskController()
.apply { infoReference.set(expectedInfo) } .apply { infoReference.set(expectedInfo) }
@@ -117,7 +117,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Test @Test
fun onBubbleExpandChanged_collapsing_logNoteTaskClosed() { fun onBubbleExpandChanged_collapsing_logNoteTaskClosed() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = false, isInMultiWindowMode = false) val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = false)
createNoteTaskController() createNoteTaskController()
.apply { infoReference.set(expectedInfo) } .apply { infoReference.set(expectedInfo) }
@@ -132,7 +132,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Test @Test
fun onBubbleExpandChanged_expandingAndKeyguardLocked_doNothing() { fun onBubbleExpandChanged_expandingAndKeyguardLocked_doNothing() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = true, isInMultiWindowMode = false) val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = true)
createNoteTaskController() createNoteTaskController()
.apply { infoReference.set(expectedInfo) } .apply { infoReference.set(expectedInfo) }
@@ -146,35 +146,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Test @Test
fun onBubbleExpandChanged_notExpandingAndKeyguardLocked_doNothing() { fun onBubbleExpandChanged_notExpandingAndKeyguardLocked_doNothing() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = true, isInMultiWindowMode = false) val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = true)
createNoteTaskController()
.apply { infoReference.set(expectedInfo) }
.onBubbleExpandChanged(
isExpanding = false,
key = Bubble.KEY_APP_BUBBLE,
)
verifyZeroInteractions(context, bubbles, keyguardManager, userManager, eventLogger)
}
@Test
fun onBubbleExpandChanged_expandingAndInMultiWindowMode_doNothing() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = false, isInMultiWindowMode = true)
createNoteTaskController()
.apply { infoReference.set(expectedInfo) }
.onBubbleExpandChanged(
isExpanding = true,
key = Bubble.KEY_APP_BUBBLE,
)
verifyZeroInteractions(context, bubbles, keyguardManager, userManager)
}
@Test
fun onBubbleExpandChanged_notExpandingAndInMultiWindowMode_doNothing() {
val expectedInfo = noteTaskInfo.copy(isKeyguardLocked = false, isInMultiWindowMode = true)
createNoteTaskController() createNoteTaskController()
.apply { infoReference.set(expectedInfo) } .apply { infoReference.set(expectedInfo) }
@@ -215,16 +187,14 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
val expectedInfo = val expectedInfo =
noteTaskInfo.copy( noteTaskInfo.copy(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON, entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
isKeyguardLocked = true, isKeyguardLocked = true,
) )
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) whenever(resolver.resolveInfo(any(), any())).thenReturn(expectedInfo)
createNoteTaskController() createNoteTaskController()
.showNoteTask( .showNoteTask(
entryPoint = expectedInfo.entryPoint!!, entryPoint = expectedInfo.entryPoint!!,
isInMultiWindowMode = expectedInfo.isInMultiWindowMode,
) )
val intentCaptor = argumentCaptor<Intent>() val intentCaptor = argumentCaptor<Intent>()
@@ -250,16 +220,14 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
val expectedInfo = val expectedInfo =
noteTaskInfo.copy( noteTaskInfo.copy(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON, entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
isKeyguardLocked = false, isKeyguardLocked = false,
) )
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo) whenever(resolver.resolveInfo(any(), any())).thenReturn(expectedInfo)
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked) whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
createNoteTaskController() createNoteTaskController()
.showNoteTask( .showNoteTask(
entryPoint = expectedInfo.entryPoint!!, entryPoint = expectedInfo.entryPoint!!,
isInMultiWindowMode = expectedInfo.isInMultiWindowMode,
) )
verifyZeroInteractions(context) verifyZeroInteractions(context)
@@ -274,50 +242,11 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
verifyZeroInteractions(eventLogger) verifyZeroInteractions(eventLogger)
} }
@Test
fun showNoteTask_isInMultiWindowMode_shouldStartActivityAndLogUiEvent() {
val expectedInfo =
noteTaskInfo.copy(
entryPoint = NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT,
isInMultiWindowMode = true,
isKeyguardLocked = false,
)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
createNoteTaskController()
.showNoteTask(
entryPoint = expectedInfo.entryPoint!!,
isInMultiWindowMode = expectedInfo.isInMultiWindowMode,
)
val intentCaptor = argumentCaptor<Intent>()
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 ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
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(userCaptor.value).isEqualTo(userTracker.userHandle)
verify(eventLogger).logNoteTaskOpened(expectedInfo)
verifyZeroInteractions(bubbles)
}
@Test @Test
fun showNoteTask_bubblesIsNull_shouldDoNothing() { fun showNoteTask_bubblesIsNull_shouldDoNothing() {
createNoteTaskController(bubbles = null) createNoteTaskController(bubbles = null)
.showNoteTask( .showNoteTask(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON, entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
) )
verifyZeroInteractions(context, bubbles, eventLogger) verifyZeroInteractions(context, bubbles, eventLogger)
@@ -325,12 +254,11 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
@Test @Test
fun showNoteTask_intentResolverReturnsNull_shouldDoNothing() { fun showNoteTask_intentResolverReturnsNull_shouldDoNothing() {
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(null) whenever(resolver.resolveInfo(any(), any())).thenReturn(null)
createNoteTaskController() createNoteTaskController()
.showNoteTask( .showNoteTask(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON, entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
) )
verifyZeroInteractions(context, bubbles, eventLogger) verifyZeroInteractions(context, bubbles, eventLogger)
@@ -341,7 +269,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
createNoteTaskController(isEnabled = false) createNoteTaskController(isEnabled = false)
.showNoteTask( .showNoteTask(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON, entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
) )
verifyZeroInteractions(context, bubbles, eventLogger) verifyZeroInteractions(context, bubbles, eventLogger)
@@ -354,7 +281,6 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
createNoteTaskController() createNoteTaskController()
.showNoteTask( .showNoteTask(
entryPoint = NoteTaskEntryPoint.TAIL_BUTTON, entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
isInMultiWindowMode = false,
) )
verifyZeroInteractions(context, bubbles, eventLogger) verifyZeroInteractions(context, bubbles, eventLogger)
@@ -405,11 +331,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
) )
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
createNoteTaskController() createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
.showNoteTask(
isInMultiWindowMode = false,
entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE
)
verifyZeroInteractions(context, bubbles, eventLogger) verifyZeroInteractions(context, bubbles, eventLogger)
} }
@@ -425,11 +347,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
) )
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
createNoteTaskController() createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
.showNoteTask(
isInMultiWindowMode = false,
entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE
)
verifyZeroInteractions(context, bubbles, eventLogger) verifyZeroInteractions(context, bubbles, eventLogger)
} }
@@ -445,11 +363,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
) )
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_SHORTCUTS_ALL)
createNoteTaskController() createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
.showNoteTask(
isInMultiWindowMode = false,
entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE
)
val intentCaptor = argumentCaptor<Intent>() val intentCaptor = argumentCaptor<Intent>()
verify(bubbles).showOrHideAppBubble(capture(intentCaptor)) verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
@@ -472,11 +386,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
) )
.thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL) .thenReturn(DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL)
createNoteTaskController() createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
.showNoteTask(
isInMultiWindowMode = false,
entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE
)
val intentCaptor = argumentCaptor<Intent>() val intentCaptor = argumentCaptor<Intent>()
verify(bubbles).showOrHideAppBubble(capture(intentCaptor)) verify(bubbles).showOrHideAppBubble(capture(intentCaptor))

View File

@@ -31,41 +31,19 @@ internal class NoteTaskInfoTest : SysuiTestCase() {
NoteTaskInfo(packageName = NOTES_PACKAGE_NAME, uid = NOTES_UID) NoteTaskInfo(packageName = NOTES_PACKAGE_NAME, uid = NOTES_UID)
@Test @Test
fun launchMode_notInMultiWindowModeAndKeyguardUnlocked_launchModeAppBubble() { fun launchMode_keyguardLocked_launchModeActivity() {
val underTest = val underTest = createNoteTaskInfo().copy(isKeyguardLocked = true)
createNoteTaskInfo()
.copy( assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.Activity)
isKeyguardLocked = false, }
isInMultiWindowMode = false,
) @Test
fun launchMode_keyguardUnlocked_launchModeActivity() {
val underTest = createNoteTaskInfo().copy(isKeyguardLocked = false)
assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.AppBubble) assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.AppBubble)
} }
@Test
fun launchMode_inMultiWindowMode_launchModeActivity() {
val underTest =
createNoteTaskInfo()
.copy(
isKeyguardLocked = false,
isInMultiWindowMode = true,
)
assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.Activity)
}
@Test
fun launchMode_keyguardLocked_launchModeActivity() {
val underTest =
createNoteTaskInfo()
.copy(
isKeyguardLocked = true,
isInMultiWindowMode = false,
)
assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.Activity)
}
private companion object { private companion object {
const val NOTES_PACKAGE_NAME = "com.android.note.app" const val NOTES_PACKAGE_NAME = "com.android.note.app"
const val NOTES_UID = 123456 const val NOTES_UID = 123456