RESTRICT AUTOMERGE Support split-mode on Note Shortcut am: a896a94ed7

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

Change-Id: I4401c2279cafaba9d11d553ac1d7f8271a0ec42d
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Marcello Galhardo
2023-06-08 09:36:28 +00:00
committed by Automerger Merge Worker
9 changed files with 119 additions and 73 deletions

View File

@@ -996,7 +996,6 @@
android:name=".notetask.shortcut.LaunchNoteTaskActivity"
android:exported="true"
android:excludeFromRecents="true"
android:resizeableActivity="false"
android:theme="@android:style/Theme.NoDisplay" >
<intent-filter>
@@ -1012,7 +1011,6 @@
android:exported="false"
android:enabled="true"
android:excludeFromRecents="true"
android:resizeableActivity="false"
android:theme="@android:style/Theme.NoDisplay" />
<activity

View File

@@ -215,7 +215,7 @@ constructor(
debugLog { "onShowNoteTask - opened as app bubble: $info" }
}
is NoteTaskLaunchMode.Activity -> {
if (activityManager.isInForeground(info.packageName)) {
if (info.isKeyguardLocked && activityManager.isInForeground(info.packageName)) {
// Force note task into background by calling home.
val intent = createHomeIntent()
context.startActivityAsUser(intent, user)

View File

@@ -25,12 +25,14 @@ import com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity
* An entry point represents where the note task has ben called from. In rare cases, it may
* represent a "re-entry" (i.e., [APP_CLIPS]).
*/
enum class
NoteTaskEntryPoint {
enum class NoteTaskEntryPoint {
/** @see [LaunchNoteTaskActivity] */
WIDGET_PICKER_SHORTCUT,
/** @see [LaunchNoteTaskActivity] */
WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE,
/** @see [NoteTaskQuickAffordanceConfig] */
QUICK_AFFORDANCE,

View File

@@ -22,6 +22,8 @@ import com.android.systemui.notetask.NoteTaskEntryPoint.KEYBOARD_SHORTCUT
import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT
import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE
import com.android.systemui.notetask.NoteTaskEventLogger.NoteTaskUiEvent
import com.android.systemui.notetask.NoteTaskEventLogger.NoteTaskUiEvent.NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE
import com.android.systemui.notetask.NoteTaskEventLogger.NoteTaskUiEvent.NOTE_OPENED_VIA_SHORTCUT
import com.android.systemui.notetask.NoteTaskEventLogger.NoteTaskUiEvent.NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON
@@ -41,40 +43,45 @@ class NoteTaskEventLogger @Inject constructor(private val uiEventLogger: UiEvent
/** Logs a [NoteTaskInfo] as an **open** [NoteTaskUiEvent], including package name and uid. */
fun logNoteTaskOpened(info: NoteTaskInfo) {
val event =
when (info.entryPoint) {
TAIL_BUTTON -> {
if (info.isKeyguardLocked) {
NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED
} else {
NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON
when (info.entryPoint) {
TAIL_BUTTON -> {
if (info.isKeyguardLocked) {
NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON_LOCKED
} else {
NOTE_OPENED_VIA_STYLUS_TAIL_BUTTON
}
}
WIDGET_PICKER_SHORTCUT,
WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE -> NOTE_OPENED_VIA_SHORTCUT
QUICK_AFFORDANCE -> NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE
APP_CLIPS,
KEYBOARD_SHORTCUT,
null -> return
}
WIDGET_PICKER_SHORTCUT -> NOTE_OPENED_VIA_SHORTCUT
QUICK_AFFORDANCE -> NOTE_OPENED_VIA_KEYGUARD_QUICK_AFFORDANCE
APP_CLIPS -> return
KEYBOARD_SHORTCUT -> return
null -> return
}
uiEventLogger.log(event, info.uid, info.packageName)
}
/** Logs a [NoteTaskInfo] as a **closed** [NoteTaskUiEvent], including package name and uid. */
fun logNoteTaskClosed(info: NoteTaskInfo) {
val event =
when (info.entryPoint) {
TAIL_BUTTON -> {
if (info.isKeyguardLocked) {
NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON_LOCKED
} else {
NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON
when (info.entryPoint) {
TAIL_BUTTON -> {
if (info.isKeyguardLocked) {
NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON_LOCKED
} else {
NoteTaskUiEvent.NOTE_CLOSED_VIA_STYLUS_TAIL_BUTTON
}
}
WIDGET_PICKER_SHORTCUT,
WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE,
QUICK_AFFORDANCE,
APP_CLIPS,
KEYBOARD_SHORTCUT,
null -> return
}
WIDGET_PICKER_SHORTCUT -> return
QUICK_AFFORDANCE -> return
APP_CLIPS -> return
KEYBOARD_SHORTCUT -> return
null -> return
}
uiEventLogger.log(event, info.uid, info.packageName)
}

View File

@@ -16,6 +16,7 @@
package com.android.systemui.notetask
import android.os.UserHandle
import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE
/** Contextual information required to launch a Note Task by [NoteTaskController]. */
data class NoteTaskInfo(
@@ -27,7 +28,7 @@ data class NoteTaskInfo(
) {
val launchMode: NoteTaskLaunchMode =
if (isKeyguardLocked) {
if (isKeyguardLocked || entryPoint == WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE) {
NoteTaskLaunchMode.Activity
} else {
NoteTaskLaunchMode.AppBubble

View File

@@ -51,7 +51,8 @@ internal object NoteTaskRoleManagerExt {
val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget)
return ShortcutInfo.Builder(context, NoteTaskController.SHORTCUT_ID)
.setIntent(LaunchNoteTaskActivity.newIntent(context = context))
.setIntent(LaunchNoteTaskActivity.createIntent(context))
.setActivity(LaunchNoteTaskActivity.createComponent(context))
.setShortLabel(context.getString(R.string.note_task_button_label))
.setLongLived(true)
.setIcon(icon)

View File

@@ -16,6 +16,7 @@
package com.android.systemui.notetask.shortcut
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Bundle
@@ -72,7 +73,13 @@ constructor(
controller.startNoteTaskProxyActivityForUser(mainUser)
}
} else {
controller.showNoteTask(entryPoint = NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT)
val entryPoint =
if (isInMultiWindowMode) {
NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE
} else {
NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT
}
controller.showNoteTask(entryPoint)
}
finish()
}
@@ -80,11 +87,14 @@ constructor(
companion object {
/** Creates a new [Intent] set to start [LaunchNoteTaskActivity]. */
fun newIntent(context: Context): Intent {
return Intent(context, LaunchNoteTaskActivity::class.java).apply {
fun createIntent(context: Context): Intent =
Intent(context, LaunchNoteTaskActivity::class.java).apply {
// Intent's action must be set in shortcuts, or an exception will be thrown.
action = Intent.ACTION_CREATE_NOTE
}
}
/** Creates a new [ComponentName] for [LaunchNoteTaskActivity]. */
fun createComponent(context: Context): ComponentName =
ComponentName(context, LaunchNoteTaskActivity::class.java)
}
}

View File

@@ -72,6 +72,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
import org.mockito.Mockito.atLeastOnce
import org.mockito.Mockito.doNothing
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
@@ -227,31 +228,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
// region showNoteTask
@Test
fun showNoteTask_keyguardIsLocked_shouldStartActivityAndLogUiEvent() {
val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
val intentCaptor = argumentCaptor<Intent>()
val userCaptor = argumentCaptor<UserHandle>()
verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
assertThat(intentCaptor.value).run {
hasAction(ACTION_CREATE_NOTE)
hasPackage(NOTE_TASK_PACKAGE_NAME)
hasFlags(FLAG_ACTIVITY_NEW_TASK)
hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
}
assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
verify(eventLogger).logNoteTaskOpened(expectedInfo)
verifyZeroInteractions(bubbles)
}
@Test
fun showNoteTaskWithUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() {
fun showNoteTaskAsUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() {
val user10 = UserHandle.of(/* userId= */ 10)
val expectedInfo =
NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true, user = user10)
@@ -277,6 +254,30 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
verifyZeroInteractions(bubbles)
}
@Test
fun showNoteTask_keyguardIsLocked_notesIsClosed_shouldStartActivityAndLogUiEvent() {
val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
val intentCaptor = argumentCaptor<Intent>()
val userCaptor = argumentCaptor<UserHandle>()
verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
assertThat(intentCaptor.value).run {
hasAction(ACTION_CREATE_NOTE)
hasPackage(NOTE_TASK_PACKAGE_NAME)
hasFlags(FLAG_ACTIVITY_NEW_TASK)
hasFlags(FLAG_ACTIVITY_MULTIPLE_TASK)
hasFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
extras().bool(EXTRA_USE_STYLUS_MODE).isTrue()
}
assertThat(userCaptor.value).isEqualTo(userTracker.userHandle)
verify(eventLogger).logNoteTaskOpened(expectedInfo)
verifyZeroInteractions(bubbles)
}
@Test
fun showNoteTask_keyguardIsLocked_noteIsOpen_shouldCloseActivityAndLogUiEvent() {
val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = true)
@@ -301,7 +302,7 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
}
@Test
fun showNoteTask_keyguardIsUnlocked_shouldStartBubblesWithoutLoggingUiEvent() {
fun showNoteTask_keyguardIsUnlocked_noteIsClosed_shouldStartBubblesWithoutLoggingUiEvent() {
val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = false)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
@@ -309,7 +310,23 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
// Context package name used to create bubble icon from drawable resource id
verify(context).packageName
verify(context, atLeastOnce()).packageName
verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
verifyZeroInteractions(eventLogger)
}
@Test
fun showNoteTask_keyguardIsUnlocked_noteIsOpen_shouldStartBubblesWithoutLoggingUiEvent() {
val expectedInfo = NOTE_TASK_INFO.copy(entryPoint = TAIL_BUTTON, isKeyguardLocked = false)
whenever(resolver.resolveInfo(any(), any(), any())).thenReturn(expectedInfo)
whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
whenever(activityManager.getRunningTasks(anyInt()))
.thenReturn(listOf(NOTE_RUNNING_TASK_INFO))
createNoteTaskController().showNoteTask(entryPoint = expectedInfo.entryPoint!!)
// Context package name used to create bubble icon from drawable resource id
verify(context, atLeastOnce()).packageName
verifyNoteTaskOpenInBubbleInUser(userTracker.userHandle)
verifyZeroInteractions(eventLogger)
}

View File

@@ -16,37 +16,47 @@
package com.android.systemui.notetask
import android.os.UserHandle
import android.test.suitebuilder.annotation.SmallTest
import androidx.test.runner.AndroidJUnit4
import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.notetask.NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
/** atest SystemUITests:NoteTaskInfoTest */
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWith(AndroidTestingRunner::class)
internal class NoteTaskInfoTest : SysuiTestCase() {
private fun createNoteTaskInfo(): NoteTaskInfo =
NoteTaskInfo(packageName = NOTES_PACKAGE_NAME, uid = NOTES_UID, UserHandle.of(0))
@Test
fun launchMode_keyguardLocked_launchModeActivity() {
val underTest = createNoteTaskInfo().copy(isKeyguardLocked = true)
val underTest = DEFAULT_INFO.copy(isKeyguardLocked = true)
assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.Activity)
}
@Test
fun launchMode_keyguardUnlocked_launchModeActivity() {
val underTest = createNoteTaskInfo().copy(isKeyguardLocked = false)
fun launchMode_multiWindowMode_launchModeActivity() {
val underTest = DEFAULT_INFO.copy(entryPoint = WIDGET_PICKER_SHORTCUT_IN_MULTI_WINDOW_MODE)
assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.Activity)
}
@Test
fun launchMode_keyguardUnlocked_launchModeAppBubble() {
val underTest = DEFAULT_INFO.copy(isKeyguardLocked = false)
assertThat(underTest.launchMode).isEqualTo(NoteTaskLaunchMode.AppBubble)
}
private companion object {
const val NOTES_PACKAGE_NAME = "com.android.note.app"
const val NOTES_UID = 123456
val DEFAULT_INFO =
NoteTaskInfo(
packageName = "com.android.note.app",
uid = 123456,
user = UserHandle.of(0),
)
}
}