/widgets/access-shim/src/com/googlecode/eyesfree/widget/AccessibilityShim.java

http://eyes-free.googlecode.com/ · Java · 145 lines · 53 code · 18 blank · 74 comment · 7 complexity · b576c15b732ce0613156cdc2bfb90d39 MD5 · raw file

  1. /*
  2. * Copyright (C) 2011 Google Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * 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, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.googlecode.eyesfree.widget;
  17. import android.app.Activity;
  18. import android.app.Dialog;
  19. import android.content.Context;
  20. import android.content.pm.ApplicationInfo;
  21. import android.content.pm.PackageManager;
  22. import android.provider.Settings;
  23. import android.view.View;
  24. import android.view.ViewGroup;
  25. import android.view.accessibility.AccessibilityManager;
  26. /**
  27. * <p>
  28. * The AccessibilityShim class inserts itself into an {@link Activity} or
  29. * {@link Dialog}'s view heirarchy and adds Touch Exploration. It is only
  30. * enabled when {@link AccessibilityManager} is enabled.
  31. * </p>
  32. * <p>
  33. * To add Touch Exploration to your activity, add the following line to your
  34. * onCreate() method after any calls to setContentView():
  35. * </p>
  36. * <p>
  37. * <code>AccessiblityShim.attachToActivity(this);</code>
  38. * <p>
  39. * If your activity uses dialogs, also add the following line at the end of your
  40. * onCreateDialog() method:
  41. * </p>
  42. * <p>
  43. * <code>AccessiblityShim.attachToDialog(dialog);</code>
  44. * </p>
  45. *
  46. * @author alanv@google.com (Alan Viverette)
  47. */
  48. public class AccessibilityShim {
  49. private static final String KEY_DISABLE_EXPLORATION = "disableTouchExploration";
  50. /**
  51. * If Accessibility is enabled, adds touch exploration to a view heirarchy.
  52. *
  53. * @param decorView The view to which touch exploration will be added.
  54. */
  55. public static void attachToView(View decorView) {
  56. final Context context = decorView.getContext();
  57. if (!isAccessibilityEnabled(context)) {
  58. return;
  59. }
  60. if (isTouchExplorationDisabled(context)) {
  61. return;
  62. }
  63. final AccessibleFrameLayout frame = new AccessibleFrameLayout(decorView.getContext());
  64. if (decorView instanceof ViewGroup) {
  65. frame.inject((ViewGroup) decorView);
  66. }
  67. }
  68. /**
  69. * Returns <code>true</code> if the user has enabled Accessibility within
  70. * the system's settings.
  71. *
  72. * @param context The application's {@link Context}.
  73. * @return Returns <code>true</code> if Accessibility is enabled.
  74. */
  75. private static boolean isAccessibilityEnabled(Context context) {
  76. final int enabled = Settings.Secure.getInt(context.getContentResolver(),
  77. Settings.Secure.ACCESSIBILITY_ENABLED, -1);
  78. return (enabled == 1);
  79. }
  80. /**
  81. * Returns <code>true</code> if the application has explicitly disabled
  82. * touch exploration using a meta tag.
  83. * <p>
  84. * <code><meta-data android:name="disableTouchExploration" android:value="true" /> * </code>
  85. * .
  86. * </p>
  87. *
  88. * @param context The application's {@link Context}.
  89. * @return Returns <code>true</code> if the application has explicitly
  90. * disabled touch exploration.
  91. */
  92. private static boolean isTouchExplorationDisabled(Context context) {
  93. try {
  94. final ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(
  95. context.getPackageName(), PackageManager.GET_META_DATA);
  96. if (appInfo.metaData != null && appInfo.metaData.containsKey(KEY_DISABLE_EXPLORATION)) {
  97. return true;
  98. }
  99. } catch (PackageManager.NameNotFoundException e) {
  100. e.printStackTrace();
  101. }
  102. return false;
  103. }
  104. /**
  105. * Enables touch exploration within an activity's view heirarchy. If your
  106. * application uses dialogs, you must also use attachToDialog inside of your
  107. * activity's onCreateDialog method.
  108. *
  109. * @param activity The activity to which touch exploration will be added.
  110. */
  111. public static void attachToActivity(Activity activity) {
  112. final View decorView = activity.getWindow().getDecorView();
  113. attachToView(decorView);
  114. }
  115. /**
  116. * Enables touch exploration within a dialog's view heirarchy.
  117. *
  118. * @param dialog The dialog to which touch exploration will be added.
  119. */
  120. public static void attachToDialog(Dialog dialog) {
  121. final View decorView = dialog.getWindow().getDecorView();
  122. attachToView(decorView);
  123. }
  124. private AccessibilityShim() {
  125. // This class is non-instantiable.
  126. }
  127. }