зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1343613 - [2.3] Add GeckoView event queuing in EventDispatcher. r=jchen,snorp
This commit is contained in:
Родитель
5db48b0409
Коммит
5728cb6576
|
@ -9,6 +9,7 @@ import org.mozilla.gecko.annotation.RobocopTarget;
|
|||
import org.mozilla.gecko.annotation.WrapForJNI;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.mozglue.JNIObject;
|
||||
import org.mozilla.gecko.NativeQueue.StateHolder;
|
||||
import org.mozilla.gecko.util.BundleEventListener;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GeckoBundle;
|
||||
|
@ -57,6 +58,7 @@ public final class EventDispatcher extends JNIObject {
|
|||
new HashMap<String, List<BundleEventListener>>(DEFAULT_BACKGROUND_EVENTS_COUNT);
|
||||
|
||||
private boolean mAttachedToGecko;
|
||||
private final StateHolder mStateHolder;
|
||||
|
||||
@ReflectionTarget
|
||||
@WrapForJNI(calledFrom = "gecko")
|
||||
|
@ -65,6 +67,15 @@ public final class EventDispatcher extends JNIObject {
|
|||
}
|
||||
|
||||
/* package */ EventDispatcher() {
|
||||
mStateHolder = GeckoThread.getStateHolder();
|
||||
}
|
||||
|
||||
/* package */ EventDispatcher(final NativeQueue.StateHolder stateHolder) {
|
||||
mStateHolder = stateHolder;
|
||||
}
|
||||
|
||||
private boolean isReadyForDispatchingToGecko() {
|
||||
return mStateHolder.isReady();
|
||||
}
|
||||
|
||||
@WrapForJNI(dispatchTo = "gecko") @Override // JNIObject
|
||||
|
@ -228,7 +239,7 @@ public final class EventDispatcher extends JNIObject {
|
|||
public void dispatch(final String type, final GeckoBundle message,
|
||||
final EventCallback callback) {
|
||||
synchronized (this) {
|
||||
if (mAttachedToGecko && hasGeckoListener(type)) {
|
||||
if (isReadyForDispatchingToGecko() && hasGeckoListener(type)) {
|
||||
dispatchToGecko(type, message, JavaCallbackDelegate.wrap(callback));
|
||||
return;
|
||||
}
|
||||
|
@ -279,15 +290,18 @@ public final class EventDispatcher extends JNIObject {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!GeckoThread.isRunning()) {
|
||||
// Usually, we discard an event if there is no listeners for it by the time of
|
||||
// the dispatch. However, if Gecko is not ready and there is no listener for
|
||||
// this event that's possibly headed to Gecko, we make a special exception to
|
||||
// queue this event until Gecko is ready. This way, Gecko can first register
|
||||
// its listeners, and accept the event when it is ready.
|
||||
GeckoThread.queueNativeCall(this, "dispatchToGecko",
|
||||
String.class, type, GeckoBundle.class, message,
|
||||
EventCallback.class, JavaCallbackDelegate.wrap(callback));
|
||||
if (!isReadyForDispatchingToGecko()) {
|
||||
// Usually, we discard an event if there is no listeners for it by
|
||||
// the time of the dispatch. However, if Gecko(View) is not ready and
|
||||
// there is no listener for this event that's possibly headed to
|
||||
// Gecko, we make a special exception to queue this event until
|
||||
// Gecko(View) is ready. This way, Gecko can first register its
|
||||
// listeners, and accept the event when it is ready.
|
||||
NativeQueue.queueUntil(mStateHolder,
|
||||
mStateHolder.getReadyState(), this, "dispatchToGecko",
|
||||
String.class, type,
|
||||
GeckoBundle.class, message,
|
||||
EventCallback.class, JavaCallbackDelegate.wrap(callback));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,7 +74,8 @@ public class GeckoView extends LayerView
|
|||
mStateHolder.setState(newState);
|
||||
}
|
||||
|
||||
private final EventDispatcher mEventDispatcher = new EventDispatcher();
|
||||
private final EventDispatcher mEventDispatcher =
|
||||
new EventDispatcher(mStateHolder);
|
||||
|
||||
private ChromeDelegate mChromeDelegate;
|
||||
/* package */ ContentListener mContentListener;
|
||||
|
|
|
@ -573,8 +573,15 @@ nsAppShell::Observe(nsISupports* aSubject,
|
|||
java::GeckoThread::State::PROFILE_READY(),
|
||||
java::GeckoThread::State::RUNNING());
|
||||
}
|
||||
removeObserver = true;
|
||||
|
||||
// Enable the window event dispatcher for the given GeckoView.
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aSubject);
|
||||
MOZ_ASSERT(doc);
|
||||
nsCOMPtr<nsIWidget> widget =
|
||||
WidgetUtils::DOMWindowToWidget(doc->GetWindow());
|
||||
MOZ_ASSERT(widget);
|
||||
const auto window = static_cast<nsWindow*>(widget.get());
|
||||
window->EnableEventDispatcher();
|
||||
} else if (!strcmp(aTopic, "quit-application-granted")) {
|
||||
if (jni::IsAvailable()) {
|
||||
java::GeckoThread::SetState(
|
||||
|
|
|
@ -237,12 +237,12 @@ public:
|
|||
Impl* operator->() const { return mImpl; }
|
||||
};
|
||||
|
||||
|
||||
class nsWindow::GeckoViewSupport final
|
||||
: public GeckoView::Window::Natives<GeckoViewSupport>
|
||||
, public SupportsWeakPtr<GeckoViewSupport>
|
||||
{
|
||||
nsWindow& window;
|
||||
GeckoView::GlobalRef mView;
|
||||
|
||||
public:
|
||||
typedef GeckoView::Window::Natives<GeckoViewSupport> Base;
|
||||
|
@ -268,6 +268,7 @@ public:
|
|||
const GeckoView::Window::LocalRef& aInstance,
|
||||
GeckoView::Param aView)
|
||||
: window(*aWindow)
|
||||
, mView(aView)
|
||||
{
|
||||
Base::AttachNative(aInstance, static_cast<SupportsWeakPtr*>(this));
|
||||
}
|
||||
|
@ -301,6 +302,8 @@ public:
|
|||
jni::Object::Param aDispatcher);
|
||||
|
||||
void LoadUri(jni::String::Param aUri, int32_t aFlags);
|
||||
|
||||
void EnableEventDispatcher();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1535,6 +1538,15 @@ nsWindow::GetRootLayerId() const
|
|||
return mCompositorSession ? mCompositorSession->RootLayerTreeId() : 0;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::EnableEventDispatcher()
|
||||
{
|
||||
if (!mGeckoViewSupport) {
|
||||
return;
|
||||
}
|
||||
mGeckoViewSupport->EnableEventDispatcher();
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::SetParent(nsIWidget *aNewParent)
|
||||
{
|
||||
|
@ -2061,6 +2073,13 @@ nsWindow::GetEventTimeStamp(int64_t aEventTime)
|
|||
return TimeStamp::FromSystemTime(tick);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::GeckoViewSupport::EnableEventDispatcher()
|
||||
{
|
||||
MOZ_ASSERT(mView);
|
||||
mView->SetState(GeckoView::State::READY());
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::UserActivity()
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ public:
|
|||
|
||||
static void InitNatives();
|
||||
void SetScreenId(uint32_t aScreenId) { mScreenId = aScreenId; }
|
||||
void EnableEventDispatcher();
|
||||
|
||||
private:
|
||||
uint32_t mScreenId;
|
||||
|
|
Загрузка…
Ссылка в новой задаче