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