Bug 1322576 - [5.3] Make GeckoView settings accessible through nsIAndroidView. r=jchen
authorEugen Sawin <esawin@mozilla.com>
Fri, 17 Feb 2017 00:26:20 +0100
changeset 344304 6cf3a4f98a622d3c1b40a24d3ae9f486339f8b1c
parent 344303 fb8a931adf8e834ded30116a5bf193c333f33405
child 344305 31ca9ebd033a6b88c3b03357491b602fe588512c
push id31406
push userkwierso@gmail.com
push dateWed, 22 Feb 2017 23:01:18 +0000
treeherdermozilla-central@32dcdde1fc64 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjchen
bugs1322576
milestone54.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 1322576 - [5.3] Make GeckoView settings accessible through nsIAndroidView. r=jchen
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
mobile/android/modules/GeckoViewModule.jsm
widget/android/EventDispatcher.cpp
widget/android/EventDispatcher.h
widget/android/GeneratedJNIWrappers.h
widget/android/nsIAndroidBridge.idl
widget/android/nsWindow.cpp
widget/android/nsWindow.h
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java
@@ -57,18 +57,20 @@ public class GeckoView extends LayerView
     protected String chromeURI;
     protected int screenId = 0; // default to the primary screen
 
     @WrapForJNI(dispatchTo = "proxy")
     protected static final class Window extends JNIObject {
         @WrapForJNI(skip = true)
         /* package */ Window() {}
 
-        static native void open(Window instance, GeckoView view, Object compositor,
-                                EventDispatcher dispatcher, String chromeURI, int screenId);
+        static native void open(Window instance, GeckoView view,
+                                Object compositor, EventDispatcher dispatcher,
+                                String chromeURI, GeckoBundle settings,
+                                int screenId);
 
         @Override protected native void disposeNative();
         native void close();
         native void reattach(GeckoView view, Object compositor, EventDispatcher dispatcher);
         native void loadUri(String uri, int flags);
     }
 
     // Object to hold onto our nsWindow connection when GeckoView gets destroyed.
@@ -226,22 +228,27 @@ public class GeckoView extends LayerView
 
     protected void openWindow() {
         if (chromeURI == null) {
             chromeURI = getGeckoInterface().getDefaultChromeURI();
         }
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             Window.open(window, this, getCompositor(), eventDispatcher,
-                        chromeURI, screenId);
+                        chromeURI, mSettings.asBundle(), screenId);
         } else {
-            GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY, Window.class,
-                    "open", window, GeckoView.class, this, Object.class, getCompositor(),
-                    EventDispatcher.class, eventDispatcher,
-                    String.class, chromeURI, screenId);
+            GeckoThread.queueNativeCallUntil(
+                GeckoThread.State.PROFILE_READY,
+                Window.class, "open", window,
+                GeckoView.class, this,
+                Object.class, getCompositor(),
+                EventDispatcher.class, eventDispatcher,
+                String.class, chromeURI,
+                GeckoBundle.class, mSettings.asBundle(),
+                screenId);
         }
     }
 
     protected void reattachWindow() {
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             window.reattach(this, getCompositor(), eventDispatcher);
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
--- a/mobile/android/modules/GeckoViewModule.jsm
+++ b/mobile/android/modules/GeckoViewModule.jsm
@@ -32,15 +32,15 @@ class GeckoViewModule {
   // Override this with module initialization.
   init() {}
 
   // Called when settings have changed. Access settings via this.settings.
   onSettingsUpdate() {}
 
   get settings() {
     let view = this.window.arguments[0].QueryInterface(Ci.nsIAndroidView);
-    return view.settings;
+    return Object.freeze(view.settings);
   }
 
   get messageManager() {
     return this.browser.messageManager;
   }
 }
--- a/widget/android/EventDispatcher.cpp
+++ b/widget/android/EventDispatcher.cpp
@@ -961,10 +961,18 @@ EventDispatcher::DispatchToGecko(jni::St
     if (aCallback) {
         callback = new JavaCallbackDelegate(
                 java::EventCallback::Ref::From(aCallback));
     }
 
     DispatchOnGecko(list, event, data, callback);
 }
 
+/* static */
+nsresult
+EventDispatcher::UnboxBundle(JSContext* aCx, jni::Object::Param aData,
+                             JS::MutableHandleValue aOut)
+{
+    return detail::UnboxBundle(aCx, aData, aOut);
+}
+
 } // namespace widget
 } // namespace mozilla
