Loading packages/SystemUI/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ android_library { "androidx.test.uiautomator_uiautomator", "mockito-target-extended-minus-junit4", "androidx.test.ext.junit", "androidx.test.ext.truth", ], libs: [ "android.test.runner", Loading packages/SystemUI/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -992,6 +992,16 @@ android:excludeFromRecents="true" android:resizeableActivity="false" android:theme="@android:style/Theme.NoDisplay" /> <!-- LaunchNoteTaskManagedProfileProxyActivity MUST NOT be exported because it allows caller to specify an Android user when launching the default notes app. --> <activity android:name=".notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity" android:exported="false" android:enabled="true" android:excludeFromRecents="true" android:resizeableActivity="false" android:theme="@android:style/Theme.NoDisplay" /> <!-- endregion --> <!-- started from ControlsRequestReceiver --> Loading packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +13 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity import com.android.systemui.settings.UserTracker import com.android.systemui.shared.system.ActivityManagerKt.isInForeground import com.android.systemui.util.kotlin.getOrNull Loading Loading @@ -97,6 +98,18 @@ constructor( } } /** Starts [LaunchNoteTaskProxyActivity] on the given [user]. */ fun startNoteTaskProxyActivityForUser(user: UserHandle) { context.startActivityAsUser( Intent().apply { component = ComponentName(context, LaunchNoteTaskManagedProfileProxyActivity::class.java) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }, user ) } /** * Shows a note task. How the task is shown will depend on when the method is invoked. * Loading packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt +4 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.systemui.flags.Flags import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceModule import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity import dagger.Binds import dagger.Module import dagger.Provides Loading @@ -36,6 +37,9 @@ interface NoteTaskModule { @[Binds IntoMap ClassKey(LaunchNoteTaskActivity::class)] fun LaunchNoteTaskActivity.bindNoteTaskLauncherActivity(): Activity @[Binds IntoMap ClassKey(LaunchNoteTaskManagedProfileProxyActivity::class)] fun LaunchNoteTaskManagedProfileProxyActivity.bindNoteTaskLauncherProxyActivity(): Activity @[Binds IntoMap ClassKey(CreateNoteTaskShortcutActivity::class)] fun CreateNoteTaskShortcutActivity.bindNoteTaskShortcutActivity(): Activity Loading packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt +36 −2 Original line number Diff line number Diff line Loading @@ -18,10 +18,13 @@ package com.android.systemui.notetask.shortcut import android.content.Context import android.content.Intent import android.content.pm.UserInfo import android.os.Bundle import android.os.UserManager import androidx.activity.ComponentActivity import com.android.systemui.notetask.NoteTaskController import com.android.systemui.notetask.NoteTaskEntryPoint import com.android.systemui.settings.UserTracker import javax.inject.Inject /** Activity responsible for launching the note experience, and finish. */ Loading @@ -29,11 +32,43 @@ class LaunchNoteTaskActivity @Inject constructor( private val controller: NoteTaskController, private val userManager: UserManager, private val userTracker: UserTracker, ) : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Under the hood, notes app shortcuts are shown in a floating window, called Bubble. // Bubble API is only available in the main user but not work profile. // // On devices with work profile (WP), SystemUI provides both personal notes app shortcuts & // work profile notes app shortcuts. In order to make work profile notes app shortcuts to // show in Bubble, a few redirections across users are required: // 1. When `LaunchNoteTaskActivity` is started in the work profile user, we launch // `LaunchNoteTaskManagedProfileProxyActivity` on the main user, which has access to the // Bubble API. // 2. `LaunchNoteTaskManagedProfileProxyActivity` calls `Bubble#showOrHideAppBubble` with // the work profile user ID. // 3. Bubble renders the work profile notes app activity in a floating window, which is // hosted in the main user. // // WP main user // ------------------------ ------------------------------------------- // | LaunchNoteTaskActivity | -> | LaunchNoteTaskManagedProfileProxyActivity | // ------------------------ ------------------------------------------- // | // main user | // ---------------------------- | // | Bubble#showOrHideAppBubble | <-------------- // | (with WP user ID) | // ---------------------------- val mainUser: UserInfo? = userTracker.userProfiles.firstOrNull { it.isMain } if (userManager.isManagedProfile && mainUser != null) { controller.startNoteTaskProxyActivityForUser(mainUser.userHandle) } else { controller.showNoteTask(entryPoint = NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT) } finish() } Loading @@ -43,7 +78,6 @@ constructor( fun newIntent(context: Context): Intent { return Intent(context, LaunchNoteTaskActivity::class.java).apply { // Intent's action must be set in shortcuts, or an exception will be thrown. // TODO(b/254606432): Use Intent.ACTION_CREATE_NOTE instead. action = Intent.ACTION_CREATE_NOTE } } Loading Loading
packages/SystemUI/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -354,6 +354,7 @@ android_library { "androidx.test.uiautomator_uiautomator", "mockito-target-extended-minus-junit4", "androidx.test.ext.junit", "androidx.test.ext.truth", ], libs: [ "android.test.runner", Loading
packages/SystemUI/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -992,6 +992,16 @@ android:excludeFromRecents="true" android:resizeableActivity="false" android:theme="@android:style/Theme.NoDisplay" /> <!-- LaunchNoteTaskManagedProfileProxyActivity MUST NOT be exported because it allows caller to specify an Android user when launching the default notes app. --> <activity android:name=".notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity" android:exported="false" android:enabled="true" android:excludeFromRecents="true" android:resizeableActivity="false" android:theme="@android:style/Theme.NoDisplay" /> <!-- endregion --> <!-- started from ControlsRequestReceiver --> Loading
packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt +13 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser import com.android.systemui.notetask.NoteTaskRoleManagerExt.getDefaultRoleHolderAsUser import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity import com.android.systemui.settings.UserTracker import com.android.systemui.shared.system.ActivityManagerKt.isInForeground import com.android.systemui.util.kotlin.getOrNull Loading Loading @@ -97,6 +98,18 @@ constructor( } } /** Starts [LaunchNoteTaskProxyActivity] on the given [user]. */ fun startNoteTaskProxyActivityForUser(user: UserHandle) { context.startActivityAsUser( Intent().apply { component = ComponentName(context, LaunchNoteTaskManagedProfileProxyActivity::class.java) addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) }, user ) } /** * Shows a note task. How the task is shown will depend on when the method is invoked. * Loading
packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt +4 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import com.android.systemui.flags.Flags import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceModule import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity import dagger.Binds import dagger.Module import dagger.Provides Loading @@ -36,6 +37,9 @@ interface NoteTaskModule { @[Binds IntoMap ClassKey(LaunchNoteTaskActivity::class)] fun LaunchNoteTaskActivity.bindNoteTaskLauncherActivity(): Activity @[Binds IntoMap ClassKey(LaunchNoteTaskManagedProfileProxyActivity::class)] fun LaunchNoteTaskManagedProfileProxyActivity.bindNoteTaskLauncherProxyActivity(): Activity @[Binds IntoMap ClassKey(CreateNoteTaskShortcutActivity::class)] fun CreateNoteTaskShortcutActivity.bindNoteTaskShortcutActivity(): Activity Loading
packages/SystemUI/src/com/android/systemui/notetask/shortcut/LaunchNoteTaskActivity.kt +36 −2 Original line number Diff line number Diff line Loading @@ -18,10 +18,13 @@ package com.android.systemui.notetask.shortcut import android.content.Context import android.content.Intent import android.content.pm.UserInfo import android.os.Bundle import android.os.UserManager import androidx.activity.ComponentActivity import com.android.systemui.notetask.NoteTaskController import com.android.systemui.notetask.NoteTaskEntryPoint import com.android.systemui.settings.UserTracker import javax.inject.Inject /** Activity responsible for launching the note experience, and finish. */ Loading @@ -29,11 +32,43 @@ class LaunchNoteTaskActivity @Inject constructor( private val controller: NoteTaskController, private val userManager: UserManager, private val userTracker: UserTracker, ) : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Under the hood, notes app shortcuts are shown in a floating window, called Bubble. // Bubble API is only available in the main user but not work profile. // // On devices with work profile (WP), SystemUI provides both personal notes app shortcuts & // work profile notes app shortcuts. In order to make work profile notes app shortcuts to // show in Bubble, a few redirections across users are required: // 1. When `LaunchNoteTaskActivity` is started in the work profile user, we launch // `LaunchNoteTaskManagedProfileProxyActivity` on the main user, which has access to the // Bubble API. // 2. `LaunchNoteTaskManagedProfileProxyActivity` calls `Bubble#showOrHideAppBubble` with // the work profile user ID. // 3. Bubble renders the work profile notes app activity in a floating window, which is // hosted in the main user. // // WP main user // ------------------------ ------------------------------------------- // | LaunchNoteTaskActivity | -> | LaunchNoteTaskManagedProfileProxyActivity | // ------------------------ ------------------------------------------- // | // main user | // ---------------------------- | // | Bubble#showOrHideAppBubble | <-------------- // | (with WP user ID) | // ---------------------------- val mainUser: UserInfo? = userTracker.userProfiles.firstOrNull { it.isMain } if (userManager.isManagedProfile && mainUser != null) { controller.startNoteTaskProxyActivityForUser(mainUser.userHandle) } else { controller.showNoteTask(entryPoint = NoteTaskEntryPoint.WIDGET_PICKER_SHORTCUT) } finish() } Loading @@ -43,7 +78,6 @@ constructor( fun newIntent(context: Context): Intent { return Intent(context, LaunchNoteTaskActivity::class.java).apply { // Intent's action must be set in shortcuts, or an exception will be thrown. // TODO(b/254606432): Use Intent.ACTION_CREATE_NOTE instead. action = Intent.ACTION_CREATE_NOTE } } Loading