Bug 1415994 - 5. Use LayerSession from GeckoSession; r=snorp draft
authorJim Chen <nchen@mozilla.com>
Tue, 14 Nov 2017 18:18:35 -0500
changeset 697879 ee4ae96e974d15c8cb9ad569ea9abf0ace4d0fa5
parent 697878 040442539fd7cc1af8e13e4be1d9ebfb1625f778
child 697880 ef470fb95aa6ad17cb53ea65079116e93451ba74
push id89133
push userbmo:nchen@mozilla.com
push dateTue, 14 Nov 2017 23:19:10 +0000
reviewerssnorp
bugs1415994
milestone59.0a1
Bug 1415994 - 5. Use LayerSession from GeckoSession; r=snorp Make GeckoSession inherit from LayerSession, and connect its Compositor to native code as part of the GeckoSession routine. MozReview-Commit-ID: wQaH1A0a7z
mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
widget/android/nsWindow.cpp
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoSession.java
@@ -6,16 +6,17 @@
 
 package org.mozilla.gecko;
 
 import java.net.URLConnection;
 import java.util.ArrayList;
 import java.util.Arrays;
 
 import org.mozilla.gecko.annotation.WrapForJNI;
+import org.mozilla.gecko.gfx.LayerSession;
 import org.mozilla.gecko.mozglue.JNIObject;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
 
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.res.Resources;
@@ -26,17 +27,18 @@ import android.os.IBinder;
 import android.os.IInterface;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 
-public class GeckoSession implements Parcelable {
+public class GeckoSession extends LayerSession
+                          implements Parcelable {
     private static final String LOGTAG = "GeckoSession";
     private static final boolean DEBUG = false;
 
     /* package */ enum State implements NativeQueue.State {
         INITIAL(0),
         READY(1);
 
         private final int mRank;
@@ -294,40 +296,42 @@ public class GeckoSession implements Par
             if (mBinder == null) {
                 mBinder = new Binder();
                 mBinder.attachInterface(this, Window.class.getName());
             }
             return mBinder;
         }
 
         @WrapForJNI(dispatchTo = "proxy")
-        static native void open(Window instance, EventDispatcher dispatcher,
-                                GeckoBundle settings, String chromeUri,
-                                int screenId, boolean privateMode);
+        public static native void open(Window instance, Compositor compositor,
+                                       EventDispatcher dispatcher,
+                                       GeckoBundle settings, String chromeUri,
+                                       int screenId, boolean privateMode);
 
         @WrapForJNI(dispatchTo = "proxy")
         @Override protected native void disposeNative();
 
         @WrapForJNI(dispatchTo = "proxy")
-        native void close();
+        public native void close();
 
         @WrapForJNI(dispatchTo = "proxy")
-        native void transfer(EventDispatcher dispatcher, GeckoBundle settings);
+        public native void transfer(Compositor compositor, EventDispatcher dispatcher,
+                                    GeckoBundle settings);
 
         @WrapForJNI(calledFrom = "gecko")
         private synchronized void onTransfer(final EventDispatcher dispatcher) {
             final NativeQueue nativeQueue = dispatcher.getNativeQueue();
             if (mNativeQueue != nativeQueue) {
                 nativeQueue.setState(mNativeQueue.getState());
                 mNativeQueue = nativeQueue;
             }
         }
 
         @WrapForJNI(dispatchTo = "proxy")
-        native void attach(GeckoView view, Object compositor);
+        public native void attach(GeckoView view);
 
         @WrapForJNI(calledFrom = "gecko")
         private synchronized void onReady() {
             if (mNativeQueue.checkAndSetState(State.INITIAL, State.READY)) {
                 Log.i(LOGTAG, "zerdatime " + SystemClock.elapsedRealtime() +
                       " - chrome startup finished");
             }
         }
@@ -375,20 +379,21 @@ public class GeckoSession implements Par
             throw new IllegalStateException("Session is open");
         }
 
         mWindow = window;
         mSettings = new GeckoSessionSettings(settings, this);
 
         if (mWindow != null) {
             if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
-                mWindow.transfer(mEventDispatcher, mSettings.asBundle());
+                mWindow.transfer(mCompositor, mEventDispatcher, mSettings.asBundle());
             } else {
                 GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                         mWindow, "transfer",
+                        Compositor.class, mCompositor,
                         EventDispatcher.class, mEventDispatcher,
                         GeckoBundle.class, mSettings.asBundle());
             }
         }
     }
 
     /* package */ void transferFrom(final GeckoSession session) {
         transferFrom(session.mWindow, session.mSettings);
@@ -478,42 +483,42 @@ public class GeckoSession implements Par
 
         final String chromeUri = mSettings.getString(GeckoSessionSettings.CHROME_URI);
         final int screenId = mSettings.getInt(GeckoSessionSettings.SCREEN_ID);
         final boolean isPrivate = mSettings.getBoolean(GeckoSessionSettings.USE_PRIVATE_MODE);
 
         mWindow = new Window(mNativeQueue);
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
-            Window.open(mWindow, mEventDispatcher, mSettings.asBundle(),
-                        chromeUri, screenId, isPrivate);
+            Window.open(mWindow, mCompositor, mEventDispatcher,
+                        mSettings.asBundle(), chromeUri, screenId, isPrivate);
         } else {
             GeckoThread.queueNativeCallUntil(
                 GeckoThread.State.PROFILE_READY,
                 Window.class, "open",
                 Window.class, mWindow,
+                Compositor.class, mCompositor,
                 EventDispatcher.class, mEventDispatcher,
                 GeckoBundle.class, mSettings.asBundle(),
                 String.class, chromeUri,
                 screenId, isPrivate);
         }
     }
 
     public void attachView(final GeckoView view) {
         if (view == null) {
             return;
         }
 
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
-            mWindow.attach(view, view.getCompositor());
+            mWindow.attach(view);
         } else {
             GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
                     mWindow, "attach",
-                    GeckoView.class, view,
-                    Object.class, view.getCompositor());
+                    GeckoView.class, view);
         }
     }
 
     public void closeWindow() {
         if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
             mWindow.close();
             mWindow.disposeNative();
         } else {
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -274,33 +274,35 @@ public:
      */
 private:
     nsCOMPtr<nsPIDOMWindowOuter> mDOMWindow;
 
 public:
     // Create and attach a window.
     static void Open(const jni::Class::LocalRef& aCls,
                      GeckoSession::Window::Param aWindow,
+                     jni::Object::Param aCompositor,
                      jni::Object::Param aDispatcher,
                      jni::Object::Param aSettings,
                      jni::String::Param aChromeURI,
                      int32_t aScreenId,
                      bool aPrivateMode);
 
     // Close and destroy the nsWindow.
     void Close();
 
     // Transfer this nsWindow to new GeckoSession objects.
     void Transfer(const GeckoSession::Window::LocalRef& inst,
+                  jni::Object::Param aCompositor,
                   jni::Object::Param aDispatcher,
                   jni::Object::Param aSettings);
 
     // Reattach this nsWindow to a new GeckoView.
     void Attach(const GeckoSession::Window::LocalRef& inst,
-                jni::Object::Param aView, jni::Object::Param aCompositor);
+                jni::Object::Param aView);
 
     void EnableEventDispatcher();
 };
 
 /**
  * NativePanZoomController handles its native calls on the UI thread, so make
  * it separate from GeckoViewSupport.
  */
