PageRenderTime 58ms CodeModel.GetById 28ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 1ms

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

http://eyes-free.googlecode.com/
Java | 181 lines | 96 code | 19 blank | 66 comment | 11 complexity | 45efb8a3bb1c5b8adea82690de727899 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 */
 33class SpeechRuleLoader implements InfrastructureStateListener {
 34
 35    /**
 36     * The {@link SpeechRuleProcessor} that manages speech rules.
 37     */
 38    private final SpeechRuleProcessor mSpeechRuleProcessor;
 39
 40    /**
 41     * The directory that contains external speech strategies.
 42     */
 43    private final File mExternalSpeechStrategyDirectory;
 44
 45    /**
 46     * File observer for grabbing external speech strategies.
 47     */
 48    private final FileObserver mFileObserver;
 49
 50    /**
 51     * Creates a new instance.
 52     *
 53     * @param packageName The TalkBack package name.
 54     * @param speechRuleProcessor The {@link SpeechRuleProcessor} to which to add rules.
 55     * @param deviceIsPhone Flag if the device is a phone.
 56     */
 57    public SpeechRuleLoader(String packageName, SpeechRuleProcessor speechRuleProcessor,
 58            boolean deviceIsPhone) {
 59        mSpeechRuleProcessor = speechRuleProcessor;
 60        mExternalSpeechStrategyDirectory = new File(Environment.getExternalStorageDirectory(),
 61                "/Android/data/" + packageName + "/speechstrategy");
 62
 63        final String speechStrategyDirectory = mExternalSpeechStrategyDirectory.toString();
 64        // Note: FileObserver.MODIFY is fired in both create and modify cases, so
 65        //       we register only for FileObserver.MODIFY and FileObserver.DELETE
 66        //       to avoid multiple reloads 
 67        int flags = FileObserver.DELETE | FileObserver.MODIFY; 
 68        mFileObserver = new FileObserver(speechStrategyDirectory, flags) {
 69            @Override
 70            public void onEvent(int event, String speechStrategyRelativePath) {
 71                switch (event) {
 72                    case FileObserver.DELETE:
 73                        unloadExternalSpeechStrategy(speechStrategyRelativePath);
 74                        break;
 75                    case FileObserver.MODIFY:
 76                        loadExternalSpeechStrategy(speechStrategyRelativePath);
 77                        break;
 78                }
 79            }
 80        };
 81    }
 82
 83    /**
 84     * Load all speech rules - internal and external.
 85     */
 86    public void loadSpeechRules() {
 87        // add user defined external speech strategies first or if
 88        // no such create the external speech strategy directory
 89        if (hasExternalSpeechRulesDirectory()) {
 90            loadExternalSpeechStrategies();
 91        } else {
 92            createExternalSpeechRulesDirectory();
 93        }
 94
 95        // add speech strategy for specific built-in Android apps
 96        mSpeechRuleProcessor.addSpeechStrategy(R.raw.speechstrategy_apps);
 97
 98        // add generic speech strategy for views in any app; this should always
 99        // be last so that the app-specific rules above can override the
100        // generic rules
101        mSpeechRuleProcessor.addSpeechStrategy(R.raw.speechstrategy);
102    }
103
104    /**
105     * Creates the external speech rule directory on the SD card if such.
106     */
107    private void createExternalSpeechRulesDirectory() {
108        String state = Environment.getExternalStorageState();
109        if (Environment.MEDIA_MOUNTED.equals(state)) {
110            try {
111                if (mExternalSpeechStrategyDirectory.mkdirs()) {
112                    LogUtils.log(SpeechRuleLoader.class, Log.DEBUG, "Created external speech "
113                            + "rules directory: %s", mExternalSpeechStrategyDirectory);
114                }
115            } catch (SecurityException se) {
116                LogUtils.log(SpeechRuleLoader.class, Log.WARN, "Could not create external "
117                        + "speech rules directory.\n%s", se.toString());
118            }
119        } else {
120            LogUtils.log(SpeechRuleLoader.class, Log.WARN, "Could not create external speech "
121                    + "rules directory: No external storage.");
122        }
123    }
124
125    /**
126     * @return True if the external speech rule strategy exists.
127     */
128    private boolean hasExternalSpeechRulesDirectory() {
129        String state = Environment.getExternalStorageState();
130        if (Environment.MEDIA_MOUNTED.equals(state)
131                || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
132            return mExternalSpeechStrategyDirectory.exists();
133        }
134        return false;
135    }
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    /**
150     * Loads an external speech strategy with the given
151     * <code>speechStrategyPath</code>.
152     */
153    private void loadExternalSpeechStrategy(String speechStrategyRelativePath) {
154        File speechStrategyFile = new File(mExternalSpeechStrategyDirectory,
155                speechStrategyRelativePath);
156        mSpeechRuleProcessor.addSpeechStrategy(speechStrategyFile);
157        LogUtils.log(SpeechRuleLoader.class, Log.INFO, "Loaded external speech strategy: %s",
158                speechStrategyRelativePath);
159    }
160
161    /**
162     * Unloads an external speech strategy with the given
163     * <code>speechStrategyPath</code>.
164     */
165    private void unloadExternalSpeechStrategy(String speechStrategyRelativePath) {
166        File speechStrategyFile = new File(mExternalSpeechStrategyDirectory,
167                speechStrategyRelativePath);
168        mSpeechRuleProcessor.removeSpeechStrategy(speechStrategyFile);
169        LogUtils.log(SpeechRuleLoader.class, Log.INFO, "Removed external speech strategy: %s",
170                speechStrategyRelativePath);
171    }
172
173    @Override
174    public void onInfrastructureStateChange(boolean isInitialized) {
175        if (isInitialized) {
176            mFileObserver.startWatching();
177        } else {
178            mFileObserver.stopWatching();
179        }
180    }
181}