PageRenderTime 32ms CodeModel.GetById 16ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/ime/latinime/src/com/googlecode/eyesfree/inputmethod/latin/tutorial/TutorialReader.java

http://eyes-free.googlecode.com/
Java | 175 lines | 119 code | 34 blank | 22 comment | 11 complexity | f4fc2ba8100caa5e47c45a5550d045bf MD5 | raw file
  1/*
  2 * Copyright (C) 2011 Google Inc.
  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.googlecode.eyesfree.inputmethod.latin.tutorial;
 18
 19import android.content.Context;
 20import android.speech.tts.TextToSpeech;
 21import android.util.Log;
 22import android.view.accessibility.AccessibilityManager;
 23
 24import java.util.HashMap;
 25import java.util.LinkedList;
 26
 27/**
 28 * This class provides text-to-speech for the {@link LatinIMETutorial} class.
 29 *
 30 * @author alanv@google.com (Alan Viverette)
 31 */
 32public class TutorialReader
 33        implements TextToSpeech.OnInitListener, TextToSpeech.OnUtteranceCompletedListener {
 34    private final AccessibilityManager mAccessibilityManager;
 35    private final LinkedList<ReaderUnit> mSpeechQueue;
 36    private final HashMap<String, String> mParams;
 37    private final TextToSpeech mTts;
 38
 39    private ReaderListener mListener;
 40    private boolean mInitialized;
 41
 42    public TutorialReader(Context context) {
 43        mInitialized = false;
 44
 45        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
 46                Context.ACCESSIBILITY_SERVICE);
 47        mSpeechQueue = new LinkedList<ReaderUnit>();
 48        mParams = new HashMap<String, String>();
 49
 50        synchronized(this) {
 51            mTts = new TextToSpeech(context, this);
 52        }
 53    }
 54
 55    public void setListener(ReaderListener listener) {
 56        mListener = listener;
 57    }
 58
 59    public void release() {
 60        mInitialized = false;
 61
 62        mTts.stop();
 63        mTts.shutdown();
 64    }
 65
 66    public void clear() {
 67        if (mAccessibilityManager.isEnabled()) {
 68            mAccessibilityManager.interrupt();
 69        }
 70
 71        synchronized (mSpeechQueue) {
 72            mSpeechQueue.clear();
 73        }
 74
 75        mTts.stop();
 76    }
 77
 78    public void queue(String text, int utteranceId) {
 79        LatinTutorialLogger.log(Log.DEBUG, "queue(%s, %s)", text, utteranceId);
 80
 81        ReaderUnit readerUnit = new ReaderUnit(text, utteranceId);
 82
 83        boolean initialized = false;
 84        boolean wasEmpty = false;
 85
 86        synchronized (mSpeechQueue) {
 87            initialized = mInitialized;
 88            wasEmpty = mSpeechQueue.isEmpty();
 89            mSpeechQueue.addLast(readerUnit);
 90        }
 91
 92        if (initialized && wasEmpty) {
 93            next();
 94        }
 95    }
 96
 97    public void next() {
 98        LatinTutorialLogger.log(Log.DEBUG, "next()");
 99
100        boolean initialized = false;
101        ReaderUnit nextUnit = null;
102
103        synchronized (mSpeechQueue) {
104            initialized = mInitialized;
105
106            if (!mSpeechQueue.isEmpty()) {
107                nextUnit = mSpeechQueue.getFirst();
108            }
109        }
110
111        if (initialized && nextUnit != null) {
112            String strUtteranceId = Integer.toString(nextUnit.utteranceId);
113            HashMap<String, String> params = new HashMap<String, String>(mParams);
114            params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, strUtteranceId);
115            mTts.speak(nextUnit.text, TextToSpeech.QUEUE_FLUSH, params);
116        }
117    }
118
119    @Override
120    public void onInit(int status) {
121        LatinTutorialLogger.log(Log.DEBUG, "onInit(%d)", status);
122
123        // We have to synchronize because *somehow* the TTS engine is initializing before
124        // it can return to the constructor of TutorialReader and set mTts to itself.
125        synchronized (this) {
126            mTts.setOnUtteranceCompletedListener(this);
127        }
128
129        switch (status) {
130            case TextToSpeech.SUCCESS:
131                synchronized (mSpeechQueue) {
132                    mInitialized = true;
133                    next();
134                }
135                break;
136        }
137    }
138
139    @Override
140    public void onUtteranceCompleted(String utteranceId) {
141        LatinTutorialLogger.log(Log.DEBUG, "onUtteranceCompleted(%s)", utteranceId);
142
143        synchronized (mSpeechQueue) {
144            if (!mSpeechQueue.isEmpty()) {
145                mSpeechQueue.removeFirst();
146                next();
147            }
148        }
149
150        if (mListener == null) {
151            return;
152        }
153
154        try {
155            int intUtteranceId = Integer.parseInt(utteranceId);
156            mListener.onUtteranceCompleted(intUtteranceId);
157        } catch (NumberFormatException e) {
158            e.printStackTrace();
159        }
160    }
161
162    private class ReaderUnit {
163        final String text;
164        final int utteranceId;
165
166        public ReaderUnit(String text, int utteranceId) {
167            this.text = text;
168            this.utteranceId = utteranceId;
169        }
170    }
171
172    public interface ReaderListener {
173        public void onUtteranceCompleted(int utteranceId);
174    }
175}