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