Backed out 2 changesets (bug 1343613) for Android crashes in nsWindow::GeckoViewSupport::EnableEventDispatcher]

Backed out changeset f9632a8f4b14 (bug 1343613)
Backed out changeset 4aa287ae1cec (bug 1343613)
This commit is contained in:
Phil Ringnalda 2017-03-07 18:56:35 -08:00
Родитель ee0cad3420
Коммит 394951281e
10 изменённых файлов: 217 добавлений и 461 удалений

Просмотреть файл

@ -287,7 +287,6 @@ gvjar.sources += [geckoview_source_dir + 'java/org/mozilla/gecko/' + x
'gfx/VsyncSource.java',
'InputConnectionListener.java',
'InputMethods.java',
'NativeQueue.java',
'NotificationListener.java',
'NSSBridge.java',
'permissions/PermissionBlock.java',

Просмотреть файл

@ -9,7 +9,6 @@ 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;
@ -58,7 +57,6 @@ 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")
@ -67,15 +65,6 @@ 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
@ -239,7 +228,7 @@ public final class EventDispatcher extends JNIObject {
public void dispatch(final String type, final GeckoBundle message,
final EventCallback callback) {
synchronized (this) {
if (isReadyForDispatchingToGecko() && hasGeckoListener(type)) {
if (mAttachedToGecko && hasGeckoListener(type)) {
dispatchToGecko(type, message, JavaCallbackDelegate.wrap(callback));
return;
}
@ -290,18 +279,15 @@ public final class EventDispatcher extends JNIObject {
return true;
}
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));
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));
return true;
}

Просмотреть файл

