Bug 676375 - Implement "send URI for display" command in Sync Clients engine; r=rnewman
authorGregory Szorc <gps@mozilla.com>
Tue, 09 Aug 2011 09:23:55 -0700
changeset 77023 0815c4e5b498ec351363d982d886a67a8e47f6f3
parent 75094 a0e3c589c8fad05ab6e67efe7cd4911469561dbf
child 77024 7550224fb6c1b689f0a4772b92e46be432b31b93
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrnewman
bugs676375
milestone8.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 676375 - Implement "send URI for display" command in Sync Clients engine; r=rnewman
services/sync/modules/engines/clients.js
services/sync/tests/unit/test_clients_engine.js
--- a/services/sync/modules/engines/clients.js
+++ b/services/sync/modules/engines/clients.js
@@ -194,17 +194,18 @@ ClientEngine.prototype = {
    * and the value is a hash containing information about the command such as
    * number of arguments and description.
    */
   _commands: {
     resetAll:    { args: 0, desc: "Clear temporary local data for all engines" },
     resetEngine: { args: 1, desc: "Clear temporary local data for engine" },
     wipeAll:     { args: 0, desc: "Delete all client data for all engines" },
     wipeEngine:  { args: 1, desc: "Delete all client data for engine" },
-    logout:      { args: 0, desc: "Log out client" }
+    logout:      { args: 0, desc: "Log out client" },
+    displayURI:  { args: 2, desc: "Instruct a client to display a URI" }
   },
 
   /**
    * Remove any commands for the local client and mark it for upload.
    */
   clearCommands: function clearCommands() {
     delete this.localCommands;
     this._tracker.addChangedID(this.localID);
@@ -279,16 +280,19 @@ ClientEngine.prototype = {
             engines = null;
             // Fallthrough
           case "wipeEngine":
             Weave.Service.wipeClient(engines);
             break;
           case "logout":
             Weave.Service.logout();
             return false;
+          case "displayURI":
+            this._handleDisplayURI(args[0], args[1]);
+            break;
           default:
             this._log.debug("Received an unknown command: " + command);
             break;
         }
       }
 
       return true;
     })();
@@ -325,16 +329,62 @@ ClientEngine.prototype = {
 
     if (clientId) {
       this._sendCommandToClient(command, args, clientId);
     } else {
       for (let id in this._store._remoteClients) {
         this._sendCommandToClient(command, args, id);
       }
     }
+  },
+
+  /**
+   * Send a URI to another client for display.
+   *
+   * A side effect is the score is increased dramatically to incur an
+   * immediate sync.
+   *
+   * If an unknown client ID is specified, sendCommand() will throw an
+   * Error object.
+   *
+   * @param uri
+   *        URI (as a string) to send and display on the remote client
+   * @param clientId
+   *        ID of client to send the command to. If not defined, will be sent
+   *        to all remote clients.
+   */
+  sendURIToClientForDisplay: function sendURIToClientForDisplay(uri, clientId) {
+    this._log.info("Sending URI to client: " + uri + " -> " + clientId);
+    this.sendCommand("displayURI", [uri, this.syncID], clientId);
+
+    Clients._tracker.score += SCORE_INCREMENT_XLARGE;
+  },
+
+  /**
+   * Handle a single received 'displayURI' command.
+   *
+   * Interested parties should observe the "weave:engine:clients:display-uri"
+   * topic. The callback will receive an object as the subject parameter with
+   * the following keys:
+   *
+   *   uri       URI (string) that is requested for display
+   *   clientId  ID of client that sent the command
+   *
+   * The 'data' parameter to the callback will not be defined.
+   *
+   * @param uri
+   *        String URI that was received
+   * @param clientId
+   *        ID of client that sent URI
+   */
+  _handleDisplayURI: function _handleDisplayURI(uri, clientId) {
+    this._log.info("Received a URI for display: " + uri + " from " + clientId);
+
+    let subject = { uri: uri, client: clientId };
+    Svc.Obs.notify("weave:engine:clients:display-uri", subject);
   }
 };
 
 function ClientStore(name) {
   Store.call(this, name);
 }
 ClientStore.prototype = {
   __proto__: Store.prototype,
--- a/services/sync/tests/unit/test_clients_engine.js
+++ b/services/sync/tests/unit/test_clients_engine.js
@@ -444,13 +444,94 @@ add_test(function test_command_sync() {
 
   } finally {
     Svc.Prefs.resetBranch("");
     Records.clearCache();
     server.stop(run_next_test);
   }
 });
 
+add_test(function test_send_uri_to_client_for_display() {
+  _("Ensure sendURIToClientForDisplay() sends command properly.");
+
+  let tracker = Clients._tracker;
+  let store = Clients._store;
+
+  let remoteId = Utils.makeGUID();
+  let rec = new ClientsRec("clients", remoteId);
+  rec.name = "remote";
+  store.create(rec);
+  let remoteRecord = store.createRecord(remoteId, "clients");
+
+  tracker.clearChangedIDs();
+  let initialScore = tracker.score;
+
+  let uri = "http://www.mozilla.org/";
+  Clients.sendURIToClientForDisplay(uri, remoteId);
+
+  let newRecord = store._remoteClients[remoteId];
+
+  do_check_neq(newRecord, undefined);
+  do_check_eq(newRecord.commands.length, 1);
+
+  let command = newRecord.commands[0];
+  do_check_eq(command.command, "displayURI");
+  do_check_eq(command.args.length, 2);
+  do_check_eq(command.args[0], uri);
+
+  do_check_true(tracker.score > initialScore);
+  do_check_true(tracker.score - initialScore >= SCORE_INCREMENT_XLARGE);
+
+  _("Ensure unknown client IDs result in exception.");
+  let unknownId = Utils.makeGUID();
+  let error;
+
+  try {
+    Clients.sendURIToClientForDisplay(uri, unknownId);
+  } catch (ex) {
+    error = ex;
+  }
+
+  do_check_eq(error.message.indexOf("Unknown remote client ID: "), 0);
+
+  run_next_test();
+});
+
+add_test(function test_receive_display_uri() {
+  _("Ensure processing of received 'displayURI' commands works.");
+
+  // We don't set up WBOs and perform syncing because other tests verify
+  // the command API works as advertised. This saves us a little work.
+
+  let uri = "http://www.mozilla.org/";
+  let remoteId = Utils.makeGUID();
+
+  let command = {
+    command: "displayURI",
+    args: [uri, remoteId],
+  };
+
+  Clients.localCommands = [command];
+
+  // Received 'displayURI' command should result in the topic defined below
+  // being called.
+  let ev = "weave:engine:clients:display-uri";
+
+  let handler = function(subject, data) {
+    Svc.Obs.remove(ev, handler);
+
+    do_check_eq(subject.uri, uri);
+    do_check_eq(subject.client, remoteId);
+    do_check_eq(data, null);
+
+    run_next_test();
+  };
+
+  Svc.Obs.add(ev, handler);
+
+  do_check_true(Clients.processIncomingCommands());
+});
+
 function run_test() {
   initTestLogging("Trace");
   Log4Moz.repository.getLogger("Sync.Engine.Clients").level = Log4Moz.Level.Trace;
   run_next_test();
 }