Bug 1407728 - Add reason field to messages sent with /notify. r?Grisha draft
authorEdouard Oger <eoger@fastmail.com>
Wed, 11 Oct 2017 15:45:25 -0400
changeset 679512 99cce0c3ac1063bffdea2924361f3af58c937487
parent 677774 a0488ecc201c04f2617e7b02f039344e8fbf0d9a
child 735620 1d377b8ea55c31cf805b86277c69dbf749f77f71
push id84245
push userbmo:eoger@fastmail.com
push dateThu, 12 Oct 2017 20:01:17 +0000
reviewersGrisha
bugs1407728
milestone58.0a1
Bug 1407728 - Add reason field to messages sent with /notify. r?Grisha MozReview-Commit-ID: EZbXl2ZoMxK
mobile/android/services/src/main/java/org/mozilla/gecko/sync/stage/SyncClientsEngineStage.java
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/sync/stage/SyncClientsEngineStage.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/sync/stage/SyncClientsEngineStage.java
@@ -62,16 +62,20 @@ public class SyncClientsEngineStage exte
   private static final String LOG_TAG = "SyncClientsEngineStage";
 
   public static final String COLLECTION_NAME       = "clients";
   public static final String STAGE_NAME            = COLLECTION_NAME;
   public static final int CLIENTS_TTL_REFRESH      = 604800000;   // 7 days in milliseconds.
   public static final int MAX_UPLOAD_FAILURE_COUNT = 5;
   public static final long NOTIFY_TAB_SENT_TTL_SECS = TimeUnit.SECONDS.convert(1L, TimeUnit.HOURS); // 1 hour
 
+  // Reasons behind sending collection_changed push notifications.
+  public static final String COLLECTION_MODIFIED_REASON_SENDTAB = "sendtab";
+  public static final String COLLECTION_MODIFIED_REASON_FIRSTSYNC = "firstsync";
+
   protected final ClientRecordFactory factory = new ClientRecordFactory();
   protected ClientUploadDelegate clientUploadDelegate;
   protected ClientDownloadDelegate clientDownloadDelegate;
 
   // Be sure to use this safely via getClientsDatabaseAccessor/closeDataAccessor.
   protected ClientsDatabaseAccessor db;
 
   protected volatile boolean shouldWipe;
@@ -179,35 +183,37 @@ public class SyncClientsEngineStage exte
         // This method is synchronous, there's no risk of notifying the clients
         // before we actually uploaded the records
         uploadRemoteRecords();
 
         // We will send a push notification later anyway.
         if (!isFirstLocalClientRecordUpload && account != null) {
           // Notify the clients who got their record written
           final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account);
-          notifyClients(fxAccount, devicesToNotify);
+          notifyClients(fxAccount, devicesToNotify, NOTIFY_TAB_SENT_TTL_SECS, COLLECTION_MODIFIED_REASON_SENDTAB);
         }
 
         return;
       }
       checkAndUpload();
       if (isFirstLocalClientRecordUpload && account != null) {
         final AndroidFxAccount fxAccount = new AndroidFxAccount(context, account);
-        notifyAllClients(fxAccount);
+        notifyAllClients(fxAccount, 0, COLLECTION_MODIFIED_REASON_FIRSTSYNC);
       }
     }
 
-    private void notifyClients(@NonNull AndroidFxAccount fxAccount, @NonNull List<String> devicesToNotify) {
-      final ExtendedJSONObject body = createNotifyClientsBody(devicesToNotify);
+    private void notifyClients(@NonNull AndroidFxAccount fxAccount, @NonNull List<String> devicesToNotify,
+                               long ttl, @NonNull String reason) {
+      final ExtendedJSONObject body = createNotifyClientsBody(devicesToNotify, ttl, reason);
       notifyClientsHelper(fxAccount, body);
     }
 
-    private void notifyAllClients(@NonNull AndroidFxAccount fxAccount) {
-      final ExtendedJSONObject body = createNotifyAllClientsBody(fxAccount.getDeviceId());
+    private void notifyAllClients(@NonNull AndroidFxAccount fxAccount, long ttl,
+                                  @NonNull String reason) {
+      final ExtendedJSONObject body = createNotifyAllClientsBody(fxAccount.getDeviceId(), ttl, reason);
       notifyClientsHelper(fxAccount, body);
     }
 
     private void notifyClientsHelper(@NonNull AndroidFxAccount fxAccount, @NonNull ExtendedJSONObject body) {
       final byte[] sessionToken;
       try {
         sessionToken = fxAccount.getState().getSessionToken();
       } catch (State.NotASessionTokenState e) {
@@ -235,52 +241,56 @@ public class SyncClientsEngineStage exte
         public void handleSuccess(ExtendedJSONObject result) {
           Log.i(LOG_TAG, "Devices notified");
         }
       });
     }
 
     @NonNull
     @SuppressWarnings("unchecked")
-    private ExtendedJSONObject createNotifyClientsBody(@NonNull List<String> devicesToNotify) {
+    private ExtendedJSONObject createNotifyClientsBody(@NonNull List<String> devicesToNotify,
+                                                       long ttl, @NonNull String reason) {
       final ExtendedJSONObject body = new ExtendedJSONObject();
       final JSONArray to = new JSONArray();
       to.addAll(devicesToNotify);
       body.put("to", to);
-      createNotifyClientsHelper(body);
+      createNotifyClientsHelper(body, ttl, reason);
       return body;
     }
 
     @NonNull
     @SuppressWarnings("unchecked")
-    private ExtendedJSONObject createNotifyAllClientsBody(@NonNull String localFxADeviceId) {
+    private ExtendedJSONObject createNotifyAllClientsBody(@NonNull String localFxADeviceId,
+                                                          long ttl, @NonNull String reason) {
       final ExtendedJSONObject body = new ExtendedJSONObject();
       body.put("to", "all");
       final JSONArray excluded = new JSONArray();
       excluded.add(localFxADeviceId);
       body.put("excluded", excluded);
-      createNotifyClientsHelper(body);
+      createNotifyClientsHelper(body, ttl, reason);
       return body;
     }
 
-    private void createNotifyClientsHelper(ExtendedJSONObject body) {
-      body.put("payload", createNotifyDevicesPayload());
-      body.put("TTL", NOTIFY_TAB_SENT_TTL_SECS);
+    private void createNotifyClientsHelper(ExtendedJSONObject body, long ttl,
+                                           @NonNull String reason) {
+      body.put("payload", createNotifyDevicesPayload(reason));
+      body.put("TTL", ttl);
     }
 
     @NonNull
     @SuppressWarnings("unchecked")
-    private ExtendedJSONObject createNotifyDevicesPayload() {
+    private ExtendedJSONObject createNotifyDevicesPayload(@NonNull String reason) {
       final ExtendedJSONObject payload = new ExtendedJSONObject();
       payload.put("version", 1);
       payload.put("command", "sync:collection_changed");
       final ExtendedJSONObject data = new ExtendedJSONObject();
       final JSONArray collections = new JSONArray();
       collections.add("clients");
       data.put("collections", collections);
+      data.put("reason", reason);
       payload.put("data", data);
       return payload;
     }
 
     @Override
     public void handleRequestFailure(SyncStorageResponse response) {
       BaseResource.consumeEntity(response); // We don't need the response at all, and any exception handling shouldn't need the response body.
       localAccountGUIDDownloaded = false;