From 80710c9297ccfd6a466908e0893f3676c539e25e Mon Sep 17 00:00:00 2001 From: Eugen Sawin Date: Tue, 28 Mar 2017 21:56:30 +0200 Subject: [PATCH] Bug 1346542 - [1.2] Move state holder to GeckoView::Window and set ready state when reattaching to window. r=jchen --- .../org/mozilla/gecko/EventDispatcher.java | 8 +++- .../java/org/mozilla/gecko/GeckoView.java | 30 +++++++++---- widget/android/GeneratedJNIWrappers.cpp | 16 +++---- widget/android/GeneratedJNIWrappers.h | 42 +++++++++---------- widget/android/nsWindow.cpp | 16 +++---- 5 files changed, 66 insertions(+), 46 deletions(-) diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/EventDispatcher.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/EventDispatcher.java index 96bcf4c09a68..c7c989807565 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/EventDispatcher.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/EventDispatcher.java @@ -55,7 +55,7 @@ public final class EventDispatcher extends JNIObject { new HashMap>(DEFAULT_BACKGROUND_EVENTS_COUNT); private boolean mAttachedToGecko; - private final StateHolder mStateHolder; + private volatile StateHolder mStateHolder; @ReflectionTarget @WrapForJNI(calledFrom = "gecko") @@ -71,6 +71,12 @@ public final class EventDispatcher extends JNIObject { mStateHolder = stateHolder; } + /* package */ void setStateHolder(final NativeQueue.StateHolder stateHolder) { + mStateHolder = stateHolder; + // Force queue flushing. + mStateHolder.setState(mStateHolder.getState()); + } + private boolean isReadyForDispatchingToGecko() { return mStateHolder.isReady(); } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java index 195a6ce204d8..f7cb74959110 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoView.java @@ -67,16 +67,11 @@ public class GeckoView extends LayerView } } - private final StateHolder mStateHolder = + private static final StateHolder sDummyStateHolder = new StateHolder(State.INITIAL, State.READY); - @WrapForJNI(calledFrom = "gecko") - private void setState(final State newState) { - mStateHolder.setState(newState); - } - private final EventDispatcher mEventDispatcher = - new EventDispatcher(mStateHolder); + new EventDispatcher(sDummyStateHolder); private ChromeDelegate mChromeDelegate; /* package */ ContentListener mContentListener; @@ -92,6 +87,10 @@ public class GeckoView extends LayerView @WrapForJNI(dispatchTo = "proxy") protected static final class Window extends JNIObject { + @WrapForJNI(skip = true) + /* package */ final StateHolder mStateHolder = + new StateHolder(State.INITIAL, State.READY); + @WrapForJNI(skip = true) /* package */ Window() {} @@ -101,9 +100,18 @@ public class GeckoView extends LayerView int screenId); @Override protected native void disposeNative(); + native void close(); - native void reattach(GeckoView view, Object compositor, EventDispatcher dispatcher); + + native void reattach(GeckoView view, Object compositor, + EventDispatcher dispatcher); + native void loadUri(String uri, int flags); + + @WrapForJNI(calledFrom = "gecko") + private void setState(final State newState) { + mStateHolder.setState(newState); + } } // Object to hold onto our nsWindow connection when GeckoView gets destroyed. @@ -244,7 +252,7 @@ public class GeckoView extends LayerView final StateBinder stateBinder = (StateBinder) state; if (stateBinder.window != null) { - this.window = stateBinder.window; + window = stateBinder.window; } stateSaved = false; @@ -279,6 +287,8 @@ public class GeckoView extends LayerView } protected void reattachWindow() { + mEventDispatcher.setStateHolder(mWindow.mStateHolder); + if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) { window.reattach(this, getCompositor(), mEventDispatcher); } else { @@ -295,6 +305,7 @@ public class GeckoView extends LayerView if (window == null) { // Open a new nsWindow if we didn't have one from before. window = new Window(); + mEventDispatcher.setStateHolder(window.mStateHolder); openWindow(); } else { reattachWindow(); @@ -325,6 +336,7 @@ public class GeckoView extends LayerView window, "disposeNative"); } + mEventDispatcher.setStateHolder(sDummyStateHolder); mOnAttachedToWindowCalled = false; } diff --git a/widget/android/GeneratedJNIWrappers.cpp b/widget/android/GeneratedJNIWrappers.cpp index c497f519b3a9..bf8a2eba3d25 100644 --- a/widget/android/GeneratedJNIWrappers.cpp +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -967,14 +967,6 @@ auto GeckoThread::State::RUNNING() -> State::LocalRef const char GeckoView::name[] = "org/mozilla/gecko/GeckoView"; -constexpr char GeckoView::SetState_t::name[]; -constexpr char GeckoView::SetState_t::signature[]; - -auto GeckoView::SetState(mozilla::jni::Object::Param a0) const -> void -{ - return mozilla::jni::Method::Call(GeckoView::mCtx, nullptr, a0); -} - const char GeckoView::State::name[] = "org/mozilla/gecko/GeckoView$State"; @@ -1012,6 +1004,14 @@ constexpr char GeckoView::Window::Open_t::signature[]; constexpr char GeckoView::Window::Reattach_t::name[]; constexpr char GeckoView::Window::Reattach_t::signature[]; +constexpr char GeckoView::Window::SetState_t::name[]; +constexpr char GeckoView::Window::SetState_t::signature[]; + +auto GeckoView::Window::SetState(mozilla::jni::Object::Param a0) const -> void +{ + return mozilla::jni::Method::Call(Window::mCtx, nullptr, a0); +} + const char PrefsHelper::name[] = "org/mozilla/gecko/PrefsHelper"; diff --git a/widget/android/GeneratedJNIWrappers.h b/widget/android/GeneratedJNIWrappers.h index 1988950426d0..5b97d1a95894 100644 --- a/widget/android/GeneratedJNIWrappers.h +++ b/widget/android/GeneratedJNIWrappers.h @@ -2883,26 +2883,6 @@ public: class State; class Window; - struct SetState_t { - typedef GeckoView Owner; - typedef void ReturnType; - typedef void SetterType; - typedef mozilla::jni::Args< - mozilla::jni::Object::Param> Args; - static constexpr char name[] = "setState"; - static constexpr char signature[] = - "(Lorg/mozilla/gecko/GeckoView$State;)V"; - static const bool isStatic = false; - static const mozilla::jni::ExceptionMode exceptionMode = - mozilla::jni::ExceptionMode::ABORT; - static const mozilla::jni::CallingThread callingThread = - mozilla::jni::CallingThread::GECKO; - static const mozilla::jni::DispatchTarget dispatchTarget = - mozilla::jni::DispatchTarget::CURRENT; - }; - - auto SetState(mozilla::jni::Object::Param) const -> void; - static const int32_t LOAD_DEFAULT = 0; static const int32_t LOAD_NEW_TAB = 1; @@ -2910,7 +2890,7 @@ public: static const int32_t LOAD_SWITCH_TAB = 2; static const mozilla::jni::CallingThread callingThread = - mozilla::jni::CallingThread::GECKO; + mozilla::jni::CallingThread::ANY; }; @@ -3068,6 +3048,26 @@ public: mozilla::jni::DispatchTarget::PROXY; }; + struct SetState_t { + typedef Window Owner; + typedef void ReturnType; + typedef void SetterType; + typedef mozilla::jni::Args< + mozilla::jni::Object::Param> Args; + static constexpr char name[] = "setState"; + static constexpr char signature[] = + "(Lorg/mozilla/gecko/GeckoView$State;)V"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::GECKO; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto SetState(mozilla::jni::Object::Param) const -> void; + static const mozilla::jni::CallingThread callingThread = mozilla::jni::CallingThread::ANY; diff --git a/widget/android/nsWindow.cpp b/widget/android/nsWindow.cpp index a5f63bdc45e3..4be5ac55144c 100644 --- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -242,7 +242,7 @@ class nsWindow::GeckoViewSupport final , public SupportsWeakPtr { nsWindow& window; - GeckoView::GlobalRef mView; + GeckoView::Window::GlobalRef mGeckoViewWindow; public: typedef GeckoView::Window::Natives Base; @@ -265,10 +265,9 @@ public: } GeckoViewSupport(nsWindow* aWindow, - const GeckoView::Window::LocalRef& aInstance, - GeckoView::Param aView) + const GeckoView::Window::LocalRef& aInstance) : window(*aWindow) - , mView(aView) + , mGeckoViewWindow(aInstance) { Base::AttachNative(aInstance, static_cast(this)); } @@ -1252,7 +1251,7 @@ nsWindow::GeckoViewSupport::Open(const jni::Class::LocalRef& aCls, // Attach a new GeckoView support object to the new window. window->mGeckoViewSupport = mozilla::MakeUnique( - window, GeckoView::Window::LocalRef(aCls.Env(), aWindow), aView); + window, (GeckoView::Window::LocalRef(aCls.Env(), aWindow))); window->mGeckoViewSupport->mDOMWindow = pdomWindow; @@ -1297,6 +1296,7 @@ nsWindow::GeckoViewSupport::Close() mDOMWindow->ForceClose(); mDOMWindow = nullptr; + mGeckoViewWindow = nullptr; } void @@ -2078,8 +2078,10 @@ nsWindow::GetEventTimeStamp(int64_t aEventTime) void nsWindow::GeckoViewSupport::EnableEventDispatcher() { - MOZ_ASSERT(mView); - mView->SetState(GeckoView::State::READY()); + if (!mGeckoViewWindow) { + return; + } + mGeckoViewWindow->SetState(GeckoView::State::READY()); } void