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 
18 package com.android.systemui.keyguard.ui.binder
19 
20 import android.os.Bundle
21 import android.view.View
22 import android.view.accessibility.AccessibilityNodeInfo
23 import androidx.lifecycle.Lifecycle
24 import androidx.lifecycle.repeatOnLifecycle
25 import com.android.systemui.keyguard.ui.viewmodel.AccessibilityActionsViewModel
26 import com.android.systemui.lifecycle.repeatWhenAttached
27 import com.android.systemui.res.R
28 import kotlinx.coroutines.DisposableHandle
29 import kotlinx.coroutines.launch
30 
31 /** View binder for accessibility actions placeholder on keyguard. */
32 object AccessibilityActionsViewBinder {
33     fun bind(
34         view: View,
35         viewModel: AccessibilityActionsViewModel,
36     ): DisposableHandle {
37         val disposableHandle =
38             view.repeatWhenAttached {
39                 repeatOnLifecycle(Lifecycle.State.STARTED) {
40                     view.contentDescription =
41                         view.resources.getString(R.string.accessibility_desc_lock_screen)
42 
43                     launch {
44                         viewModel.isOnKeyguard.collect { isOnKeyguard ->
45                             view.importantForAccessibility =
46                                 if (isOnKeyguard) {
47                                     View.IMPORTANT_FOR_ACCESSIBILITY_YES
48                                 } else {
49                                     // The border won't be displayed when keyguard is not showing or
50                                     // when the focus was previously on it but is now transitioning
51                                     // away from the keyguard.
52                                     View.IMPORTANT_FOR_ACCESSIBILITY_NO
53                                 }
54                         }
55                     }
56 
57                     launch {
58                         viewModel.isCommunalAvailable.collect { canOpenGlanceableHub ->
59                             view.accessibilityDelegate =
60                                 object : View.AccessibilityDelegate() {
61                                     override fun onInitializeAccessibilityNodeInfo(
62                                         host: View,
63                                         info: AccessibilityNodeInfo
64                                     ) {
65                                         super.onInitializeAccessibilityNodeInfo(host, info)
66                                         // Add custom actions
67                                         if (canOpenGlanceableHub) {
68                                             val action =
69                                                 AccessibilityNodeInfo.AccessibilityAction(
70                                                     R.id.accessibility_action_open_communal_hub,
71                                                     view.resources.getString(
72                                                         R.string
73                                                             .accessibility_action_open_communal_hub
74                                                     ),
75                                                 )
76                                             info.addAction(action)
77                                         }
78                                     }
79 
80                                     override fun performAccessibilityAction(
81                                         host: View,
82                                         action: Int,
83                                         args: Bundle?
84                                     ): Boolean {
85                                         return if (
86                                             action == R.id.accessibility_action_open_communal_hub
87                                         ) {
88                                             viewModel.openCommunalHub()
89                                             true
90                                         } else super.performAccessibilityAction(host, action, args)
91                                     }
92                                 }
93                         }
94                     }
95                 }
96             }
97         return disposableHandle
98     }
99 }
100