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 android.service.dreams.utils;
18 
19 import android.annotation.NonNull;
20 import android.content.Context;
21 import android.view.View;
22 import android.view.accessibility.AccessibilityNodeInfo;
23 
24 import com.android.internal.R;
25 
26 /**
27  * {@link DreamAccessibility} allows customization of accessibility
28  * actions for the root view of the dream overlay.
29  * @hide
30  */
31 public class DreamAccessibility {
32     private final Context mContext;
33     private final View mView;
34     private final View.AccessibilityDelegate mAccessibilityDelegate;
35 
DreamAccessibility(@onNull Context context, @NonNull View view)36     public DreamAccessibility(@NonNull Context context, @NonNull View view) {
37         mContext = context;
38         mView = view;
39         mAccessibilityDelegate = createNewAccessibilityDelegate(mContext);
40     }
41 
42     /**
43      * @param interactive
44      * Removes and add accessibility configuration depending if the dream is interactive or not
45      */
updateAccessibilityConfiguration(Boolean interactive)46     public void updateAccessibilityConfiguration(Boolean interactive) {
47         if (!interactive) {
48             addAccessibilityConfiguration();
49         } else {
50             removeCustomAccessibilityAction();
51         }
52     }
53 
54     /**
55      * Configures the accessibility actions for the given root view.
56      */
addAccessibilityConfiguration()57     private void addAccessibilityConfiguration() {
58         mView.setAccessibilityDelegate(mAccessibilityDelegate);
59     }
60 
61     /**
62      * Removes Configured the accessibility actions for the given root view.
63      */
removeCustomAccessibilityAction()64     private void removeCustomAccessibilityAction() {
65         if (mView.getAccessibilityDelegate() == mAccessibilityDelegate) {
66             mView.setAccessibilityDelegate(null);
67         }
68     }
69 
createNewAccessibilityDelegate(Context context)70     private View.AccessibilityDelegate createNewAccessibilityDelegate(Context context) {
71         return new View.AccessibilityDelegate() {
72             @Override
73             public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
74                 super.onInitializeAccessibilityNodeInfo(host, info);
75                 for (AccessibilityNodeInfo.AccessibilityAction action : info.getActionList()) {
76                     if (action.getId() == AccessibilityNodeInfo.ACTION_CLICK) {
77                         info.removeAction(action);
78                         break;
79                     }
80                 }
81                 info.addAction(new AccessibilityNodeInfo.AccessibilityAction(
82                         AccessibilityNodeInfo.ACTION_CLICK,
83                         context.getResources().getString(R.string.dream_accessibility_action_click)
84                 ));
85             }
86         };
87     }
88 }
89