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.
5 // Populated by constants from the browser. Used only by this file.
6 var NetInfoSources
= null;
9 * This class provides a "bridge" for communicating between the javascript and
12 var BrowserBridge
= (function() {
16 * Delay in milliseconds between updates of certain browser information.
18 var POLL_INTERVAL_MS
= 5000;
23 function BrowserBridge() {
24 assertFirstConstructorCall(BrowserBridge
);
26 // List of observers for various bits of browser state.
27 this.connectionTestsObservers_
= [];
28 this.hstsObservers_
= [];
29 this.constantsObservers_
= [];
30 this.crosONCFileParseObservers_
= [];
31 this.storeDebugLogsObservers_
= [];
32 this.setNetworkDebugModeObservers_
= [];
33 // Unprocessed data received before the constants. This serves to protect
34 // against passing along data before having information on how to interpret
36 this.earlyReceivedData_
= [];
38 this.pollableDataHelpers_
= {};
40 // Add PollableDataHelpers for NetInfoSources, which retrieve information
41 // directly from the network stack.
42 this.addNetInfoPollableDataHelper('proxySettings',
43 'onProxySettingsChanged');
44 this.addNetInfoPollableDataHelper('badProxies', 'onBadProxiesChanged');
45 this.addNetInfoPollableDataHelper('hostResolverInfo',
46 'onHostResolverInfoChanged');
47 this.addNetInfoPollableDataHelper('socketPoolInfo',
48 'onSocketPoolInfoChanged');
49 this.addNetInfoPollableDataHelper('spdySessionInfo',
50 'onSpdySessionInfoChanged');
51 this.addNetInfoPollableDataHelper('spdyStatus', 'onSpdyStatusChanged');
52 this.addNetInfoPollableDataHelper('spdyAlternateProtocolMappings',
53 'onSpdyAlternateProtocolMappingsChanged');
54 this.addNetInfoPollableDataHelper('quicInfo', 'onQuicInfoChanged');
55 this.addNetInfoPollableDataHelper('sdchInfo', 'onSdchInfoChanged');
56 this.addNetInfoPollableDataHelper('httpCacheInfo',
57 'onHttpCacheInfoChanged');
59 // Add other PollableDataHelpers.
60 this.pollableDataHelpers_
.sessionNetworkStats
=
61 new PollableDataHelper('onSessionNetworkStatsChanged',
62 this.sendGetSessionNetworkStats
.bind(this));
63 this.pollableDataHelpers_
.historicNetworkStats
=
64 new PollableDataHelper('onHistoricNetworkStatsChanged',
65 this.sendGetHistoricNetworkStats
.bind(this));
67 this.pollableDataHelpers_
.serviceProviders
=
68 new PollableDataHelper('onServiceProvidersChanged',
69 this.sendGetServiceProviders
.bind(this));
71 this.pollableDataHelpers_
.prerenderInfo
=
72 new PollableDataHelper('onPrerenderInfoChanged',
73 this.sendGetPrerenderInfo
.bind(this));
74 this.pollableDataHelpers_
.extensionInfo
=
75 new PollableDataHelper('onExtensionInfoChanged',
76 this.sendGetExtensionInfo
.bind(this));
77 this.pollableDataHelpers_
.dataReductionProxyInfo
=
78 new PollableDataHelper('onDataReductionProxyInfoChanged',
79 this.sendGetDataReductionProxyInfo
.bind(this));
81 // Setting this to true will cause messages from the browser to be ignored,
82 // and no messages will be sent to the browser, either. Intended for use
83 // when viewing log files.
84 this.disabled_
= false;
86 // Interval id returned by window.setInterval for polling timer.
87 this.pollIntervalId_
= null;
90 cr
.addSingletonGetter(BrowserBridge
);
92 BrowserBridge
.prototype = {
94 //--------------------------------------------------------------------------
95 // Messages sent to the browser
96 //--------------------------------------------------------------------------
99 * Wraps |chrome.send|. Doesn't send anything when disabled.
101 send: function(value1
, value2
) {
102 if (!this.disabled_
) {
103 if (arguments
.length
== 1) {
105 } else if (arguments
.length
== 2) {
106 chrome
.send(value1
, value2
);
108 throw 'Unsupported number of arguments.';
113 sendReady: function() {
114 this.send('notifyReady');
115 this.setPollInterval(POLL_INTERVAL_MS
);
119 * Some of the data we are interested is not currently exposed as a
120 * stream. This starts polling those with active observers (visible
121 * views) every |intervalMs|. Subsequent calls override previous calls
122 * to this function. If |intervalMs| is 0, stops polling.
124 setPollInterval: function(intervalMs
) {
125 if (this.pollIntervalId_
!== null) {
126 window
.clearInterval(this.pollIntervalId_
);
127 this.pollIntervalId_
= null;
130 if (intervalMs
> 0) {
131 this.pollIntervalId_
=
132 window
.setInterval(this.checkForUpdatedInfo
.bind(this, false),
137 sendGetNetInfo: function(netInfoSource
) {
138 // If don't have constants yet, don't do anything yet.
140 this.send('getNetInfo', [NetInfoSources
[netInfoSource
]]);
143 sendReloadProxySettings: function() {
144 this.send('reloadProxySettings');
147 sendClearBadProxies: function() {
148 this.send('clearBadProxies');
151 sendClearHostResolverCache: function() {
152 this.send('clearHostResolverCache');
155 sendClearBrowserCache: function() {
156 this.send('clearBrowserCache');
159 sendClearAllCache: function() {
160 this.sendClearHostResolverCache();
161 this.sendClearBrowserCache();
164 sendStartConnectionTests: function(url
) {
165 this.send('startConnectionTests', [url
]);
168 sendHSTSQuery: function(domain
) {
169 this.send('hstsQuery', [domain
]);
172 sendHSTSAdd: function(domain
, sts_include_subdomains
,
173 pkp_include_subdomains
, pins
) {
174 this.send('hstsAdd', [domain
, sts_include_subdomains
,
175 pkp_include_subdomains
, pins
]);
178 sendHSTSDelete: function(domain
) {
179 this.send('hstsDelete', [domain
]);
182 sendGetSessionNetworkStats: function() {
183 this.send('getSessionNetworkStats');
186 sendGetHistoricNetworkStats: function() {
187 this.send('getHistoricNetworkStats');
190 sendCloseIdleSockets: function() {
191 this.send('closeIdleSockets');
194 sendFlushSocketPools: function() {
195 this.send('flushSocketPools');
198 sendGetServiceProviders: function() {
199 this.send('getServiceProviders');
202 sendGetPrerenderInfo: function() {
203 this.send('getPrerenderInfo');
206 sendGetExtensionInfo: function() {
207 this.send('getExtensionInfo');
210 sendGetDataReductionProxyInfo: function() {
211 this.send('getDataReductionProxyInfo');
214 setCaptureMode: function(captureMode
) {
215 this.send('setCaptureMode', ['' + captureMode
]);
218 importONCFile: function(fileContent
, passcode
) {
219 this.send('importONCFile', [fileContent
, passcode
]);
222 storeDebugLogs: function() {
223 this.send('storeDebugLogs');
226 setNetworkDebugMode: function(subsystem
) {
227 this.send('setNetworkDebugMode', [subsystem
]);
230 //--------------------------------------------------------------------------
231 // Messages received from the browser.
232 //--------------------------------------------------------------------------
234 receive: function(command
, params
) {
235 // Does nothing if disabled.
239 // If no constants have been received, and params does not contain the
240 // constants, delay handling the data.
241 if (Constants
== null && command
!= 'receivedConstants') {
242 this.earlyReceivedData_
.push({ command
: command
, params
: params
});
246 this[command
](params
);
248 // Handle any data that was received early in the order it was received,
249 // once the constants have been processed.
250 if (this.earlyReceivedData_
!= null) {
251 for (var i
= 0; i
< this.earlyReceivedData_
.length
; i
++) {
252 var command
= this.earlyReceivedData_
[i
];
253 this[command
.command
](command
.params
);
255 this.earlyReceivedData_
= null;
259 receivedConstants: function(constants
) {
260 NetInfoSources
= constants
.netInfoSources
;
261 for (var i
= 0; i
< this.constantsObservers_
.length
; i
++)
262 this.constantsObservers_
[i
].onReceivedConstants(constants
);
263 // May have been waiting for the constants to be received before getting
264 // information for the currently displayed tab.
265 this.checkForUpdatedInfo();
268 receivedLogEntries: function(logEntries
) {
269 EventsTracker
.getInstance().addLogEntries(logEntries
);
272 receivedNetInfo: function(netInfo
) {
273 // Dispatch |netInfo| to the various PollableDataHelpers listening to
274 // each field it contains.
276 // Currently information is only received from one source at a time, but
277 // the API does allow for data from more that one to be requested at once.
278 for (var source
in netInfo
)
279 this.pollableDataHelpers_
[source
].update(netInfo
[source
]);
282 receivedSessionNetworkStats: function(sessionNetworkStats
) {
283 this.pollableDataHelpers_
.sessionNetworkStats
.update(sessionNetworkStats
);
286 receivedHistoricNetworkStats: function(historicNetworkStats
) {
287 this.pollableDataHelpers_
.historicNetworkStats
.update(
288 historicNetworkStats
);
291 receivedServiceProviders: function(serviceProviders
) {
292 this.pollableDataHelpers_
.serviceProviders
.update(serviceProviders
);
295 receivedStartConnectionTestSuite: function() {
296 for (var i
= 0; i
< this.connectionTestsObservers_
.length
; i
++)
297 this.connectionTestsObservers_
[i
].onStartedConnectionTestSuite();
300 receivedStartConnectionTestExperiment: function(experiment
) {
301 for (var i
= 0; i
< this.connectionTestsObservers_
.length
; i
++) {
302 this.connectionTestsObservers_
[i
].onStartedConnectionTestExperiment(
307 receivedCompletedConnectionTestExperiment: function(info
) {
308 for (var i
= 0; i
< this.connectionTestsObservers_
.length
; i
++) {
309 this.connectionTestsObservers_
[i
].onCompletedConnectionTestExperiment(
310 info
.experiment
, info
.result
);
314 receivedCompletedConnectionTestSuite: function() {
315 for (var i
= 0; i
< this.connectionTestsObservers_
.length
; i
++)
316 this.connectionTestsObservers_
[i
].onCompletedConnectionTestSuite();
319 receivedHSTSResult: function(info
) {
320 for (var i
= 0; i
< this.hstsObservers_
.length
; i
++)
321 this.hstsObservers_
[i
].onHSTSQueryResult(info
);
324 receivedONCFileParse: function(error
) {
325 for (var i
= 0; i
< this.crosONCFileParseObservers_
.length
; i
++)
326 this.crosONCFileParseObservers_
[i
].onONCFileParse(error
);
329 receivedStoreDebugLogs: function(status
) {
330 for (var i
= 0; i
< this.storeDebugLogsObservers_
.length
; i
++)
331 this.storeDebugLogsObservers_
[i
].onStoreDebugLogs(status
);
334 receivedSetNetworkDebugMode: function(status
) {
335 for (var i
= 0; i
< this.setNetworkDebugModeObservers_
.length
; i
++)
336 this.setNetworkDebugModeObservers_
[i
].onSetNetworkDebugMode(status
);
339 receivedPrerenderInfo: function(prerenderInfo
) {
340 this.pollableDataHelpers_
.prerenderInfo
.update(prerenderInfo
);
343 receivedExtensionInfo: function(extensionInfo
) {
344 this.pollableDataHelpers_
.extensionInfo
.update(extensionInfo
);
347 receivedDataReductionProxyInfo: function(dataReductionProxyInfo
) {
348 this.pollableDataHelpers_
.dataReductionProxyInfo
.update(
349 dataReductionProxyInfo
);
352 //--------------------------------------------------------------------------
355 * Prevents receiving/sending events to/from the browser.
357 disable: function() {
358 this.disabled_
= true;
359 this.setPollInterval(0);
363 * Returns true if the BrowserBridge has been disabled.
365 isDisabled: function() {
366 return this.disabled_
;
370 * Adds a listener of the proxy settings. |observer| will be called back
371 * when data is received, through:
373 * observer.onProxySettingsChanged(proxySettings)
375 * |proxySettings| is a dictionary with (up to) two properties:
377 * "original" -- The settings that chrome was configured to use
378 * (i.e. system settings.)
379 * "effective" -- The "effective" proxy settings that chrome is using.
380 * (decides between the manual/automatic modes of the
383 * Each of these two configurations is formatted as a string, and may be
384 * omitted if not yet initialized.
386 * If |ignoreWhenUnchanged| is true, data is only sent when it changes.
387 * If it's false, data is sent whenever it's received from the browser.
389 addProxySettingsObserver: function(observer
, ignoreWhenUnchanged
) {
390 this.pollableDataHelpers_
.proxySettings
.addObserver(observer
,
391 ignoreWhenUnchanged
);
395 * Adds a listener of the proxy settings. |observer| will be called back
396 * when data is received, through:
398 * observer.onBadProxiesChanged(badProxies)
400 * |badProxies| is an array, where each entry has the property:
401 * badProxies[i].proxy_uri: String identify the proxy.
402 * badProxies[i].bad_until: The time when the proxy stops being considered
403 * bad. Note the time is in time ticks.
405 addBadProxiesObserver: function(observer
, ignoreWhenUnchanged
) {
406 this.pollableDataHelpers_
.badProxies
.addObserver(observer
,
407 ignoreWhenUnchanged
);
411 * Adds a listener of the host resolver info. |observer| will be called back
412 * when data is received, through:
414 * observer.onHostResolverInfoChanged(hostResolverInfo)
416 addHostResolverInfoObserver: function(observer
, ignoreWhenUnchanged
) {
417 this.pollableDataHelpers_
.hostResolverInfo
.addObserver(
418 observer
, ignoreWhenUnchanged
);
422 * Adds a listener of the socket pool. |observer| will be called back
423 * when data is received, through:
425 * observer.onSocketPoolInfoChanged(socketPoolInfo)
427 addSocketPoolInfoObserver: function(observer
, ignoreWhenUnchanged
) {
428 this.pollableDataHelpers_
.socketPoolInfo
.addObserver(observer
,
429 ignoreWhenUnchanged
);
433 * Adds a listener of the network session. |observer| will be called back
434 * when data is received, through:
436 * observer.onSessionNetworkStatsChanged(sessionNetworkStats)
438 addSessionNetworkStatsObserver: function(observer
, ignoreWhenUnchanged
) {
439 this.pollableDataHelpers_
.sessionNetworkStats
.addObserver(
440 observer
, ignoreWhenUnchanged
);
444 * Adds a listener of persistent network session data. |observer| will be
445 * called back when data is received, through:
447 * observer.onHistoricNetworkStatsChanged(historicNetworkStats)
449 addHistoricNetworkStatsObserver: function(observer
, ignoreWhenUnchanged
) {
450 this.pollableDataHelpers_
.historicNetworkStats
.addObserver(
451 observer
, ignoreWhenUnchanged
);
455 * Adds a listener of the QUIC info. |observer| will be called back
456 * when data is received, through:
458 * observer.onQuicInfoChanged(quicInfo)
460 addQuicInfoObserver: function(observer
, ignoreWhenUnchanged
) {
461 this.pollableDataHelpers_
.quicInfo
.addObserver(
462 observer
, ignoreWhenUnchanged
);
466 * Adds a listener of the SPDY info. |observer| will be called back
467 * when data is received, through:
469 * observer.onSpdySessionInfoChanged(spdySessionInfo)
471 addSpdySessionInfoObserver: function(observer
, ignoreWhenUnchanged
) {
472 this.pollableDataHelpers_
.spdySessionInfo
.addObserver(
473 observer
, ignoreWhenUnchanged
);
477 * Adds a listener of the SPDY status. |observer| will be called back
478 * when data is received, through:
480 * observer.onSpdyStatusChanged(spdyStatus)
482 addSpdyStatusObserver: function(observer
, ignoreWhenUnchanged
) {
483 this.pollableDataHelpers_
.spdyStatus
.addObserver(observer
,
484 ignoreWhenUnchanged
);
488 * Adds a listener of the AlternateProtocolMappings. |observer| will be
489 * called back when data is received, through:
491 * observer.onSpdyAlternateProtocolMappingsChanged(
492 * spdyAlternateProtocolMappings)
494 addSpdyAlternateProtocolMappingsObserver: function(observer
,
495 ignoreWhenUnchanged
) {
496 this.pollableDataHelpers_
.spdyAlternateProtocolMappings
.addObserver(
497 observer
, ignoreWhenUnchanged
);
501 * Adds a listener of the service providers info. |observer| will be called
502 * back when data is received, through:
504 * observer.onServiceProvidersChanged(serviceProviders)
506 * Will do nothing if on a platform other than Windows, as service providers
507 * are only present on Windows.
509 addServiceProvidersObserver: function(observer
, ignoreWhenUnchanged
) {
510 if (this.pollableDataHelpers_
.serviceProviders
) {
511 this.pollableDataHelpers_
.serviceProviders
.addObserver(
512 observer
, ignoreWhenUnchanged
);
517 * Adds a listener for the progress of the connection tests.
518 * The observer will be called back with:
520 * observer.onStartedConnectionTestSuite();
521 * observer.onStartedConnectionTestExperiment(experiment);
522 * observer.onCompletedConnectionTestExperiment(experiment, result);
523 * observer.onCompletedConnectionTestSuite();
525 addConnectionTestsObserver: function(observer
) {
526 this.connectionTestsObservers_
.push(observer
);
530 * Adds a listener for the http cache info results.
531 * The observer will be called back with:
533 * observer.onHttpCacheInfoChanged(info);
535 addHttpCacheInfoObserver: function(observer
, ignoreWhenUnchanged
) {
536 this.pollableDataHelpers_
.httpCacheInfo
.addObserver(
537 observer
, ignoreWhenUnchanged
);
541 * Adds a listener for the results of HSTS (HTTPS Strict Transport Security)
542 * queries. The observer will be called back with:
544 * observer.onHSTSQueryResult(result);
546 addHSTSObserver: function(observer
) {
547 this.hstsObservers_
.push(observer
);
551 * Adds a listener for ONC file parse status. The observer will be called
554 * observer.onONCFileParse(error);
556 addCrosONCFileParseObserver: function(observer
) {
557 this.crosONCFileParseObservers_
.push(observer
);
561 * Adds a listener for storing log file status. The observer will be called
564 * observer.onStoreDebugLogs(status);
566 addStoreDebugLogsObserver: function(observer
) {
567 this.storeDebugLogsObservers_
.push(observer
);
571 * Adds a listener for network debugging mode status. The observer
572 * will be called back with:
574 * observer.onSetNetworkDebugMode(status);
576 addSetNetworkDebugModeObserver: function(observer
) {
577 this.setNetworkDebugModeObservers_
.push(observer
);
581 * Adds a listener for the received constants event. |observer| will be
582 * called back when the constants are received, through:
584 * observer.onReceivedConstants(constants);
586 addConstantsObserver: function(observer
) {
587 this.constantsObservers_
.push(observer
);
591 * Adds a listener for updated prerender info events
592 * |observer| will be called back with:
594 * observer.onPrerenderInfoChanged(prerenderInfo);
596 addPrerenderInfoObserver: function(observer
, ignoreWhenUnchanged
) {
597 this.pollableDataHelpers_
.prerenderInfo
.addObserver(
598 observer
, ignoreWhenUnchanged
);
602 * Adds a listener of extension information. |observer| will be called
603 * back when data is received, through:
605 * observer.onExtensionInfoChanged(extensionInfo)
607 addExtensionInfoObserver: function(observer
, ignoreWhenUnchanged
) {
608 this.pollableDataHelpers_
.extensionInfo
.addObserver(
609 observer
, ignoreWhenUnchanged
);
613 * Adds a listener of the data reduction proxy info. |observer| will be
614 * called back when data is received, through:
616 * observer.onDataReductionProxyInfoChanged(dataReductionProxyInfo)
618 addDataReductionProxyInfoObserver: function(observer
, ignoreWhenUnchanged
) {
619 this.pollableDataHelpers_
.dataReductionProxyInfo
.addObserver(
620 observer
, ignoreWhenUnchanged
);
624 * Adds a listener of SDCH information. |observer| will be called
625 * back when data is received, through:
627 * observer.onSdchInfoChanged(sdchInfo)
629 addSdchInfoObserver: function(observer
, ignoreWhenUnchanged
) {
630 this.pollableDataHelpers_
.sdchInfo
.addObserver(
631 observer
, ignoreWhenUnchanged
);
635 * If |force| is true, calls all startUpdate functions. Otherwise, just
636 * runs updates with active observers.
638 checkForUpdatedInfo: function(force
) {
639 for (var name
in this.pollableDataHelpers_
) {
640 var helper
= this.pollableDataHelpers_
[name
];
641 if (force
|| helper
.hasActiveObserver())
642 helper
.startUpdate();
647 * Calls all startUpdate functions and, if |callback| is non-null,
648 * calls it with the results of all updates.
650 updateAllInfo: function(callback
) {
652 new UpdateAllObserver(callback
, this.pollableDataHelpers_
);
653 this.checkForUpdatedInfo(true);
657 * Adds a PollableDataHelper that listens to the specified NetInfoSource.
659 addNetInfoPollableDataHelper: function(sourceName
, observerMethodName
) {
660 this.pollableDataHelpers_
[sourceName
] = new PollableDataHelper(
661 observerMethodName
, this.sendGetNetInfo
.bind(this, sourceName
));
666 * This is a helper class used by BrowserBridge, to keep track of:
667 * - the list of observers interested in some piece of data.
668 * - the last known value of that piece of data.
669 * - the name of the callback method to invoke on observers.
670 * - the update function.
673 function PollableDataHelper(observerMethodName
, startUpdateFunction
) {
674 this.observerMethodName_
= observerMethodName
;
675 this.startUpdate
= startUpdateFunction
;
676 this.observerInfos_
= [];
679 PollableDataHelper
.prototype = {
680 getObserverMethodName: function() {
681 return this.observerMethodName_
;
684 isObserver: function(object
) {
685 for (var i
= 0; i
< this.observerInfos_
.length
; i
++) {
686 if (this.observerInfos_
[i
].observer
=== object
)
693 * If |ignoreWhenUnchanged| is true, we won't send data again until it
696 addObserver: function(observer
, ignoreWhenUnchanged
) {
697 this.observerInfos_
.push(new ObserverInfo(observer
, ignoreWhenUnchanged
));
700 removeObserver: function(observer
) {
701 for (var i
= 0; i
< this.observerInfos_
.length
; i
++) {
702 if (this.observerInfos_
[i
].observer
=== observer
) {
703 this.observerInfos_
.splice(i
, 1);
710 * Helper function to handle calling all the observers, but ONLY if the data
711 * has actually changed since last time or the observer has yet to receive
712 * any data. This is used for data we received from browser on an update
715 update: function(data
) {
716 var prevData
= this.currentData_
;
719 // If the data hasn't changed since last time, will only need to notify
720 // observers that have not yet received any data.
721 if (!prevData
|| JSON
.stringify(prevData
) != JSON
.stringify(data
)) {
723 this.currentData_
= data
;
726 // Notify the observers of the change, as needed.
727 for (var i
= 0; i
< this.observerInfos_
.length
; i
++) {
728 var observerInfo
= this.observerInfos_
[i
];
729 if (changed
|| !observerInfo
.hasReceivedData
||
730 !observerInfo
.ignoreWhenUnchanged
) {
731 observerInfo
.observer
[this.observerMethodName_
](this.currentData_
);
732 observerInfo
.hasReceivedData
= true;
738 * Returns true if one of the observers actively wants the data
741 hasActiveObserver: function() {
742 for (var i
= 0; i
< this.observerInfos_
.length
; i
++) {
743 if (this.observerInfos_
[i
].observer
.isActive())
751 * This is a helper class used by PollableDataHelper, to keep track of
752 * each observer and whether or not it has received any data. The
753 * latter is used to make sure that new observers get sent data on the
754 * update following their creation.
757 function ObserverInfo(observer
, ignoreWhenUnchanged
) {
758 this.observer
= observer
;
759 this.hasReceivedData
= false;
760 this.ignoreWhenUnchanged
= ignoreWhenUnchanged
;
764 * This is a helper class used by BrowserBridge to send data to
765 * a callback once data from all polls has been received.
767 * It works by keeping track of how many polling functions have
768 * yet to receive data, and recording the data as it it received.
772 function UpdateAllObserver(callback
, pollableDataHelpers
) {
773 this.callback_
= callback
;
774 this.observingCount_
= 0;
775 this.updatedData_
= {};
777 for (var name
in pollableDataHelpers
) {
778 ++this.observingCount_
;
779 var helper
= pollableDataHelpers
[name
];
780 helper
.addObserver(this);
781 this[helper
.getObserverMethodName()] =
782 this.onDataReceived_
.bind(this, helper
, name
);
786 UpdateAllObserver
.prototype = {
787 isActive: function() {
791 onDataReceived_: function(helper
, name
, data
) {
792 helper
.removeObserver(this);
793 --this.observingCount_
;
794 this.updatedData_
[name
] = data
;
795 if (this.observingCount_
== 0)
796 this.callback_(this.updatedData_
);
800 return BrowserBridge
;