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