Bug 1235246 - Configure GeckoLayerClient after GLController is initialized; r=snorp

LayerView used to call GeckoLayerClient.onGeckoReady directly if Gecko
is sufficiently loaded. However, onGeckoReady indirectly calls
GLController.createCompositor, and it's possible for the
createCompositor event to be prioritized so that it happens before we
initialize GLController, causing a crash. This patch moves the
onGeckoReady call to the Gecko thread, after GLController is
initialized, to avoid this race condition.
This commit is contained in:
Jim Chen 2016-01-06 21:33:18 -05:00
parent 8b313ba329
commit 8ab9b775f0
5 changed files with 28 additions and 12 deletions

View File

@ -5,7 +5,6 @@
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.annotation.ReflectionTarget;
import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.GeckoAppShell;
@ -151,9 +150,8 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return mGeckoIsReady;
}
// Used by GeckoThread.queueNativeCallUntil through LayerView.onAttachedToWindow.
@ReflectionTarget
public void onGeckoReady() {
@WrapForJNI
private void onGeckoReady() {
mGeckoIsReady = true;
mRootLayer = new VirtualLayer(new IntSize(mView.getWidth(), mView.getHeight()));

View File

@ -268,14 +268,6 @@ public class LayerView extends ScrollView implements Tabs.OnTabsChangedListener
@Override
protected void onAttachedToWindow() {
// Configure GeckoLayerClient once Gecko is ready, but after GeckoView has opened a window.
if (GeckoThread.isStateAtLeast(GeckoThread.State.PROFILE_READY)) {
mLayerClient.onGeckoReady();
} else {
GeckoThread.queueNativeCallUntil(GeckoThread.State.PROFILE_READY,
mLayerClient, "onGeckoReady");
}
// We are adding descendants to this LayerView, but we don't want the
// descendants to affect the way LayerView retains its focus.
setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);

View File

@ -1326,6 +1326,14 @@ auto GeckoLayerClient::IsContentDocumentDisplayed() const -> bool
return mozilla::jni::Method<IsContentDocumentDisplayed_t>::Call(this, nullptr);
}
constexpr char GeckoLayerClient::OnGeckoReady_t::name[];
constexpr char GeckoLayerClient::OnGeckoReady_t::signature[];
auto GeckoLayerClient::OnGeckoReady() const -> void
{
return mozilla::jni::Method<OnGeckoReady_t>::Call(this, nullptr);
}
constexpr char GeckoLayerClient::ProgressiveUpdateCallback_t::name[];
constexpr char GeckoLayerClient::ProgressiveUpdateCallback_t::signature[];

View File

@ -3608,6 +3608,23 @@ public:
auto IsContentDocumentDisplayed() const -> bool;
public:
struct OnGeckoReady_t {
typedef GeckoLayerClient Owner;
typedef void ReturnType;
typedef void SetterType;
typedef mozilla::jni::Args<> Args;
static constexpr char name[] = "onGeckoReady";
static constexpr char signature[] =
"()V";
static const bool isStatic = false;
static const bool isMultithreaded = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
auto OnGeckoReady() const -> void;
public:
struct ProgressiveUpdateCallback_t {
typedef GeckoLayerClient Owner;

View File

@ -546,6 +546,7 @@ public:
// Gecko, and that's what we do here.
const bool resetting = !!mLayerClient;
mLayerClient = layerClient;
layerClient->OnGeckoReady();
if (resetting) {
// Since we are re-linking the new java objects to Gecko, we need