1 /*
<lambda>null2  * Copyright (C) 2023 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.qs.tiles.impl.saver.domain.interactor
18 
19 import android.content.Context
20 import android.content.Intent
21 import android.provider.Settings
22 import com.android.internal.jank.InteractionJankMonitor
23 import com.android.systemui.animation.DialogCuj
24 import com.android.systemui.animation.DialogTransitionAnimator
25 import com.android.systemui.dagger.qualifiers.Application
26 import com.android.systemui.dagger.qualifiers.Background
27 import com.android.systemui.dagger.qualifiers.Main
28 import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
29 import com.android.systemui.qs.tiles.base.interactor.QSTileInput
30 import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
31 import com.android.systemui.qs.tiles.impl.saver.domain.DataSaverDialogDelegate
32 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
33 import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
34 import com.android.systemui.settings.UserFileManager
35 import com.android.systemui.statusbar.phone.SystemUIDialog
36 import com.android.systemui.statusbar.policy.DataSaverController
37 import javax.inject.Inject
38 import kotlin.coroutines.CoroutineContext
39 import kotlinx.coroutines.withContext
40 
41 /** Handles data saver tile clicks. */
42 class DataSaverTileUserActionInteractor
43 @Inject
44 constructor(
45     @Application private val context: Context,
46     @Main private val coroutineContext: CoroutineContext,
47     @Background private val backgroundContext: CoroutineContext,
48     private val dataSaverController: DataSaverController,
49     private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
50     private val dialogTransitionAnimator: DialogTransitionAnimator,
51     private val systemUIDialogFactory: SystemUIDialog.Factory,
52     userFileManager: UserFileManager,
53 ) : QSTileUserActionInteractor<DataSaverTileModel> {
54     companion object {
55         private const val INTERACTION_JANK_TAG = "start_data_saver"
56         const val PREFS = "data_saver"
57         const val DIALOG_SHOWN = "data_saver_dialog_shown"
58     }
59 
60     val sharedPreferences =
61         userFileManager.getSharedPreferences(PREFS, Context.MODE_PRIVATE, context.userId)
62 
63     override suspend fun handleInput(input: QSTileInput<DataSaverTileModel>): Unit =
64         with(input) {
65             when (action) {
66                 is QSTileUserAction.Click -> {
67                     val wasEnabled: Boolean = data.isEnabled
68                     if (wasEnabled || sharedPreferences.getBoolean(DIALOG_SHOWN, false)) {
69                         withContext(backgroundContext) {
70                             dataSaverController.setDataSaverEnabled(!wasEnabled)
71                         }
72                         return@with
73                     }
74                     // Show a dialog to confirm first. Dialogs shown by the DialogTransitionAnimator
75                     // must be created and shown on the main thread, so we post it to the UI
76                     // handler
77                     withContext(coroutineContext) {
78                         val dialogDelegate =
79                             DataSaverDialogDelegate(
80                                 systemUIDialogFactory,
81                                 context,
82                                 backgroundContext,
83                                 dataSaverController,
84                                 sharedPreferences
85                             )
86                         val dialog = systemUIDialogFactory.create(dialogDelegate, context)
87 
88                         action.expandable
89                             ?.dialogTransitionController(
90                                 DialogCuj(
91                                     InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
92                                     INTERACTION_JANK_TAG
93                                 )
94                             )
95                             ?.let { controller ->
96                                 dialogTransitionAnimator.show(dialog, controller)
97                             }
98                             ?: dialog.show()
99                     }
100                 }
101                 is QSTileUserAction.LongClick -> {
102                     qsTileIntentUserActionHandler.handle(
103                         action.expandable,
104                         Intent(Settings.ACTION_DATA_SAVER_SETTINGS)
105                     )
106                 }
107             }
108         }
109 }
110