Bug 1562761 - Add support for dispatching java runnables to Gecko event targets. r=snorp

Differential Revision: https://phabricator.services.mozilla.com/D52197

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Bobby Holley 2019-11-08 18:08:03 +00:00
parent 98904c4e42
commit 105c2ab943
4 changed files with 106 additions and 4 deletions

View File

@ -179,8 +179,6 @@ class BaseProcessLauncher {
return XRE_ChildProcessTypeToString(mProcessType); return XRE_ChildProcessTypeToString(mProcessType);
} }
nsCOMPtr<nsIEventTarget> GetIPCLauncher();
nsCOMPtr<nsISerialEventTarget> mLaunchThread; nsCOMPtr<nsISerialEventTarget> mLaunchThread;
GeckoProcessType mProcessType; GeckoProcessType mProcessType;
UniquePtr<base::LaunchOptions> mLaunchOptions; UniquePtr<base::LaunchOptions> mLaunchOptions;
@ -840,7 +838,7 @@ IPCLaunchThreadObserver::Observe(nsISupports* aSubject, const char* aTopic,
return rv; return rv;
} }
nsCOMPtr<nsIEventTarget> BaseProcessLauncher::GetIPCLauncher() { nsCOMPtr<nsIEventTarget> GetIPCLauncher() {
StaticMutexAutoLock lock(gIPCLaunchThreadMutex); StaticMutexAutoLock lock(gIPCLaunchThreadMutex);
if (!gIPCLaunchThread) { if (!gIPCLaunchThread) {
nsCOMPtr<nsIThread> thread; nsCOMPtr<nsIThread> thread;
@ -867,7 +865,7 @@ nsCOMPtr<nsIEventTarget> BaseProcessLauncher::GetIPCLauncher() {
// Other platforms use an on-demand thread pool. // Other platforms use an on-demand thread pool.
nsCOMPtr<nsIEventTarget> BaseProcessLauncher::GetIPCLauncher() { nsCOMPtr<nsIEventTarget> GetIPCLauncher() {
nsCOMPtr<nsIEventTarget> pool = nsCOMPtr<nsIEventTarget> pool =
mozilla::SharedThreadPool::Get(NS_LITERAL_CSTRING("IPC Launch")); mozilla::SharedThreadPool::Get(NS_LITERAL_CSTRING("IPC Launch"));
MOZ_DIAGNOSTIC_ASSERT(pool); MOZ_DIAGNOSTIC_ASSERT(pool);

View File

@ -271,6 +271,8 @@ class GeckoChildProcessHost : public ChildProcessHost,
static StaticMutex sMutex; static StaticMutex sMutex;
}; };
nsCOMPtr<nsIEventTarget> GetIPCLauncher();
} /* namespace ipc */ } /* namespace ipc */
} /* namespace mozilla */ } /* namespace mozilla */

View File

@ -0,0 +1,58 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.util;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.mozglue.JNIObject;
/**
* Wrapper for nsIEventTarget, enabling seamless dispatch of java runnables to
* Gecko event queues.
*/
@WrapForJNI
public final class XPCOMEventTarget extends JNIObject {
public void dispatch(final Runnable runnable) {
dispatchNative(new JNIRunnable(runnable));
}
public static synchronized XPCOMEventTarget mainThread() {
if (mMainThread == null) {
mMainThread = createWrapper("main");
}
return mMainThread;
}
private static XPCOMEventTarget mMainThread = null;
public static synchronized XPCOMEventTarget launcherThread() {
if (mLauncherThread == null) {
mLauncherThread = createWrapper("launcher");
}
return mLauncherThread;
}
private static XPCOMEventTarget mLauncherThread = null;
public native boolean isOnCurrentThread();
private native void dispatchNative(JNIRunnable runnable);
private static native XPCOMEventTarget createWrapper(String name);
@Override
protected native void disposeNative();
@WrapForJNI
final class JNIRunnable {
JNIRunnable(final Runnable inner) {
mInner = inner;
}
@WrapForJNI
void run() {
mInner.run();
}
private Runnable mInner;
}
}

View File

@ -34,6 +34,7 @@
#include "mozilla/Hal.h" #include "mozilla/Hal.h"
#include "mozilla/dom/BrowserChild.h" #include "mozilla/dom/BrowserChild.h"
#include "mozilla/intl/OSPreferences.h" #include "mozilla/intl/OSPreferences.h"
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/widget/ScreenManager.h" #include "mozilla/widget/ScreenManager.h"
#include "prenv.h" #include "prenv.h"
@ -350,6 +351,47 @@ class GeckoAppShellSupport final
} }
}; };
class XPCOMEventTargetWrapper final
: public java::XPCOMEventTarget::Natives<XPCOMEventTargetWrapper> {
public:
// Wraps a java runnable into an XPCOM runnable and dispatches it to mTarget.
void DispatchNative(mozilla::jni::Object::Param aJavaRunnable) {
java::XPCOMEventTarget::JNIRunnable::GlobalRef r =
java::XPCOMEventTarget::JNIRunnable::Ref::From(aJavaRunnable);
mTarget->Dispatch(NS_NewRunnableFunction(
"XPCOMEventTargetWrapper::DispatchNative",
[runnable = std::move(r)]() { runnable->Run(); }));
}
bool IsOnCurrentThread() { return mTarget->IsOnCurrentThread(); }
// Instantiates a wrapper. The Java code calls this only once per wrapped
// thread, and caches the result.
static java::XPCOMEventTarget::LocalRef CreateWrapper(
mozilla::jni::String::Param aName) {
nsString name(aName->ToString());
nsCOMPtr<nsIEventTarget> target;
if (name.EqualsLiteral("main")) {
target = do_GetMainThread();
} else if (name.EqualsLiteral("launcher")) {
target = ipc::GetIPCLauncher();
} else {
MOZ_CRASH("Trying to create JNI wrapper for unknown XPCOM thread");
}
auto java = java::XPCOMEventTarget::New();
auto native = MakeUnique<XPCOMEventTargetWrapper>(target.forget());
AttachNative(java, std::move(native));
return java;
}
explicit XPCOMEventTargetWrapper(already_AddRefed<nsIEventTarget> aTarget)
: mTarget(aTarget) {}
private:
nsCOMPtr<nsIEventTarget> mTarget;
};
nsAppShell::nsAppShell() nsAppShell::nsAppShell()
: mSyncRunFinished(*(sAppShellLock = new Mutex("nsAppShell")), : mSyncRunFinished(*(sAppShellLock = new Mutex("nsAppShell")),
"nsAppShell.SyncRun"), "nsAppShell.SyncRun"),
@ -365,6 +407,7 @@ nsAppShell::nsAppShell()
if (jni::IsAvailable()) { if (jni::IsAvailable()) {
GeckoThreadSupport::Init(); GeckoThreadSupport::Init();
GeckoAppShellSupport::Init(); GeckoAppShellSupport::Init();
XPCOMEventTargetWrapper::Init();
mozilla::GeckoSystemStateListener::Init(); mozilla::GeckoSystemStateListener::Init();
mozilla::widget::Telemetry::Init(); mozilla::widget::Telemetry::Init();
mozilla::widget::GeckoTelemetryDelegate::Init(); mozilla::widget::GeckoTelemetryDelegate::Init();
@ -383,6 +426,7 @@ nsAppShell::nsAppShell()
AndroidBridge::ConstructBridge(); AndroidBridge::ConstructBridge();
GeckoAppShellSupport::Init(); GeckoAppShellSupport::Init();
GeckoThreadSupport::Init(); GeckoThreadSupport::Init();
XPCOMEventTargetWrapper::Init();
mozilla::GeckoBatteryManager::Init(); mozilla::GeckoBatteryManager::Init();
mozilla::GeckoNetworkManager::Init(); mozilla::GeckoNetworkManager::Init();
mozilla::GeckoProcessManager::Init(); mozilla::GeckoProcessManager::Init();