| Index: netlog_viewer/browser_bridge.js
|
| diff --git a/netlog_viewer/browser_bridge.js b/netlog_viewer/browser_bridge.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e2d8ed193c628debf584a818b68d920a39378893
|
| --- /dev/null
|
| +++ b/netlog_viewer/browser_bridge.js
|
| @@ -0,0 +1,805 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// Populated by constants from the browser. Used only by this file.
|
| +var NetInfoSources = null;
|
| +
|
| +/**
|
| + * This class provides a "bridge" for communicating between the javascript and
|
| + * the browser.
|
| + */
|
| +var BrowserBridge = (function() {
|
| + 'use strict';
|
| +
|
| + /**
|
| + * Delay in milliseconds between updates of certain browser information.
|
| + */
|
| + var POLL_INTERVAL_MS = 5000;
|
| +
|
| + /**
|
| + * @constructor
|
| + */
|
| + function BrowserBridge() {
|
| + assertFirstConstructorCall(BrowserBridge);
|
| +
|
| + // List of observers for various bits of browser state.
|
| + this.connectionTestsObservers_ = [];
|
| + this.hstsObservers_ = [];
|
| + this.constantsObservers_ = [];
|
| + this.crosONCFileParseObservers_ = [];
|
| + this.storeDebugLogsObservers_ = [];
|
| + this.setNetworkDebugModeObservers_ = [];
|
| + // Unprocessed data received before the constants. This serves to protect
|
| + // against passing along data before having information on how to interpret
|
| + // it.
|
| + this.earlyReceivedData_ = [];
|
| +
|
| + this.pollableDataHelpers_ = {};
|
| +
|
| + // Add PollableDataHelpers for NetInfoSources, which retrieve information
|
| + // directly from the network stack.
|
| + this.addNetInfoPollableDataHelper('proxySettings',
|
| + 'onProxySettingsChanged');
|
| + this.addNetInfoPollableDataHelper('badProxies', 'onBadProxiesChanged');
|
| + this.addNetInfoPollableDataHelper('hostResolverInfo',
|
| + 'onHostResolverInfoChanged');
|
| + this.addNetInfoPollableDataHelper('socketPoolInfo',
|
| + 'onSocketPoolInfoChanged');
|
| + this.addNetInfoPollableDataHelper('spdySessionInfo',
|
| + 'onSpdySessionInfoChanged');
|
| + this.addNetInfoPollableDataHelper('spdyStatus', 'onSpdyStatusChanged');
|
| + this.addNetInfoPollableDataHelper('altSvcMappings',
|
| + 'onAltSvcMappingsChanged');
|
| + this.addNetInfoPollableDataHelper('quicInfo', 'onQuicInfoChanged');
|
| + this.addNetInfoPollableDataHelper('sdchInfo', 'onSdchInfoChanged');
|
| + this.addNetInfoPollableDataHelper('httpCacheInfo',
|
| + 'onHttpCacheInfoChanged');
|
| +
|
| + // Add other PollableDataHelpers.
|
| + this.pollableDataHelpers_.sessionNetworkStats =
|
| + new PollableDataHelper('onSessionNetworkStatsChanged',
|
| + this.sendGetSessionNetworkStats.bind(this));
|
| + this.pollableDataHelpers_.historicNetworkStats =
|
| + new PollableDataHelper('onHistoricNetworkStatsChanged',
|
| + this.sendGetHistoricNetworkStats.bind(this));
|
| + if (cr.isWindows) {
|
| + this.pollableDataHelpers_.serviceProviders =
|
| + new PollableDataHelper('onServiceProvidersChanged',
|
| + this.sendGetServiceProviders.bind(this));
|
| + }
|
| + this.pollableDataHelpers_.prerenderInfo =
|
| + new PollableDataHelper('onPrerenderInfoChanged',
|
| + this.sendGetPrerenderInfo.bind(this));
|
| + this.pollableDataHelpers_.extensionInfo =
|
| + new PollableDataHelper('onExtensionInfoChanged',
|
| + this.sendGetExtensionInfo.bind(this));
|
| + this.pollableDataHelpers_.dataReductionProxyInfo =
|
| + new PollableDataHelper('onDataReductionProxyInfoChanged',
|
| + this.sendGetDataReductionProxyInfo.bind(this));
|
| +
|
| + // Setting this to true will cause messages from the browser to be ignored,
|
| + // and no messages will be sent to the browser, either. Intended for use
|
| + // when viewing log files.
|
| + this.disabled_ = false;
|
| +
|
| + // Interval id returned by window.setInterval for polling timer.
|
| + this.pollIntervalId_ = null;
|
| + }
|
| +
|
| + cr.addSingletonGetter(BrowserBridge);
|
| +
|
| + BrowserBridge.prototype = {
|
| +
|
| + //--------------------------------------------------------------------------
|
| + // Messages sent to the browser
|
| + //--------------------------------------------------------------------------
|
| +
|
| + /**
|
| + * Wraps |chrome.send|. Doesn't send anything when disabled.
|
| + */
|
| + send: function(value1, value2) {
|
| + if (console && console.warn) {
|
| + console.warn('TODO: Called deprecated BrowserBridge.send');
|
| + }
|
| + return;
|
| +
|
| + /*if (!this.disabled_) {
|
| + if (arguments.length == 1) {
|
| + chrome.send(value1);
|
| + } else if (arguments.length == 2) {
|
| + chrome.send(value1, value2);
|
| + } else {
|
| + throw 'Unsupported number of arguments.';
|
| + }
|
| + }*/
|
| + },
|
| +
|
| + sendReady: function() {
|
| + this.send('notifyReady');
|
| + this.setPollInterval(POLL_INTERVAL_MS);
|
| + },
|
| +
|
| + /**
|
| + * Some of the data we are interested is not currently exposed as a
|
| + * stream. This starts polling those with active observers (visible
|
| + * views) every |intervalMs|. Subsequent calls override previous calls
|
| + * to this function. If |intervalMs| is 0, stops polling.
|
| + */
|
| + setPollInterval: function(intervalMs) {
|
| + if (this.pollIntervalId_ !== null) {
|
| + window.clearInterval(this.pollIntervalId_);
|
| + this.pollIntervalId_ = null;
|
| + }
|
| +
|
| + if (intervalMs > 0) {
|
| + this.pollIntervalId_ =
|
| + window.setInterval(this.checkForUpdatedInfo.bind(this, false),
|
| + intervalMs);
|
| + }
|
| + },
|
| +
|
| + sendGetNetInfo: function(netInfoSource) {
|
| + // If don't have constants yet, don't do anything yet.
|
| + if (NetInfoSources)
|
| + this.send('getNetInfo', [NetInfoSources[netInfoSource]]);
|
| + },
|
| +
|
| + sendReloadProxySettings: function() {
|
| + this.send('reloadProxySettings');
|
| + },
|
| +
|
| + sendClearBadProxies: function() {
|
| + this.send('clearBadProxies');
|
| + },
|
| +
|
| + sendClearHostResolverCache: function() {
|
| + this.send('clearHostResolverCache');
|
| + },
|
| +
|
| + sendClearBrowserCache: function() {
|
| + this.send('clearBrowserCache');
|
| + },
|
| +
|
| + sendClearAllCache: function() {
|
| + this.sendClearHostResolverCache();
|
| + this.sendClearBrowserCache();
|
| + },
|
| +
|
| + sendStartConnectionTests: function(url) {
|
| + this.send('startConnectionTests', [url]);
|
| + },
|
| +
|
| + sendHSTSQuery: function(domain) {
|
| + this.send('hstsQuery', [domain]);
|
| + },
|
| +
|
| + sendHSTSAdd: function(domain, sts_include_subdomains,
|
| + pkp_include_subdomains, pins) {
|
| + this.send('hstsAdd', [domain, sts_include_subdomains,
|
| + pkp_include_subdomains, pins]);
|
| + },
|
| +
|
| + sendHSTSDelete: function(domain) {
|
| + this.send('hstsDelete', [domain]);
|
| + },
|
| +
|
| + sendGetSessionNetworkStats: function() {
|
| + this.send('getSessionNetworkStats');
|
| + },
|
| +
|
| + sendGetHistoricNetworkStats: function() {
|
| + this.send('getHistoricNetworkStats');
|
| + },
|
| +
|
| + sendCloseIdleSockets: function() {
|
| + this.send('closeIdleSockets');
|
| + },
|
| +
|
| + sendFlushSocketPools: function() {
|
| + this.send('flushSocketPools');
|
| + },
|
| +
|
| + sendGetServiceProviders: function() {
|
| + this.send('getServiceProviders');
|
| + },
|
| +
|
| + sendGetPrerenderInfo: function() {
|
| + this.send('getPrerenderInfo');
|
| + },
|
| +
|
| + sendGetExtensionInfo: function() {
|
| + this.send('getExtensionInfo');
|
| + },
|
| +
|
| + sendGetDataReductionProxyInfo: function() {
|
| + this.send('getDataReductionProxyInfo');
|
| + },
|
| +
|
| + setCaptureMode: function(captureMode) {
|
| + this.send('setCaptureMode', ['' + captureMode]);
|
| + },
|
| +
|
| + importONCFile: function(fileContent, passcode) {
|
| + this.send('importONCFile', [fileContent, passcode]);
|
| + },
|
| +
|
| + storeDebugLogs: function() {
|
| + this.send('storeDebugLogs');
|
| + },
|
| +
|
| + setNetworkDebugMode: function(subsystem) {
|
| + this.send('setNetworkDebugMode', [subsystem]);
|
| + },
|
| +
|
| + //--------------------------------------------------------------------------
|
| + // Messages received from the browser.
|
| + //--------------------------------------------------------------------------
|
| +
|
| + receive: function(command, params) {
|
| + // Does nothing if disabled.
|
| + if (this.disabled_)
|
| + return;
|
| +
|
| + // If no constants have been received, and params does not contain the
|
| + // constants, delay handling the data.
|
| + if (Constants == null && command != 'receivedConstants') {
|
| + this.earlyReceivedData_.push({ command: command, params: params });
|
| + return;
|
| + }
|
| +
|
| + this[command](params);
|
| +
|
| + // Handle any data that was received early in the order it was received,
|
| + // once the constants have been processed.
|
| + if (this.earlyReceivedData_ != null) {
|
| + for (var i = 0; i < this.earlyReceivedData_.length; i++) {
|
| + var command = this.earlyReceivedData_[i];
|
| + this[command.command](command.params);
|
| + }
|
| + this.earlyReceivedData_ = null;
|
| + }
|
| + },
|
| +
|
| + receivedConstants: function(constants) {
|
| + NetInfoSources = constants.netInfoSources;
|
| + for (var i = 0; i < this.constantsObservers_.length; i++)
|
| + this.constantsObservers_[i].onReceivedConstants(constants);
|
| + // May have been waiting for the constants to be received before getting
|
| + // information for the currently displayed tab.
|
| + this.checkForUpdatedInfo();
|
| + },
|
| +
|
| + receivedLogEntries: function(logEntries) {
|
| + EventsTracker.getInstance().addLogEntries(logEntries);
|
| + },
|
| +
|
| + receivedNetInfo: function(netInfo) {
|
| + // Dispatch |netInfo| to the various PollableDataHelpers listening to
|
| + // each field it contains.
|
| + //
|
| + // Currently information is only received from one source at a time, but
|
| + // the API does allow for data from more that one to be requested at once.
|
| + for (var source in netInfo)
|
| + this.pollableDataHelpers_[source].update(netInfo[source]);
|
| + },
|
| +
|
| + receivedSessionNetworkStats: function(sessionNetworkStats) {
|
| + this.pollableDataHelpers_.sessionNetworkStats.update(sessionNetworkStats);
|
| + },
|
| +
|
| + receivedHistoricNetworkStats: function(historicNetworkStats) {
|
| + this.pollableDataHelpers_.historicNetworkStats.update(
|
| + historicNetworkStats);
|
| + },
|
| +
|
| + receivedServiceProviders: function(serviceProviders) {
|
| + this.pollableDataHelpers_.serviceProviders.update(serviceProviders);
|
| + },
|
| +
|
| + receivedStartConnectionTestSuite: function() {
|
| + for (var i = 0; i < this.connectionTestsObservers_.length; i++)
|
| + this.connectionTestsObservers_[i].onStartedConnectionTestSuite();
|
| + },
|
| +
|
| + receivedStartConnectionTestExperiment: function(experiment) {
|
| + for (var i = 0; i < this.connectionTestsObservers_.length; i++) {
|
| + this.connectionTestsObservers_[i].onStartedConnectionTestExperiment(
|
| + experiment);
|
| + }
|
| + },
|
| +
|
| + receivedCompletedConnectionTestExperiment: function(info) {
|
| + for (var i = 0; i < this.connectionTestsObservers_.length; i++) {
|
| + this.connectionTestsObservers_[i].onCompletedConnectionTestExperiment(
|
| + info.experiment, info.result);
|
| + }
|
| + },
|
| +
|
| + receivedCompletedConnectionTestSuite: function() {
|
| + for (var i = 0; i < this.connectionTestsObservers_.length; i++)
|
| + this.connectionTestsObservers_[i].onCompletedConnectionTestSuite();
|
| + },
|
| +
|
| + receivedHSTSResult: function(info) {
|
| + for (var i = 0; i < this.hstsObservers_.length; i++)
|
| + this.hstsObservers_[i].onHSTSQueryResult(info);
|
| + },
|
| +
|
| + receivedONCFileParse: function(error) {
|
| + for (var i = 0; i < this.crosONCFileParseObservers_.length; i++)
|
| + this.crosONCFileParseObservers_[i].onONCFileParse(error);
|
| + },
|
| +
|
| + receivedStoreDebugLogs: function(status) {
|
| + for (var i = 0; i < this.storeDebugLogsObservers_.length; i++)
|
| + this.storeDebugLogsObservers_[i].onStoreDebugLogs(status);
|
| + },
|
| +
|
| + receivedSetNetworkDebugMode: function(status) {
|
| + for (var i = 0; i < this.setNetworkDebugModeObservers_.length; i++)
|
| + this.setNetworkDebugModeObservers_[i].onSetNetworkDebugMode(status);
|
| + },
|
| +
|
| + receivedPrerenderInfo: function(prerenderInfo) {
|
| + this.pollableDataHelpers_.prerenderInfo.update(prerenderInfo);
|
| + },
|
| +
|
| + receivedExtensionInfo: function(extensionInfo) {
|
| + this.pollableDataHelpers_.extensionInfo.update(extensionInfo);
|
| + },
|
| +
|
| + receivedDataReductionProxyInfo: function(dataReductionProxyInfo) {
|
| + this.pollableDataHelpers_.dataReductionProxyInfo.update(
|
| + dataReductionProxyInfo);
|
| + },
|
| +
|
| + //--------------------------------------------------------------------------
|
| +
|
| + /**
|
| + * Prevents receiving/sending events to/from the browser.
|
| + */
|
| + disable: function() {
|
| + this.disabled_ = true;
|
| + this.setPollInterval(0);
|
| + },
|
| +
|
| + /**
|
| + * Returns true if the BrowserBridge has been disabled.
|
| + */
|
| + isDisabled: function() {
|
| + return this.disabled_;
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the proxy settings. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onProxySettingsChanged(proxySettings)
|
| + *
|
| + * |proxySettings| is a dictionary with (up to) two properties:
|
| + *
|
| + * "original" -- The settings that chrome was configured to use
|
| + * (i.e. system settings.)
|
| + * "effective" -- The "effective" proxy settings that chrome is using.
|
| + * (decides between the manual/automatic modes of the
|
| + * fetched settings).
|
| + *
|
| + * Each of these two configurations is formatted as a string, and may be
|
| + * omitted if not yet initialized.
|
| + *
|
| + * If |ignoreWhenUnchanged| is true, data is only sent when it changes.
|
| + * If it's false, data is sent whenever it's received from the browser.
|
| + */
|
| + addProxySettingsObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.proxySettings.addObserver(observer,
|
| + ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the proxy settings. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onBadProxiesChanged(badProxies)
|
| + *
|
| + * |badProxies| is an array, where each entry has the property:
|
| + * badProxies[i].proxy_uri: String identify the proxy.
|
| + * badProxies[i].bad_until: The time when the proxy stops being considered
|
| + * bad. Note the time is in time ticks.
|
| + */
|
| + addBadProxiesObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.badProxies.addObserver(observer,
|
| + ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the host resolver info. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onHostResolverInfoChanged(hostResolverInfo)
|
| + */
|
| + addHostResolverInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.hostResolverInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the socket pool. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onSocketPoolInfoChanged(socketPoolInfo)
|
| + */
|
| + addSocketPoolInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.socketPoolInfo.addObserver(observer,
|
| + ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the network session. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onSessionNetworkStatsChanged(sessionNetworkStats)
|
| + */
|
| + addSessionNetworkStatsObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.sessionNetworkStats.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of persistent network session data. |observer| will be
|
| + * called back when data is received, through:
|
| + *
|
| + * observer.onHistoricNetworkStatsChanged(historicNetworkStats)
|
| + */
|
| + addHistoricNetworkStatsObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.historicNetworkStats.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the QUIC info. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onQuicInfoChanged(quicInfo)
|
| + */
|
| + addQuicInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.quicInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the SPDY info. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onSpdySessionInfoChanged(spdySessionInfo)
|
| + */
|
| + addSpdySessionInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.spdySessionInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the SPDY status. |observer| will be called back
|
| + * when data is received, through:
|
| + *
|
| + * observer.onSpdyStatusChanged(spdyStatus)
|
| + */
|
| + addSpdyStatusObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.spdyStatus.addObserver(observer,
|
| + ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the altSvcMappings. |observer| will be
|
| + * called back when data is received, through:
|
| + *
|
| + * observer.onAltSvcMappingsChanged(altSvcMappings)
|
| + */
|
| + addAltSvcMappingsObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.altSvcMappings.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the service providers info. |observer| will be called
|
| + * back when data is received, through:
|
| + *
|
| + * observer.onServiceProvidersChanged(serviceProviders)
|
| + *
|
| + * Will do nothing if on a platform other than Windows, as service providers
|
| + * are only present on Windows.
|
| + */
|
| + addServiceProvidersObserver: function(observer, ignoreWhenUnchanged) {
|
| + if (this.pollableDataHelpers_.serviceProviders) {
|
| + this.pollableDataHelpers_.serviceProviders.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for the progress of the connection tests.
|
| + * The observer will be called back with:
|
| + *
|
| + * observer.onStartedConnectionTestSuite();
|
| + * observer.onStartedConnectionTestExperiment(experiment);
|
| + * observer.onCompletedConnectionTestExperiment(experiment, result);
|
| + * observer.onCompletedConnectionTestSuite();
|
| + */
|
| + addConnectionTestsObserver: function(observer) {
|
| + this.connectionTestsObservers_.push(observer);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for the http cache info results.
|
| + * The observer will be called back with:
|
| + *
|
| + * observer.onHttpCacheInfoChanged(info);
|
| + */
|
| + addHttpCacheInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.httpCacheInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for the results of HSTS (HTTPS Strict Transport Security)
|
| + * queries. The observer will be called back with:
|
| + *
|
| + * observer.onHSTSQueryResult(result);
|
| + */
|
| + addHSTSObserver: function(observer) {
|
| + this.hstsObservers_.push(observer);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for ONC file parse status. The observer will be called
|
| + * back with:
|
| + *
|
| + * observer.onONCFileParse(error);
|
| + */
|
| + addCrosONCFileParseObserver: function(observer) {
|
| + this.crosONCFileParseObservers_.push(observer);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for storing log file status. The observer will be called
|
| + * back with:
|
| + *
|
| + * observer.onStoreDebugLogs(status);
|
| + */
|
| + addStoreDebugLogsObserver: function(observer) {
|
| + this.storeDebugLogsObservers_.push(observer);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for network debugging mode status. The observer
|
| + * will be called back with:
|
| + *
|
| + * observer.onSetNetworkDebugMode(status);
|
| + */
|
| + addSetNetworkDebugModeObserver: function(observer) {
|
| + this.setNetworkDebugModeObservers_.push(observer);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for the received constants event. |observer| will be
|
| + * called back when the constants are received, through:
|
| + *
|
| + * observer.onReceivedConstants(constants);
|
| + */
|
| + addConstantsObserver: function(observer) {
|
| + this.constantsObservers_.push(observer);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener for updated prerender info events
|
| + * |observer| will be called back with:
|
| + *
|
| + * observer.onPrerenderInfoChanged(prerenderInfo);
|
| + */
|
| + addPrerenderInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.prerenderInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of extension information. |observer| will be called
|
| + * back when data is received, through:
|
| + *
|
| + * observer.onExtensionInfoChanged(extensionInfo)
|
| + */
|
| + addExtensionInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.extensionInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of the data reduction proxy info. |observer| will be
|
| + * called back when data is received, through:
|
| + *
|
| + * observer.onDataReductionProxyInfoChanged(dataReductionProxyInfo)
|
| + */
|
| + addDataReductionProxyInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.dataReductionProxyInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * Adds a listener of SDCH information. |observer| will be called
|
| + * back when data is received, through:
|
| + *
|
| + * observer.onSdchInfoChanged(sdchInfo)
|
| + */
|
| + addSdchInfoObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.pollableDataHelpers_.sdchInfo.addObserver(
|
| + observer, ignoreWhenUnchanged);
|
| + },
|
| +
|
| + /**
|
| + * If |force| is true, calls all startUpdate functions. Otherwise, just
|
| + * runs updates with active observers.
|
| + */
|
| + checkForUpdatedInfo: function(force) {
|
| + for (var name in this.pollableDataHelpers_) {
|
| + var helper = this.pollableDataHelpers_[name];
|
| + if (force || helper.hasActiveObserver())
|
| + helper.startUpdate();
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Calls all startUpdate functions and, if |callback| is non-null,
|
| + * calls it with the results of all updates.
|
| + */
|
| + updateAllInfo: function(callback) {
|
| + if (callback)
|
| + new UpdateAllObserver(callback, this.pollableDataHelpers_);
|
| + this.checkForUpdatedInfo(true);
|
| + },
|
| +
|
| + /**
|
| + * Adds a PollableDataHelper that listens to the specified NetInfoSource.
|
| + */
|
| + addNetInfoPollableDataHelper: function(sourceName, observerMethodName) {
|
| + this.pollableDataHelpers_[sourceName] = new PollableDataHelper(
|
| + observerMethodName, this.sendGetNetInfo.bind(this, sourceName));
|
| + },
|
| + };
|
| +
|
| + /**
|
| + * This is a helper class used by BrowserBridge, to keep track of:
|
| + * - the list of observers interested in some piece of data.
|
| + * - the last known value of that piece of data.
|
| + * - the name of the callback method to invoke on observers.
|
| + * - the update function.
|
| + * @constructor
|
| + */
|
| + function PollableDataHelper(observerMethodName, startUpdateFunction) {
|
| + this.observerMethodName_ = observerMethodName;
|
| + this.startUpdate = startUpdateFunction;
|
| + this.observerInfos_ = [];
|
| + }
|
| +
|
| + PollableDataHelper.prototype = {
|
| + getObserverMethodName: function() {
|
| + return this.observerMethodName_;
|
| + },
|
| +
|
| + isObserver: function(object) {
|
| + for (var i = 0; i < this.observerInfos_.length; i++) {
|
| + if (this.observerInfos_[i].observer === object)
|
| + return true;
|
| + }
|
| + return false;
|
| + },
|
| +
|
| + /**
|
| + * If |ignoreWhenUnchanged| is true, we won't send data again until it
|
| + * changes.
|
| + */
|
| + addObserver: function(observer, ignoreWhenUnchanged) {
|
| + this.observerInfos_.push(new ObserverInfo(observer, ignoreWhenUnchanged));
|
| + },
|
| +
|
| + removeObserver: function(observer) {
|
| + for (var i = 0; i < this.observerInfos_.length; i++) {
|
| + if (this.observerInfos_[i].observer === observer) {
|
| + this.observerInfos_.splice(i, 1);
|
| + return;
|
| + }
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Helper function to handle calling all the observers, but ONLY if the data
|
| + * has actually changed since last time or the observer has yet to receive
|
| + * any data. This is used for data we received from browser on an update
|
| + * loop.
|
| + */
|
| + update: function(data) {
|
| + var prevData = this.currentData_;
|
| + var changed = false;
|
| +
|
| + // If the data hasn't changed since last time, will only need to notify
|
| + // observers that have not yet received any data.
|
| + if (!prevData || JSON.stringify(prevData) != JSON.stringify(data)) {
|
| + changed = true;
|
| + this.currentData_ = data;
|
| + }
|
| +
|
| + // Notify the observers of the change, as needed.
|
| + for (var i = 0; i < this.observerInfos_.length; i++) {
|
| + var observerInfo = this.observerInfos_[i];
|
| + if (changed || !observerInfo.hasReceivedData ||
|
| + !observerInfo.ignoreWhenUnchanged) {
|
| + observerInfo.observer[this.observerMethodName_](this.currentData_);
|
| + observerInfo.hasReceivedData = true;
|
| + }
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Returns true if one of the observers actively wants the data
|
| + * (i.e. is visible).
|
| + */
|
| + hasActiveObserver: function() {
|
| + for (var i = 0; i < this.observerInfos_.length; i++) {
|
| + if (this.observerInfos_[i].observer.isActive())
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| + };
|
| +
|
| + /**
|
| + * This is a helper class used by PollableDataHelper, to keep track of
|
| + * each observer and whether or not it has received any data. The
|
| + * latter is used to make sure that new observers get sent data on the
|
| + * update following their creation.
|
| + * @constructor
|
| + */
|
| + function ObserverInfo(observer, ignoreWhenUnchanged) {
|
| + this.observer = observer;
|
| + this.hasReceivedData = false;
|
| + this.ignoreWhenUnchanged = ignoreWhenUnchanged;
|
| + }
|
| +
|
| + /**
|
| + * This is a helper class used by BrowserBridge to send data to
|
| + * a callback once data from all polls has been received.
|
| + *
|
| + * It works by keeping track of how many polling functions have
|
| + * yet to receive data, and recording the data as it it received.
|
| + *
|
| + * @constructor
|
| + */
|
| + function UpdateAllObserver(callback, pollableDataHelpers) {
|
| + this.callback_ = callback;
|
| + this.observingCount_ = 0;
|
| + this.updatedData_ = {};
|
| +
|
| + for (var name in pollableDataHelpers) {
|
| + ++this.observingCount_;
|
| + var helper = pollableDataHelpers[name];
|
| + helper.addObserver(this);
|
| + this[helper.getObserverMethodName()] =
|
| + this.onDataReceived_.bind(this, helper, name);
|
| + }
|
| + }
|
| +
|
| + UpdateAllObserver.prototype = {
|
| + isActive: function() {
|
| + return true;
|
| + },
|
| +
|
| + onDataReceived_: function(helper, name, data) {
|
| + helper.removeObserver(this);
|
| + --this.observingCount_;
|
| + this.updatedData_[name] = data;
|
| + if (this.observingCount_ == 0)
|
| + this.callback_(this.updatedData_);
|
| + }
|
| + };
|
| +
|
| + return BrowserBridge;
|
| +})();
|
| +
|
|
|