Bug 1380201 - Make access to some members in GeckoHlsPlayer guarded. r=JamesCheng
authorKilik Kuo <kikuo@mozilla.com>
Thu, 13 Jul 2017 00:39:27 +0800
changeset 368515 835d645c14f001fc4ad1e350b656203bfa76fcca
parent 368514 15707ac8813f9a79c063e9bb90d8bd4a05daa03a
child 368516 b78777da01e8378072ea647da1bc29b95ac21232
push id32164
push userkwierso@gmail.com
push dateThu, 13 Jul 2017 00:58:33 +0000
treeherdermozilla-central@30ea2905130e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersJamesCheng
bugs1380201
milestone56.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1380201 - Make access to some members in GeckoHlsPlayer guarded. r=JamesCheng MozReview-Commit-ID: 689pXP35NoS
mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/BaseHlsPlayer.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHLSResourceWrapper.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsPlayer.java
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/BaseHlsPlayer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/BaseHlsPlayer.java
@@ -56,19 +56,17 @@ public interface BaseHlsPlayer {
     }
 
     // Used to identify player instance.
     public int getId();
 
     // =======================================================================
     // API for GeckoHLSResourceWrapper
     // =======================================================================
-    public void addResourceWrapperCallbackListener(ResourceCallbacks callback);
-
-    public void init(String url);
+    public void init(String url, ResourceCallbacks callback);
 
     public boolean isLiveStream();
 
     // =======================================================================
     // API for GeckoHLSDemuxerWrapper
     // =======================================================================
     public void addDemuxerWrapperCallbackListener(DemuxerCallbacks callback);
 
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHLSResourceWrapper.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHLSResourceWrapper.java
@@ -37,18 +37,17 @@ public class GeckoHLSResourceWrapper {
 
     private GeckoHLSResourceWrapper(String url,
                                     BaseHlsPlayer.ResourceCallbacks callback) {
         if (DEBUG) Log.d(LOGTAG, "GeckoHLSResourceWrapper created with url = " + url);
         assertTrue(callback != null);
 
         mPlayer = GeckoPlayerFactory.getPlayer();
         try {
-            mPlayer.addResourceWrapperCallbackListener(callback);
-            mPlayer.init(url);
+            mPlayer.init(url, callback);
         } catch (Exception e) {
             Log.e(LOGTAG, "Failed to create GeckoHlsResourceWrapper !", e);
             callback.onError(BaseHlsPlayer.ResourceError.UNKNOWN.code());
         }
     }
 
     @WrapForJNI(calledFrom = "gecko")
     public static GeckoHLSResourceWrapper create(String url,
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsPlayer.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/media/GeckoHlsPlayer.java
@@ -94,20 +94,27 @@ public class GeckoHlsPlayer implements B
     // Provide statistical information of tracks.
     private class HlsMediaTracksInfo {
         private int mNumVideoTracks = 0;
         private int mNumAudioTracks = 0;
         private boolean mVideoInfoUpdated = false;
         private boolean mAudioInfoUpdated = false;
         private boolean mVideoDataArrived = false;
         private boolean mAudioDataArrived = false;
-        HlsMediaTracksInfo(int numVideoTracks, int numAudioTracks) {
-            this.mNumVideoTracks = numVideoTracks;
-            this.mNumAudioTracks = numAudioTracks;
+        HlsMediaTracksInfo() {}
+        public void reset() {
+            mNumVideoTracks = 0;
+            mNumAudioTracks = 0;
+            mVideoInfoUpdated = false;
+            mAudioInfoUpdated = false;
+            mVideoDataArrived = false;
+            mAudioDataArrived = false;
         }
+        public void updateNumOfVideoTracks(int numOfTracks) { mNumVideoTracks = numOfTracks; }
+        public void updateNumOfAudioTracks(int numOfTracks) { mNumAudioTracks = numOfTracks; }
         public boolean hasVideo() { return mNumVideoTracks > 0; }
         public boolean hasAudio() { return mNumAudioTracks > 0; }
         public int getNumOfVideoTracks() { return mNumVideoTracks; }
         public int getNumOfAudioTracks() { return mNumAudioTracks; }
         public void onVideoInfoUpdated() { mVideoInfoUpdated = true; }
         public void onAudioInfoUpdated() { mAudioInfoUpdated = true; }
         public void onDataArrived(int trackType) {
             if (trackType == C.TRACK_TYPE_VIDEO) {
@@ -118,17 +125,17 @@ public class GeckoHlsPlayer implements B
         }
         public boolean videoReady() {
             return !hasVideo() || (mVideoInfoUpdated && mVideoDataArrived);
         }
         public boolean audioReady() {
             return !hasAudio() || (mAudioInfoUpdated && mAudioDataArrived);
         }
     }
-    private HlsMediaTracksInfo mTracksInfo = null;
+    private HlsMediaTracksInfo mTracksInfo = new HlsMediaTracksInfo();
 
     private boolean mIsPlayerInitDone = false;
     private boolean mIsDemuxerInitDone = false;
 
     private BaseHlsPlayer.DemuxerCallbacks mDemuxerCallbacks;
     private BaseHlsPlayer.ResourceCallbacks mResourceCallbacks;
 
     private static void assertTrue(boolean condition) {
@@ -157,53 +164,47 @@ public class GeckoHlsPlayer implements B
         }
     }
 
     public final class ComponentEventDispatcher {
         // Called on GeckoHlsPlayerThread from GeckoHls{Audio,Video}Renderer/ExoPlayer
         public void onDataArrived(final int trackType) {
             assertTrue(mMainHandler != null);
             assertTrue(mComponentListener != null);
-            if (!mIsPlayerInitDone) {
-                return;
-            }
+
             if (mMainHandler != null && mComponentListener != null) {
                 mMainHandler.post(new Runnable() {
                     @Override
                     public void run() {
                         mComponentListener.onDataArrived(trackType);
                     }
                 });
             }
         }
 
         // Called on GeckoHlsPlayerThread from GeckoHls{Audio,Video}Renderer
         public void onVideoInputFormatChanged(final Format format) {
             assertTrue(mMainHandler != null);
             assertTrue(mComponentListener != null);
-            if (!mIsPlayerInitDone) {
-                return;
-            }
+
             if (mMainHandler != null && mComponentListener != null) {
                 mMainHandler.post(new Runnable() {
                     @Override
                     public void run() {
                         mComponentListener.onVideoInputFormatChanged(format);
                     }
                 });
             }
         }
 
         // Called on GeckoHlsPlayerThread from GeckoHls{Audio,Video}Renderer
         public void onAudioInputFormatChanged(final Format format) {
             assertTrue(mMainHandler != null);
             assertTrue(mComponentListener != null);
-            if (!mIsPlayerInitDone) {
-                return;
-            }
+
             if (mMainHandler != null && mComponentListener != null) {
                 mMainHandler.post(new Runnable() {
                     @Override
                     public void run() {
                         mComponentListener.onAudioInputFormatChanged(format);
                     }
                 });
             }
@@ -215,68 +216,48 @@ public class GeckoHlsPlayer implements B
         // General purpose implementation
         // Called on GeckoHlsPlayerThread
         public void onDataArrived(int trackType) {
             synchronized (GeckoHlsPlayer.this) {
                 if (DEBUG) { Log.d(LOGTAG, "[CB][onDataArrived] id " + mPlayerId); }
                 if (!mIsPlayerInitDone) {
                     return;
                 }
-                assertTrue(mResourceCallbacks != null);
-                assertTrue(mTracksInfo != null);
-
-                if (mTracksInfo == null || mResourceCallbacks == null) {
-                    Log.e(LOGTAG, "Encounter an abnormal calling sequence.");
-                    return;
-                }
                 mTracksInfo.onDataArrived(trackType);
                 mResourceCallbacks.onDataArrived();
-
                 checkInitDone();
             }
         }
 
         // Called on GeckoHlsPlayerThread
         public void onVideoInputFormatChanged(Format format) {
             synchronized (GeckoHlsPlayer.this) {
                 if (DEBUG) {
                     Log.d(LOGTAG, "[CB] onVideoInputFormatChanged [" + format + "]");
                     Log.d(LOGTAG, "[CB] SampleMIMEType [" +
                             format.sampleMimeType + "], ContainerMIMEType [" +
                             format.containerMimeType + "], id : " + mPlayerId);
                 }
                 if (!mIsPlayerInitDone) {
                     return;
                 }
-                assertTrue(mTracksInfo != null);
-
-                if (mTracksInfo == null) {
-                    Log.e(LOGTAG, "Encounter a abnormal calling sequence. mTracksInfo is null");
-                    return;
-                }
                 mTracksInfo.onVideoInfoUpdated();
                 checkInitDone();
             }
         }
 
         // Called on GeckoHlsPlayerThread
         public void onAudioInputFormatChanged(Format format) {
             synchronized (GeckoHlsPlayer.this) {
                 if (DEBUG) {
                     Log.d(LOGTAG, "[CB] onAudioInputFormatChanged [" + format + "], mPlayerId :" + mPlayerId);
                 }
                 if (!mIsPlayerInitDone) {
                     return;
                 }
-                assertTrue(mTracksInfo != null);
-
-                if (mTracksInfo == null) {
-                    Log.e(LOGTAG, "Encounter a abnormal calling sequence. mTracksInfo is null");
-                    return;
-                }
                 mTracksInfo.onAudioInfoUpdated();
                 checkInitDone();
             }
         }
     }
 
     private DataSource.Factory buildDataSourceFactory(Context ctx, DefaultBandwidthMeter bandwidthMeter) {
         return new DefaultDataSourceFactory(ctx, bandwidthMeter,
@@ -316,24 +297,17 @@ public class GeckoHlsPlayer implements B
     // Called on Gecko's main thread
     @Override
     public int getId() {
         return mPlayerId;
     }
 
     // Called on Gecko's main thread
     @Override
-    public void addResourceWrapperCallbackListener(BaseHlsPlayer.ResourceCallbacks callback) {
-        if (DEBUG) { Log.d(LOGTAG, " addResourceWrapperCallbackListener ..."); }
-        mResourceCallbacks = callback;
-    }
-
-    // Called on Gecko's main thread
-    @Override
-    public void addDemuxerWrapperCallbackListener(BaseHlsPlayer.DemuxerCallbacks callback) {
+    public synchronized void addDemuxerWrapperCallbackListener(BaseHlsPlayer.DemuxerCallbacks callback) {
         if (DEBUG) { Log.d(LOGTAG, " addDemuxerWrapperCallbackListener ..."); }
         mDemuxerCallbacks = callback;
     }
 
     // Called on GeckoHlsPlayerThread from ExoPlayer
     @Override
     public synchronized void onLoadingChanged(boolean isLoading) {
         if (DEBUG) { Log.d(LOGTAG, "loading [" + isLoading + "]"); }
@@ -433,17 +407,17 @@ public class GeckoHlsPlayer implements B
                                 ", supported=" + formatSupport);
                     }
                     Log.d(LOGTAG, "    ]");
                 }
                 Log.d(LOGTAG, "  ]");
             }
             Log.d(LOGTAG, "]");
         }
-        mTracksInfo = null;
+        mTracksInfo.reset();
         int numVideoTracks = 0;
         int numAudioTracks = 0;
         for (int j = 0; j < ignored.length; j++) {
             TrackGroup tg = ignored.get(j);
             for (int i = 0; i < tg.length; i++) {
                 Format fmt = tg.getFormat(i);
                 if (fmt.sampleMimeType != null) {
                     if (mRendererController.isVideoRendererEnabled() &&
@@ -451,17 +425,18 @@ public class GeckoHlsPlayer implements B
                         numVideoTracks++;
                     } else if (mRendererController.isAudioRendererEnabled() &&
                                fmt.sampleMimeType.startsWith(new String("audio"))) {
                         numAudioTracks++;
                     }
                 }
             }
         }
-        mTracksInfo = new HlsMediaTracksInfo(numVideoTracks, numAudioTracks);
+        mTracksInfo.updateNumOfVideoTracks(numVideoTracks);
+        mTracksInfo.updateNumOfAudioTracks(numAudioTracks);
     }
 
     // Called on GeckoHlsPlayerThread from ExoPlayer
     @Override
     public synchronized void onTimelineChanged(Timeline timeline, Object manifest) {
         // For now, we use the interface ExoPlayer.getDuration() for gecko,
         // so here we create local variable 'window' & 'peroid' to obtain
         // the dynamic duration.
@@ -586,21 +561,22 @@ public class GeckoHlsPlayer implements B
         mPlayer.prepare(mMediaSource);
         mIsPlayerInitDone = true;
     }
     // =======================================================================
     // API for GeckoHLSResourceWrapper
     // =======================================================================
     // Called on Gecko Main Thread
     @Override
-    public synchronized void init(final String url) {
+    public synchronized void init(final String url, BaseHlsPlayer.ResourceCallbacks callback) {
         if (DEBUG) { Log.d(LOGTAG, " init"); }
-        assertTrue(mResourceCallbacks != null);
+        assertTrue(callback != null);
         assertTrue(!mIsPlayerInitDone);
 
+        mResourceCallbacks = callback;
         mThread = new HandlerThread("GeckoHlsPlayerThread");
         mThread.start();
         mMainHandler = new Handler(mThread.getLooper());
 
         mMainHandler.post(new Runnable() {
             @Override
             public void run() {
                 createExoPlayer(url);
@@ -639,32 +615,29 @@ public class GeckoHlsPlayer implements B
         if (DEBUG) { Log.d(LOGTAG, "getBufferedPosition : " + bufferedPos + "(Us)"); }
         return bufferedPos;
     }
 
     // Called on MFR's TaskQueue
     @Override
     public synchronized int getNumberOfTracks(TrackType trackType) {
         if (DEBUG) { Log.d(LOGTAG, "getNumberOfTracks : type " + trackType); }
-        assertTrue(mTracksInfo != null);
-
         if (trackType == TrackType.VIDEO) {
             return mTracksInfo.getNumOfVideoTracks();
         } else if (trackType == TrackType.AUDIO) {
             return mTracksInfo.getNumOfAudioTracks();
         }
         return 0;
     }
 
     // Called on MFR's TaskQueue
     @Override
-    public GeckoVideoInfo getVideoInfo(int index) {
+    public synchronized GeckoVideoInfo getVideoInfo(int index) {
         if (DEBUG) { Log.d(LOGTAG, "getVideoInfo"); }
         assertTrue(mVRenderer != null);
-        assertTrue(mTracksInfo != null);
         if (!mTracksInfo.hasVideo()) {
             return null;
         }
         Format fmt = mVRenderer.getFormat(index);
         if (fmt == null) {
             return null;
         }
         GeckoVideoInfo vInfo = new GeckoVideoInfo(fmt.width, fmt.height,
@@ -672,20 +645,19 @@ public class GeckoHlsPlayer implements B
                                                   fmt.rotationDegrees, fmt.stereoMode,
                                                   getDuration(), fmt.sampleMimeType,
                                                   null, null);
         return vInfo;
     }
 
     // Called on MFR's TaskQueue
     @Override
-    public GeckoAudioInfo getAudioInfo(int index) {
+    public synchronized GeckoAudioInfo getAudioInfo(int index) {
         if (DEBUG) { Log.d(LOGTAG, "getAudioInfo"); }
         assertTrue(mARenderer != null);
-        assertTrue(mTracksInfo != null);
         if (!mTracksInfo.hasAudio()) {
             return null;
         }
         Format fmt = mARenderer.getFormat(index);
         if (fmt == null) {
             return null;
         }
         /* According to https://github.com/google/ExoPlayer/blob