Merge "Remove BlockingMediaPlayer."
diff --git a/core/java/android/speech/tts/AudioPlaybackQueueItem.java b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
index 668b459..1a1fda81 100644
--- a/core/java/android/speech/tts/AudioPlaybackQueueItem.java
+++ b/core/java/android/speech/tts/AudioPlaybackQueueItem.java
@@ -15,27 +15,91 @@
  */
 package android.speech.tts;
 
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.os.ConditionVariable;
 import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
 import android.util.Log;
 
 class AudioPlaybackQueueItem extends PlaybackQueueItem {
-    private final BlockingMediaPlayer mPlayer;
+    private static final String TAG = "TTS.AudioQueueItem";
+
+    private final Context mContext;
+    private final Uri mUri;
+    private final int mStreamType;
+
+    private final ConditionVariable mDone;
+    private MediaPlayer mPlayer;
+    private volatile boolean mFinished;
 
     AudioPlaybackQueueItem(UtteranceProgressDispatcher dispatcher,
-            Object callerIdentity, BlockingMediaPlayer player) {
+            Object callerIdentity,
+            Context context, Uri uri, int streamType) {
         super(dispatcher, callerIdentity);
-        mPlayer = player;
+
+        mContext = context;
+        mUri = uri;
+        mStreamType = streamType;
+
+        mDone = new ConditionVariable();
+        mPlayer = null;
+        mFinished = false;
     }
     @Override
     public void run() {
-        getDispatcher().dispatchOnStart();
-        // TODO: This can be avoided. Will be fixed later in this CL.
-        mPlayer.startAndWait();
-        getDispatcher().dispatchOnDone();
+        final UtteranceProgressDispatcher dispatcher = getDispatcher();
+
+        dispatcher.dispatchOnStart();
+        mPlayer = MediaPlayer.create(mContext, mUri);
+        if (mPlayer == null) {
+            dispatcher.dispatchOnError();
+            return;
+        }
+
+        try {
+            mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+                @Override
+                public boolean onError(MediaPlayer mp, int what, int extra) {
+                    Log.w(TAG, "Audio playback error: " + what + ", " + extra);
+                    mDone.open();
+                    return true;
+                }
+            });
+            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+                @Override
+                public void onCompletion(MediaPlayer mp) {
+                    mFinished = true;
+                    mDone.open();
+                }
+            });
+            mPlayer.setAudioStreamType(mStreamType);
+            mPlayer.start();
+            mDone.block();
+            finish();
+        } catch (IllegalArgumentException ex) {
+            Log.w(TAG, "MediaPlayer failed", ex);
+            mDone.open();
+        }
+
+        if (mFinished) {
+            dispatcher.dispatchOnDone();
+        } else {
+            dispatcher.dispatchOnError();
+        }
+    }
+
+    private void finish() {
+        try {
+            mPlayer.stop();
+        } catch (IllegalStateException ex) {
+            // Do nothing, the player is already stopped
+        }
+        mPlayer.release();
     }
 
     @Override
     void stop(boolean isError) {
-        mPlayer.stop();
+        mDone.open();
     }
 }
