mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Bug 1415074 - Fix unresponsiveness after restoring GeckoView states; r=jchen
Fix a bug where GeckoView becomes unresponsive to dispatched events after restoring states, due to the native queue not being restored. r=me for small, tested patch. MozReview-Commit-ID: K1cVjjNaZK1 --HG-- extra : rebase_source : b1329c84d82f5bdc06767bf310ca87e52ff6ec9b
This commit is contained in:
parent
c15f333a09
commit
832cd8d996
@ -71,6 +71,10 @@ public final class EventDispatcher extends JNIObject {
|
||||
mNativeQueue = queue;
|
||||
}
|
||||
|
||||
public NativeQueue getNativeQueue() {
|
||||
return mNativeQueue;
|
||||
}
|
||||
|
||||
private boolean isReadyForDispatchingToGecko() {
|
||||
return mNativeQueue.isReady();
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ public class GeckoSession implements Parcelable {
|
||||
private final Listener mListener = new Listener();
|
||||
|
||||
protected static final class Window extends JNIObject implements IInterface {
|
||||
private final NativeQueue mNativeQueue;
|
||||
private NativeQueue mNativeQueue;
|
||||
private Binder mBinder;
|
||||
|
||||
public Window(final NativeQueue nativeQueue) {
|
||||
@ -309,6 +309,18 @@ public class GeckoSession implements Parcelable {
|
||||
@WrapForJNI(dispatchTo = "proxy")
|
||||
native void close();
|
||||
|
||||
@WrapForJNI(dispatchTo = "proxy")
|
||||
native void transfer(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);
|
||||
|
||||
@ -358,13 +370,28 @@ public class GeckoSession implements Parcelable {
|
||||
mListener.registerListeners();
|
||||
}
|
||||
|
||||
/* package */ void transferFrom(final GeckoSession session) {
|
||||
private void transferFrom(final Window window, final GeckoSessionSettings settings) {
|
||||
if (isOpen()) {
|
||||
throw new IllegalStateException("Session is open");
|
||||
}
|
||||
|
||||
mWindow = session.mWindow;
|
||||
mSettings = new GeckoSessionSettings(session.mSettings, this);
|
||||
mWindow = window;
|
||||
mSettings = new GeckoSessionSettings(settings, this);
|
||||
|
||||
if (mWindow != null) {
|
||||
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
|
||||
mWindow.transfer(mEventDispatcher, mSettings.asBundle());
|
||||
} else {
|
||||
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
|
||||
mWindow, "transfer",
|
||||
EventDispatcher.class, mEventDispatcher,
|
||||
GeckoBundle.class, mSettings.asBundle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void transferFrom(final GeckoSession session) {
|
||||
transferFrom(session.mWindow, session.mSettings);
|
||||
session.mWindow = null;
|
||||
}
|
||||
|
||||
@ -381,22 +408,13 @@ public class GeckoSession implements Parcelable {
|
||||
|
||||
// AIDL code may call readFromParcel even though it's not part of Parcelable.
|
||||
public void readFromParcel(final Parcel source) {
|
||||
if (isOpen()) {
|
||||
throw new IllegalStateException("Session is open");
|
||||
}
|
||||
|
||||
final IBinder binder = source.readStrongBinder();
|
||||
final IInterface window = (binder != null) ?
|
||||
final IInterface ifce = (binder != null) ?
|
||||
binder.queryLocalInterface(Window.class.getName()) : null;
|
||||
if (window instanceof Window) {
|
||||
mWindow = (Window) window;
|
||||
} else {
|
||||
mWindow = null;
|
||||
}
|
||||
|
||||
final Window window = (ifce instanceof Window) ? (Window) ifce : null;
|
||||
final GeckoSessionSettings settings =
|
||||
source.readParcelable(getClass().getClassLoader());
|
||||
mSettings = new GeckoSessionSettings(settings, this);
|
||||
transferFrom(window, settings);
|
||||
}
|
||||
|
||||
public static final Creator<GeckoSession> CREATOR = new Creator<GeckoSession>() {
|
||||
|
@ -222,7 +222,7 @@ template<class Impl>
|
||||
class GeckoSession::Window::Natives : public mozilla::jni::NativeImpl<Window, Impl>
|
||||
{
|
||||
public:
|
||||
static const JNINativeMethod methods[4];
|
||||
static const JNINativeMethod methods[5];
|
||||
};
|
||||
|
||||
template<class Impl>
|
||||
@ -242,7 +242,11 @@ const JNINativeMethod GeckoSession::Window::Natives<Impl>::methods[] = {
|
||||
|
||||
mozilla::jni::MakeNativeMethod<GeckoSession::Window::Open_t>(
|
||||
mozilla::jni::NativeStub<GeckoSession::Window::Open_t, Impl>
|
||||
::template Wrap<&Impl::Open>)
|
||||
::template Wrap<&Impl::Open>),
|
||||
|
||||
mozilla::jni::MakeNativeMethod<GeckoSession::Window::Transfer_t>(
|
||||
mozilla::jni::NativeStub<GeckoSession::Window::Transfer_t, Impl>
|
||||
::template Wrap<&Impl::Transfer>)
|
||||
};
|
||||
|
||||
template<class Impl>
|
||||
|
@ -792,9 +792,20 @@ auto GeckoSession::Window::OnReady() const -> void
|
||||
return mozilla::jni::Method<OnReady_t>::Call(Window::mCtx, nullptr);
|
||||
}
|
||||
|
||||
constexpr char GeckoSession::Window::OnTransfer_t::name[];
|
||||
constexpr char GeckoSession::Window::OnTransfer_t::signature[];
|
||||
|
||||
auto GeckoSession::Window::OnTransfer(mozilla::jni::Object::Param a0) const -> void
|
||||
{
|
||||
return mozilla::jni::Method<OnTransfer_t>::Call(Window::mCtx, nullptr, a0);
|
||||
}
|
||||
|
||||
constexpr char GeckoSession::Window::Open_t::name[];
|
||||
constexpr char GeckoSession::Window::Open_t::signature[];
|
||||
|
||||
constexpr char GeckoSession::Window::Transfer_t::name[];
|
||||
constexpr char GeckoSession::Window::Transfer_t::signature[];
|
||||
|
||||
const char GeckoThread::name[] =
|
||||
"org/mozilla/gecko/GeckoThread";
|
||||
|
||||
|
@ -2420,6 +2420,26 @@ public:
|
||||
|
||||
auto OnReady() const -> void;
|
||||
|
||||
struct OnTransfer_t {
|
||||
typedef Window Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<
|
||||
mozilla::jni::Object::Param> Args;
|
||||
static constexpr char name[] = "onTransfer";
|
||||
static constexpr char signature[] =
|
||||
"(Lorg/mozilla/gecko/EventDispatcher;)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 OnTransfer(mozilla::jni::Object::Param) const -> void;
|
||||
|
||||
struct Open_t {
|
||||
typedef Window Owner;
|
||||
typedef void ReturnType;
|
||||
@ -2443,6 +2463,25 @@ public:
|
||||
mozilla::jni::DispatchTarget::PROXY;
|
||||
};
|
||||
|
||||
struct Transfer_t {
|
||||
typedef Window Owner;
|
||||
typedef void ReturnType;
|
||||
typedef void SetterType;
|
||||
typedef mozilla::jni::Args<
|
||||
mozilla::jni::Object::Param,
|
||||
mozilla::jni::Object::Param> Args;
|
||||
static constexpr char name[] = "transfer";
|
||||
static constexpr char signature[] =
|
||||
"(Lorg/mozilla/gecko/EventDispatcher;Lorg/mozilla/gecko/util/GeckoBundle;)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::ANY;
|
||||
static const mozilla::jni::DispatchTarget dispatchTarget =
|
||||
mozilla::jni::DispatchTarget::PROXY;
|
||||
};
|
||||
|
||||
static const mozilla::jni::CallingThread callingThread =
|
||||
mozilla::jni::CallingThread::ANY;
|
||||
|
||||
|
@ -288,6 +288,11 @@ public:
|
||||
// Close and destroy the nsWindow.
|
||||
void Close();
|
||||
|
||||
// Transfer this nsWindow to new GeckoSession objects.
|
||||
void Transfer(const GeckoSession::Window::LocalRef& inst,
|
||||
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);
|
||||
@ -1353,6 +1358,22 @@ nsWindow::GeckoViewSupport::Close()
|
||||
mGeckoViewWindow = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::GeckoViewSupport::Transfer(const GeckoSession::Window::LocalRef& inst,
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user