chrome_sync.js revision dc0f95d653279beabeb9817299e2902918ba123e
1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Use of this source code is governed by a BSD-style license that can be 3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// found in the LICENSE file. 4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 5dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvar chrome = chrome || {}; 6dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TODO(akalin): Add mocking code for e.g. chrome.send() so that we 7dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// can test this without rebuilding chrome. 8dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync = chrome.sync || {}; 9dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen(function () { 10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// This Event class is a simplified version of the one from 12dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// event_bindings.js. 13dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction Event() { 14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.listeners_ = []; 15dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 17dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenEvent.prototype.addListener = function(listener) { 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.listeners_.push(listener); 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 21dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenEvent.prototype.removeListener = function(listener) { 22dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var i = this.findListener_(listener); 23dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (i == -1) { 24dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return; 25dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 26dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.listeners_.splice(i, 1); 27dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 29dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenEvent.prototype.hasListener = function(listener) { 30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return this.findListener_(listener) > -1; 31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 33dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenEvent.prototype.hasListeners = function(listener) { 34dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return this.listeners_.length > 0; 35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Returns the index of the given listener, or -1 if not found. 38dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenEvent.prototype.findListener_ = function(listener) { 39dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (var i = 0; i < this.listeners_.length; i++) { 40dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (this.listeners_[i] == listener) { 41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return i; 42dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return -1; 45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Fires the event. Called by the actual event callback. Any 48dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// exceptions thrown by a listener are caught and logged. 49dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenEvent.prototype.dispatch_ = function() { 50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var args = Array.prototype.slice.call(arguments); 51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen for (var i = 0; i < this.listeners_.length; i++) { 52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen try { 53dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.listeners_[i].apply(null, args); 54dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } catch (e) { 55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen if (e instanceof Error) { 56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Non-standard, but useful. 57dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen console.error(e.stack); 58dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } else { 59dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen console.error(e); 60dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 62dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen } 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}; 64dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 65dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Service events. 66dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onSyncServiceStateChanged = new Event(); 67dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 68dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Notifier events. 69dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onSyncNotificationStateChange = new Event(); 70dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onSyncIncomingNotification = new Event(); 71dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 72dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Manager events. 73dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onChangesApplied = new Event(); 74dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onChangesComplete = new Event(); 75dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onSyncCycleCompleted = new Event(); 76dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onAuthError = new Event(); 77dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onUpdatedToken = new Event(); 78dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onPassphraseRequired = new Event(); 79dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onPassphraseAccepted = new Event(); 80dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onInitializationComplete = new Event(); 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onPaused = new Event(); 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onResumed = new Event(); 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onStopSyncingPermanently = new Event(); 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onClearServerDataSucceeded = new Event(); 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.onClearServerDataFailed = new Event(); 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction AsyncFunction(name) { 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.name_ = name; 89dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.callbacks_ = []; 90dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 92dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Calls the function, assuming the last argument is a callback to be 93dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// called with the return value. 94dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAsyncFunction.prototype.call = function() { 95dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var args = Array.prototype.slice.call(arguments); 96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen this.callbacks_.push(args.pop()); 97dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.send(this.name_, args); 98dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 99dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 100dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Handle a reply, assuming that messages are processed in FIFO order. 101dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenAsyncFunction.prototype.handleReply = function() { 102dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var args = Array.prototype.slice.call(arguments); 103dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // Remove the callback before we call it since the callback may 104dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen // throw. 105dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen var callback = this.callbacks_.shift(); 106dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen callback.apply(null, args); 107dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 108dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 109dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Sync service functions. 110dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getAboutInfo_ = new AsyncFunction('getAboutInfo'); 111dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getAboutInfo = function(callback) { 112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getAboutInfo_.call(callback); 113dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 114dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 115dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Notification functions. 116dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getNotificationState_ = 117dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen new AsyncFunction('getNotificationState'); 118dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getNotificationState = function(callback) { 119dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getNotificationState_.call(callback); 120dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 121dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 122dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Node lookup functions. 123dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getRootNode_ = new AsyncFunction('getRootNode'); 124dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getRootNode = function(callback) { 125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getRootNode_.call(callback); 126dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 128dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getNodeById_ = new AsyncFunction('getNodeById'); 129dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenchrome.sync.getNodeById = function(id, callback) { 130dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getNodeById_.call(id, callback); 131dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen})(); 134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TODO(akalin): Rewrite the C++ side to not need the handlers below. 136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Sync service event handlers. 138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onSyncServiceStateChanged() { 140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onSyncServiceStateChanged.dispatch_(); 141dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 142dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 143dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Notification event handlers. 144dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onSyncNotificationStateChange(notificationsEnabled) { 146dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onSyncNotificationStateChange.dispatch_(notificationsEnabled); 147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onSyncIncomingNotification(changedTypes) { 150dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onSyncIncomingNotification.dispatch_(changedTypes); 151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 153dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Sync manager event handlers. 154dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 155dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onChangesApplied(modelType, changes) { 156dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onChangesApplied.dispatch_(modelType, changes); 157dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 158dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 159dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onChangesComplete(modelType) { 160dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onChangesComplete.dispatch_(modelType); 161dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 162dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 163dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onSyncCycleCompleted(snapshot) { 164dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onSyncCycleCompleted.dispatch_(snapshot); 165dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 167dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onAuthError(authError) { 168dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onAuthError.dispatch_(authError); 169dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 170dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 171dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onUpdatedToken(token) { 172dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onUpdatedToken.dispatch_(token); 173dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 174dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onPassphraseRequired(forDecryption) { 176dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onPassphraseRequired.dispatch_(forDecryption); 177dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onPassphraseAccepted(bootstrapToken) { 180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onPassphraseAccepted.dispatch_(bootstrapToken); 181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onInitializationComplete() { 184dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onInitializationComplete.dispatch_(); 185dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onPaused() { 188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onPaused.dispatch_(); 189dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 190dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 191dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onResumed() { 192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onResumed.dispatch_(); 193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onStopSyncingPermanently() { 196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onStopSyncingPermanently.dispatch_(); 197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 198dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 199dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onClearServerDataSucceeded() { 200dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onClearServerDataSucceeded(); 201dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 202dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onClearServerDataFailed() { 204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.onClearServerDataFailed(); 205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Function reply handlers. 208dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 209dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onGetAboutInfoFinished(aboutInfo) { 210dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getAboutInfo_.handleReply(aboutInfo); 211dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 212dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 213dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onGetNotificationStateFinished(notificationState) { 214dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getNotificationState_.handleReply(notificationState); 215dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 216dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 217dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onGetRootNodeFinished(rootNode) { 218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getRootNode_.handleReply(rootNode); 219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenfunction onGetNodeByIdFinished(node) { 222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen chrome.sync.getNodeById_.handleReply(node); 223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 224