PageRenderTime 33ms CodeModel.GetById 18ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/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
 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}