Bug 1272354 - (DLC) Sync Action: Add telemetry to track sync success/failure. r?grisha draft
authorSebastian Kaspari <s.kaspari@gmail.com>
Mon, 03 Apr 2017 16:46:43 +0200
changeset 561412 9605f6571c857adb2ca77f2fb9013cb12adb7e15
parent 561411 3b98647a9342809b7303548e3c5c300308a8327e
child 561413 4389765c25659f48b74335164d7e8fd87fb03b05
push id53725
push users.kaspari@gmail.com
push dateWed, 12 Apr 2017 16:41:42 +0000
reviewersgrisha
bugs1272354
milestone55.0a1
Bug 1272354 - (DLC) Sync Action: Add telemetry to track sync success/failure. r?grisha MozReview-Commit-ID: A74A4pc9anK
mobile/android/base/java/org/mozilla/gecko/dlc/DownloadContentTelemetry.java
mobile/android/base/java/org/mozilla/gecko/dlc/SyncAction.java
--- a/mobile/android/base/java/org/mozilla/gecko/dlc/DownloadContentTelemetry.java
+++ b/mobile/android/base/java/org/mozilla/gecko/dlc/DownloadContentTelemetry.java
@@ -18,16 +18,18 @@ import org.mozilla.gecko.dlc.BaseAction.
 /**
  * Helper class to send DLC telemetry events.
  */
 public class DownloadContentTelemetry {
     private static final String EXTRA_ACTION = "action";
     private static final String EXTRA_RESULT = "result";
     private static final String EXTRA_CONTENT = "content";
     private static final String EXTRA_ERROR = "error";
+    private static final String EXTRA_UPDATED = "updated";
+    private static final String EXTRA_ACTION_REQUIRED = "action_required";
 
     private static final String ACTION_DOWNLOAD = "dlc_download";
     private static final String ACTION_SYNC = "dlc_sync";
 
     private static final String RESULT_SUCCESS = "success";
     private static final String RESULT_FAILURE = "failure";
 
     @StringDef({ERROR_NO_NETWORK, ERROR_NETWORK_METERED, ERROR_DISK_SPACE, ERROR_CHECKSUM, ERROR_DISK_IO,
@@ -53,40 +55,71 @@ public class DownloadContentTelemetry {
 
             Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.SERVICE, extras.toString());
         } catch (JSONException e) {
             throw new AssertionError("Should not happen: Can't build telemetry extra JSON", e);
         }
     }
 
     /* package */ static void eventDownloadFailure(DownloadContent content, RecoverableDownloadContentException e) {
-        switch (e.getErrorType()) {
-            case RecoverableDownloadContentException.DISK_IO:
-                eventDownloadFailure(content, ERROR_DISK_IO);
-                break;
-            case RecoverableDownloadContentException.MEMORY:
-                eventDownloadFailure(content, ERROR_MEMORY);
-                break;
-            case RecoverableDownloadContentException.NETWORK:
-                eventDownloadFailure(content, ERROR_NETWORK_IO);
-                break;
-            case RecoverableDownloadContentException.SERVER:
-                eventDownloadFailure(content, ERROR_SERVER);
-                break;
-            default:
-                throw new AssertionError("Unknown error type: " + e.getErrorType());
-        }
+        eventDownloadFailure(content, translateErrorType(e.getErrorType()));
     }
 
     /* package */ static void eventDownloadFailure(DownloadContent content, @Error String errorType) {
         try {
             final JSONObject extras = new JSONObject();
             extras.put(EXTRA_ACTION, ACTION_DOWNLOAD);
             extras.put(EXTRA_RESULT, RESULT_FAILURE);
             extras.put(EXTRA_CONTENT, content.getId());
             extras.put(EXTRA_ERROR, errorType);
 
             Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.SERVICE, extras.toString());
         } catch (JSONException e) {
             throw new AssertionError("Should not happen: Can't build telemetry extra JSON", e);
         }
     }
+
+    /* package */ static void eventSyncSuccess(boolean updated, boolean actionRequired) {
+        try {
+            final JSONObject extras = new JSONObject();
+            extras.put(EXTRA_ACTION, ACTION_SYNC);
+            extras.put(EXTRA_RESULT, RESULT_SUCCESS);
+            extras.put(EXTRA_UPDATED, updated);
+            extras.put(EXTRA_ACTION_REQUIRED, actionRequired);
+
+            Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.SERVICE, extras.toString());
+        } catch (JSONException e) {
+            throw new AssertionError("Should not happen: Can't build telemetry extra JSON", e);
+        }
+    }
+
+    /* package */ static void eventSyncFailure(RecoverableDownloadContentException e) {
+        eventSyncFailure(translateErrorType(e.getErrorType()));
+    }
+
+    /* package */ static void eventSyncFailure(@Error String errorType) {
+        try {
+            final JSONObject extras = new JSONObject();
+            extras.put(EXTRA_ACTION, ACTION_SYNC);
+            extras.put(EXTRA_RESULT, RESULT_FAILURE);
+            extras.put(EXTRA_ERROR, errorType);
+
+            Telemetry.sendUIEvent(TelemetryContract.Event.ACTION, TelemetryContract.Method.SERVICE, extras.toString());
+        } catch (JSONException e) {
+            throw new AssertionError("Should not happen: Can't build telemetry extra JSON", e);
+        }
+    }
+
+    private static String translateErrorType(@RecoverableDownloadContentException.ErrorType int errorType) {
+        switch (errorType) {
+            case RecoverableDownloadContentException.DISK_IO:
+                return ERROR_DISK_IO;
+            case RecoverableDownloadContentException.MEMORY:
+                return ERROR_MEMORY;
+            case RecoverableDownloadContentException.NETWORK:
+                return ERROR_NETWORK_IO;
+            case RecoverableDownloadContentException.SERVER:
+                return ERROR_SERVER;
+            default:
+                throw new AssertionError("Unknown error type: " + errorType);
+        }
+    }
 }
--- a/mobile/android/base/java/org/mozilla/gecko/dlc/SyncAction.java
+++ b/mobile/android/base/java/org/mozilla/gecko/dlc/SyncAction.java
@@ -86,20 +86,26 @@ public class SyncAction extends BaseActi
                 if (isDeleted) {
                     cleanupRequired |= deleteContent(catalog, id);
                 } else if (existingContent != null) {
                     studyRequired |= updateContent(catalog, object, existingContent);
                 } else {
                     studyRequired |= createContent(catalog, object);
                 }
             }
+
+            DownloadContentTelemetry.eventSyncSuccess(rawCatalog.length() > 0, cleanupRequired || studyRequired);
         } catch (UnrecoverableDownloadContentException e) {
             Log.e(LOGTAG, "UnrecoverableDownloadContentException", e);
+
+            DownloadContentTelemetry.eventSyncFailure(DownloadContentTelemetry.ERROR_UNRECOVERABLE);
         } catch (RecoverableDownloadContentException e) {
             Log.e(LOGTAG, "RecoverableDownloadContentException");
+
+            DownloadContentTelemetry.eventSyncFailure(e);
         } catch (JSONException e) {
             Log.e(LOGTAG, "JSONException", e);
         }
 
         if (studyRequired) {
             startStudyAction(context);
         }