@ -8,10 +8,12 @@ package org.mozilla.gecko;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.NativeQueue.StateHolder;
import org.mozilla.gecko.util.FileUtils;
import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@ -26,14 +28,19 @@ import android.util.Log;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.StringTokenizer;
public class GeckoThread extends Thread {
private static final String LOGTAG = "GeckoThread";
public enum State implements NativeQueue.State {
public enum State {
// After being loaded by class loader.
@WrapForJNI INITIAL(0),
// After launching Gecko thread
@ -66,30 +73,47 @@ public class GeckoThread extends Thread {
this.rank = rank;
}
@Override
public boolean is(final NativeQueue.State other) {
public boolean is(final State other) {
return this == other;
}
@Override
public boolean isAtLeast(final NativeQueue.State other) {
if (other instanceof State) {
return this.rank >= ((State) other).rank;
}
return false;
public boolean isAtLeast(final State other) {
return this.rank >= other.rank;
}
}
private static final StateHolder sStateHolder =
new StateHolder(State.INITIAL, State.RUNNING);
public boolean isAtMost(final State other) {
return this.rank <= other.rank;
}
/* package */ static StateHolder getStateHolder() {
return sStateHolder;
// Inclusive
public boolean isBetween(final State min, final State max) {
return this.rank >= min.rank && this.rank <= max.rank;
}
}
public static final State MIN_STATE = State.INITIAL;
public static final State MAX_STATE = State.EXITED;
private static volatile State sState = State.INITIAL;
private static class QueuedCall {
public Method method;
public Object target;
public Object[] args;
public State state;
public QueuedCall(final Method method, final Object target,
final Object[] args, final State state) {
this.method = method;
this.target = target;
this.args = args;
this.state = state;
}
}
private static final int QUEUED_CALLS_COUNT = 16;
private static final ArrayList<QueuedCall> QUEUED_CALLS = new ArrayList<>(QUEUED_CALLS_COUNT);
private static final Runnable UI_THREAD_CALLBACK = new Runnable() {
@Override
public void run() {
@ -234,6 +258,153 @@ public class GeckoThread extends Thread {
return isState(State.RUNNING);
}
// Invoke the given Method and handle checked Exceptions.
private static void invokeMethod(final Method method, final Object obj, final Object[] args) {
try {
method.setAccessible(true);
method.invoke(obj, args);
} catch (final IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
} catch (final InvocationTargetException e) {
throw new UnsupportedOperationException("Cannot make call", e.getCause());
}
}
// Queue a call to the given method.
private static void queueNativeCallLocked(final Class<?> cls, final String methodName,
final Object obj, final Object[] args,
final State state) {
final ArrayList<Class<?>> argTypes = new ArrayList<>(args.length);
final ArrayList<Object> argValues = new ArrayList<>(args.length);
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Class) {
argTypes.add((Class<?>) args[i]);
argValues.add(args[++i]);
continue;
}
Class<?> argType = args[i].getClass();
if (argType == Boolean.class) argType = Boolean.TYPE;
else if (argType == Byte.class) argType = Byte.TYPE;
else if (argType == Character.class) argType = Character.TYPE;
else if (argType == Double.class) argType = Double.TYPE;
else if (argType == Float.class) argType = Float.TYPE;
else if (argType == Integer.class) argType = Integer.TYPE;
else if (argType == Long.class) argType = Long.TYPE;
else if (argType == Short.class) argType = Short.TYPE;
argTypes.add(argType);
argValues.add(args[i]);
}
final Method method;
try {
method = cls.getDeclaredMethod(
methodName, argTypes.toArray(new Class<?>[argTypes.size()]));
} catch (final NoSuchMethodException e) {
throw new IllegalArgumentException("Cannot find method", e);
}
if (!Modifier.isNative(method.getModifiers())) {
// As a precaution, we disallow queuing non-native methods. Queuing non-native
// methods is dangerous because the method could end up being called on either
// the original thread or the Gecko thread depending on timing. Native methods
// usually handle this by posting an event to the Gecko thread automatically,
// but there is no automatic mechanism for non-native methods.
throw new UnsupportedOperationException("Not allowed to queue non-native methods");
}
if (isStateAtLeast(state)) {
invokeMethod(method, obj, argValues.toArray());
return;
}
QUEUED_CALLS.add(new QueuedCall(
method, obj, argValues.toArray(), state));
}
/**
* Queue a call to the given static method until Gecko is in the given state.
*
* @param state The Gecko state in which the native call could be executed.
* Default is State.RUNNING, which means this queued call will
* run when Gecko is at or after RUNNING state.
* @param cls Class that declares the static method.
* @param methodName Name of the static method.
* @param args Args to call the static method with; to specify a parameter type,
* pass in a Class instance first, followed by the value.
*/
public static void queueNativeCallUntil(final State state, final Class<?> cls,
final String methodName, final Object... args) {
synchronized (QUEUED_CALLS) {
queueNativeCallLocked(cls, methodName, null, args, state);
}
}
/**
* Queue a call to the given static method until Gecko is in the RUNNING state.
*/
public static void queueNativeCall(final Class<?> cls, final String methodName,
final Object... args) {
synchronized (QUEUED_CALLS) {
queueNativeCallLocked(cls, methodName, null, args, State.RUNNING);
}
}
/**
* Queue a call to the given instance method until Gecko is in the given state.
*
* @param state The Gecko state in which the native call could be executed.
* @param obj Object that declares the instance method.
* @param methodName Name of the instance method.
* @param args Args to call the instance method with; to specify a parameter type,
* pass in a Class instance first, followed by the value.
*/
public static void queueNativeCallUntil(final State state, final Object obj,
final String methodName, final Object... args) {
synchronized (QUEUED_CALLS) {
queueNativeCallLocked(obj.getClass(), methodName, obj, args, state);
}
}
/**
* Queue a call to the given instance method until Gecko is in the RUNNING state.
*/
public static void queueNativeCall(final Object obj, final String methodName,
final Object... args) {
synchronized (QUEUED_CALLS) {
queueNativeCallLocked(obj.getClass(), methodName, obj, args, State.RUNNING);
}
}
// Run all queued methods
private static void flushQueuedNativeCallsLocked(final State state) {
int lastSkipped = -1;
for (int i = 0; i < QUEUED_CALLS.size(); i++) {
final QueuedCall call = QUEUED_CALLS.get(i);
if (call == null) {
// We already handled the call.
continue;
}
if (!state.isAtLeast(call.state)) {
// The call is not ready yet; skip it.
lastSkipped = i;
continue;
}
// Mark as handled.
QUEUED_CALLS.set(i, null);
invokeMethod(call.method, call.target, call.args);
}
if (lastSkipped < 0) {
// We're done here; release the memory
QUEUED_CALLS.clear();
QUEUED_CALLS.trimToSize();
} else if (lastSkipped < QUEUED_CALLS.size() - 1) {
// We skipped some; free up null entries at the end,
// but keep all the previous entries for later.
QUEUED_CALLS.subList(lastSkipped + 1, QUEUED_CALLS.size()).clear();
}
}
private static void loadGeckoLibs(final Context context, final String resourcePath) {
GeckoLoader.loadSQLiteLibs(context, resourcePath);
GeckoLoader.loadNSSLibs(context, resourcePath);
@ -445,7 +616,7 @@ public class GeckoThread extends Thread {
* @return True if the current Gecko thread state matches
*/
public static boolean isState(final State state) {
return sStateHolder.getState().is(state);
return sState.is(state);
}
/**
@ -456,7 +627,7 @@ public class GeckoThread extends Thread {
* @return True if the current Gecko thread state matches
*/
public static boolean isStateAtLeast(final State state) {
return sStateHolder.getState().isAtLeast(state);
return sState.isAtLeast(state);
}
/**
@ -467,7 +638,7 @@ public class GeckoThread extends Thread {
* @return True if the current Gecko thread state matches
*/
public static boolean isStateAtMost(final State state) {
return state.isAtLeast(sStateHolder.getState());
return sState.isAtMost(state);
}
/**
@ -479,18 +650,28 @@ public class GeckoThread extends Thread {
* @return True if the current Gecko thread state matches
*/
public static boolean isStateBetween(final State minState, final State maxState) {
return isStateAtLeast(minState) && isStateAtMost(maxState);
return sState.isBetween(minState, maxState);
}
@WrapForJNI(calledFrom = "gecko")
private static void setState(final State newState) {
sStateHolder.setState(newState);
ThreadUtils.assertOnGeckoThread();
synchronized (QUEUED_CALLS) {
flushQueuedNativeCallsLocked(newState);
sState = newState;
}
}
@WrapForJNI(calledFrom = "gecko")
private static boolean checkAndSetState(final State expectedState,
final State newState) {
return sStateHolder.checkAndSetState(expectedState, newState);
private static boolean checkAndSetState(final State currentState, final State newState) {
synchronized (QUEUED_CALLS) {
if (sState == currentState) {
flushQueuedNativeCallsLocked(newState);
sState = newState;
return true;
}
}
return false;
}
@WrapForJNI(stubName = "SpeculativeConnect")
@ -554,36 +735,4 @@ public class GeckoThread extends Thread {
private static void requestUiThreadCallback(long delay) {
ThreadUtils.getUiHandler().postDelayed(UI_THREAD_CALLBACK, delay);
}
/**
* Queue a call to the given static method until Gecko is in the RUNNING state.
*/
public static void queueNativeCall(final Class<?> cls, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), State.RUNNING, cls, methodName, args);
}
/**
* Queue a call to the given instance method until Gecko is in the RUNNING state.
*/
public static void queueNativeCall(final Object obj, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), State.RUNNING, obj, methodName, args);
}
/**
* Queue a call to the given instance method until Gecko is in the RUNNING state.
*/
public static void queueNativeCallUntil(final State state, final Object obj, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), state, obj, methodName, args);
}
/**
* Queue a call to the given static method until Gecko is in the RUNNING state.
*/
public static void queueNativeCallUntil(final State state, final Class<?> cls, final String methodName,
final Object... args) {
NativeQueue.queueUntil(getStateHolder(), state, cls, methodName, args);
}
}

Просмотреть файл

@ -12,7 +12,6 @@ import org.mozilla.gecko.annotation.ReflectionTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.gfx.LayerView;
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;
@ -42,40 +41,7 @@ public class GeckoView extends LayerView
private static final boolean DEBUG = false;
/* package */ enum State implements NativeQueue.State {
@WrapForJNI INITIAL(0),
@WrapForJNI READY(1);
private int rank;
private State(int rank) {
this.rank = rank;
}
@Override
public boolean is(final NativeQueue.State other) {
return this == other;
}
@Override
public boolean isAtLeast(final NativeQueue.State other) {
if (other instanceof State) {
return this.rank >= ((State) other).rank;
}
return false;
}
}
private final StateHolder mStateHolder =
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);
private final EventDispatcher mEventDispatcher = new EventDispatcher();
private ChromeDelegate mChromeDelegate;
/* package */ ContentListener mContentListener;

