/talkback_preics/src/com/google/android/marvin/talkback/SpeechRuleLoader.java

http://eyes-free.googlecode.com/ · Java · 199 lines · 100 code · 23 blank · 76 comment · 12 complexity · 1aaf5cc16d3432b5f0981e96e5f4aac4 MD5 · raw file

  1. /*
  2. * Copyright (C) 2010 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. package com.google.android.marvin.talkback;
  17. import com.google.android.marvin.talkback.TalkBackService.InfrastructureStateListener;
  18. import android.os.Environment;
  19. import android.os.FileObserver;
  20. import android.util.Log;
  21. import java.io.File;
  22. import java.util.Arrays;
  23. /**
  24. * This class is responsible for loading speech rules.
  25. *
  26. * @author svetoslavganov@google.com (Svetoslav Ganov)
  27. */
  28. public class SpeechRuleLoader implements InfrastructureStateListener {
  29. /**
  30. * Tag used for logging.
  31. */
  32. private static final String LOG_TAG = SpeechRuleLoader.class.getSimpleName();
  33. /**
  34. * The {@link SpeechRuleProcessor} that manages speech rules.
  35. */
  36. private final SpeechRuleProcessor mSpeechRuleProcessor;
  37. /**
  38. * Flag if the device is a phone.
  39. */
  40. private final boolean mDeviceIsPhone;
  41. /**
  42. * The directory that contains external speech strategies.
  43. */
  44. private final File mExternalSpeechStrategyDirectory;
  45. /**
  46. * File observer for grabbing external speech strategies.
  47. */
  48. private final FileObserver mFileObserver;
  49. /**
  50. * Creates a new instance.
  51. *
  52. * @param packageName The TalkBack package name.
  53. * @param speechRuleProcessor The {@link SpeechRuleProcessor} to which to add rules.
  54. * @param deviceIsPhone Flag if the device is a phone.
  55. */
  56. SpeechRuleLoader(String packageName, SpeechRuleProcessor speechRuleProcessor,
  57. boolean deviceIsPhone) {
  58. mSpeechRuleProcessor = speechRuleProcessor;
  59. mDeviceIsPhone = deviceIsPhone;
  60. mExternalSpeechStrategyDirectory = new File(Environment.getExternalStorageDirectory(),
  61. "/Android/data/" + packageName + "/speechstrategy");
  62. final String speechStrategyDirectory = mExternalSpeechStrategyDirectory.toString();
  63. // Note: FileObserver.MODIFY is fired in both create and modify cases, so
  64. // we register only for FileObserver.MODIFY and FileObserver.DELETE
  65. // to avoid multiple reloads
  66. int flags = FileObserver.DELETE | FileObserver.MODIFY;
  67. mFileObserver = new FileObserver(speechStrategyDirectory, flags) {
  68. @Override
  69. public void onEvent(int event, String speechStrategyRelativePath) {
  70. switch (event) {
  71. case FileObserver.DELETE:
  72. unloadExternalSpeechStrategy(speechStrategyRelativePath);
  73. break;
  74. case FileObserver.MODIFY:
  75. loadExternalSpeechStrategy(speechStrategyRelativePath);
  76. break;
  77. }
  78. }
  79. };
  80. }
  81. /**
  82. * Load all speech rules - internal and external.
  83. */
  84. public void loadSpeechRules() {
  85. // add user defined external speech strategies first or if
  86. // no such create the external speech strategy directory
  87. if (hasExternalSpeechRulesDirectory()) {
  88. loadExternalSpeechStrategies();
  89. } else {
  90. createExternalSpeechRulesDirectory();
  91. }
  92. // add speech strategy for third-party apps; later this may be loaded
  93. // dynamically from another file
  94. mSpeechRuleProcessor.addSpeechStrategy(R.raw.speechstrategy_thirdparty);
  95. // add speech strategy for specific built-in Android apps
  96. mSpeechRuleProcessor.addSpeechStrategy(R.raw.speechstrategy_apps);
  97. if (!mDeviceIsPhone) {
  98. // add the speech strategy for Google TV; this should always be
  99. // after the application specific ones but before the generic
  100. mSpeechRuleProcessor.addSpeechStrategy(R.raw.speechstrategy_googletv);
  101. }
  102. // add generic speech strategy for views in any app; this should always
  103. // be last so that the app-specific rules above can override the
  104. // generic rules
  105. mSpeechRuleProcessor.addSpeechStrategy(R.raw.speechstrategy);
  106. }
  107. /**
  108. * Creates the external speech rule directory on the SD card if such.
  109. */
  110. private void createExternalSpeechRulesDirectory() {
  111. String state = Environment.getExternalStorageState();
  112. if (Environment.MEDIA_MOUNTED.equals(state)) {
  113. try {
  114. if (mExternalSpeechStrategyDirectory.mkdirs()) {
  115. Log.d(LOG_TAG, "Created external speech rules directory: "
  116. + mExternalSpeechStrategyDirectory);
  117. }
  118. } catch (SecurityException se) {
  119. Log.w(LOG_TAG, "Could not create external speech rules directory.", se);
  120. }
  121. } else {
  122. Log.w(LOG_TAG, "Could not create external speech rules directory."
  123. + " No external storage.");
  124. }
  125. }
  126. /**
  127. * @return True if the external speech rule strategy exists.
  128. */
  129. private boolean hasExternalSpeechRulesDirectory() {
  130. String state = Environment.getExternalStorageState();
  131. if (Environment.MEDIA_MOUNTED.equals(state)
  132. || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
  133. return mExternalSpeechStrategyDirectory.exists();
  134. }
  135. return false;
  136. }
  137. /**
  138. * Loads the external speech rules in alphabetical order.
  139. */
  140. private void loadExternalSpeechStrategies() {
  141. String[] speechStrategyPaths = mExternalSpeechStrategyDirectory.list();
  142. // we load in alphabetical order
  143. Arrays.sort(speechStrategyPaths);
  144. for (String speechStrategyPath : speechStrategyPaths) {
  145. loadExternalSpeechStrategy(speechStrategyPath);
  146. }
  147. }
  148. /**
  149. * Loads an external speech strategy with the given
  150. * <code>speechStrategyPath</code>.
  151. */
  152. private void loadExternalSpeechStrategy(String speechStrategyRelativePath) {
  153. File speechStrategyFile = new File(mExternalSpeechStrategyDirectory,
  154. speechStrategyRelativePath);
  155. mSpeechRuleProcessor.addSpeechStrategy(speechStrategyFile);
  156. Log.i(LOG_TAG, "Loaded external speech strategy: " + speechStrategyRelativePath);
  157. }
  158. /**
  159. * Unloads an external speech strategy with the given
  160. * <code>speechStrategyPath</code>.
  161. */
  162. private void unloadExternalSpeechStrategy(String speechStrategyRelativePath) {
  163. File speechStrategyFile = new File(mExternalSpeechStrategyDirectory,
  164. speechStrategyRelativePath);
  165. mSpeechRuleProcessor.removeSpeechStrategy(speechStrategyFile);
  166. Log.i(LOG_TAG, "Removed external speech strategy: " + speechStrategyRelativePath);
  167. }
  168. @Override
  169. public void onInfrastructureStateChange(boolean isInitialized) {
  170. if (isInitialized) {
  171. mFileObserver.startWatching();
  172. } else {
  173. mFileObserver.stopWatching();
  174. }
  175. }
  176. }