1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.carlauncher.repositories.appactions 18 19 import android.car.media.CarMediaManager 20 import android.content.ComponentName 21 import android.content.Context 22 import android.os.Process 23 import android.os.UserHandle 24 import android.view.Display.INVALID_DISPLAY 25 import android.view.View 26 import com.android.car.carlaunchercommon.shortcuts.AppInfoShortcutItem 27 import com.android.car.carlaunchercommon.shortcuts.ForceStopShortcutItem 28 import com.android.car.carlaunchercommon.shortcuts.PinShortcutItem 29 import com.android.car.dockutil.Flags 30 import com.android.car.dockutil.events.DockCompatUtils.isDockSupportedOnDisplay 31 import com.android.car.dockutil.events.DockEventSenderHelper 32 import com.android.car.ui.shortcutspopup.CarUiShortcutsPopup 33 34 /** 35 * This class is responsible for creating and displaying app shortcuts popups within the 36 * car UI. It generates shortcuts for actions like "Stop App," "App Info," and potentially 37 * "Pin to Dock." The class interacts with CarMediaManager and relies on a ShortcutsListener 38 * to track interactions with the shortcuts popup. 39 * 40 * @param carMediaManager For controlling car media settings. 41 * @param mediaServiceComponents A set of ComponentNames identifying installed media services. 42 * @param shortcutsListener Listener for handling events triggered by the shortcuts popup. 43 */ 44 class AppShortcutsFactory( 45 private val carMediaManager: CarMediaManager, 46 private val mediaServiceComponents: Set<ComponentName>, 47 private val shortcutsListener: ShortcutsListener 48 ) { 49 50 /** 51 * Displays a car UI shortcuts popup anchored to the provided view. The popup includes 52 * shortcuts for "Force Stop," "App Info," and potentially "Pin to Dock" (if the feature 53 * is enabled). 54 * 55 * @param componentName The ComponentName of the app for which shortcuts are generated. 56 * @param displayName The display name of the app. 57 * @param context Application context. 58 * @param anchorView The UI view to anchor the shortcuts popup. 59 */ showShortcutsnull60 fun showShortcuts( 61 componentName: ComponentName, 62 displayName: CharSequence, 63 context: Context, 64 anchorView: View 65 ) { 66 val carUiShortcutsPopupBuilder = 67 CarUiShortcutsPopup.Builder() 68 .addShortcut( 69 ForceStopShortcutItem( 70 context, 71 componentName.packageName, 72 displayName, 73 carMediaManager, 74 mediaServiceComponents 75 ) 76 ) 77 .addShortcut( 78 AppInfoShortcutItem( 79 context, 80 componentName.packageName, 81 UserHandle.getUserHandleForUid(Process.myUid()) 82 ) 83 ) 84 if (Flags.dockFeature() && 85 isDockSupportedOnDisplay(context, context.display?.displayId ?: INVALID_DISPLAY) 86 ) { 87 carUiShortcutsPopupBuilder 88 .addShortcut(buildPinToDockShortcut(componentName, context)) 89 } 90 val carUiShortcutsPopup = 91 carUiShortcutsPopupBuilder 92 .build(context, anchorView) 93 carUiShortcutsPopup.show() 94 shortcutsListener.onShortcutsShow(carUiShortcutsPopup) 95 } 96 97 /** 98 * Helper function to construct a shortcut item for the "Pin to Dock" action 99 * within the shortcuts popup. 100 * 101 * @param componentName ComponentName of the app to be pinned. 102 * @param context Application context. 103 * @return A CarUiShortcutsPopup.ShortcutItem for the "Pin to Dock" action, or null 104 * if the feature is not enabled. 105 */ buildPinToDockShortcutnull106 private fun buildPinToDockShortcut( 107 componentName: ComponentName, 108 context: Context 109 ): CarUiShortcutsPopup.ShortcutItem? { 110 val helper = DockEventSenderHelper(context) 111 return PinShortcutItem( 112 context.resources, 113 false, 114 { helper.sendPinEvent(componentName) } 115 ) 116 { helper.sendUnpinEvent(componentName) } 117 } 118 119 /** 120 * Simple callback interface for notifying clients when a car UI shortcuts 121 * popup is displayed. 122 */ 123 interface ShortcutsListener { 124 /** 125 * Called when a CarUiShortcutsPopup view becomes visible. 126 * 127 * @param carUiShortcutsPopup The displayed popup view. 128 */ onShortcutsShownull129 fun onShortcutsShow(carUiShortcutsPopup: CarUiShortcutsPopup) 130 } 131 } 132