Bug 1064669 - Initialize MediaPlayers in delayed startup. r=mfinkle, a=sledru
☠☠ backed out by a7a2895b9191 ☠ ☠
authorWes Johnston <wjohnston@mozilla.com>
Fri, 19 Sep 2014 16:55:18 -0700
changeset 225268 27cb26c18799504d3944e620b51cd5b82cbe48bd
parent 225267 9f37e24b19153d303da9278043439012be749849
child 225269 c93ccef3df6438c283829571fd0866a42c16c9a4
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmfinkle, sledru
bugs1064669
milestone34.0a2
Bug 1064669 - Initialize MediaPlayers in delayed startup. r=mfinkle, a=sledru
mobile/android/base/BrowserApp.java
mobile/android/base/GeckoApp.java
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -596,25 +596,16 @@ public class BrowserApp extends GeckoApp
             public void onEnabledChanged(boolean enabled) {
                 setDynamicToolbarEnabled(enabled);
             }
         });
 
         // Set the maximum bits-per-pixel the favicon system cares about.
         IconDirectoryEntry.setMaxBPP(GeckoAppShell.getScreenDepth());
 
-        Class<?> mediaManagerClass = getMediaPlayerManager();
-        if (mediaManagerClass != null) {
-            try {
-                Method init = mediaManagerClass.getMethod("init", Context.class);
-                init.invoke(null, this);
-            } catch(Exception ex) {
-                Log.i(LOGTAG, "Error initializing media manager", ex);
-            }
-        }
     }
 
     private void registerOnboardingReceiver(Context context) {
         final LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
 
         // Receiver for launching first run start pane on new profile creation.
         mOnboardingReceiver = new BroadcastReceiver() {
             @Override
@@ -1417,21 +1408,35 @@ public class BrowserApp extends GeckoApp
                     @Override
                     public void run() {
                         // Force tabs panel inflation once the initial
                         // pageload is finished.
                         ensureTabsPanelExists();
                     }
                 });
 
+                if (AppConstants.MOZ_MEDIA_PLAYER) {
+                    // If casting is disabled, these classes aren't built. We use reflection to initialize them.
+                    Class<?> mediaManagerClass = getMediaPlayerManager();
+                    if (mediaManagerClass != null) {
+                        try {
+                            Method init = mediaManagerClass.getMethod("init", Context.class);
+                            init.invoke(null, this);
+                        } catch(Exception ex) {
+                            Log.e(LOGTAG, "Error initializing media manager", ex);
+                        }
+                    }
+                }
+
                 if (AppConstants.MOZ_STUMBLER_BUILD_TIME_ENABLED) {
                     // Start (this acts as ping if started already) the stumbler lib; if the stumbler has queued data it will upload it.
                     // Stumbler operates on its own thread, and startup impact is further minimized by delaying work (such as upload) a few seconds.
                     GeckoPreferences.broadcastStumblerPref(this);
                 }
+
                 super.handleMessage(event, message);
             } else if (event.equals("Gecko:Ready")) {
                 // Handle this message in GeckoApp, but also enable the Settings
                 // menuitem, which is specific to BrowserApp.
                 super.handleMessage(event, message);
                 final Menu menu = mMenu;
                 ThreadUtils.postToUiThread(new Runnable() {
                     @Override
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -185,16 +185,17 @@ public abstract class GeckoApp
     private HashMap<String, PowerManager.WakeLock> mWakeLocks = new HashMap<String, PowerManager.WakeLock>();
 
     protected boolean mShouldRestore;
     protected boolean mInitialized;
     private Telemetry.Timer mJavaUiStartupTimer;
     private Telemetry.Timer mGeckoReadyStartupTimer;
 
     private String mPrivateBrowsingSession;
+    private volatile boolean mIsPaused = true;
 
     private volatile HealthRecorder mHealthRecorder;
     private volatile Locale mLastLocale;
 
     private EventListener mWebappEventListener;
 
     abstract public int getLayout();
     abstract public boolean hasTabsSideBar();
@@ -240,17 +241,23 @@ public abstract class GeckoApp
         return this;
     }
 
     public View getCameraView() {
         return mCameraView;
     }
 
     public void addAppStateListener(GeckoAppShell.AppStateListener listener) {
+        ThreadUtils.assertOnUiThread();
         mAppStateListeners.add(listener);
+
+        // If we're already resumed, make sure the listener gets a notification.
+        if (!mIsPaused) {
+            listener.onResume();
+        }
     }
 
     public void removeAppStateListener(GeckoAppShell.AppStateListener listener) {
         mAppStateListeners.remove(listener);
     }
 
     public FormAssistPopup getFormAssistPopup() {
         return mFormAssistPopup;
@@ -1939,16 +1946,18 @@ public abstract class GeckoApp
             GeckoAccessibility.updateAccessibilitySettings(this);
         }
 
         if (mAppStateListeners != null) {
             for (GeckoAppShell.AppStateListener listener: mAppStateListeners) {
                 listener.onResume();
             }
         }
+        // Setting this state will force any listeners added after this to have their onResume() method called
+        mIsPaused = false;
 
         // We use two times: a pseudo-unique wall-clock time to identify the
         // current session across power cycles, and the elapsed realtime to
         // track the duration of the session.
         final long now = System.currentTimeMillis();
         final long realTime = android.os.SystemClock.elapsedRealtime();
 
         ThreadUtils.postToBackgroundThread(new Runnable() {
@@ -2015,16 +2024,19 @@ public abstract class GeckoApp
 
                 // In theory, the first browser session will not run long enough that we need to
                 // prune during it and we'd rather run it when the browser is inactive so we wait
                 // until here to register the prune service.
                 GeckoPreferences.broadcastHealthReportPrune(context);
             }
         });
 
+        // Setting this state will keep any listeners registered after this from having their onResume
+        // method called.
+        mIsPaused = true;
         if (mAppStateListeners != null) {
             for(GeckoAppShell.AppStateListener listener: mAppStateListeners) {
                 listener.onPause();
             }
         }
 
         super.onPause();
     }