diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 433d8b6860a..a6a354e1dca 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -4825,6 +4825,22 @@ + + + + + + + + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index a67c713bfdc..505aac0f6d5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -12047,4 +12047,7 @@ "This app can only be opened in 1 window" + + + Notetaking diff --git a/src/com/android/settings/notetask/shortcut/CreateNoteTaskShortcutActivity.kt b/src/com/android/settings/notetask/shortcut/CreateNoteTaskShortcutActivity.kt new file mode 100644 index 00000000000..b9846226df6 --- /dev/null +++ b/src/com/android/settings/notetask/shortcut/CreateNoteTaskShortcutActivity.kt @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2023 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. + */ + +package com.android.settings.notetask.shortcut + +import android.app.Activity +import android.app.role.RoleManager +import android.app.role.RoleManager.ROLE_NOTES +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.pm.ShortcutInfo +import android.content.pm.ShortcutManager +import android.graphics.drawable.Icon +import android.os.Bundle +import android.os.PersistableBundle +import android.os.UserHandle +import androidx.activity.ComponentActivity +import androidx.core.content.getSystemService +import com.android.settings.R + +/** + * Activity responsible for create 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 Creating + * a custom shortcut activity + */ +internal class CreateNoteTaskShortcutActivity : ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + val roleManager = requireNotNull(getSystemService()) + val shortcutManager = requireNotNull(getSystemService()) + + super.onCreate(savedInstanceState) + + val shortcutInfo = roleManager.createNoteShortcutInfoAsUser(context = this, user) + val shortcutIntent = shortcutManager.createShortcutResultIntent(shortcutInfo) + setResult(Activity.RESULT_OK, shortcutIntent) + + finish() + } + + private companion object { + + private const val SHORTCUT_ID = "note_task_shortcut_id" + private const val EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE = + "extra_shortcut_badge_override_package" + private const val ACTION_LAUNCH_NOTE_TASK = "com.android.systemui.action.LAUNCH_NOTE_TASK" + + private fun RoleManager.createNoteShortcutInfoAsUser( + context: Context, + user: UserHandle, + ): ShortcutInfo? { + val systemUiComponent = context.getSystemUiComponent() ?: return null + + val extras = PersistableBundle() + getDefaultRoleHolderAsUser(ROLE_NOTES, user)?.let { packageName -> + // Set custom app badge using the icon from ROLES_NOTES default app. + extras.putString(EXTRA_SHORTCUT_BADGE_OVERRIDE_PACKAGE, packageName) + } + + val icon = Icon.createWithResource(context, R.drawable.ic_note_task_shortcut_widget) + + val intent = Intent(ACTION_LAUNCH_NOTE_TASK).apply { + setPackage(systemUiComponent.packageName) + } + + return ShortcutInfo.Builder(context, SHORTCUT_ID) + .setIntent(intent) + .setShortLabel(context.getString(R.string.note_task_button_label)) + .setLongLived(true) + .setIcon(icon) + .setExtras(extras) + .build() + } + + private fun RoleManager.getDefaultRoleHolderAsUser( + role: String, + user: UserHandle, + ): String? = getRoleHoldersAsUser(role, user).firstOrNull() + + private fun Context.getSystemUiComponent(): ComponentName? { + val flattenName = getString( + com.android.internal.R.string.config_systemUIServiceComponent) + check(flattenName.isNotEmpty()) { + "No 'com.android.internal.R.string.config_systemUIServiceComponent' resource" + } + return try { + ComponentName.unflattenFromString(flattenName) + } catch (e: RuntimeException) { + val message = "Invalid component name defined by 'com.android.internal.R.string." + + "config_systemUIServiceComponent' resource: $flattenName" + throw IllegalStateException(message, e) + } + } + } +}