--- 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;