• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5var chrome = chrome || {};
6
7// TODO(akalin): Add mocking code for e.g. chrome.send() so that we
8// can test this without rebuilding chrome.
9
10/**
11 * Organize sync event listeners and asynchronous requests.
12 * This object is one of a kind; its constructor is not public.
13 * @type {Object}
14 */
15chrome.sync = chrome.sync || {};
16(function() {
17
18// This Event class is a simplified version of the one from
19// event_bindings.js.
20function Event() {
21  this.listeners_ = [];
22}
23
24Event.prototype.addListener = function(listener) {
25  this.listeners_.push(listener);
26};
27
28Event.prototype.removeListener = function(listener) {
29  var i = this.findListener_(listener);
30  if (i == -1) {
31    return;
32  }
33  this.listeners_.splice(i, 1);
34};
35
36Event.prototype.removeListeners = function() {
37  this.listeners_ = [];
38}
39
40Event.prototype.hasListener = function(listener) {
41  return this.findListener_(listener) > -1;
42};
43
44Event.prototype.hasListeners = function(listener) {
45  return this.listeners_.length > 0;
46};
47
48// Returns the index of the given listener, or -1 if not found.
49Event.prototype.findListener_ = function(listener) {
50  for (var i = 0; i < this.listeners_.length; i++) {
51    if (this.listeners_[i] == listener) {
52      return i;
53    }
54  }
55  return -1;
56};
57
58// Fires the event.  Called by the actual event callback.  Any
59// exceptions thrown by a listener are caught and logged.
60Event.prototype.fire = function() {
61  var args = Array.prototype.slice.call(arguments);
62  for (var i = 0; i < this.listeners_.length; i++) {
63    try {
64      this.listeners_[i].apply(null, args);
65    } catch (e) {
66      if (e instanceof Error) {
67        // Non-standard, but useful.
68        console.error(e.stack);
69      } else {
70        console.error(e);
71      }
72    }
73  }
74};
75
76chrome.sync.events = {
77  'service': [
78    'onServiceStateChanged'
79  ],
80
81  // See chrome/browser/sync/engine/syncapi.h for docs.
82  'notifier': [
83    'onNotificationStateChange',
84    'onIncomingNotification'
85  ],
86
87  'manager': [
88    'onChangesApplied',
89    'onChangesComplete',
90    'onSyncCycleCompleted',
91    'onConnectionStatusChange',
92    'onPassphraseRequired',
93    'onPassphraseAccepted',
94    'onInitializationComplete',
95    'onStopSyncingPermanently',
96    'onClearServerDataSucceeded',
97    'onClearServerDataFailed',
98    'onEncryptedTypesChanged',
99    'onEncryptionComplete',
100    'onActionableError',
101  ],
102
103  'transaction': [
104    'onTransactionWrite',
105  ]
106};
107
108for (var eventType in chrome.sync.events) {
109  var events = chrome.sync.events[eventType];
110  for (var i = 0; i < events.length; ++i) {
111    var event = events[i];
112    chrome.sync[event] = new Event();
113  }
114}
115
116function makeSyncFunction(name) {
117  var callbacks = [];
118
119  // Calls the function, assuming the last argument is a callback to be
120  // called with the return value.
121  var fn = function() {
122    var args = Array.prototype.slice.call(arguments);
123    callbacks.push(args.pop());
124    chrome.send(name, args);
125  };
126
127  // Handle a reply, assuming that messages are processed in FIFO order.
128  // Called by SyncInternalsUI::HandleJsReply().
129  fn.handleReply = function() {
130    var args = Array.prototype.slice.call(arguments);
131    // Remove the callback before we call it since the callback may
132    // throw.
133    var callback = callbacks.shift();
134    callback.apply(null, args);
135  };
136
137  return fn;
138}
139
140var syncFunctions = [
141  // Sync service functions.
142  'getAboutInfo',
143
144  // Notification functions.  See chrome/browser/sync/engine/syncapi.h
145  // for docs.
146  'getNotificationState',
147  'getNotificationInfo',
148
149  // Client server communication logging functions.
150  'getClientServerTraffic',
151
152  // Node lookup functions.  See chrome/browser/sync/engine/syncapi.h
153  // for docs.
154  'getRootNodeDetails',
155  'getNodeSummariesById',
156  'getNodeDetailsById',
157  'getChildNodeIds',
158  'getAllNodes',
159];
160
161for (var i = 0; i < syncFunctions.length; ++i) {
162  var syncFunction = syncFunctions[i];
163  chrome.sync[syncFunction] = makeSyncFunction(syncFunction);
164}
165
166/**
167 * Returns an object which measures elapsed time.
168 */
169chrome.sync.makeTimer = function() {
170  var start = new Date();
171
172  return {
173    /**
174     * @return {number} The number of seconds since the timer was
175     * created.
176     */
177    get elapsedSeconds() {
178      return ((new Date()).getTime() - start.getTime()) / 1000.0;
179    }
180  };
181};
182
183})();
184