--- a/widget/android/EventDispatcher.h
+++ b/widget/android/EventDispatcher.h
@@ -43,16 +43,20 @@ public:
 
     using NativesBase::DisposeNative;
 
     bool HasGeckoListener(jni::String::Param aEvent);
     void DispatchToGecko(jni::String::Param aEvent,
                          jni::Object::Param aData,
                          jni::Object::Param aCallback);
 
+    static nsresult UnboxBundle(JSContext* aCx,
+                                const jni::Object::Param aData,
+                                JS::MutableHandleValue aOut);
+
 private:
     java::EventDispatcher::GlobalRef mDispatcher;
     nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow;
 
     virtual ~EventDispatcher() {}
 
     struct ListenersList {
         nsCOMArray<nsIAndroidEventListener> listeners{/* count */ 1};
--- a/widget/android/GeneratedJNIWrappers.h
+++ b/widget/android/GeneratedJNIWrappers.h
@@ -3014,20 +3014,21 @@ public:
         typedef void ReturnType;
         typedef void SetterType;
         typedef mozilla::jni::Args<
                 Window::Param,
                 GeckoView::Param,
                 mozilla::jni::Object::Param,
                 mozilla::jni::Object::Param,
                 mozilla::jni::String::Param,
+                mozilla::jni::Object::Param,
                 int32_t> Args;
         static constexpr char name[] = "open";
         static constexpr char signature[] =
-                "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Lorg/mozilla/gecko/EventDispatcher;Ljava/lang/String;I)V";
+                "(Lorg/mozilla/gecko/GeckoView$Window;Lorg/mozilla/gecko/GeckoView;Ljava/lang/Object;Lorg/mozilla/gecko/EventDispatcher;Ljava/lang/String;Lorg/mozilla/gecko/util/GeckoBundle;I)V";
         static const bool isStatic = true;
         static const mozilla::jni::ExceptionMode exceptionMode =
                 mozilla::jni::ExceptionMode::ABORT;
         static const mozilla::jni::CallingThread callingThread =
                 mozilla::jni::CallingThread::ANY;
         static const mozilla::jni::DispatchTarget dispatchTarget =
                 mozilla::jni::DispatchTarget::PROXY;
     };