Просмотреть файл

@ -1,219 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import android.util.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
public class NativeQueue {
private static final String LOGTAG = "GeckoNativeQueue";
public interface State {
boolean is(final State other);
boolean isAtLeast(final State other);
}
public static class StateHolder {
private volatile State mState;
private final State mReadyState;
public StateHolder(final State initial, final State ready) {
this.mState = initial;
this.mReadyState = ready;
}
public boolean isReady() {
return getState().isAtLeast(mReadyState);
}
public State getReadyState() {
return mReadyState;
}
public State getState() {
return mState;
}
public boolean setState(final State newState) {
return checkAndSetState(null, newState);
}
public boolean checkAndSetState(final State expectedState,
final State newState) {
synchronized (NativeQueue.sQueue) {
if (expectedState != null && !mState.is(expectedState)) {
return false;
}
NativeQueue.flushQueuedLocked(newState);
mState = newState;
return true;
}
}
}
private static class QueuedCall {
public Method method;
public Object target;
public Object[] args;
public State state;
public QueuedCall(final Method method, final Object target,
final Object[] args, final State state) {
this.method = method;
this.target = target;
this.args = args;
this.state = state;
}
}
private static final int QUEUED_CALLS_COUNT = 16;
/* package */ static final ArrayList<QueuedCall> sQueue =
new ArrayList<>(QUEUED_CALLS_COUNT);
// Invoke the given Method and handle checked Exceptions.
private static void invokeMethod(final Method method, final Object obj,
final Object[] args) {
try {
method.setAccessible(true);
method.invoke(obj, args);
} catch (final IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
} catch (final InvocationTargetException e) {
throw new UnsupportedOperationException("Cannot make call", e.getCause());
}
}
// Queue a call to the given method.
private static void queueNativeCallLocked(final StateHolder stateHolder,
final Class<?> cls,
final String methodName,
final Object obj,
final Object[] args,
final State state) {
final ArrayList<Class<?>> argTypes = new ArrayList<>(args.length);
final ArrayList<Object> argValues = new ArrayList<>(args.length);
for (int i = 0; i < args.length; i++) {
if (args[i] instanceof Class) {
argTypes.add((Class<?>) args[i]);
argValues.add(args[++i]);
continue;
}
Class<?> argType = args[i].getClass();
if (argType == Boolean.class) argType = Boolean.TYPE;
else if (argType == Byte.class) argType = Byte.TYPE;
else if (argType == Character.class) argType = Character.TYPE;
else if (argType == Double.class) argType = Double.TYPE;
else if (argType == Float.class) argType = Float.TYPE;
else if (argType == Integer.class) argType = Integer.TYPE;
else if (argType == Long.class) argType = Long.TYPE;
else if (argType == Short.class) argType = Short.TYPE;
argTypes.add(argType);
argValues.add(args[i]);
}
final Method method;
try {
method = cls.getDeclaredMethod(
methodName, argTypes.toArray(new Class<?>[argTypes.size()]));
} catch (final NoSuchMethodException e) {
throw new IllegalArgumentException("Cannot find method", e);
}
if (!Modifier.isNative(method.getModifiers())) {
// As a precaution, we disallow queuing non-native methods. Queuing non-native
// methods is dangerous because the method could end up being called on either
// the original thread or the Gecko thread depending on timing. Native methods
// usually handle this by posting an event to the Gecko thread automatically,
// but there is no automatic mechanism for non-native methods.
throw new UnsupportedOperationException("Not allowed to queue non-native methods");
}
if (stateHolder.getState().isAtLeast(state)) {
invokeMethod(method, obj, argValues.toArray());
return;
}
sQueue.add(new QueuedCall(
method, obj, argValues.toArray(), state));
}
/**
* Queue a call to the given instance method if the given current state does
* not satisfy the given state.
*
* @param stateHolder The state holder used to query the current state.
* @param state The state in which the native call could be executed.
* @param obj Object that declares the instance method.
* @param methodName Name of the instance method.
* @param args Args to call the instance method with; to specify a parameter
* type, pass in a Class instance first, followed by the value.
*/
public static void queueUntil(final StateHolder stateHolder,
final State state,
final Object obj,
final String methodName,
final Object... args) {
synchronized (sQueue) {
queueNativeCallLocked(stateHolder, obj.getClass(), methodName, obj,
args, state);
}
}
/**
* Queue a call to the given static method if the given current state does
* not satisfy the given state.
*
* @param stateHolder The state holder used to query the current state.
* @param state The state in which the native call could be executed.
* @param cls Class that declares the static method.
* @param methodName Name of the instance method.
* @param args Args to call the instance method with; to specify a parameter
* type, pass in a Class instance first, followed by the value.
*/
public static void queueUntil(final StateHolder stateHolder,
final State state,
final Class<?> cls,
final String methodName,
final Object... args) {
synchronized (sQueue) {
queueNativeCallLocked(stateHolder, cls, methodName, null, args, state);
}
}
// Run all queued methods
private static void flushQueuedLocked(final State state) {
int lastSkipped = -1;
for (int i = 0; i < sQueue.size(); i++) {
final QueuedCall call = sQueue.get(i);
if (call == null) {
// We already handled the call.
continue;
}
if (!state.isAtLeast(call.state)) {
// The call is not ready yet; skip it.
lastSkipped = i;
continue;
}
// Mark as handled.
sQueue.set(i, null);
invokeMethod(call.method, call.target, call.args);
}
if (lastSkipped < 0) {
// We're done here; release the memory
sQueue.clear();
sQueue.trimToSize();
} else if (lastSkipped < sQueue.size() - 1) {
// We skipped some; free up null entries at the end,
// but keep all the previous entries for later.
sQueue.subList(lastSkipped + 1, sQueue.size()).clear();
}
}
}

