1 /*
<lambda>null2  * 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.systemui.screenshot
18 
19 import android.app.assist.AssistContent
20 import android.content.Context
21 import android.util.Log
22 import androidx.appcompat.content.res.AppCompatResources
23 import com.android.internal.logging.UiEventLogger
24 import com.android.systemui.log.DebugLogger.debugLog
25 import com.android.systemui.res.R
26 import com.android.systemui.screenshot.ActionIntentCreator.createEdit
27 import com.android.systemui.screenshot.ActionIntentCreator.createShareWithSubject
28 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_EDIT_TAPPED
29 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_PREVIEW_TAPPED
30 import com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_SHARE_TAPPED
31 import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance
32 import com.android.systemui.screenshot.ui.viewmodel.PreviewAction
33 import dagger.assisted.Assisted
34 import dagger.assisted.AssistedFactory
35 import dagger.assisted.AssistedInject
36 import java.util.UUID
37 
38 /**
39  * Provides actions for screenshots. This class can be overridden by a vendor-specific SysUI
40  * implementation.
41  */
42 interface ScreenshotActionsProvider {
43     fun onScrollChipReady(onClick: Runnable)
44 
45     fun onScrollChipInvalidated()
46 
47     fun setCompletedScreenshot(result: ScreenshotSavedResult)
48 
49     /**
50      * Provide the AssistContent for the focused task if available, null if the focused task isn't
51      * known or didn't return data.
52      */
53     fun onAssistContent(assistContent: AssistContent?) {}
54 
55     interface Factory {
56         fun create(
57             requestId: UUID,
58             request: ScreenshotData,
59             actionExecutor: ActionExecutor,
60             actionsCallback: ScreenshotActionsController.ActionsCallback,
61         ): ScreenshotActionsProvider
62     }
63 }
64 
65 class DefaultScreenshotActionsProvider
66 @AssistedInject
67 constructor(
68     private val context: Context,
69     private val uiEventLogger: UiEventLogger,
70     @Assisted val requestId: UUID,
71     @Assisted val request: ScreenshotData,
72     @Assisted val actionExecutor: ActionExecutor,
73     @Assisted val actionsCallback: ScreenshotActionsController.ActionsCallback,
74 ) : ScreenshotActionsProvider {
75     private var addedScrollChip = false
76     private var onScrollClick: Runnable? = null
77     private var pendingAction: ((ScreenshotSavedResult) -> Unit)? = null
78     private var result: ScreenshotSavedResult? = null
79 
80     init {
81         actionsCallback.providePreviewAction(
<lambda>null82             PreviewAction(context.resources.getString(R.string.screenshot_edit_description)) {
83                 debugLog(LogConfig.DEBUG_ACTIONS) { "Preview tapped" }
84                 uiEventLogger.log(SCREENSHOT_PREVIEW_TAPPED, 0, request.packageNameString)
85                 onDeferrableActionTapped { result ->
86                     actionExecutor.startSharedTransition(
87                         createEdit(result.uri, context),
88                         result.user,
89                         true
90                     )
91                 }
92             }
93         )
94 
95         actionsCallback.provideActionButton(
96             ActionButtonAppearance(
97                 AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_share),
98                 context.resources.getString(R.string.screenshot_share_label),
99                 context.resources.getString(R.string.screenshot_share_description),
100             ),
101             showDuringEntrance = true,
<lambda>null102         ) {
103             debugLog(LogConfig.DEBUG_ACTIONS) { "Share tapped" }
104             uiEventLogger.log(SCREENSHOT_SHARE_TAPPED, 0, request.packageNameString)
105             onDeferrableActionTapped { result ->
106                 actionExecutor.startSharedTransition(
107                     createShareWithSubject(result.uri, result.subject),
108                     result.user,
109                     false
110                 )
111             }
112         }
113 
114         actionsCallback.provideActionButton(
115             ActionButtonAppearance(
116                 AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_edit),
117                 context.resources.getString(R.string.screenshot_edit_label),
118                 context.resources.getString(R.string.screenshot_edit_description),
119             ),
120             showDuringEntrance = true,
<lambda>null121         ) {
122             debugLog(LogConfig.DEBUG_ACTIONS) { "Edit tapped" }
123             uiEventLogger.log(SCREENSHOT_EDIT_TAPPED, 0, request.packageNameString)
124             onDeferrableActionTapped { result ->
125                 actionExecutor.startSharedTransition(
126                     createEdit(result.uri, context),
127                     result.user,
128                     true
129                 )
130             }
131         }
132     }
133 
onScrollChipReadynull134     override fun onScrollChipReady(onClick: Runnable) {
135         onScrollClick = onClick
136         if (!addedScrollChip) {
137             actionsCallback.provideActionButton(
138                 ActionButtonAppearance(
139                     AppCompatResources.getDrawable(context, R.drawable.ic_screenshot_scroll),
140                     context.resources.getString(R.string.screenshot_scroll_label),
141                     context.resources.getString(R.string.screenshot_scroll_label),
142                 ),
143                 showDuringEntrance = true,
144             ) {
145                 onScrollClick?.run()
146             }
147             addedScrollChip = true
148         }
149     }
150 
onScrollChipInvalidatednull151     override fun onScrollChipInvalidated() {
152         onScrollClick = null
153     }
154 
setCompletedScreenshotnull155     override fun setCompletedScreenshot(result: ScreenshotSavedResult) {
156         if (this.result != null) {
157             Log.e(TAG, "Got a second completed screenshot for existing request!")
158             return
159         }
160         this.result = result
161         pendingAction?.invoke(result)
162     }
163 
onDeferrableActionTappednull164     private fun onDeferrableActionTapped(onResult: (ScreenshotSavedResult) -> Unit) {
165         result?.let { onResult.invoke(it) } ?: run { pendingAction = onResult }
166     }
167 
168     @AssistedFactory
169     interface Factory : ScreenshotActionsProvider.Factory {
createnull170         override fun create(
171             requestId: UUID,
172             request: ScreenshotData,
173             actionExecutor: ActionExecutor,
174             actionsCallback: ScreenshotActionsController.ActionsCallback,
175         ): DefaultScreenshotActionsProvider
176     }
177 
178     companion object {
179         private const val TAG = "ScreenshotActionsProvider"
180     }
181 }
182