Bug 1259507 - Add UI Telemetry probes for DOM Push API in Fennec. r=mfinkle
authorNick Alexander <nalexander@mozilla.com>
Tue, 29 Mar 2016 11:39:35 -0700
changeset 291313 230a0a44d0871347fb8215cd65d2d126cecfa93c
parent 291312 4b8075ea02463c44f5d6c08584ac81c5dc0d62fd
child 291314 bc439c65ecdcabcf039b9a4c6074380088d8530a
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1259507, 277456, 361795, 393600
Bug 1259507 - Add UI Telemetry probes for DOM Push API in Fennec. r=mfinkle The probes in this patch are annotated with the extra "dom-push-api" to distinguish from future Fennec-specific push messages. These probes allow to determine for each user the difference: {# sites subscribed to} - {# sites unsubscribed from}. If we assume the same site is not subscribed to multiple times, this is a good approximation to the total number of sites the user receives push messages from. To test manually: 0) Install Fennec and execute |adb shell setprop log.tag.Telemetry DEBUG|. 1) Subscribe to notifications on a site like serviceworke.rs. Observe a UI Telemetry SAVE event, like: D/Telemetry( 7109): SendUIEvent: event = save.1 method = service timestamp = 277456 extras = dom-push-api 2) Send a push notification using the sites' interface. Observe a UI Telemetry PUSH_RECEIVED_MESSAGE event, like: D/Telemetry( 7109): SendUIEvent: event = action.1 method = service timestamp = 361795 extras = dom-push-api 3) Unsubscribe to notifications by revoking permission using Site Settings from the URL bar. Observe a UI Telemetry PUSH_UNSUBSCRIBED_FROM_SITE event, like: D/Telemetry( 7109): SendUIEvent: event = unsave.1 method = service timestamp = 393600 extras = dom-push-api MozReview-Commit-ID: IOCwfXFnowA
--- a/mobile/android/base/java/org/mozilla/gecko/push/PushService.java
+++ b/mobile/android/base/java/org/mozilla/gecko/push/PushService.java
@@ -9,19 +9,20 @@ import android.content.Context;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 import android.util.Log;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoEvent;
 import org.mozilla.gecko.GeckoProfile;
 import org.mozilla.gecko.GeckoThread;
+import org.mozilla.gecko.Telemetry;
+import org.mozilla.gecko.TelemetryContract;
 import org.mozilla.gecko.annotation.ReflectionTarget;
 import org.mozilla.gecko.gcm.GcmTokenClient;
 import org.mozilla.gecko.push.autopush.AutopushClientException;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.ThreadUtils;
 import java.io.IOException;
@@ -141,16 +142,20 @@ public class PushService implements Bund
             final String profileName = subscription.serviceData.optString("profileName", null);
             final String profilePath = subscription.serviceData.optString("profilePath", null);
             if (profileName == null || profilePath == null) {
                 Log.e(LOG_TAG, "Corrupt serviceData found for chid: " + chid + "; ignoring dom/push message.");
+            // Let's look to the future, when we'll deliver messages without regard to whether
+            // Gecko is running or not.
+            Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.SERVICE, "dom-push-api");
             if (!GeckoThread.isRunning()) {
                 Log.w(LOG_TAG, "dom/push message received but no Gecko thread is running; ignoring message.");
             final GeckoAppShell.GeckoInterface geckoInterface = GeckoAppShell.getGeckoInterface();
             if (geckoInterface == null) {
                 Log.w(LOG_TAG, "dom/push message received but no Gecko interface is registered; ignoring message.");
@@ -285,29 +290,32 @@ public class PushService implements Bund
                 try {
                     json.put("channelID", subscription.chid);
                     json.put("endpoint", subscription.webpushEndpoint);
                 } catch (JSONException e) {
                     Log.e(LOG_TAG, "Got exception in " + event, e);
                     callback.sendError("Got exception handling message [" + event + "]: " + e.toString());
+                Telemetry.sendUIEvent(TelemetryContract.Event.SAVE, TelemetryContract.Method.SERVICE, "dom-push-api");
             if ("PushServiceAndroidGCM:UnsubscribeChannel".equals(event)) {
                 final String channelID = message.getString("channelID");
                 if (channelID == null) {
                     callback.sendError("channelID must not be null in " + event);
                 // Fire and forget.  See comments in the function itself.
                 final PushSubscription pushSubscription = pushManager.unsubscribeChannel(channelID);
                 if (pushSubscription != null) {
+                    Telemetry.sendUIEvent(TelemetryContract.Event.UNSAVE, TelemetryContract.Method.SERVICE, "dom-push-api");
                 callback.sendError("Could not unsubscribe from channel: " + channelID);
         } catch (GcmTokenClient.NeedsGooglePlayServicesException e) {
--- a/mobile/android/docs/uitelemetry.rst
+++ b/mobile/android/docs/uitelemetry.rst
@@ -143,19 +143,18 @@ Events
   Sent when a user has accepted the data notification policy. Can be ``false``
   instead of ``true`` if an error occurs.
   Sent when the user chooses to clear private data.
-``save.1`` ``unsave.1``
+``save.1``, ``unsave.1``
   Saving or unsaving a resource (reader, bookmark, etc.) for viewing later.
-  Note: Only used in JavaScript for now.
   Sent when the user performs a search. Currently used in the search activity.
   Sent when the user removes a search engine.