From ed78114ffdd9e7fdd2c3b804a4359ae28fa38019 Mon Sep 17 00:00:00 2001 From: Robert Shih Date: Thu, 26 May 2016 14:02:51 -0700 Subject: [PATCH] Fix deadlock when showing subtitles MediaPlayer Move all SubtitleTrack operations to TimeProvider's event handler thread. Bug: 28784397 Change-Id: Iff848635390e99ffb19add03277a9d62feece4cc --- media/java/android/media/MediaPlayer.java | 28 +++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index cee7d60a9f368..3f6081bf183d9 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -2276,6 +2276,8 @@ public class MediaPlayer extends PlayerBase 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 @@ public class MediaPlayer extends PlayerBase synchronized (mIndexTrackPairs) { mIndexTrackPairs.add(Pair.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 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 @@ public class MediaPlayer extends PlayerBase mIndexTrackPairs.add(Pair.create(null, track)); } + getMediaTimeProvider(); + final FileDescriptor fd3 = fd2; final long offset2 = offset; final long length2 = length; @@ -2526,7 +2535,12 @@ public class MediaPlayer extends PlayerBase 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 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 @@ public class MediaPlayer extends PlayerBase 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 @@ public class MediaPlayer extends PlayerBase } } + private synchronized void notifyTrackData(Pair 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 @@ public class MediaPlayer extends PlayerBase case NOTIFY_SEEK: notifySeek(); break; + case NOTIFY_TRACK_DATA: + notifyTrackData((Pair)msg.obj); + break; } } }