Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / android / java / src / org / chromium / chrome / browser / AccessibilityUtil.java
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser;
6
7 import android.accessibilityservice.AccessibilityServiceInfo;
8 import android.app.AlertDialog;
9 import android.content.Context;
10 import android.content.DialogInterface;
11 import android.content.Intent;
12 import android.content.pm.PackageInfo;
13 import android.content.pm.PackageManager;
14 import android.net.Uri;
15 import android.os.Build;
16 import android.view.accessibility.AccessibilityManager;
17
18 import org.chromium.base.CalledByNative;
19 import org.chromium.chrome.R;
20
21 import java.util.List;
22
23 /**
24  * Exposes information about the current accessibility state
25  */
26 public class AccessibilityUtil {
27     // Whether we've already shown an alert that they have an old version of TalkBack running.
28     private static boolean sOldTalkBackVersionAlertShown = false;
29
30     // The link to download or update TalkBack from the Play Store.
31     private static final String TALKBACK_MARKET_LINK =
32             "market://search?q=pname:com.google.android.marvin.talkback";
33
34     // The package name for TalkBack, an Android accessibility service.
35     private static final String TALKBACK_PACKAGE_NAME =
36             "com.google.android.marvin.talkback";
37
38     // The minimum TalkBack version that we support. This is the version that shipped with
39     // KitKat, from fall 2013. Versions older than that should be updated.
40     private static final int MIN_TALKBACK_VERSION = 105;
41
42     private AccessibilityUtil() { }
43
44     /**
45      * Checks to see that this device has accessibility and touch exploration enabled.
46      * @param context A {@link Context} instance.
47      * @return        Whether or not accessibility and touch exploration are enabled.
48      */
49     @CalledByNative
50     public static boolean isAccessibilityEnabled(Context context) {
51         AccessibilityManager manager = (AccessibilityManager)
52                 context.getSystemService(Context.ACCESSIBILITY_SERVICE);
53         return manager != null && manager.isEnabled() && manager.isTouchExplorationEnabled();
54     }
55
56     /**
57      * Checks to see if an old version of TalkBack is running that Chrome doesn't support,
58      * and if so, shows an alert dialog prompting the user to update the app.
59      * @param context A {@link Context} instance.
60      * @return        True if the dialog was shown.
61      */
62     public static boolean showWarningIfOldTalkbackRunning(Context context) {
63         AccessibilityManager manager = (AccessibilityManager)
64                 context.getSystemService(Context.ACCESSIBILITY_SERVICE);
65         if (manager == null) return false;
66
67         boolean isTalkbackRunning = false;
68         try {
69             List<AccessibilityServiceInfo> services =
70                     manager.getEnabledAccessibilityServiceList(
71                             AccessibilityServiceInfo.FEEDBACK_SPOKEN);
72             for (AccessibilityServiceInfo service : services) {
73                 if (service.getId().contains(TALKBACK_PACKAGE_NAME)) isTalkbackRunning = true;
74             }
75         } catch (NullPointerException e) {
76             // getEnabledAccessibilityServiceList() can throw an NPE due to a bad
77             // AccessibilityService.
78         }
79         if (!isTalkbackRunning) return false;
80
81         try {
82             PackageInfo talkbackInfo = context.getPackageManager().getPackageInfo(
83                     TALKBACK_PACKAGE_NAME, 0);
84             if (talkbackInfo != null && talkbackInfo.versionCode < MIN_TALKBACK_VERSION &&
85                     Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN &&
86                     !sOldTalkBackVersionAlertShown) {
87                 showOldTalkbackVersionAlertOnce(context);
88                 return true;
89             }
90         } catch (PackageManager.NameNotFoundException e) {
91             // Do nothing, default to false.
92         }
93
94         return false;
95     }
96
97     private static void showOldTalkbackVersionAlertOnce(final Context context) {
98         if (sOldTalkBackVersionAlertShown) return;
99         sOldTalkBackVersionAlertShown = true;
100
101         AlertDialog.Builder builder = new AlertDialog.Builder(context)
102                 .setTitle(R.string.old_talkback_title)
103                 .setPositiveButton(R.string.update_from_market,
104                         new DialogInterface.OnClickListener() {
105                         @Override
106                             public void onClick(DialogInterface dialog, int id) {
107                                 Uri marketUri = Uri.parse(TALKBACK_MARKET_LINK);
108                                 Intent marketIntent = new Intent(
109                                         Intent.ACTION_VIEW, marketUri);
110                                 context.startActivity(marketIntent);
111                             }
112                         })
113                 .setNegativeButton(R.string.cancel_talkback_alert,
114                         new DialogInterface.OnClickListener() {
115                         @Override
116                             public void onClick(DialogInterface dialog, int id) {
117                                 // Do nothing, this alert is only shown once either way.
118                             }
119                         });
120         AlertDialog dialog = builder.create();
121         dialog.show();
122     }
123 }