Bug 1085591: Move most initialization off of onWindowFocusChanged; r=mhaigh
authorGeoff Brown <gbrown@mozilla.com>
Thu, 02 Jul 2015 15:24:29 -0600
changeset 251197 fa4e7b0b946bba1f64cee3edafe420a2dfcb80a1
parent 251196 85c8317aeb3742ded4e8d445e7d71299bd94ceed
child 251198 48abf470ef5b50ab1e8d1229a866c29adf130622
push id61793
push usergbrown@mozilla.com
push dateThu, 02 Jul 2015 21:24:35 +0000
treeherdermozilla-inbound@fa4e7b0b946b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmhaigh
bugs1085591
milestone42.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 1085591: Move most initialization off of onWindowFocusChanged; r=mhaigh
mobile/android/base/GeckoApp.java
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -82,16 +82,17 @@ import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.OrientationEventListener;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewStub;
+import android.view.ViewTreeObserver;
 import android.view.Window;
 import android.widget.AbsoluteLayout;
 import android.widget.FrameLayout;
 import android.widget.ListView;
 import android.widget.RelativeLayout;
 import android.widget.SimpleAdapter;
 import android.widget.TextView;
 import android.widget.Toast;
@@ -120,17 +121,18 @@ public abstract class GeckoApp
     ContextGetter,
     GeckoAppShell.GeckoInterface,
     GeckoEventListener,
     GeckoMenu.Callback,
     GeckoMenu.MenuPresenter,
     LocationListener,
     NativeEventListener,
     SensorEventListener,
-    Tabs.OnTabsChangedListener {
+    Tabs.OnTabsChangedListener,
+    ViewTreeObserver.OnGlobalLayoutListener {
 
     private static final String LOGTAG = "GeckoApp";
     private static final int ONE_DAY_MS = 1000*60*60*24;
 
     private static enum StartupAction {
         NORMAL,     /* normal application start */
         URL,        /* launched with a passed URL */
         PREFETCH    /* launched with a passed URL that we prefetch */
@@ -184,16 +186,17 @@ public abstract class GeckoApp
 
     private FullScreenHolder mFullScreenPluginContainer;
     private View mFullScreenPluginView;
 
     private final HashMap<String, PowerManager.WakeLock> mWakeLocks = new HashMap<String, PowerManager.WakeLock>();
 
     protected boolean mShouldRestore;
     protected boolean mInitialized;
+    protected boolean mWindowFocusInitialized;
     private Telemetry.Timer mJavaUiStartupTimer;
     private Telemetry.Timer mGeckoReadyStartupTimer;
 
     private String mPrivateBrowsingSession;
 
     private volatile HealthRecorder mHealthRecorder;
     private volatile Locale mLastLocale;
 
@@ -1276,16 +1279,19 @@ public abstract class GeckoApp
         setContentView(getLayout());
 
         // Set up Gecko layout.
         mRootLayout = (OuterLayout) findViewById(R.id.root_layout);
         mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
         mMainLayout = (RelativeLayout) findViewById(R.id.main_layout);
         mLayerView = (LayerView) findViewById(R.id.layer_view);
 
+        // Use global layout state change to kick off additional initialization
+        mMainLayout.getViewTreeObserver().addOnGlobalLayoutListener(this);
+
         // Determine whether we should restore tabs.
         mShouldRestore = getSessionRestoreState(savedInstanceState);
         if (mShouldRestore && savedInstanceState != null) {
             boolean wasInBackground =
                 savedInstanceState.getBoolean(SAVED_STATE_IN_BACKGROUND, false);
 
             // Don't log OOM-kills if only one activity was destroyed. (For example
             // from "Don't keep activities" on ICS)
@@ -1413,23 +1419,16 @@ public abstract class GeckoApp
 
         if (mCameraView == null) {
             // Pre-ICS devices need the camera surface in a visible layout.
             if (Versions.preICS) {
                 mCameraView = new SurfaceView(this);
                 ((SurfaceView)mCameraView).getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
             }
         }
-
-        // XXX our editor tests require the GeckoView to have focus to pass, so we have to
-        // manually shift focus to the GeckoView. requestFocus apparently doesn't work at
-        // this stage of starting up, so we have to unset and reset the focusability.
-        mLayerView.setFocusable(false);
-        mLayerView.setFocusable(true);
-        mLayerView.setFocusableInTouchMode(true);
     }
 
     /**
      * Loads the initial tab at Fennec startup. If we don't restore tabs, this
      * tab will be about:home. If we restore tabs, we don't need to create a new tab.
      */
     protected void loadStartupTabWithAboutHome(final int flags) {
         if (!mShouldRestore) {
@@ -1612,16 +1611,28 @@ public abstract class GeckoApp
 
         if (ACTION_ALERT_CALLBACK.equals(action)) {
             processAlertCallback(intent);
         } else if (NotificationHelper.HELPER_BROADCAST_ACTION.equals(action)) {
             NotificationHelper.getInstance(getApplicationContext()).handleNotificationIntent(intent);
         }
     }
 
+    @Override
+    public void onGlobalLayout() {
+        if (Versions.preJB) {
+            mMainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
+        } else {
+            mMainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+        }
+        if (!mInitialized) {
+            initialize();
+        }
+    }
+
     protected void processActionViewIntent(final Runnable openTabsRunnable) {
         // We need to ensure that if we receive a VIEW action and there are tabs queued then the
         // site loaded from the intent is on top (last loaded) and selected with all other tabs
         // being opened behind it. We process the tab queue first and request a callback from the JS - the
         // listener will open the url from the intent as normal when the tab queue has been processed.
         ThreadUtils.postToBackgroundThread(new Runnable() {
             @Override
             public void run() {
@@ -1948,18 +1959,24 @@ public abstract class GeckoApp
             }
         });
     }
 
     @Override
     public void onWindowFocusChanged(boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
 
-        if (!mInitialized && hasFocus) {
-            initialize();
+        if (!mWindowFocusInitialized && hasFocus) {
+            mWindowFocusInitialized = true;
+            // XXX our editor tests require the GeckoView to have focus to pass, so we have to
+            // manually shift focus to the GeckoView. requestFocus apparently doesn't work at
+            // this stage of starting up, so we have to unset and reset the focusability.
+            mLayerView.setFocusable(false);
+            mLayerView.setFocusable(true);
+            mLayerView.setFocusableInTouchMode(true);
             getWindow().setBackgroundDrawable(null);
         }
     }
 
     @Override
     public void onPause()
     {
         final HealthRecorder rec = mHealthRecorder;