1 /*
2  * 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 
18 package com.android.customization.picker.clock.ui.binder
19 
20 import android.content.Context
21 import android.os.Bundle
22 import android.view.View
23 import android.view.accessibility.AccessibilityNodeInfo
24 import com.android.themepicker.R
25 
26 class CarouselAccessibilityDelegate(
27     private val context: Context,
28     private val scrollForwardCallback: () -> Unit,
29     private val scrollBackwardCallback: () -> Unit
30 ) : View.AccessibilityDelegate() {
31 
32     var contentDescriptionOfSelectedClock = ""
33 
34     private val ACTION_SCROLL_BACKWARD = R.id.action_scroll_backward
35     private val ACTION_SCROLL_FORWARD = R.id.action_scroll_forward
36 
onInitializeAccessibilityNodeInfonull37     override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfo) {
38         super.onInitializeAccessibilityNodeInfo(host, info)
39         info.isScrollable = true
40 
41         // for some reason this action is needed for the subsequent two action to appear in the
42         // accessibility action menu (this action doesn't show)
43         info.addAction(AccessibilityNodeInfo.ACTION_CLICK) // Standard click action
44 
45         info.addAction(
46             AccessibilityNodeInfo.AccessibilityAction(
47                 ACTION_SCROLL_FORWARD,
48                 context.getString(R.string.scroll_forward_and_select)
49             )
50         )
51         info.addAction(
52             AccessibilityNodeInfo.AccessibilityAction(
53                 ACTION_SCROLL_BACKWARD,
54                 context.getString(R.string.scroll_backward_and_select)
55             )
56         )
57         info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS)
58         // We need to specifically set the content description since for some reason the talkback
59         // service does not go to children of the clock carousel in the view hierarchy
60         info.contentDescription = contentDescriptionOfSelectedClock
61     }
62 
performAccessibilityActionnull63     override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean {
64         when (action) {
65             ACTION_SCROLL_BACKWARD -> {
66                 scrollBackwardCallback.invoke()
67                 return true
68             }
69             ACTION_SCROLL_FORWARD -> {
70                 scrollForwardCallback.invoke()
71                 return true
72             }
73         }
74         return super.performAccessibilityAction(host, action, args)
75     }
76 }
77