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.View
25 import com.android.car.carlaunchercommon.shortcuts.AppInfoShortcutItem
26 import com.android.car.carlaunchercommon.shortcuts.ForceStopShortcutItem
27 import com.android.car.carlaunchercommon.shortcuts.PinShortcutItem
28 import com.android.car.dockutil.Flags
29 import com.android.car.dockutil.events.DockEventSenderHelper
30 import com.android.car.ui.shortcutspopup.CarUiShortcutsPopup
31 
32 /**
33  * This class is responsible for creating and displaying app shortcuts popups within the
34  * car UI. It generates shortcuts for actions like "Stop App," "App Info," and potentially
35  * "Pin to Dock." The class interacts with CarMediaManager and relies on a ShortcutsListener
36  * to track interactions with the shortcuts popup.
37  *
38  * @param carMediaManager For controlling car media settings.
39  * @param mediaServiceComponents A set of ComponentNames identifying installed media services.
40  * @param shortcutsListener Listener for handling events triggered by the shortcuts popup.
41  */
42 class AppShortcutsFactory(
43     private val carMediaManager: CarMediaManager,
44     private val mediaServiceComponents: Set<ComponentName>,
45     private val shortcutsListener: ShortcutsListener
46 ) {
47 
48     /**
49      * Displays a car UI shortcuts popup anchored to the provided view.  The popup includes
50      * shortcuts for "Force Stop," "App Info," and potentially "Pin to Dock" (if the feature
51      * is enabled).
52      *
53      * @param componentName The ComponentName of the app for which shortcuts are generated.
54      * @param displayName The display name of the app.
55      * @param context Application context.
56      * @param anchorView The UI view to anchor the shortcuts popup.
57      */
showShortcutsnull58     fun showShortcuts(
59         componentName: ComponentName,
60         displayName: CharSequence,
61         context: Context,
62         anchorView: View
63     ) {
64         val carUiShortcutsPopupBuilder =
65             CarUiShortcutsPopup.Builder()
66                 .addShortcut(
67                     ForceStopShortcutItem(
68                         context,
69                         componentName.packageName,
70                         displayName,
71                         carMediaManager,
72                         mediaServiceComponents
73                     )
74                 )
75                 .addShortcut(
76                     AppInfoShortcutItem(
77                         context,
78                         componentName.packageName,
79                         UserHandle.getUserHandleForUid(Process.myUid())
80                     )
81                 )
82         if (Flags.dockFeature()) {
83             carUiShortcutsPopupBuilder
84                 .addShortcut(buildPinToDockShortcut(componentName, context))
85         }
86         val carUiShortcutsPopup =
87             carUiShortcutsPopupBuilder
88                 .build(context, anchorView)
89         carUiShortcutsPopup.show()
90         shortcutsListener.onShortcutsShow(carUiShortcutsPopup)
91     }
92 
93     /**
94      * Helper function to construct a shortcut item for the "Pin to Dock" action
95      * within the shortcuts popup.
96      *
97      * @param componentName ComponentName of the app to be pinned.
98      * @param context Application context.
99      * @return A CarUiShortcutsPopup.ShortcutItem for the "Pin to Dock" action, or null
100      *         if the feature is not enabled.
101      */
buildPinToDockShortcutnull102     private fun buildPinToDockShortcut(
103         componentName: ComponentName,
104         context: Context
105     ): CarUiShortcutsPopup.ShortcutItem? {
106         val helper = DockEventSenderHelper(context)
107         return PinShortcutItem(
108             context.resources,
109             false,
110             { helper.sendPinEvent(componentName) }
111         )
112         { helper.sendUnpinEvent(componentName) }
113     }
114 
115     /**
116      *  Simple callback interface for notifying clients when a car UI shortcuts
117      *  popup is displayed.
118      */
119     interface ShortcutsListener {
120         /**
121          *  Called when a CarUiShortcutsPopup view becomes visible.
122          *
123          *  @param carUiShortcutsPopup The displayed popup view.
124          */
onShortcutsShownull125         fun onShortcutsShow(carUiShortcutsPopup: CarUiShortcutsPopup)
126     }
127 }
128