--- a/widget/android/nsIAndroidBridge.idl
+++ b/widget/android/nsIAndroidBridge.idl
@@ -60,16 +60,17 @@ interface nsIAndroidEventDispatcher : ns
   [implicit_jscontext]
   void unregisterListener(in nsIAndroidEventListener listener,
                           in jsval events);
 };
 
 [scriptable, uuid(60a78a94-6117-432f-9d49-304913a931c5)]
 interface nsIAndroidView : nsIAndroidEventDispatcher
 {
+  [implicit_jscontext] readonly attribute jsval settings;
 };
 
 [scriptable, uuid(1beb70d3-70f3-4742-98cc-a3d301b26c0c)]
 interface nsIAndroidBridge : nsIAndroidEventDispatcher
 {
   [implicit_jscontext] void handleGeckoMessage(in jsval message);
   attribute nsIAndroidBrowserApp browserApp;
   void contentDocumentChanged(in mozIDOMWindowProxy window);
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -359,16 +359,17 @@ private:
 
 public:
     // Create and attach a window.
     static void Open(const jni::Class::LocalRef& aCls,
                      GeckoView::Window::Param aWindow,
                      GeckoView::Param aView, jni::Object::Param aCompositor,
                      jni::Object::Param aDispatcher,
                      jni::String::Param aChromeURI,
+                     jni::Object::Param aSettings,
                      int32_t screenId);
 
     // Close and destroy the nsWindow.
     void Close();
 
     // Reattach this nsWindow to a new GeckoView.
     void Reattach(const GeckoView::Window::LocalRef& inst,
                   GeckoView::Param aView, jni::Object::Param aCompositor,
@@ -951,16 +952,33 @@ public:
 
 template<> const char
 nsWindow::NativePtr<nsWindow::NPZCSupport>::sName[] = "NPZCSupport";
 
 NS_IMPL_ISUPPORTS(nsWindow::AndroidView,
                   nsIAndroidEventDispatcher,
                   nsIAndroidView)
 
+
+nsresult
+nsWindow::AndroidView::GetSettings(JSContext* aCx, JS::MutableHandleValue aOut)
+{
+    if (!mSettings) {
+        aOut.setNull();
+        return NS_OK;
+    }
+
+    JNIEnv* const env = jni::GetGeckoThreadEnv();
+    env->MonitorEnter(mSettings.Get());
+    nsresult rv = widget::EventDispatcher::UnboxBundle(aCx, mSettings, aOut);
+    env->MonitorExit(mSettings.Get());
+
+    return rv;
+}
+
 /**
  * Compositor has some unique requirements for its native calls, so make it
  * separate from GeckoViewSupport.
  */
 class nsWindow::LayerViewSupport final
     : public LayerView::Compositor::Natives<LayerViewSupport>
 {
     using LockedWindowPtr = WindowPtr<LayerViewSupport>::Locked;
@@ -1366,16 +1384,17 @@ nsWindow::GeckoViewSupport::~GeckoViewSu
 
 /* static */ void
 nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
                                  GeckoView::Window::Param aWindow,
                                  GeckoView::Param aView,
                                  jni::Object::Param aCompositor,
                                  jni::Object::Param aDispatcher,
                                  jni::String::Param aChromeURI,
+                                 jni::Object::Param aSettings,
                                  int32_t aScreenId)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
     PROFILER_LABEL("nsWindow", "GeckoViewSupport::Open",
                    js::ProfileEntry::Category::OTHER);
 
     nsCOMPtr<nsIWindowWatcher> ww = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
@@ -1389,16 +1408,19 @@ nsWindow::GeckoViewSupport::Open(const j
         if (!url) {
             url = NS_LITERAL_CSTRING("chrome://browser/content/browser.xul");
         }
     }
 
     RefPtr<AndroidView> androidView = new AndroidView();
     androidView->mEventDispatcher->Attach(
             java::EventDispatcher::Ref::From(aDispatcher), nullptr);
+    if (aSettings) {
+        androidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
+    }
 
     nsCOMPtr<mozIDOMWindowProxy> domWindow;
     ww->OpenWindow(nullptr, url, nullptr, "chrome,dialog=0,resizable,scrollbars=yes",
                    androidView, getter_AddRefs(domWindow));
     MOZ_RELEASE_ASSERT(domWindow);
 
     nsCOMPtr<nsPIDOMWindowOuter> pdomWindow =
             nsPIDOMWindowOuter::From(domWindow);
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -105,16 +105,18 @@ private:
             new mozilla::widget::EventDispatcher()};
 
         AndroidView() {}
 
         NS_DECL_ISUPPORTS
         NS_DECL_NSIANDROIDVIEW
 
         NS_FORWARD_NSIANDROIDEVENTDISPATCHER(mEventDispatcher->)
+
+        mozilla::java::GeckoBundle::GlobalRef mSettings;
     };
 
     RefPtr<AndroidView> mAndroidView;
 
     class LayerViewSupport;
     // Object that implements native LayerView calls.
     // Owned by the Java LayerView instance.
     NativePtr<LayerViewSupport> mLayerViewSupport;