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.systemui.screenshot
18 
19 import android.app.assist.AssistContent
20 import com.android.systemui.screenshot.ui.viewmodel.ActionButtonAppearance
21 import com.android.systemui.screenshot.ui.viewmodel.PreviewAction
22 import com.android.systemui.screenshot.ui.viewmodel.ScreenshotViewModel
23 import dagger.assisted.Assisted
24 import dagger.assisted.AssistedFactory
25 import dagger.assisted.AssistedInject
26 import java.util.UUID
27 
28 /**
29  * Responsible for obtaining the actions for each screenshot and sending them to the view model.
30  * Ensures that only actions from screenshots that are currently being shown are added to the view
31  * model.
32  */
33 class ScreenshotActionsController
34 @AssistedInject
35 constructor(
36     private val viewModel: ScreenshotViewModel,
37     private val actionsProviderFactory: ScreenshotActionsProvider.Factory,
38     @Assisted val actionExecutor: ActionExecutor
39 ) {
40     private val actionProviders: MutableMap<UUID, ScreenshotActionsProvider> = mutableMapOf()
41     private var currentScreenshotId: UUID? = null
42 
setCurrentScreenshotnull43     fun setCurrentScreenshot(screenshot: ScreenshotData): UUID {
44         val screenshotId = UUID.randomUUID()
45         currentScreenshotId = screenshotId
46         actionProviders[screenshotId] =
47             actionsProviderFactory.create(
48                 screenshotId,
49                 screenshot,
50                 actionExecutor,
51                 ActionsCallback(screenshotId),
52             )
53         return screenshotId
54     }
55 
endScreenshotSessionnull56     fun endScreenshotSession() {
57         currentScreenshotId = null
58     }
59 
onAssistContentnull60     fun onAssistContent(screenshotId: UUID, assistContent: AssistContent?) {
61         actionProviders[screenshotId]?.onAssistContent(assistContent)
62     }
63 
onScrollChipReadynull64     fun onScrollChipReady(screenshotId: UUID, onClick: Runnable) {
65         if (screenshotId == currentScreenshotId) {
66             actionProviders[screenshotId]?.onScrollChipReady(onClick)
67         }
68     }
69 
onScrollChipInvalidatednull70     fun onScrollChipInvalidated() {
71         for (provider in actionProviders.values) {
72             provider.onScrollChipInvalidated()
73         }
74     }
75 
setCompletedScreenshotnull76     fun setCompletedScreenshot(screenshotId: UUID, result: ScreenshotSavedResult) {
77         if (screenshotId == currentScreenshotId) {
78             actionProviders[screenshotId]?.setCompletedScreenshot(result)
79         }
80     }
81 
82     @AssistedFactory
83     interface Factory {
getControllernull84         fun getController(actionExecutor: ActionExecutor): ScreenshotActionsController
85     }
86 
87     inner class ActionsCallback(private val screenshotId: UUID) {
88         fun providePreviewAction(previewAction: PreviewAction) {
89             if (screenshotId == currentScreenshotId) {
90                 viewModel.setPreviewAction(previewAction)
91             }
92         }
93 
94         fun provideActionButton(
95             appearance: ActionButtonAppearance,
96             showDuringEntrance: Boolean,
97             onClick: () -> Unit
98         ): Int {
99             if (screenshotId == currentScreenshotId) {
100                 return viewModel.addAction(appearance, showDuringEntrance, onClick)
101             }
102             return 0
103         }
104 
105         fun updateActionButtonAppearance(buttonId: Int, appearance: ActionButtonAppearance) {
106             if (screenshotId == currentScreenshotId) {
107                 viewModel.updateActionAppearance(buttonId, appearance)
108             }
109         }
110 
111         fun updateActionButtonVisibility(buttonId: Int, visible: Boolean) {
112             if (screenshotId == currentScreenshotId) {
113                 viewModel.setActionVisibility(buttonId, visible)
114             }
115         }
116     }
117 }
118