@@ -1259,16 +1261,17 @@ nsWindow::GeckoViewSupport::~GeckoViewSu
     if (window.mLayerViewSupport) {
         window.mLayerViewSupport.Detach();
     }
 }
 
 /* static */ void
 nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls,
                                  GeckoSession::Window::Param aWindow,
+                                 jni::Object::Param aCompositor,
                                  jni::Object::Param aDispatcher,
                                  jni::Object::Param aSettings,
                                  jni::String::Param aChromeURI,
                                  int32_t aScreenId,
                                  bool aPrivateMode)
 {
     MOZ_ASSERT(NS_IsMainThread());
 
@@ -1282,22 +1285,21 @@ nsWindow::GeckoViewSupport::Open(const j
         url = aChromeURI->ToCString();
     } else {
         nsresult rv = Preferences::GetCString("toolkit.defaultChromeURI", url);
         if (NS_FAILED(rv)) {
             url = NS_LITERAL_CSTRING("chrome://geckoview/content/geckoview.xul");
         }
     }
 
+    // Prepare an nsIAndroidView to pass as argument to the window.
     RefPtr<AndroidView> androidView = new AndroidView();
     androidView->mEventDispatcher->Attach(
             java::EventDispatcher::Ref::From(aDispatcher), nullptr);
-    if (aSettings) {
-        androidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
-    }
+    androidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
 
     nsAutoCString chromeFlags("chrome,dialog=0,resizable,scrollbars");
     if (aPrivateMode) {
         chromeFlags += ",private";
     }
     nsCOMPtr<mozIDOMWindowProxy> domWindow;
     ww->OpenWindow(nullptr, url.get(), nullptr, chromeFlags.get(),
                    androidView, getter_AddRefs(domWindow));
@@ -1307,33 +1309,33 @@ nsWindow::GeckoViewSupport::Open(const j
             nsPIDOMWindowOuter::From(domWindow);
     nsCOMPtr<nsIWidget> widget = WidgetUtils::DOMWindowToWidget(pdomWindow);
     MOZ_ASSERT(widget);
 
     const auto window = static_cast<nsWindow*>(widget.get());
     window->SetScreenId(aScreenId);
 
     // Attach a new GeckoView support object to the new window.
-    window->mGeckoViewSupport = mozilla::MakeUnique<GeckoViewSupport>(
-        window, (GeckoSession::Window::LocalRef(aCls.Env(), aWindow)));
+    GeckoSession::Window::LocalRef sessionWindow(aCls.Env(), aWindow);
+    window->mGeckoViewSupport =
+            mozilla::MakeUnique<GeckoViewSupport>(window, sessionWindow);
+    window->mGeckoViewSupport->mDOMWindow = pdomWindow;
+    window->mAndroidView = androidView;
 
-    window->mGeckoViewSupport->mDOMWindow = pdomWindow;
+    // Attach other session support objects.
+    window->mGeckoViewSupport->Transfer(
+            sessionWindow, aCompositor, aDispatcher, aSettings);
 
     // Attach a new GeckoEditable support object to the new window.
     auto editable = GeckoEditable::New();
     auto editableChild = GeckoEditableChild::New(editable);
     editable->SetDefaultEditableChild(editableChild);
     window->mEditable = editable;
     window->mEditableSupport.Attach(editableChild, window, editableChild);
 
-    // Attach again using the new window.
-    androidView->mEventDispatcher->Attach(
-            java::EventDispatcher::Ref::From(aDispatcher), pdomWindow);
-    window->mAndroidView = androidView;
-
     if (window->mWidgetListener) {
         nsCOMPtr<nsIXULWindow> xulWindow(
                 window->mWidgetListener->GetXULWindow());
         if (xulWindow) {
             // Our window is not intrinsically sized, so tell nsXULWindow to
             // not set a size for us.
             xulWindow->SetIntrinsicallySized(false);
         }
@@ -1353,55 +1355,48 @@ nsWindow::GeckoViewSupport::Close()
 
     mDOMWindow->ForceClose();
     mDOMWindow = nullptr;
     mGeckoViewWindow = nullptr;
 }
 
 void
 nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
+                                     jni::Object::Param aCompositor,
                                      jni::Object::Param aDispatcher,
                                      jni::Object::Param aSettings)
 {
-    if (!window.mAndroidView) {
-        return;
-    }
-
-    window.mAndroidView->mEventDispatcher->Attach(
-            java::EventDispatcher::Ref::From(aDispatcher), mDOMWindow);
-    window.mAndroidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
-
-    inst->OnTransfer(aDispatcher);
-}
-
-void
-nsWindow::GeckoViewSupport::Attach(const GeckoSession::Window::LocalRef& inst,
-                                   jni::Object::Param aView,
-                                   jni::Object::Param aCompositor)
-{
-    // Associate our previous GeckoEditable with the new GeckoView.
-    MOZ_ASSERT(window.mEditable);
-    window.mEditable->OnViewChange(aView);
-
-    // mNPZCSupport might have already been detached through the Java side calling
-    // NativePanZoomController.destroy().
     if (window.mNPZCSupport) {
         window.mNPZCSupport.Detach();
     }
 
     if (window.mLayerViewSupport) {
         window.mLayerViewSupport.Detach();
     }
 
-    if (aCompositor) {
-        auto compositor = LayerView::Compositor::LocalRef(
-                inst.Env(), LayerView::Compositor::Ref::From(aCompositor));
-        window.mLayerViewSupport.Attach(compositor, &window, compositor);
-        compositor->Reattach();
+    auto compositor = LayerSession::Compositor::LocalRef(
+            inst.Env(), LayerSession::Compositor::Ref::From(aCompositor));
+    window.mLayerViewSupport.Attach(compositor, &window, compositor);
+
+    if (window.mAndroidView) {
+        window.mAndroidView->mEventDispatcher->Attach(
+                java::EventDispatcher::Ref::From(aDispatcher), mDOMWindow);
+        window.mAndroidView->mSettings = java::GeckoBundle::Ref::From(aSettings);
     }
+
+    inst->OnTransfer(aDispatcher);
+}
+
+void
+nsWindow::GeckoViewSupport::Attach(const GeckoSession::Window::LocalRef& inst,
+                                   jni::Object::Param aView)
+{
+    // Associate our previous GeckoEditable with the new GeckoView.
+    MOZ_ASSERT(window.mEditable);
+    window.mEditable->OnViewChange(aView);
 }
 
 void
 nsWindow::InitNatives()
 {
     nsWindow::GeckoViewSupport::Base::Init();
     nsWindow::LayerViewSupport::Init();
     nsWindow::NPZCSupport::Init();