diff --git a/core/java/android/speech/tts/BlockingMediaPlayer.java b/core/java/android/speech/tts/BlockingMediaPlayer.java
deleted file mode 100644
index 1ccc6e4..0000000
--- a/core/java/android/speech/tts/BlockingMediaPlayer.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.speech.tts;
-
-import android.content.Context;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.util.Log;
-
-/**
- * A media player that allows blocking to wait for it to finish.
- */
-class BlockingMediaPlayer {
-
-    private static final String TAG = "BlockMediaPlayer";
-
-    private static final String MEDIA_PLAYER_THREAD_NAME = "TTS-MediaPlayer";
-
-    private final Context mContext;
-    private final Uri mUri;
-    private final int mStreamType;
-    private final ConditionVariable mDone;
-    // Only accessed on the Handler thread
-    private MediaPlayer mPlayer;
-    private volatile boolean mFinished;
-
-    /**
-     * Creates a new blocking media player.
-     * Creating a blocking media player is a cheap operation.
-     *
-     * @param context
-     * @param uri
-     * @param streamType
-     */
-    public BlockingMediaPlayer(Context context, Uri uri, int streamType) {
-        mContext = context;
-        mUri = uri;
-        mStreamType = streamType;
-        mDone = new ConditionVariable();
-    }
-
-    /**
-     * Starts playback and waits for it to finish.
-     * Can be called from any thread.
-     *
-     * @return {@code true} if the playback finished normally, {@code false} if the playback
-     *         failed or {@link #stop} was called before the playback finished.
-     */
-    public boolean startAndWait() {
-        HandlerThread thread = new HandlerThread(MEDIA_PLAYER_THREAD_NAME);
-        thread.start();
-        Handler handler = new Handler(thread.getLooper());
-        mFinished = false;
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                startPlaying();
-            }
-        });
-        mDone.block();
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                finish();
-                // No new messages should get posted to the handler thread after this
-                Looper.myLooper().quit();
-            }
-        });
-        return mFinished;
-    }
-
-    /**
-     * Stops playback. Can be called multiple times.
-     * Can be called from any thread.
-     */
-    public void stop() {
-        mDone.open();
-    }
-
-    /**
-     * Starts playback.
-     * Called on the handler thread.
-     */
-    private void startPlaying() {
-        mPlayer = MediaPlayer.create(mContext, mUri);
-        if (mPlayer == null) {
-            Log.w(TAG, "Failed to play " + mUri);
-            mDone.open();
-            return;
-        }
-        try {
-            mPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
-                @Override
-                public boolean onError(MediaPlayer mp, int what, int extra) {
-                    Log.w(TAG, "Audio playback error: " + what + ", " + extra);
-                    mDone.open();
-                    return true;
-                }
-            });
-            mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
-                @Override
-                public void onCompletion(MediaPlayer mp) {
-                    mFinished = true;
-                    mDone.open();
-                }
-            });
-            mPlayer.setAudioStreamType(mStreamType);
-            mPlayer.start();
-        } catch (IllegalArgumentException ex) {
-            Log.w(TAG, "MediaPlayer failed", ex);
-            mDone.open();
-        }
-    }
-
-    /**
-     * Stops playback and release the media player.
-     * Called on the handler thread.
-     */
-    private void finish() {
-        try {
-            mPlayer.stop();
-        } catch (IllegalStateException ex) {
-            // Do nothing, the player is already stopped
-        }
-        mPlayer.release();
-    }
-
-}
\ No newline at end of file
diff --git a/core/java/android/speech/tts/MessageParams.java b/core/java/android/speech/tts/MessageParams.java
deleted file mode 100644
index f83b793..0000000
--- a/core/java/android/speech/tts/MessageParams.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package android.speech.tts;
-
-import android.speech.tts.TextToSpeechService.UtteranceProgressDispatcher;
-
-abstract class MessageParams {
-    static final int TYPE_SYNTHESIS = 1;
-    static final int TYPE_AUDIO = 2;
-    static final int TYPE_SILENCE = 3;
-
-    private final UtteranceProgressDispatcher mDispatcher;
-    private final Object mCallerIdentity;
-
-    MessageParams(UtteranceProgressDispatcher dispatcher, Object callerIdentity) {
-        mDispatcher = dispatcher;
-        mCallerIdentity = callerIdentity;
-    }
-
-    UtteranceProgressDispatcher getDispatcher() {
-        return mDispatcher;
-    }
-
-    Object getCallerIdentity() {
-        return mCallerIdentity;
-    }
-
-    @Override
-    public String toString() {
-        return "MessageParams[" + hashCode() + "]";
-    }
-
-    abstract int getType();
-}
diff --git a/core/java/android/speech/tts/TextToSpeechService.java b/core/java/android/speech/tts/TextToSpeechService.java
index ba8485a..4c1a0afc 100644
--- a/core/java/android/speech/tts/TextToSpeechService.java
+++ b/core/java/android/speech/tts/TextToSpeechService.java
@@ -694,12 +694,12 @@
     }
 
     private class AudioSpeechItem extends SpeechItem {
-        private final BlockingMediaPlayer mPlayer;
-
+        private final AudioPlaybackQueueItem mItem;
         public AudioSpeechItem(Object callerIdentity, int callerUid, int callerPid,
                 Bundle params, Uri uri) {
             super(callerIdentity, callerUid, callerPid, params);
-            mPlayer = new BlockingMediaPlayer(TextToSpeechService.this, uri, getStreamType());
+            mItem = new AudioPlaybackQueueItem(this, getCallerIdentity(),
+                    TextToSpeechService.this, uri, getStreamType());
         }
 
         @Override
@@ -709,8 +709,7 @@
 
         @Override
         protected int playImpl() {
-            mAudioPlaybackHandler.enqueue(new AudioPlaybackQueueItem(
-                    this, getCallerIdentity(), mPlayer));
+            mAudioPlaybackHandler.enqueue(mItem);
             return TextToSpeech.SUCCESS;
         }