Fix StrictMode violation in voicemail playback.
Currently we are preparing the media playing on the UI thread. But, this
may involve disk access, therefore we should do this asynchronously
instead.
Bug: 5113695
Change-Id: I70bd02f1e59d26ba87eae4a3a379ae8f257b0f88
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
index 9a84f7c..7aecf08 100644
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
+++ b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
@@ -37,7 +37,6 @@
import android.view.View;
import android.widget.SeekBar;
-import java.io.IOException;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -101,6 +100,7 @@
CHECK_FOR_CONTENT,
CHECK_CONTENT_AFTER_CHANGE,
PREPARE_MEDIA_PLAYER,
+ RESET_PREPARE_START_MEDIA_PLAYER,
}
/** Update rate for the slider, 30fps. */
@@ -169,6 +169,7 @@
*/
private FetchResultHandler mFetchResultHandler;
private PowerManager.WakeLock mWakeLock;
+ private AsyncTask<Void, ?, ?> mPrepareTask;
public VoicemailPlaybackPresenter(PlaybackView view, MediaPlayerProxy player,
Uri voicemailUri, ScheduledExecutorService executorService,
@@ -431,29 +432,49 @@
}
}
- private void resetPrepareStartPlaying(int clipPositionInMillis) {
- try {
- mPlayer.reset();
- mPlayer.setDataSource(mView.getDataSourceContext(), mVoicemailUri);
- mPlayer.setAudioStreamType(PLAYBACK_STREAM);
- mPlayer.prepare();
- mDuration.set(mPlayer.getDuration());
- int startPosition = constrain(clipPositionInMillis, 0, mDuration.get());
- mView.setClipPosition(startPosition, mDuration.get());
- mPlayer.seekTo(startPosition);
- mPlayer.start();
- mView.playbackStarted();
- if (!mWakeLock.isHeld()) {
- mWakeLock.acquire();
- }
- // Only enable if we are not currently using the speaker phone.
- if (!mView.isSpeakerPhoneOn()) {
- mView.enableProximitySensor();
- }
- mPositionUpdater.startUpdating(startPosition, mDuration.get());
- } catch (IOException e) {
- handleError(e);
+ private void resetPrepareStartPlaying(final int clipPositionInMillis) {
+ if (mPrepareTask != null) {
+ mPrepareTask.cancel(false);
}
+ mPrepareTask = mAsyncTaskExecutor.submit(Tasks.RESET_PREPARE_START_MEDIA_PLAYER,
+ new AsyncTask<Void, Void, Exception>() {
+ @Override
+ public Exception doInBackground(Void... params) {
+ try {
+ mPlayer.reset();
+ mPlayer.setDataSource(mView.getDataSourceContext(), mVoicemailUri);
+ mPlayer.setAudioStreamType(PLAYBACK_STREAM);
+ mPlayer.prepare();
+ return null;
+ } catch (Exception e) {
+ return e;
+ }
+ }
+
+ @Override
+ public void onPostExecute(Exception exception) {
+ mPrepareTask = null;
+ if (exception == null) {
+ mDuration.set(mPlayer.getDuration());
+ int startPosition =
+ constrain(clipPositionInMillis, 0, mDuration.get());
+ mView.setClipPosition(startPosition, mDuration.get());
+ mPlayer.seekTo(startPosition);
+ mPlayer.start();
+ mView.playbackStarted();
+ if (!mWakeLock.isHeld()) {
+ mWakeLock.acquire();
+ }
+ // Only enable if we are not currently using the speaker phone.
+ if (!mView.isSpeakerPhoneOn()) {
+ mView.enableProximitySensor();
+ }
+ mPositionUpdater.startUpdating(startPosition, mDuration.get());
+ } else {
+ handleError(exception);
+ }
+ }
+ });
}
private void handleError(Exception e) {
@@ -599,6 +620,9 @@
if (mPlayer.isPlaying()) {
stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
}
+ if (mPrepareTask != null) {
+ mPrepareTask.cancel(false);
+ }
if (mWakeLock.isHeld()) {
mWakeLock.release();
}