Bug 1511063 - Only send GeckoView history messages when there are listeners r=lina,geckoview-reviewers

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
James Willcox 2018-12-10 22:58:31 +00:00
parent fced5f7055
commit a3138042ef
4 changed files with 43 additions and 4 deletions

View File

@ -26,6 +26,9 @@ using namespace mozilla::dom;
using namespace mozilla::ipc;
using namespace mozilla::widget;
static const char16_t kOnVisitedMessage[] = u"GeckoView:OnVisited";
static const char16_t kGetVisitedMessage[] = u"GeckoView:GetVisited";
// Keep in sync with `GeckoSession.HistoryDelegate.VisitFlags`.
enum class GeckoViewVisitFlags : int32_t {
VISIT_TOP_LEVEL = 1 << 0,
@ -386,6 +389,11 @@ GeckoViewHistory::VisitURI(nsIWidget* aWidget, nsIURI* aURI,
return NS_OK;
}
// If nobody is listening for this, we can stop now.
if (!dispatcher->HasListener(kOnVisitedMessage)) {
return NS_OK;
}
AutoTArray<jni::String::LocalRef, 3> keys;
AutoTArray<jni::Object::LocalRef, 3> values;
@ -444,8 +452,8 @@ GeckoViewHistory::VisitURI(nsIWidget* aWidget, nsIURI* aURI,
nsCOMPtr<nsIAndroidEventCallback> callback =
new OnVisitedCallback(this, dispatcher->GetGlobalObject(), aURI);
Unused << NS_WARN_IF(NS_FAILED(
dispatcher->Dispatch(u"GeckoView:OnVisited", bundle, callback)));
Unused << NS_WARN_IF(
NS_FAILED(dispatcher->Dispatch(kOnVisitedMessage, bundle, callback)));
return NS_OK;
}
@ -590,6 +598,11 @@ void GeckoViewHistory::QueryVisitedState(
return;
}
// If nobody is listening for this we can stop now
if (!dispatcher->HasListener(kGetVisitedMessage)) {
return;
}
// Assemble a bundle like `{ urls: ["http://example.com/1", ...] }`.
auto uris = jni::ObjectArray::New<jni::String>(aURIs.Length());
for (size_t i = 0; i < aURIs.Length(); ++i) {
@ -614,8 +627,8 @@ void GeckoViewHistory::QueryVisitedState(
nsCOMPtr<nsIAndroidEventCallback> callback =
new GetVisitedCallback(this, dispatcher->GetGlobalObject(), aURIs);
Unused << NS_WARN_IF(NS_FAILED(
dispatcher->Dispatch(u"GeckoView:GetVisited", bundle, callback)));
Unused << NS_WARN_IF(
NS_FAILED(dispatcher->Dispatch(kGetVisitedMessage, bundle, callback)));
}
/**

View File

@ -325,6 +325,21 @@ public final class EventDispatcher extends JNIObject {
return false;
}
@WrapForJNI
public boolean hasListener(final String event) {
for (final Map<String, ?> listenersMap : Arrays.asList(mGeckoThreadListeners,
mUiThreadListeners,
mBackgroundThreadListeners)) {
synchronized (listenersMap) {
if (listenersMap.get(event) != null) {
return true;
}
}
}
return false;
}
private boolean dispatchToThread(final String type,
final GeckoBundle message,
final EventCallback callback,

View File

@ -760,6 +760,16 @@ EventDispatcher::WrapCallback(nsIAndroidEventCallback* aCallback,
return callback;
}
bool EventDispatcher::HasListener(const char16_t* aEvent) {
java::EventDispatcher::LocalRef dispatcher(mDispatcher);
if (!dispatcher) {
return false;
}
nsDependentString event(aEvent);
return dispatcher->HasListener(event);
}
NS_IMETHODIMP
EventDispatcher::Dispatch(JS::HandleValue aEvent, JS::HandleValue aData,
nsIAndroidEventCallback* aCallback,

View File

@ -44,6 +44,7 @@ class EventDispatcher final
java::GeckoBundle::Param aData = nullptr,
nsIAndroidEventCallback* aCallback = nullptr);
bool HasListener(const char16_t* aEvent);
bool HasGeckoListener(jni::String::Param aEvent);
void DispatchToGecko(jni::String::Param aEvent, jni::Object::Param aData,
jni::Object::Param aCallback);