Просмотреть файл

@ -1000,33 +1000,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<SetState_t>::Call(GeckoView::mCtx, nullptr, a0);
}
const char GeckoView::State::name[] =
"org/mozilla/gecko/GeckoView$State";
constexpr char GeckoView::State::INITIAL_t::name[];
constexpr char GeckoView::State::INITIAL_t::signature[];
auto GeckoView::State::INITIAL() -> State::LocalRef
{
return mozilla::jni::Field<INITIAL_t>::Get(State::Context(), nullptr);
}
constexpr char GeckoView::State::READY_t::name[];
constexpr char GeckoView::State::READY_t::signature[];
auto GeckoView::State::READY() -> State::LocalRef
{
return mozilla::jni::Field<READY_t>::Get(State::Context(), nullptr);
}
const char GeckoView::Window::name[] =
"org/mozilla/gecko/GeckoView$Window";

Просмотреть файл

@ -2988,85 +2988,14 @@ public:
explicit GeckoView(const Context& ctx) : ObjectBase<GeckoView>(ctx) {}
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;
static const int32_t LOAD_SWITCH_TAB = 2;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::GECKO;
};
class GeckoView::State : public mozilla::jni::ObjectBase<State>
{
public:
static const char name[];
explicit State(const Context& ctx) : ObjectBase<State>(ctx) {}
struct INITIAL_t {
typedef State Owner;
typedef State::LocalRef ReturnType;
typedef State::Param SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "INITIAL";
static constexpr char signature[] =
"Lorg/mozilla/gecko/GeckoView$State;";
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::CURRENT;
};
static auto INITIAL() -> State::LocalRef;
struct READY_t {
typedef State Owner;
typedef State::LocalRef ReturnType;
typedef State::Param SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "READY";
static constexpr char signature[] =
"Lorg/mozilla/gecko/GeckoView$State;";
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::CURRENT;
};
static auto READY() -> State::LocalRef;
static const mozilla::jni::CallingThread callingThread =
mozilla::jni::CallingThread::ANY;

Просмотреть файл

@ -573,15 +573,8 @@ 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,7 +268,6 @@ public:
const GeckoView::Window::LocalRef& aInstance,
GeckoView::Param aView)
: window(*aWindow)
, mView(aView)
{
Base::AttachNative(aInstance, static_cast<SupportsWeakPtr*>(this));
}
@ -302,8 +301,6 @@ public:
jni::Object::Param aDispatcher);
void LoadUri(jni::String::Param aUri, int32_t aFlags);
void EnableEventDispatcher();
};
/**
@ -1538,15 +1535,6 @@ nsWindow::GetRootLayerId() const
return mCompositorSession ? mCompositorSession->RootLayerTreeId() : 0;
}
void
nsWindow::EnableEventDispatcher()
{
if (!mGeckoViewSupport) {
return;
}
mGeckoViewSupport->EnableEventDispatcher();
}
void
nsWindow::SetParent(nsIWidget *aNewParent)
{
@ -2073,13 +2061,6 @@ 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,7 +50,6 @@ public:
static void InitNatives();
void SetScreenId(uint32_t aScreenId) { mScreenId = aScreenId; }
void EnableEventDispatcher();
private:
uint32_t mScreenId;