Bug 1380201 - Make access to some members in GeckoHlsPlayer guarded. draft
authorKilik Kuo <kikuo@mozilla.com>
Thu, 13 Jul 2017 00:39:27 +0800
changeset 607641 c87eead9fcf01c8e3dd2acf2e4cb370d99fab5f7
parent 607639 39c10449f72649e76e04b7325ce1f0d672955d79
child 637102 ae628c8cdb61866f1967130f6a8708097123684f
push id68062
push userbmo:kikuo@mozilla.com
push dateWed, 12 Jul 2017 16:40:39 +0000
bugs1380201
milestone56.0a1
Bug 1380201 - Make access to some members in GeckoHlsPlayer guarded. 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