1 package com.android.camera;
2 
3 import android.accessibilityservice.AccessibilityServiceInfo;
4 import android.content.Context;
5 import androidx.core.view.accessibility.AccessibilityManagerCompat;
6 import android.view.View;
7 import android.view.accessibility.AccessibilityManager;
8 import android.widget.Button;
9 import com.android.camera.debug.Log;
10 import com.android.camera.ui.MainActivityLayout;
11 import com.android.camera.ui.PreviewOverlay;
12 import com.android.camera.util.AndroidServices;
13 import com.android.camera2.R;
14 
15 import java.util.List;
16 
17 /**
18  * AccessibilityUtil provides methods for use when the device is in
19  * accessibility mode
20  */
21 public class AccessibilityUtil {
22     private final static Log.Tag TAG = new Log.Tag("AccessibilityUtil");
23     private static final float MIN_ZOOM = 1f;
24 
25     // Filters for Google accessibility services
26     private static final String ACCESSIBILITY_PACKAGE_NAME_PREFIX = "com.google";
27     private PreviewOverlay mPreviewOverlay;
28     private Button mZoomPlusButton;
29     private Button mZoomMinusButton;
30     private float mMaxZoom;
31 
32     private View.OnClickListener zoomInListener = new View.OnClickListener() {
33         @Override
34         public void onClick(View view) {
35             float currentZoom = mPreviewOverlay.zoomIn(view, mMaxZoom);
36 
37             // Zooming in implies that you must be able to subsequently zoom
38             // out.
39             mZoomMinusButton.setEnabled(true);
40 
41             // Make sure it doesn't go above max zoom.
42             if (currentZoom == mMaxZoom) {
43                 mZoomPlusButton.setEnabled(false);
44             }
45         }
46     };
47 
48     private View.OnClickListener zoomOutListener = new View.OnClickListener() {
49         @Override
50         public void onClick(View view) {
51             float currentZoom = mPreviewOverlay.zoomOut(view, mMaxZoom);
52 
53             // Zooming out implies that you must be able to subsequently zoom
54             // in.
55             mZoomPlusButton.setEnabled(true);
56 
57             // Make sure it doesn't go below min zoom.
58             if (currentZoom == MIN_ZOOM) {
59                 mZoomMinusButton.setEnabled(false);
60             }
61         }
62     };
63 
AccessibilityUtil(PreviewOverlay previewOverlay, View view)64     public AccessibilityUtil(PreviewOverlay previewOverlay, View view) {
65         mPreviewOverlay = previewOverlay;
66         mZoomPlusButton = (Button) view.findViewById(R.id.accessibility_zoom_plus_button);
67         mZoomMinusButton = (Button) view.findViewById(R.id.accessibility_zoom_minus_button);
68         mZoomPlusButton.setOnClickListener(zoomInListener);
69         mZoomMinusButton.setOnClickListener(zoomOutListener);
70     }
71 
72     /**
73      * Enables the zoom UI with zoom in/zoom out buttons.
74      *
75      * @param maxZoom is maximum zoom on the given device
76      */
showZoomUI(float maxZoom)77     public void showZoomUI(float maxZoom) {
78         mMaxZoom = maxZoom;
79         mZoomPlusButton.setVisibility(View.VISIBLE);
80         mZoomMinusButton.setVisibility(View.VISIBLE);
81         mZoomMinusButton.setEnabled(false);
82     }
83 
hideZoomUI()84     public void hideZoomUI() {
85         mZoomPlusButton.setVisibility(View.GONE);
86         mZoomMinusButton.setVisibility(View.GONE);
87     }
88 
89     /**
90      * Returns the accessibility manager.
91      */
getAccessibilityManager()92     private android.view.accessibility.AccessibilityManager getAccessibilityManager() {
93         return AndroidServices.instance().provideAccessibilityManager();
94     }
95 
96     /**
97      * Returns whether touch exploration is enabled.
98      */
isTouchExplorationEnabled()99     private boolean isTouchExplorationEnabled() {
100         android.view.accessibility.AccessibilityManager accessibilityManager = getAccessibilityManager();
101         return accessibilityManager.isTouchExplorationEnabled();
102     }
103 
104     /**
105      * Checks whether Google accessibility services are enabled, including
106      * TalkBack, Switch Access, and others
107      *
108      * @return boolean
109      */
containsGoogleAccessibilityService()110     private boolean containsGoogleAccessibilityService() {
111         android.view.accessibility.AccessibilityManager accessibilityManager = getAccessibilityManager();
112         List<AccessibilityServiceInfo> enabledServices =
113                 accessibilityManager
114                         .getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
115         if (enabledServices != null) {
116             for (AccessibilityServiceInfo enabledService : enabledServices) {
117                 String serviceId = enabledService.getId();
118                 if (serviceId != null && serviceId.startsWith(ACCESSIBILITY_PACKAGE_NAME_PREFIX)) {
119                     return true;
120                 }
121             }
122         }
123         return false;
124     }
125 
126     /**
127      * Returns whether a touch exploration is enabled or a Google accessibility
128      * service is enabled.
129      */
isAccessibilityEnabled()130     public boolean isAccessibilityEnabled() {
131         return isTouchExplorationEnabled()
132                 || containsGoogleAccessibilityService();
133     }
134 }
135