Fix deadlock when showing subtitles MediaPlayer
Move all SubtitleTrack operations to TimeProvider's event handler thread.
Bug: 28784397
Change-Id: Iff848635390e99ffb19add03277a9d62feece4cc
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index cee7d60..3f6081b 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -2276,6 +2276,8 @@
Log.w(TAG, "addSubtitleSource called with null InputStream");
}
+ getMediaTimeProvider();
+
// process each subtitle in its own thread
final HandlerThread thread = new HandlerThread("SubtitleReadThread",
Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
@@ -2302,7 +2304,12 @@
synchronized (mIndexTrackPairs) {
mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
}
- track.onData(contents.getBytes(), true /* eos */, ~0 /* runID: keep forever */);
+ Handler h = mTimeProvider.mEventHandler;
+ int what = TimeProvider.NOTIFY;
+ int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+ Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, contents.getBytes());
+ Message m = h.obtainMessage(what, arg1, 0, trackData);
+ h.sendMessage(m);
return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
}
@@ -2501,6 +2508,8 @@
mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
}
+ getMediaTimeProvider();
+
final FileDescriptor fd3 = fd2;
final long offset2 = offset;
final long length2 = length;
@@ -2526,7 +2535,12 @@
total += bytes;
}
}
- track.onData(bos.toByteArray(), true /* eos */, ~0 /* runID: keep forever */);
+ Handler h = mTimeProvider.mEventHandler;
+ int what = TimeProvider.NOTIFY;
+ int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+ Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, bos.toByteArray());
+ Message m = h.obtainMessage(what, arg1, 0, trackData);
+ h.sendMessage(m);
return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
@@ -3528,6 +3542,7 @@
private static final int REFRESH_AND_NOTIFY_TIME = 1;
private static final int NOTIFY_STOP = 2;
private static final int NOTIFY_SEEK = 3;
+ private static final int NOTIFY_TRACK_DATA = 4;
private HandlerThread mHandlerThread;
/** @hide */
@@ -3667,6 +3682,12 @@
}
}
+ private synchronized void notifyTrackData(Pair<SubtitleTrack, byte[]> trackData) {
+ SubtitleTrack track = trackData.first;
+ byte[] data = trackData.second;
+ track.onData(data, true /* eos */, ~0 /* runID: keep forever */);
+ }
+
private synchronized void notifyStop() {
for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
if (listener == null) {
@@ -3899,6 +3920,9 @@
case NOTIFY_SEEK:
notifySeek();
break;
+ case NOTIFY_TRACK_DATA:
+ notifyTrackData((Pair<SubtitleTrack, byte[]>)msg.obj);
+ break;
}
}
}