Bug 1445420 - [2.5] Add default runtime fallback for Fennec and unattached views. r=snorp,jchen
authorEugen Sawin <esawin@mozilla.com>
Thu, 15 Mar 2018 00:34:45 +0100
changeset 457359 37d40aa987f070c0bd9689612c2f8e3f94f54a15
parent 457358 43c585beaad3991ab02f3f93524a42326aec8eb4
child 457360 6db5a47c33a76d099243c7204e37807bab53c3b6
push id153
push userfmarier@mozilla.com
push dateTue, 10 Apr 2018 02:28:40 +0000
reviewerssnorp, jchen
bugs1445420
milestone61.0a1
Bug 1445420 - [2.5] Add default runtime fallback for Fennec and unattached views. r=snorp,jchen
mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java
mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java
@@ -35,16 +35,17 @@ import org.mozilla.gecko.util.EventCallb
 import org.mozilla.gecko.util.FileUtils;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.HardwareUtils;
 import org.mozilla.gecko.util.PrefUtils;
 import org.mozilla.gecko.util.ThreadUtils;
 import org.mozilla.gecko.util.ViewUtil;
 import org.mozilla.gecko.widget.ActionModePresenter;
 import org.mozilla.gecko.widget.AnchoredPopup;
+import org.mozilla.geckoview.GeckoRuntime;
 import org.mozilla.geckoview.GeckoSession;
 import org.mozilla.geckoview.GeckoSessionSettings;
 import org.mozilla.geckoview.GeckoView;
 
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
 import android.annotation.TargetApi;
 import android.app.Activity;
@@ -1074,27 +1075,27 @@ public abstract class GeckoApp extends G
 
         // Set up Gecko layout.
         mRootLayout = (RelativeLayout) findViewById(R.id.root_layout);
         mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout);
         mMainLayout = (RelativeLayout) findViewById(R.id.main_layout);
         mLayerView = (GeckoView) findViewById(R.id.layer_view);
 
         final GeckoSession session = new GeckoSession();
+        session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
+                                        "chrome://browser/content/browser.xul");
+        session.setContentDelegate(this);
+
         // If the view already has a session, we need to ensure it is closed.
         if (mLayerView.getSession() != null) {
             mLayerView.getSession().close();
         }
-        mLayerView.setSession(session);
+        mLayerView.setSession(session, GeckoRuntime.getDefault(this));
         mLayerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
 
-        session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
-                                        "chrome://browser/content/browser.xul");
-        session.setContentDelegate(this);
-
         GeckoAccessibility.setDelegate(mLayerView);
 
         getAppEventDispatcher().registerGeckoThreadListener(this,
             "Locale:Set",
             "PrivateBrowsing:Data",
             null);
 
         getAppEventDispatcher().registerUiThreadListener(this,
--- a/mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/RemotePresentationService.java
@@ -2,16 +2,17 @@
  * vim: ts=4 sw=4 expandtab:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko;
 
 import org.mozilla.gecko.ScreenManagerHelper;
+import org.mozilla.geckoview.GeckoRuntime;
 import org.mozilla.geckoview.GeckoSession;
 import org.mozilla.geckoview.GeckoSessionSettings;
 import org.mozilla.geckoview.GeckoView;
 
 import com.google.android.gms.cast.CastMediaControlIntent;
 import com.google.android.gms.cast.CastPresentation;
 import com.google.android.gms.cast.CastRemoteDisplayLocalService;
 import com.google.android.gms.common.ConnectionResult;
@@ -119,25 +120,24 @@ class VirtualPresentation extends CastPr
         super.onCreate(savedInstanceState);
 
         /*
          * NOTICE: The context get from getContext() is different to the context
          * of the application. Presentaion has its own context to get correct
          * resources.
          */
 
-        // Create new GeckoView
-        view = new GeckoView(getContext());
-
         final GeckoSession session = new GeckoSession();
         session.getSettings().setString(GeckoSessionSettings.CHROME_URI,
                                         PRESENTATION_VIEW_URI + "#" + deviceId);
         session.getSettings().setInt(GeckoSessionSettings.SCREEN_ID, screenId);
 
-        view.setSession(session);
+        // Create new GeckoView
+        view = new GeckoView(getContext());
+        view.setSession(session, GeckoRuntime.getDefault(getContext()));
         view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                                               LayoutParams.MATCH_PARENT));
 
         // Create new layout to put the GeckoView
         layout = new RelativeLayout(getContext());
         layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
                                                 LayoutParams.MATCH_PARENT));
         layout.addView(view);
--- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java
@@ -53,16 +53,17 @@ import org.mozilla.gecko.text.TextSelect
 import org.mozilla.gecko.util.ActivityUtils;
 import org.mozilla.gecko.util.ColorUtil;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.IntentUtils;
 import org.mozilla.gecko.util.PackageUtil;
 import org.mozilla.gecko.webapps.WebApps;
 import org.mozilla.gecko.widget.ActionModePresenter;
 import org.mozilla.gecko.widget.GeckoPopupMenu;
