Move Note Shortcut from Settings to SystemUI

* Moves the Note Shortcut showed on Widget Picker back to SystemUI.
* By placing everything inside SystemUI, we do not need to give special
 privileges to System apps to by-pass any shortcut checks. That was
 required due to multi-process communication.

Test: atest SystemUITests:NoteTaskControllerTest
Flag: not needed
Fixes: b/280431176
Change-Id: I8239e31a3767959f8ad9beeaefe6528f7fedae99
This commit is contained in:
Marcello Galhardo
2023-05-05 14:23:25 +00:00
parent b26be926b0
commit faed436740
6 changed files with 97 additions and 26 deletions

View File

@@ -969,6 +969,22 @@
android:permission="android.permission.BIND_JOB_SERVICE"/>
<!-- region Note Task -->
<activity
android:name=".notetask.shortcut.CreateNoteTaskShortcutActivity"
android:enabled="false"
android:exported="true"
android:excludeFromRecents="true"
android:resizeableActivity="false"
android:theme="@android:style/Theme.NoDisplay"
android:label="@string/note_task_button_label"
android:icon="@drawable/ic_note_task_shortcut_widget">
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".notetask.NoteTaskControllerUpdateService" />
<activity

View File

@@ -41,6 +41,7 @@ import com.android.systemui.devicepolicy.areKeyguardShortcutsDisabled
import com.android.systemui.log.DebugLogger.debugLog
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
@@ -249,6 +250,8 @@ constructor(
* Widget Picker to all users.
*/
fun setNoteTaskShortcutEnabled(value: Boolean, user: UserHandle) {
val componentName = ComponentName(context, CreateNoteTaskShortcutActivity::class.java)
val enabledState =
if (value) {
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
@@ -267,7 +270,7 @@ constructor(
}
userContext.packageManager.setComponentEnabledSetting(
SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT,
componentName,
enabledState,
PackageManager.DONT_KILL_APP,
)
@@ -315,19 +318,6 @@ constructor(
companion object {
val TAG = NoteTaskController::class.simpleName.orEmpty()
/**
* IMPORTANT! The shortcut package name and class should be synchronized with Settings:
* [com.android.settings.notetask.shortcut.CreateNoteTaskShortcutActivity].
*
* Changing the package name or class is a breaking change.
*/
@VisibleForTesting
val SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT =
ComponentName(
"com.android.settings",
"com.android.settings.notetask.shortcut.CreateNoteTaskShortcutActivity",
)
const val SHORTCUT_ID = "note_task_shortcut_id"
/**

View File

@@ -24,6 +24,7 @@ import android.app.role.RoleManager
import com.android.systemui.flags.FeatureFlags
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
@@ -49,6 +50,9 @@ interface NoteTaskModule {
fun LaunchNotesRoleSettingsTrampolineActivity.bindLaunchNotesRoleSettingsTrampolineActivity():
Activity
@[Binds IntoMap ClassKey(CreateNoteTaskShortcutActivity::class)]
fun CreateNoteTaskShortcutActivity.bindNoteTaskShortcutActivity(): Activity
companion object {
@[Provides NoteTaskEnabledKey]

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@file:OptIn(InternalNoteTaskApi::class)
package com.android.systemui.notetask.shortcut
import android.app.Activity
import android.app.role.RoleManager
import android.content.pm.ShortcutManager
import android.os.Bundle
import androidx.activity.ComponentActivity
import com.android.systemui.notetask.InternalNoteTaskApi
import com.android.systemui.notetask.NoteTaskRoleManagerExt.createNoteShortcutInfoAsUser
import javax.inject.Inject
/**
* Activity responsible for creating a shortcut for notes action. If the shortcut is enabled, a new
* shortcut will appear in the widget picker. If the shortcut is selected, the Activity here will be
* launched, creating a new shortcut for [CreateNoteTaskShortcutActivity], and will finish.
*
* @see <a
* href="https://developer.android.com/develop/ui/views/launch/shortcuts/creating-shortcuts#custom-pinned">Creating
* a custom shortcut activity</a>
*/
class CreateNoteTaskShortcutActivity
@Inject
constructor(
private val roleManager: RoleManager,
private val shortcutManager: ShortcutManager,
) : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val shortcutInfo = roleManager.createNoteShortcutInfoAsUser(context = this, user)
val shortcutIntent = shortcutManager.createShortcutResultIntent(shortcutInfo)
setResult(Activity.RESULT_OK, shortcutIntent)
finish()
}
}

View File

@@ -45,11 +45,11 @@ import androidx.test.runner.AndroidJUnit4
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.notetask.NoteTaskController.Companion.EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE
import com.android.systemui.notetask.NoteTaskController.Companion.SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT
import com.android.systemui.notetask.NoteTaskController.Companion.SHORTCUT_ID
import com.android.systemui.notetask.NoteTaskEntryPoint.APP_CLIPS
import com.android.systemui.notetask.NoteTaskEntryPoint.QUICK_AFFORDANCE
import com.android.systemui.notetask.NoteTaskEntryPoint.TAIL_BUTTON
import com.android.systemui.notetask.shortcut.CreateNoteTaskShortcutActivity
import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity
import com.android.systemui.notetask.shortcut.LaunchNoteTaskManagedProfileProxyActivity
import com.android.systemui.settings.FakeUserTracker
@@ -427,7 +427,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
eq(PackageManager.DONT_KILL_APP),
)
assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
assertThat(argument.value.className)
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
}
@Test
@@ -441,7 +442,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
eq(COMPONENT_ENABLED_STATE_DISABLED),
eq(PackageManager.DONT_KILL_APP),
)
assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
assertThat(argument.value.className)
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
}
@Test
@@ -460,7 +463,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
eq(COMPONENT_ENABLED_STATE_ENABLED),
eq(PackageManager.DONT_KILL_APP),
)
assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
assertThat(argument.value.className)
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
}
@Test
@@ -480,7 +485,9 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
eq(COMPONENT_ENABLED_STATE_DISABLED),
eq(PackageManager.DONT_KILL_APP),
)
assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
assertThat(argument.value.className)
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
}
// endregion
@@ -664,7 +671,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
eq(COMPONENT_ENABLED_STATE_ENABLED),
eq(PackageManager.DONT_KILL_APP),
)
assertThat(actualComponent.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
assertThat(actualComponent.value.className)
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
verify(shortcutManager, never()).disableShortcuts(any())
verify(shortcutManager).enableShortcuts(listOf(SHORTCUT_ID))
val actualShortcuts = argumentCaptor<List<ShortcutInfo>>()
@@ -695,7 +703,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
eq(COMPONENT_ENABLED_STATE_DISABLED),
eq(PackageManager.DONT_KILL_APP),
)
assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
assertThat(argument.value.className)
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
verify(shortcutManager, never()).enableShortcuts(any())
verify(shortcutManager, never()).updateShortcuts(any())
@@ -712,7 +721,8 @@ internal class NoteTaskControllerTest : SysuiTestCase() {
eq(COMPONENT_ENABLED_STATE_DISABLED),
eq(PackageManager.DONT_KILL_APP),
)
assertThat(argument.value).isEqualTo(SETTINGS_CREATE_NOTE_TASK_SHORTCUT_COMPONENT)
assertThat(argument.value.className)
.isEqualTo(CreateNoteTaskShortcutActivity::class.java.name)
verify(shortcutManager).disableShortcuts(listOf(SHORTCUT_ID))
verify(shortcutManager, never()).enableShortcuts(any())
verify(shortcutManager, never()).updateShortcuts(any())

View File

@@ -1736,10 +1736,6 @@ public class ShortcutService extends IShortcutService.Stub {
return;
}
if (isCallerSystem()) {
return; // no check
}
if (!Objects.equals(callerPackage, si.getPackage())) {
android.util.EventLog.writeEvent(0x534e4554, "109824443", -1, "");
throw new SecurityException("Shortcut package name mismatch");