author | Eugen Sawin <esawin@mozilla.com> |
Tue, 13 Nov 2018 15:29:21 +0100 | |
changeset 502472 | 24e87b02707bee36e1e98eb37c94fbaf3834e898 |
parent 502471 | 8bc653b02e2f7aa97fc460cfa1dc1cd7e5e16302 |
child 502536 | b0298991e6d3f430a6d30bc32e8cf404f87f8f5a |
child 502570 | f052d5b3a612c9c12ad3e6feaf95416f06d4119a |
push id | 10290 |
push user | ffxbld-merge |
push date | Mon, 03 Dec 2018 16:23:23 +0000 |
treeherder | mozilla-beta@700bed2445e6 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jchen |
bugs | 1499418 |
milestone | 65.0a1 |
first release with | nightly linux32
24e87b02707b
/
65.0a1
/
20181113220101
/
files
nightly linux64
24e87b02707b
/
65.0a1
/
20181113220101
/
files
nightly mac
24e87b02707b
/
65.0a1
/
20181113220101
/
files
nightly win32
24e87b02707b
/
65.0a1
/
20181113220101
/
files
nightly win64
24e87b02707b
/
65.0a1
/
20181113220101
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
65.0a1
/
20181113220101
/
pushlog to previous
nightly linux64
65.0a1
/
20181113220101
/
pushlog to previous
nightly mac
65.0a1
/
20181113220101
/
pushlog to previous
nightly win32
65.0a1
/
20181113220101
/
pushlog to previous
nightly win64
65.0a1
/
20181113220101
/
pushlog to previous
|
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -315,18 +315,18 @@ public abstract class GeckoApp extends G // so just skip the tab and try the next one. } } } }; protected boolean mInitialized; protected boolean mWindowFocusInitialized; - private Telemetry.Timer mJavaUiStartupTimer; - private Telemetry.Timer mGeckoReadyStartupTimer; + private TelemetryUtils.Timer mJavaUiStartupTimer; + private TelemetryUtils.Timer mGeckoReadyStartupTimer; private String mPrivateBrowsingSession; private boolean mPrivateBrowsingSessionOutdated; private static final int MAX_PRIVATE_TABS_UPDATE_WAIT_MSEC = 500; private volatile HealthRecorder mHealthRecorder; private volatile Locale mLastLocale; @@ -973,18 +973,18 @@ public abstract class GeckoApp extends G } else { showSDKVersionError(); } finish(); return; } // The clock starts...now. Better hurry! - mJavaUiStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_JAVAUI"); - mGeckoReadyStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_GECKOREADY"); + mJavaUiStartupTimer = new TelemetryUtils.UptimeTimer("FENNEC_STARTUP_TIME_JAVAUI"); + mGeckoReadyStartupTimer = new TelemetryUtils.UptimeTimer("FENNEC_STARTUP_TIME_GECKOREADY"); final SafeIntent intent = new SafeIntent(getIntent()); handleGeckoProfilerOptions(intent); // Workaround for <http://code.google.com/p/android/issues/detail?id=20915>. try { Class.forName("android.os.AsyncTask");
--- a/mobile/android/base/java/org/mozilla/gecko/Telemetry.java +++ b/mobile/android/base/java/org/mozilla/gecko/Telemetry.java @@ -8,219 +8,91 @@ package org.mozilla.gecko; import org.mozilla.gecko.annotation.RobocopTarget; import org.mozilla.gecko.annotation.WrapForJNI; import org.mozilla.gecko.TelemetryContract.Event; import org.mozilla.gecko.TelemetryContract.Method; import org.mozilla.gecko.TelemetryContract.Reason; import org.mozilla.gecko.TelemetryContract.Session; import org.mozilla.gecko.mma.MmaDelegate; -import android.os.SystemClock; import android.util.Log; import static org.mozilla.gecko.mma.MmaDelegate.INTERACT_WITH_SEARCH_URL_AREA; import static org.mozilla.gecko.mma.MmaDelegate.OPENED_BOOKMARK; import static org.mozilla.gecko.mma.MmaDelegate.SAVED_BOOKMARK; import static org.mozilla.gecko.mma.MmaDelegate.SAVED_LOGIN_AND_PASSWORD; import static org.mozilla.gecko.mma.MmaDelegate.SCREENSHOT; -/** - * All telemetry times are relative to one of two clocks: - * - * * Real time since the device was booted, including deep sleep. Use this - * as a substitute for wall clock. - * * Uptime since the device was booted, excluding deep sleep. Use this to - * avoid timing a user activity when their phone is in their pocket! - * - * The majority of methods in this class are defined in terms of real time. - */ @RobocopTarget public class Telemetry { private static final String LOGTAG = "Telemetry"; - @WrapForJNI(stubName = "AddHistogram", dispatchTo = "gecko") - private static native void nativeAddHistogram(String name, int value); - @WrapForJNI(stubName = "AddKeyedHistogram", dispatchTo = "gecko") - private static native void nativeAddKeyedHistogram(String name, String key, int value); - @WrapForJNI(stubName = "StartUISession", dispatchTo = "gecko") - private static native void nativeStartUiSession(String name, long timestamp); - @WrapForJNI(stubName = "StopUISession", dispatchTo = "gecko") - private static native void nativeStopUiSession(String name, String reason, long timestamp); - @WrapForJNI(stubName = "AddUIEvent", dispatchTo = "gecko") - private static native void nativeAddUiEvent(String action, String method, - long timestamp, String extras); - - public static long uptime() { - return SystemClock.uptimeMillis(); - } - - public static long realtime() { - return SystemClock.elapsedRealtime(); - } - - // Define new histograms in: - // toolkit/components/telemetry/Histograms.json public static void addToHistogram(String name, int value) { - if (GeckoThread.isRunning()) { - nativeAddHistogram(name, value); - } else { - GeckoThread.queueNativeCall(Telemetry.class, "nativeAddHistogram", - String.class, name, value); - } + TelemetryUtils.addToHistogram(name, value); } public static void addToKeyedHistogram(String name, String key, int value) { - if (GeckoThread.isRunning()) { - nativeAddKeyedHistogram(name, key, value); - } else { - GeckoThread.queueNativeCall(Telemetry.class, "nativeAddKeyedHistogram", - String.class, name, String.class, key, value); - } - } - - public abstract static class Timer { - private final long mStartTime; - private final String mName; - - private volatile boolean mHasFinished; - private volatile long mElapsed = -1; - - protected abstract long now(); - - public Timer(String name) { - mName = name; - mStartTime = now(); - } - - public void cancel() { - mHasFinished = true; - } - - public long getElapsed() { - return mElapsed; - } - - public void stop() { - // Only the first stop counts. - if (mHasFinished) { - return; - } - - mHasFinished = true; - - final long elapsed = now() - mStartTime; - if (elapsed < 0) { - Log.e(LOGTAG, "Current time less than start time -- clock shenanigans?"); - return; - } - - mElapsed = elapsed; - if (elapsed > Integer.MAX_VALUE) { - Log.e(LOGTAG, "Duration of " + elapsed + "ms is too great to add to histogram."); - return; - } - - addToHistogram(mName, (int) (elapsed)); - } - } - - public static class RealtimeTimer extends Timer { - public RealtimeTimer(String name) { - super(name); - } - - @Override - protected long now() { - return Telemetry.realtime(); - } - } - - public static class UptimeTimer extends Timer { - public UptimeTimer(String name) { - super(name); - } - - @Override - protected long now() { - return Telemetry.uptime(); - } + TelemetryUtils.addToKeyedHistogram(name, key, value); } public static void startUISession(final Session session, final String sessionNameSuffix) { - final String sessionName = getSessionName(session, sessionNameSuffix); - - Log.d(LOGTAG, "StartUISession: " + sessionName); - if (GeckoThread.isRunning()) { - nativeStartUiSession(sessionName, realtime()); - } else { - GeckoThread.queueNativeCall(Telemetry.class, "nativeStartUiSession", - String.class, sessionName, realtime()); - } + TelemetryUtils.startUISession(session, sessionNameSuffix); } public static void startUISession(final Session session) { startUISession(session, null); } public static void stopUISession(final Session session, final String sessionNameSuffix, final Reason reason) { - final String sessionName = getSessionName(session, sessionNameSuffix); - - Log.d(LOGTAG, "StopUISession: " + sessionName + ", reason=" + reason); - if (GeckoThread.isRunning()) { - nativeStopUiSession(sessionName, reason.toString(), realtime()); - } else { - GeckoThread.queueNativeCall(Telemetry.class, "nativeStopUiSession", - String.class, sessionName, - String.class, reason.toString(), realtime()); - } + TelemetryUtils.stopUISession(session, sessionNameSuffix, reason); } public static void stopUISession(final Session session, final Reason reason) { stopUISession(session, null, reason); } public static void stopUISession(final Session session, final String sessionNameSuffix) { stopUISession(session, sessionNameSuffix, Reason.NONE); } public static void stopUISession(final Session session) { stopUISession(session, null, Reason.NONE); } - private static String getSessionName(final Session session, final String sessionNameSuffix) { - if (sessionNameSuffix != null) { - return session.toString() + ":" + sessionNameSuffix; - } else { - return session.toString(); - } + public static void sendUIEvent(final Event event, final Method method, final long timestamp, + final String extras) { + sendUIEvent(event.toString(), method, timestamp, extras); + } + + public static void sendUIEvent(final Event event, final Method method, final long timestamp) { + sendUIEvent(event, method, timestamp, null); + } + + public static void sendUIEvent(final Event event, final Method method, final String extras) { + sendUIEvent(event, method, TelemetryUtils.realtime(), extras); } - /** - * @param method A non-null method (if null is desired, consider using Method.NONE) - */ + public static void sendUIEvent(final Event event, final Method method) { + sendUIEvent(event, method, TelemetryUtils.realtime(), null); + } + + public static void sendUIEvent(final Event event) { + sendUIEvent(event, Method.NONE, TelemetryUtils.realtime(), null); + } + + public static void sendUIEvent(final Event event, final boolean eventStatus) { + final String eventName = event + ":" + eventStatus; + sendUIEvent(eventName, Method.NONE, TelemetryUtils.realtime(), null); + } + private static void sendUIEvent(final String eventName, final Method method, final long timestamp, final String extras) { - if (method == null) { - throw new IllegalArgumentException("Expected non-null method - use Method.NONE?"); - } - - if (!AppConstants.RELEASE_OR_BETA) { - final String logString = "SendUIEvent: event = " + eventName + " method = " + method + " timestamp = " + - timestamp + " extras = " + extras; - Log.d(LOGTAG, logString); - } - if (GeckoThread.isRunning()) { - nativeAddUiEvent(eventName, method.toString(), timestamp, extras); - } else { - GeckoThread.queueNativeCall(Telemetry.class, "nativeAddUiEvent", - String.class, eventName, String.class, method.toString(), - timestamp, String.class, extras); - } + TelemetryUtils.sendUIEvent(eventName, method, timestamp, extras); mappingMmaTracking(eventName, method, extras); } private static void mappingMmaTracking(String eventName, Method method, String extras) { if (eventName == null || method == null || extras == null) { return; } if (eventName.equalsIgnoreCase(Event.SAVE.toString()) && method == Method.MENU && extras.equals("bookmark")) { @@ -230,43 +102,9 @@ public class Telemetry { } else if (eventName.equalsIgnoreCase(Event.SHOW.toString()) && method == Method.ACTIONBAR && extras.equals("urlbar-url")) { MmaDelegate.track(INTERACT_WITH_SEARCH_URL_AREA); } else if (eventName.equalsIgnoreCase(Event.SHARE.toString()) && method == Method.BUTTON && extras.equals("screenshot")) { MmaDelegate.track(SCREENSHOT); } else if (eventName.equalsIgnoreCase(Event.ACTION.toString()) && method == Method.DOORHANGER && extras.equals("login-positive")) { MmaDelegate.track(SAVED_LOGIN_AND_PASSWORD); } } - - public static void sendUIEvent(final Event event, final Method method, final long timestamp, - final String extras) { - sendUIEvent(event.toString(), method, timestamp, extras); - } - - public static void sendUIEvent(final Event event, final Method method, final long timestamp) { - sendUIEvent(event, method, timestamp, null); - } - - public static void sendUIEvent(final Event event, final Method method, final String extras) { - sendUIEvent(event, method, realtime(), extras); - } - - public static void sendUIEvent(final Event event, final Method method) { - sendUIEvent(event, method, realtime(), null); - } - - public static void sendUIEvent(final Event event) { - sendUIEvent(event, Method.NONE, realtime(), null); - } - - /** - * Sends a UIEvent with the given status appended to the event name. - * - * This method is a slight bend of the Telemetry framework so chances - * are that you don't want to use this: please think really hard before you do. - * - * Intended for use with data policy notifications. - */ - public static void sendUIEvent(final Event event, final boolean eventStatus) { - final String eventName = event + ":" + eventStatus; - sendUIEvent(eventName, Method.NONE, realtime(), null); - } }
rename from mobile/android/base/java/org/mozilla/gecko/TelemetryContract.java rename to mobile/android/geckoview/src/main/java/org/mozilla/gecko/TelemetryContract.java
new file mode 100644 --- /dev/null +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/TelemetryUtils.java @@ -0,0 +1,247 @@ +/* -*- 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; + +import org.mozilla.gecko.annotation.WrapForJNI; +import org.mozilla.gecko.TelemetryContract.Event; +import org.mozilla.gecko.TelemetryContract.Method; +import org.mozilla.gecko.TelemetryContract.Reason; +import org.mozilla.gecko.TelemetryContract.Session; + +import android.os.SystemClock; +import android.util.Log; + +/** + * All telemetry times are relative to one of two clocks: + * + * * Real time since the device was booted, including deep sleep. Use this + * as a substitute for wall clock. + * * Uptime since the device was booted, excluding deep sleep. Use this to + * avoid timing a user activity when their phone is in their pocket! + * + * The majority of methods in this class are defined in terms of real time. + */ +public class TelemetryUtils { + + private static final boolean DEBUG = false; + private static final String LOGTAG = "TelemetryUtils"; + + @WrapForJNI(stubName = "AddHistogram", dispatchTo = "gecko") + private static native void nativeAddHistogram(String name, int value); + @WrapForJNI(stubName = "AddKeyedHistogram", dispatchTo = "gecko") + private static native void nativeAddKeyedHistogram(String name, String key, int value); + + public static long uptime() { + return SystemClock.uptimeMillis(); + } + + public static long realtime() { + return SystemClock.elapsedRealtime(); + } + + // Define new histograms in: + // toolkit/components/telemetry/Histograms.json + public static void addToHistogram(String name, int value) { + if (GeckoThread.isRunning()) { + nativeAddHistogram(name, value); + } else { + GeckoThread.queueNativeCall(TelemetryUtils.class, "nativeAddHistogram", + String.class, name, value); + } + } + + public static void addToKeyedHistogram(String name, String key, int value) { + if (GeckoThread.isRunning()) { + nativeAddKeyedHistogram(name, key, value); + } else { + GeckoThread.queueNativeCall(TelemetryUtils.class, "nativeAddKeyedHistogram", + String.class, name, String.class, key, value); + } + } + + public abstract static class Timer { + private final long mStartTime; + private final String mName; + + private volatile boolean mHasFinished; + private volatile long mElapsed = -1; + + protected abstract long now(); + + public Timer(String name) { + mName = name; + mStartTime = now(); + } + + public void cancel() { + mHasFinished = true; + } + + public long getElapsed() { + return mElapsed; + } + + public void stop() { + // Only the first stop counts. + if (mHasFinished) { + return; + } + + mHasFinished = true; + + final long elapsed = now() - mStartTime; + if (elapsed < 0) { + Log.e(LOGTAG, "Current time less than start time -- clock shenanigans?"); + return; + } + + mElapsed = elapsed; + if (elapsed > Integer.MAX_VALUE) { + Log.e(LOGTAG, "Duration of " + elapsed + "ms is too great to add to histogram."); + return; + } + + addToHistogram(mName, (int) (elapsed)); + } + } + + public static class RealtimeTimer extends Timer { + public RealtimeTimer(String name) { + super(name); + } + + @Override + protected long now() { + return TelemetryUtils.realtime(); + } + } + + public static class UptimeTimer extends Timer { + public UptimeTimer(String name) { + super(name); + } + + @Override + protected long now() { + return TelemetryUtils.uptime(); + } + } + + @WrapForJNI(stubName = "StartUISession", dispatchTo = "gecko") + private static native void nativeStartUiSession(String name, long timestamp); + @WrapForJNI(stubName = "StopUISession", dispatchTo = "gecko") + private static native void nativeStopUiSession(String name, String reason, long timestamp); + @WrapForJNI(stubName = "AddUIEvent", dispatchTo = "gecko") + private static native void nativeAddUiEvent(String action, String method, + long timestamp, String extras); + + public static void startUISession(final Session session, final String sessionNameSuffix) { + final String sessionName = getSessionName(session, sessionNameSuffix); + + Log.d(LOGTAG, "StartUISession: " + sessionName); + if (GeckoThread.isRunning()) { + nativeStartUiSession(sessionName, realtime()); + } else { + GeckoThread.queueNativeCall(TelemetryUtils.class, "nativeStartUiSession", + String.class, sessionName, realtime()); + } + } + + public static void startUISession(final Session session) { + startUISession(session, null); + } + + public static void stopUISession(final Session session, final String sessionNameSuffix, + final Reason reason) { + final String sessionName = getSessionName(session, sessionNameSuffix); + + Log.d(LOGTAG, "StopUISession: " + sessionName + ", reason=" + reason); + if (GeckoThread.isRunning()) { + nativeStopUiSession(sessionName, reason.toString(), realtime()); + } else { + GeckoThread.queueNativeCall(TelemetryUtils.class, "nativeStopUiSession", + String.class, sessionName, + String.class, reason.toString(), realtime()); + } + } + + public static void stopUISession(final Session session, final Reason reason) { + stopUISession(session, null, reason); + } + + public static void stopUISession(final Session session, final String sessionNameSuffix) { + stopUISession(session, sessionNameSuffix, Reason.NONE); + } + + public static void stopUISession(final Session session) { + stopUISession(session, null, Reason.NONE); + } + + private static String getSessionName(final Session session, final String sessionNameSuffix) { + if (sessionNameSuffix != null) { + return session.toString() + ":" + sessionNameSuffix; + } else { + return session.toString(); + } + } + + /** + * @param method A non-null method (if null is desired, consider using Method.NONE) + */ + /* package */ static void sendUIEvent(final String eventName, final Method method, + final long timestamp, final String extras) { + if (method == null) { + throw new IllegalArgumentException("Expected non-null method - use Method.NONE?"); + } + + if (DEBUG) { + final String logString = "SendUIEvent: event = " + eventName + " method = " + method + " timestamp = " + + timestamp + " extras = " + extras; + Log.d(LOGTAG, logString); + } + if (GeckoThread.isRunning()) { + nativeAddUiEvent(eventName, method.toString(), timestamp, extras); + } else { + GeckoThread.queueNativeCall(TelemetryUtils.class, "nativeAddUiEvent", + String.class, eventName, String.class, method.toString(), + timestamp, String.class, extras); + } + } + + public static void sendUIEvent(final Event event, final Method method, final long timestamp, + final String extras) { + sendUIEvent(event.toString(), method, timestamp, extras); + } + + public static void sendUIEvent(final Event event, final Method method, final long timestamp) { + sendUIEvent(event, method, timestamp, null); + } + + public static void sendUIEvent(final Event event, final Method method, final String extras) { + sendUIEvent(event, method, realtime(), extras); + } + + public static void sendUIEvent(final Event event, final Method method) { + sendUIEvent(event, method, realtime(), null); + } + + public static void sendUIEvent(final Event event) { + sendUIEvent(event, Method.NONE, realtime(), null); + } + + /** + * Sends a UIEvent with the given status appended to the event name. + * + * This method is a slight bend of the Telemetry framework so chances + * are that you don't want to use this: please think really hard before you do. + * + * Intended for use with data policy notifications. + */ + public static void sendUIEvent(final Event event, final boolean eventStatus) { + final String eventName = event + ":" + eventStatus; + sendUIEvent(eventName, Method.NONE, realtime(), null); + } +}
new file mode 100644 --- /dev/null +++ b/widget/android/Telemetry.h @@ -0,0 +1,100 @@ +/* -*- Mode: c++; 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/. */ + +#ifndef mozilla_widget_Telemetry_h__ +#define mozilla_widget_Telemetry_h__ + +#include "FennecJNINatives.h" +#include "nsAppShell.h" +#include "nsIAndroidBridge.h" + +#include "mozilla/Telemetry.h" + +namespace mozilla { +namespace widget { + +class Telemetry final + : public java::TelemetryUtils::Natives<Telemetry> +{ + Telemetry() = delete; + + static already_AddRefed<nsIUITelemetryObserver> + GetObserver() + { + nsAppShell* const appShell = nsAppShell::Get(); + if (!appShell) { + return nullptr; + } + + nsCOMPtr<nsIAndroidBrowserApp> browserApp = appShell->GetBrowserApp(); + nsCOMPtr<nsIUITelemetryObserver> obs; + + if (!browserApp || NS_FAILED(browserApp->GetUITelemetryObserver( + getter_AddRefs(obs))) || !obs) { + return nullptr; + } + + return obs.forget(); + } + +public: + static void + AddHistogram(jni::String::Param aName, int32_t aValue) + { + MOZ_ASSERT(aName); + mozilla::Telemetry::Accumulate(aName->ToCString().get(), aValue); + } + + static void + AddKeyedHistogram(jni::String::Param aName, jni::String::Param aKey, + int32_t aValue) + { + MOZ_ASSERT(aName && aKey); + mozilla::Telemetry::Accumulate(aName->ToCString().get(), + aKey->ToCString(), aValue); + } + + static void + StartUISession(jni::String::Param aName, int64_t aTimestamp) + { + MOZ_ASSERT(aName); + nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); + if (obs) { + obs->StartSession(aName->ToString().get(), aTimestamp); + } + } + + static void + StopUISession(jni::String::Param aName, jni::String::Param aReason, + int64_t aTimestamp) + { + MOZ_ASSERT(aName); + nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); + if (obs) { + obs->StopSession(aName->ToString().get(), + aReason ? aReason->ToString().get() : nullptr, + aTimestamp); + } + } + + static void + AddUIEvent(jni::String::Param aAction, jni::String::Param aMethod, + int64_t aTimestamp, jni::String::Param aExtras) + { + MOZ_ASSERT(aAction); + nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); + if (obs) { + obs->AddEvent(aAction->ToString().get(), + aMethod ? aMethod->ToString().get() : nullptr, + aTimestamp, + aExtras ? aExtras->ToString().get() : nullptr); + } + } +}; + +} // namespace widget +} // namespace mozilla + +#endif // mozilla_widget_Telemetry_h__
deleted file mode 100644 --- a/widget/android/fennec/Telemetry.h +++ /dev/null @@ -1,100 +0,0 @@ -/* -*- Mode: c++; 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/. */ - -#ifndef mozilla_widget_Telemetry_h__ -#define mozilla_widget_Telemetry_h__ - -#include "FennecJNINatives.h" -#include "nsAppShell.h" -#include "nsIAndroidBridge.h" - -#include "mozilla/Telemetry.h" - -namespace mozilla { -namespace widget { - -class Telemetry final - : public java::Telemetry::Natives<Telemetry> -{ - Telemetry() = delete; - - static already_AddRefed<nsIUITelemetryObserver> - GetObserver() - { - nsAppShell* const appShell = nsAppShell::Get(); - if (!appShell) { - return nullptr; - } - - nsCOMPtr<nsIAndroidBrowserApp> browserApp = appShell->GetBrowserApp(); - nsCOMPtr<nsIUITelemetryObserver> obs; - - if (!browserApp || NS_FAILED(browserApp->GetUITelemetryObserver( - getter_AddRefs(obs))) || !obs) { - return nullptr; - } - - return obs.forget(); - } - -public: - static void - AddHistogram(jni::String::Param aName, int32_t aValue) - { - MOZ_ASSERT(aName); - mozilla::Telemetry::Accumulate(aName->ToCString().get(), aValue); - } - - static void - AddKeyedHistogram(jni::String::Param aName, jni::String::Param aKey, - int32_t aValue) - { - MOZ_ASSERT(aName && aKey); - mozilla::Telemetry::Accumulate(aName->ToCString().get(), - aKey->ToCString(), aValue); - } - - static void - StartUISession(jni::String::Param aName, int64_t aTimestamp) - { - MOZ_ASSERT(aName); - nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); - if (obs) { - obs->StartSession(aName->ToString().get(), aTimestamp); - } - } - - static void - StopUISession(jni::String::Param aName, jni::String::Param aReason, - int64_t aTimestamp) - { - MOZ_ASSERT(aName); - nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); - if (obs) { - obs->StopSession(aName->ToString().get(), - aReason ? aReason->ToString().get() : nullptr, - aTimestamp); - } - } - - static void - AddUIEvent(jni::String::Param aAction, jni::String::Param aMethod, - int64_t aTimestamp, jni::String::Param aExtras) - { - MOZ_ASSERT(aAction); - nsCOMPtr<nsIUITelemetryObserver> obs = GetObserver(); - if (obs) { - obs->AddEvent(aAction->ToString().get(), - aMethod ? aMethod->ToString().get() : nullptr, - aTimestamp, - aExtras ? aExtras->ToString().get() : nullptr); - } - } -}; - -} // namespace widget -} // namespace mozilla - -#endif // mozilla_widget_Telemetry_h__
--- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -61,20 +61,20 @@ #include "ANRReporter.h" #include "GeckoBatteryManager.h" #include "GeckoNetworkManager.h" #include "GeckoProcessManager.h" #include "GeckoScreenOrientation.h" #include "GeckoSystemStateListener.h" #include "GeckoVRManager.h" #include "PrefsHelper.h" +#include "ScreenHelperAndroid.h" +#include "Telemetry.h" #include "fennec/MemoryMonitor.h" -#include "fennec/Telemetry.h" #include "fennec/ThumbnailHelper.h" -#include "ScreenHelperAndroid.h" #include "WebExecutorSupport.h" #ifdef DEBUG_ANDROID_EVENTS #define EVLOG(args...) ALOG(args) #else #define EVLOG(args...) do { } while (0) #endif @@ -407,16 +407,17 @@ nsAppShell::nsAppShell() } hal::Init(); if (!XRE_IsParentProcess()) { if (jni::IsAvailable()) { GeckoThreadSupport::Init(); GeckoAppShellSupport::Init(); + mozilla::widget::Telemetry::Init(); // Set the corresponding state in GeckoThread. java::GeckoThread::SetState(java::GeckoThread::State::RUNNING()); } return; } if (jni::IsAvailable()) { @@ -428,24 +429,24 @@ nsAppShell::nsAppShell() GeckoAppShellSupport::Init(); GeckoThreadSupport::Init(); mozilla::GeckoBatteryManager::Init(); mozilla::GeckoNetworkManager::Init(); mozilla::GeckoProcessManager::Init(); mozilla::GeckoScreenOrientation::Init(); mozilla::GeckoSystemStateListener::Init(); mozilla::PrefsHelper::Init(); + mozilla::widget::Telemetry::Init(); mozilla::widget::WebExecutorSupport::Init(); nsWindow::InitNatives(); if (jni::IsFennec()) { BrowserLocaleManagerSupport::Init(); mozilla::ANRReporter::Init(); mozilla::MemoryMonitor::Init(); - mozilla::widget::Telemetry::Init(); mozilla::ThumbnailHelper::Init(); } java::GeckoThread::SetState(java::GeckoThread::State::JNI_READY()); CreateAndroidUiThread(); }