+import org.mozilla.geckoview.GeckoRuntime;
 import org.mozilla.geckoview.GeckoSession;
 import org.mozilla.geckoview.GeckoSessionSettings;
 import org.mozilla.geckoview.GeckoView;
 
 import java.util.List;
 
 public class CustomTabsActivity extends AppCompatActivity
                                 implements ActionModePresenter,
@@ -120,39 +121,38 @@ public class CustomTabsActivity extends 
         actionBarPresenter.displayUrlOnly(intent.getDataString());
         actionBarPresenter.setBackgroundColor(IntentUtil.getToolbarColor(intent), getWindow());
         actionBarPresenter.setTextLongClickListener(new UrlCopyListener());
 
         mGeckoView = (GeckoView) findViewById(R.id.gecko_view);
 
         GeckoAccessibility.setDelegate(mGeckoView);
 
-        mGeckoSession = new GeckoSession();
-        mGeckoView.setSession(mGeckoSession);
-
+        final GeckoSessionSettings settings = new GeckoSessionSettings();
+        settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
+        settings.setBoolean(
+            GeckoSessionSettings.USE_REMOTE_DEBUGGER,
+            GeckoSharedPrefs.forApp(this).getBoolean(
+                GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
+        mGeckoSession = new GeckoSession(settings);
         mGeckoSession.setNavigationDelegate(this);
         mGeckoSession.setProgressDelegate(this);
         mGeckoSession.setContentDelegate(this);
 
+        mGeckoView.setSession(mGeckoSession, GeckoRuntime.getDefault(this));
+
         mPromptService = new PromptService(this, mGeckoView.getEventDispatcher());
         mDoorHangerPopup = new DoorHangerPopup(this, mGeckoView.getEventDispatcher());
 
         mFormAssistPopup = (FormAssistPopup) findViewById(R.id.form_assist_popup);
         mFormAssistPopup.create(mGeckoView);
 
         mTextSelection = TextSelection.Factory.create(mGeckoView, this);
         mTextSelection.create();
 
-        final GeckoSessionSettings settings = mGeckoView.getSettings();
-        settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
-        settings.setBoolean(
-            GeckoSessionSettings.USE_REMOTE_DEBUGGER,
-            GeckoSharedPrefs.forApp(this).getBoolean(
-                GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
-
         if (intent != null && !TextUtils.isEmpty(intent.getDataString())) {
             mGeckoSession.loadUri(intent.getDataString());
         } else {
             Log.w(LOGTAG, "No intend found for custom tab");
             finish();
         }
 
         sendTelemetry();
--- a/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
+++ b/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java
@@ -33,16 +33,17 @@ import org.mozilla.gecko.preferences.Gec
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.customtabs.CustomTabsActivity;
 import org.mozilla.gecko.permissions.Permissions;
 import org.mozilla.gecko.prompts.PromptService;
 import org.mozilla.gecko.text.TextSelection;
 import org.mozilla.gecko.util.ActivityUtils;
 import org.mozilla.gecko.util.ColorUtil;
 import org.mozilla.gecko.widget.ActionModePresenter;
+import org.mozilla.geckoview.GeckoRuntime;
 import org.mozilla.geckoview.GeckoSession;
 import org.mozilla.geckoview.GeckoSessionSettings;
 import org.mozilla.geckoview.GeckoView;
 
 public class WebAppActivity extends AppCompatActivity
                             implements ActionModePresenter,
                                        GeckoSession.ContentDelegate,
                                        GeckoSession.NavigationDelegate {
@@ -86,18 +87,24 @@ public class WebAppActivity extends AppC
             Intent lastLaunchIntent = savedInstanceState.getParcelable(SAVED_INTENT);
             setIntent(lastLaunchIntent);
         }
 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.webapp_activity);
         mGeckoView = (GeckoView) findViewById(R.id.pwa_gecko_view);
 
-        mGeckoSession = new GeckoSession();
-        mGeckoView.setSession(mGeckoSession);
+        final GeckoSessionSettings settings = new GeckoSessionSettings();
+        settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
+        settings.setBoolean(
+            GeckoSessionSettings.USE_REMOTE_DEBUGGER,
+            GeckoSharedPrefs.forApp(this).getBoolean(
+                GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
+        mGeckoSession = new GeckoSession(settings);
+        mGeckoView.setSession(mGeckoSession, GeckoRuntime.getDefault(this));
 
         mGeckoSession.setNavigationDelegate(this);
         mGeckoSession.setContentDelegate(this);
         mGeckoSession.setProgressDelegate(new GeckoSession.ProgressDelegate() {
             @Override
             public void onPageStart(GeckoSession session, String url) {
 
             }
@@ -142,23 +149,16 @@ public class WebAppActivity extends AppC
         mDoorHangerPopup = new DoorHangerPopup(this, mGeckoView.getEventDispatcher());
 
         mFormAssistPopup = (FormAssistPopup) findViewById(R.id.pwa_form_assist_popup);
         mFormAssistPopup.create(mGeckoView);
 
         mTextSelection = TextSelection.Factory.create(mGeckoView, this);
         mTextSelection.create();
 
-        final GeckoSessionSettings settings = mGeckoView.getSettings();
-        settings.setBoolean(GeckoSessionSettings.USE_MULTIPROCESS, false);
-        settings.setBoolean(
-            GeckoSessionSettings.USE_REMOTE_DEBUGGER,
-            GeckoSharedPrefs.forApp(this).getBoolean(
-                GeckoPreferences.PREFS_DEVTOOLS_REMOTE_USB_ENABLED, false));
-
         try {
             mManifest = WebAppManifest.fromFile(getIntent().getStringExtra(MANIFEST_URL),
                                                 getIntent().getStringExtra(MANIFEST_PATH));
         } catch (Exception e) {
             Log.w(LOGTAG, "Cannot retrieve manifest, launching in Firefox:" + e);
             fallbackToFennec(null);
             return;
         }
@@ -315,17 +315,17 @@ public class WebAppActivity extends AppC
                 mode = GeckoSessionSettings.DISPLAY_MODE_MINIMAL_UI;
                 break;
             case "browser":
             default:
                 mode = GeckoSessionSettings.DISPLAY_MODE_BROWSER;
                 break;
         }
 
-        mGeckoView.getSettings().setInt(GeckoSessionSettings.DISPLAY_MODE, mode);
+        mGeckoSession.getSettings().setInt(GeckoSessionSettings.DISPLAY_MODE, mode);
     }
 
     @Override // GeckoSession.NavigationDelegate
     public void onLocationChange(GeckoSession session, String url) {
     }
 
     @Override // GeckoSession.NavigationDelegate
     public void onCanGoBack(GeckoSession session, boolean canGoBack) {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
@@ -24,16 +24,39 @@ import org.mozilla.gecko.util.BundleEven
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 import org.mozilla.gecko.util.ThreadUtils;
 
 public final class GeckoRuntime implements Parcelable {
     private static final String LOGTAG = "GeckoRuntime";
     private static final boolean DEBUG = false;
 
+    private static GeckoRuntime sDefaultRuntime;
+
+    /**
+     * Get the default runtime for the given context.
+     * This will create and initialize the runtime with the default settings.
+     *
+     * Note: Only use this for session-less apps.
+     *       For regular apps, use create() and createSession() instead.
+     *
+     * @return The (static) default runtime for the context.
+     */
+    public static synchronized @NonNull GeckoRuntime getDefault(
+            final @NonNull Context context) {
+        Log.d(LOGTAG, "getDefault");
+        if (sDefaultRuntime == null) {
+            sDefaultRuntime = new GeckoRuntime();
+            sDefaultRuntime.attachTo(context);
+            sDefaultRuntime.init(new GeckoRuntimeSettings());
+        }
+
+        return sDefaultRuntime;
+    }
+
     private GeckoRuntimeSettings mSettings;
 
     /**
      * Attach the runtime to the given context.
      *
      * @param context The new context to attach to.
      */
     public void attachTo(final @NonNull Context context) {
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoView.java
@@ -300,36 +300,32 @@ public class GeckoView extends FrameLayo
     public GeckoSession getSession() {
         return mSession;
     }
 
     public EventDispatcher getEventDispatcher() {
         return mSession.getEventDispatcher();
     }
 
-    public GeckoSessionSettings getSettings() {
-        return mSession.getSettings();
-    }
-
     public PanZoomController getPanZoomController() {
         return mSession.getPanZoomController();
     }
 
     public DynamicToolbarAnimator getDynamicToolbarAnimator() {
         return mSession.getDynamicToolbarAnimator();
     }
 
     @Override
     public void onAttachedToWindow() {
         if (mSession == null) {
-            setSession(new GeckoSession());
+            setSession(new GeckoSession(), GeckoRuntime.getDefault(getContext()));
         }
 
         if (!mSession.isOpen()) {
-            mSession.open(getContext().getApplicationContext());
+            mSession.open(mRuntime);
         }
 
         mSession.getTextInput().setView(this);
 
         super.onAttachedToWindow();
     }
 
     @Override
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -129,17 +129,17 @@ public class GeckoViewActivity extends A
     }
 
     private void loadFromIntent(final Intent intent) {
         final Uri uri = intent.getData();
         mGeckoSession.loadUri(uri != null ? uri.toString() : DEFAULT_URL);
     }
 
     private void loadSettings(final Intent intent) {
-        final GeckoSessionSettings settings = mGeckoView.getSettings();
+        final GeckoSessionSettings settings = mGeckoSession.getSettings();
         settings.setBoolean(
             GeckoSessionSettings.USE_REMOTE_DEBUGGER,
             intent.getBooleanExtra(USE_REMOTE_DEBUGGER_EXTRA, false));
 
         Log.i(LOGTAG, "Load with settings " + settings);
     }
 
     @Override