Bug 1589742 - Collect telemetry on the types of user clicks r=smaug

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Sean Feng 2019-11-13 18:12:02 +00:00
Родитель 49d18ed4a2
Коммит a2de02dc9b
7 изменённых файлов: 96 добавлений и 3 удалений

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

@ -2913,6 +2913,15 @@ nsresult Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor) {
nullptr, &status);
if (NS_SUCCEEDED(rv)) {
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
if (!actEvent.DefaultPreventedByContent() &&
mouseEvent->IsTrusted() &&
mouseEvent->mInputSource !=
MouseEvent_Binding::MOZ_SOURCE_KEYBOARD &&
mouseEvent->mInputSource !=
MouseEvent_Binding::MOZ_SOURCE_UNKNOWN) {
Telemetry::AccumulateCategorical(
Telemetry::LABELS_TYPES_OF_USER_CLICKS::Link);
}
}
}
break;

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

@ -346,6 +346,12 @@ class EventTargetChainItem {
if (mManager) {
NS_ASSERTION(aVisitor.mEvent->mCurrentTarget == nullptr,
"CurrentTarget should be null!");
if (aVisitor.mEvent->mMessage == eMouseClick) {
aVisitor.mEvent->mFlags.mHadNonPrivilegedClickListeners =
aVisitor.mEvent->mFlags.mHadNonPrivilegedClickListeners ||
mManager->HasNonPrivilegedClickListeners();
}
mManager->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent,
&aVisitor.mDOMEvent, CurrentTarget(),
&aVisitor.mEventStatus, IsItemInShadowTree());

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

@ -112,7 +112,9 @@ EventListenerManagerBase::EventListenerManagerBase()
mMayHaveInputOrCompositionEventListener(false),
mMayHaveSelectionChangeEventListener(false),
mClearingListeners(false),
mIsMainThreadELM(NS_IsMainThread()) {
mIsMainThreadELM(NS_IsMainThread()),
mHasNonPrivilegedClickListeners(false),
mUnknownNonPrivilegedClickListeners(false) {
static_assert(sizeof(EventListenerManagerBase) == sizeof(uint32_t),
"Keep the size of EventListenerManagerBase size compact!");
}
@ -406,6 +408,13 @@ void EventListenerManager::AddEventListenerInternal(
EventListenerService::NotifyAboutMainThreadListenerChange(mTarget,
aTypeAtom);
}
if (!mHasNonPrivilegedClickListeners || mUnknownNonPrivilegedClickListeners) {
if (IsNonChromeClickListener(listener)) {
mHasNonPrivilegedClickListeners = true;
mUnknownNonPrivilegedClickListeners = false;
}
}
}
void EventListenerManager::ProcessApzAwareEventListenerAdd() {
@ -587,6 +596,9 @@ void EventListenerManager::RemoveEventListenerInternal(
if (EVENT_TYPE_EQUALS(listener, aEventMessage, aUserType, aAllEvents)) {
if (listener->mListener == aListenerHolder &&
listener->mFlags.EqualsForRemoval(aFlags)) {
if (IsNonChromeClickListener(listener)) {
mUnknownNonPrivilegedClickListeners = true;
}
mListeners.RemoveElementAt(i);
NotifyEventListenerRemoved(aUserType);
if (!aAllEvents && deviceType) {
@ -598,6 +610,23 @@ void EventListenerManager::RemoveEventListenerInternal(
}
}
bool EventListenerManager::HasNonPrivilegedClickListeners() {
if (mUnknownNonPrivilegedClickListeners) {
Listener* listener;
mUnknownNonPrivilegedClickListeners = false;
for (uint32_t i = 0; i < mListeners.Length(); ++i) {
listener = &mListeners.ElementAt(i);
if (IsNonChromeClickListener(listener)) {
mHasNonPrivilegedClickListeners = true;
return mHasNonPrivilegedClickListeners;
}
}
mHasNonPrivilegedClickListeners = false;
}
return mHasNonPrivilegedClickListeners;
}
bool EventListenerManager::ListenerCanHandle(const Listener* aListener,
const WidgetEvent* aEvent,
EventMessage aEventMessage) const
@ -839,6 +868,9 @@ void EventListenerManager::RemoveEventHandler(nsAtom* aName) {
Listener* listener = FindEventHandler(eventMessage, aName);
if (listener) {
if (IsNonChromeClickListener(listener)) {
mUnknownNonPrivilegedClickListeners = true;
}
mListeners.RemoveElementAt(uint32_t(listener - &mListeners.ElementAt(0)));
NotifyEventListenerRemoved(aName);
if (IsDeviceType(eventMessage)) {
@ -847,6 +879,13 @@ void EventListenerManager::RemoveEventHandler(nsAtom* aName) {
}
}
bool EventListenerManager::IsNonChromeClickListener(Listener* aListener) {
return !aListener->mFlags.mInSystemGroup && !aListener->mIsChrome &&
aListener->mEventMessage == eMouseClick &&
(aListener->GetJSEventHandler() ||
aListener->mListener.HasWebIDLCallback());
}
nsresult EventListenerManager::CompileEventHandlerInternal(
Listener* aListener, const nsAString* aBody, Element* aElement) {
MOZ_ASSERT(aListener->GetJSEventHandler());

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

@ -157,7 +157,9 @@ class EventListenerManagerBase {
uint16_t mMayHaveSelectionChangeEventListener : 1;
uint16_t mClearingListeners : 1;
uint16_t mIsMainThreadELM : 1;
// uint16_t mUnused : 4;
uint16_t mHasNonPrivilegedClickListeners : 1;
uint16_t mUnknownNonPrivilegedClickListeners : 1;
// uint16_t mUnused : 2;
};
/*
@ -426,6 +428,8 @@ class EventListenerManager final : public EventListenerManagerBase {
return mMayHaveSelectionChangeEventListener;
}
bool HasNonPrivilegedClickListeners();
/**
* Returns true if there may be a key event listener (keydown, keypress,
* or keyup) registered, or false if there definitely isn't.
@ -458,6 +462,8 @@ class EventListenerManager final : public EventListenerManagerBase {
bool IsApzAwareListener(Listener* aListener);
bool IsApzAwareEvent(nsAtom* aEvent);
// Return true if aListener is a non-chrome-privileged click event listner
bool IsNonChromeClickListener(Listener* aListener);
/**
* Remove all event listeners from the event target this EventListenerManager
* is for.

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

@ -19,6 +19,7 @@
#include "mozilla/TextEditor.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/Telemetry.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/DragEvent.h"
#include "mozilla/dom/Event.h"
@ -4999,6 +5000,11 @@ nsresult EventStateManager::InitAndDispatchClickEvent(
nsEventStatus status = nsEventStatus_eIgnore;
nsresult rv = aPresShell->HandleEventWithTarget(
&event, targetFrame, MOZ_KnownLive(target), &status);
if (event.mFlags.mHadNonPrivilegedClickListeners && !aNoContentDispatch) {
Telemetry::AccumulateCategorical(
Telemetry::LABELS_TYPES_OF_USER_CLICKS::Has_JS_Listener);
}
// Copy mMultipleActionsPrevented flag from a click event to the mouseup
// event only when it's set to true. It may be set to true if an editor has
// already handled it. This is important to avoid two or more default
@ -5125,6 +5131,14 @@ nsresult EventStateManager::DispatchClickEvents(
}
}
// notDispatchToContents is used here because we don't want to
// count auxclicks.
if (XRE_IsParentProcess() && !IsRemoteTarget(aClickTarget) &&
!notDispatchToContents) {
Telemetry::AccumulateCategorical(
Telemetry::LABELS_TYPES_OF_USER_CLICKS::Browser_Chrome);
}
return rv;
}

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

@ -14561,6 +14561,21 @@
],
"description": "The common combinations of BFCacheStatus when we determine whether the page can be BFCached or not; If it uses BFCache, we record BFCache_Success; If it's not and it falls under common failure reasons combinations, we record the corresponding combination; Otherwise, we record Other to indicate this is not a common failure"
},
"TYPES_OF_USER_CLICKS": {
"record_in_processes": ["main", "content"],
"products": ["firefox"],
"alert_emails": ["sefeng@mozilla.com", "perfteam@mozilla.com"],
"bug_numbers": [1589742],
"expires_in_version": "79",
"kind": "categorical",
"releaseChannelCollection": "opt-out",
"labels": [
"Browser_Chrome",
"Link",
"Has_JS_Listener"
],
"description": "When a user click(Mousedown + Mouseup event by using the left mouse button) happens, record if it's a click on browser chrome (parent process), a anchor element or an element which has non-privileged click event listener associated"
},
"BFCACHE_PAGE_RESTORED": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],

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

@ -175,6 +175,10 @@ struct BaseEventFlags {
// instance).
bool mPostedToRemoteProcess : 1;
// At lease one of the event in the event path had non privileged click
// listener.
bool mHadNonPrivilegedClickListeners : 1;
// If the event is being handled in target phase, returns true.
inline bool InTargetPhase() const {
return (mInBubblingPhase && mInCapturePhase);
@ -365,7 +369,7 @@ struct BaseEventFlags {
}
private:
typedef uint32_t RawFlags;
typedef uint64_t RawFlags;
inline void SetRawFlags(RawFlags aRawFlags) {
static_assert(sizeof(BaseEventFlags) <= sizeof(RawFlags),