• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 
18 package com.android.systemui.keyguard.data.quickaffordance
19 
20 import android.content.Context
21 import com.android.systemui.R
22 import com.android.systemui.animation.Expandable
23 import com.android.systemui.common.coroutine.ChannelExt.trySendWithFailureLogging
24 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
25 import com.android.systemui.common.shared.model.ContentDescription
26 import com.android.systemui.common.shared.model.Icon
27 import com.android.systemui.dagger.SysUISingleton
28 import com.android.systemui.dagger.qualifiers.Application
29 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
30 import javax.inject.Inject
31 import kotlinx.coroutines.channels.awaitClose
32 import kotlinx.coroutines.flow.Flow
33 
34 /** QR code scanner quick affordance data source. */
35 @SysUISingleton
36 class QrCodeScannerKeyguardQuickAffordanceConfig
37 @Inject
38 constructor(
39     @Application private val context: Context,
40     private val controller: QRCodeScannerController,
41 ) : KeyguardQuickAffordanceConfig {
42 
43     override val key: String = BuiltInKeyguardQuickAffordanceKeys.QR_CODE_SCANNER
44 
45     override val pickerName = context.getString(R.string.qr_code_scanner_title)
46 
47     override val pickerIconResourceId = R.drawable.ic_qr_code_scanner
48 
49     override val lockScreenState: Flow<KeyguardQuickAffordanceConfig.LockScreenState> =
<lambda>null50         conflatedCallbackFlow {
51             val callback =
52                 object : QRCodeScannerController.Callback {
53                     override fun onQRCodeScannerActivityChanged() {
54                         trySendWithFailureLogging(state(), TAG)
55                     }
56                     override fun onQRCodeScannerPreferenceChanged() {
57                         trySendWithFailureLogging(state(), TAG)
58                     }
59                 }
60 
61             controller.addCallback(callback)
62             controller.registerQRCodeScannerChangeObservers(
63                 QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
64                 QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE
65             )
66             // Registering does not push an initial update.
67             trySendWithFailureLogging(state(), "initial state", TAG)
68 
69             awaitClose {
70                 controller.unregisterQRCodeScannerChangeObservers(
71                     QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE,
72                     QRCodeScannerController.QR_CODE_SCANNER_PREFERENCE_CHANGE
73                 )
74                 controller.removeCallback(callback)
75             }
76         }
77 
getPickerScreenStatenull78     override suspend fun getPickerScreenState(): KeyguardQuickAffordanceConfig.PickerScreenState {
79         return when {
80             !controller.isAvailableOnDevice ->
81                 KeyguardQuickAffordanceConfig.PickerScreenState.UnavailableOnDevice
82             !controller.isAbleToOpenCameraApp ->
83                 KeyguardQuickAffordanceConfig.PickerScreenState.Disabled(
84                     instructions =
85                         listOf(
86                             context.getString(
87                                 R.string
88                                     .keyguard_affordance_enablement_dialog_qr_scanner_instruction
89                             ),
90                         ),
91                 )
92             else -> KeyguardQuickAffordanceConfig.PickerScreenState.Default()
93         }
94     }
95 
onTriggerednull96     override fun onTriggered(
97         expandable: Expandable?,
98     ): KeyguardQuickAffordanceConfig.OnTriggeredResult {
99         return KeyguardQuickAffordanceConfig.OnTriggeredResult.StartActivity(
100             intent = controller.intent,
101             canShowWhileLocked = true,
102         )
103     }
104 
statenull105     private fun state(): KeyguardQuickAffordanceConfig.LockScreenState {
106         return if (controller.isEnabledForLockScreenButton) {
107             KeyguardQuickAffordanceConfig.LockScreenState.Visible(
108                 icon =
109                     Icon.Resource(
110                         res = R.drawable.ic_qr_code_scanner,
111                         contentDescription =
112                             ContentDescription.Resource(
113                                 res = R.string.accessibility_qr_code_scanner_button,
114                             ),
115                     ),
116             )
117         } else {
118             KeyguardQuickAffordanceConfig.LockScreenState.Hidden
119         }
120     }
121 
122     companion object {
123         private const val TAG = "QrCodeScannerKeyguardQuickAffordanceConfig"
124     }
125 }
126