Path: blob/trunk/third_party/closure/goog/net/networktester.js
2868 views
// Copyright 2007 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Definition of goog.net.NetworkTester.16*/1718goog.provide('goog.net.NetworkTester');19goog.require('goog.Timer');20goog.require('goog.Uri');21goog.require('goog.log');22232425/**26* Creates an instance of goog.net.NetworkTester which can be used to test27* for internet connectivity by seeing if an image can be loaded from28* google.com. It can also be tested with other URLs.29* @param {Function} callback Callback that is called when the test completes.30* The callback takes a single boolean parameter. True indicates the URL31* was reachable, false indicates it wasn't.32* @param {Object=} opt_handler Handler object for the callback.33* @param {goog.Uri=} opt_uri URI to use for testing.34* @constructor @struct35* @final36*/37goog.net.NetworkTester = function(callback, opt_handler, opt_uri) {38/**39* Callback that is called when the test completes.40* The callback takes a single boolean parameter. True indicates the URL was41* reachable, false indicates it wasn't.42* @type {Function}43* @private44*/45this.callback_ = callback;4647/**48* Handler object for the callback.49* @type {Object|undefined}50* @private51*/52this.handler_ = opt_handler;5354if (!opt_uri) {55// set the default URI to be based on the cleardot image at google.com56// We need to add a 'rand' to make sure the response is not fulfilled57// by browser cache. Use protocol-relative URLs to avoid insecure content58// warnings in IE.59opt_uri = new goog.Uri('//www.google.com/images/cleardot.gif');60opt_uri.makeUnique();61}6263/**64* Uri to use for test. Defaults to using an image off of google.com65* @type {goog.Uri}66* @private67*/68this.uri_ = opt_uri;69};707172/**73* Default timeout74* @type {number}75*/76goog.net.NetworkTester.DEFAULT_TIMEOUT_MS = 10000;777879/**80* Logger object81* @type {goog.log.Logger}82* @private83*/84goog.net.NetworkTester.prototype.logger_ =85goog.log.getLogger('goog.net.NetworkTester');868788/**89* Timeout for test90* @type {number}91* @private92*/93goog.net.NetworkTester.prototype.timeoutMs_ =94goog.net.NetworkTester.DEFAULT_TIMEOUT_MS;959697/**98* Whether we've already started running.99* @type {boolean}100* @private101*/102goog.net.NetworkTester.prototype.running_ = false;103104105/**106* Number of retries to attempt107* @type {number}108* @private109*/110goog.net.NetworkTester.prototype.retries_ = 0;111112113/**114* Attempt number we're on115* @type {number}116* @private117*/118goog.net.NetworkTester.prototype.attempt_ = 0;119120121/**122* Pause between retries in milliseconds.123* @type {number}124* @private125*/126goog.net.NetworkTester.prototype.pauseBetweenRetriesMs_ = 0;127128129/**130* Timer for timeouts.131* @type {?number}132* @private133*/134goog.net.NetworkTester.prototype.timeoutTimer_ = null;135136137/**138* Timer for pauses between retries.139* @type {?number}140* @private141*/142goog.net.NetworkTester.prototype.pauseTimer_ = null;143144145/** @private {?Image} */146goog.net.NetworkTester.prototype.image_;147148149/**150* Returns the timeout in milliseconds.151* @return {number} Timeout in milliseconds.152*/153goog.net.NetworkTester.prototype.getTimeout = function() {154return this.timeoutMs_;155};156157158/**159* Sets the timeout in milliseconds.160* @param {number} timeoutMs Timeout in milliseconds.161*/162goog.net.NetworkTester.prototype.setTimeout = function(timeoutMs) {163this.timeoutMs_ = timeoutMs;164};165166167/**168* Returns the numer of retries to attempt.169* @return {number} Number of retries to attempt.170*/171goog.net.NetworkTester.prototype.getNumRetries = function() {172return this.retries_;173};174175176/**177* Sets the timeout in milliseconds.178* @param {number} retries Number of retries to attempt.179*/180goog.net.NetworkTester.prototype.setNumRetries = function(retries) {181this.retries_ = retries;182};183184185/**186* Returns the pause between retries in milliseconds.187* @return {number} Pause between retries in milliseconds.188*/189goog.net.NetworkTester.prototype.getPauseBetweenRetries = function() {190return this.pauseBetweenRetriesMs_;191};192193194/**195* Sets the pause between retries in milliseconds.196* @param {number} pauseMs Pause between retries in milliseconds.197*/198goog.net.NetworkTester.prototype.setPauseBetweenRetries = function(pauseMs) {199this.pauseBetweenRetriesMs_ = pauseMs;200};201202203/**204* Returns the uri to use for the test.205* @return {goog.Uri} The uri for the test.206*/207goog.net.NetworkTester.prototype.getUri = function() {208return this.uri_;209};210211212/**213* Returns the current attempt count.214* @return {number} The attempt count.215*/216goog.net.NetworkTester.prototype.getAttemptCount = function() {217return this.attempt_;218};219220221/**222* Sets the uri to use for the test.223* @param {goog.Uri} uri The uri for the test.224*/225goog.net.NetworkTester.prototype.setUri = function(uri) {226this.uri_ = uri;227};228229230/**231* Returns whether the tester is currently running.232* @return {boolean} True if it's running, false if it's not running.233*/234goog.net.NetworkTester.prototype.isRunning = function() {235return this.running_;236};237238239/**240* Starts the process of testing the network.241*/242goog.net.NetworkTester.prototype.start = function() {243if (this.running_) {244throw Error('NetworkTester.start called when already running');245}246this.running_ = true;247248goog.log.info(this.logger_, 'Starting');249this.attempt_ = 0;250this.startNextAttempt_();251};252253254/**255* Stops the testing of the network. This is a noop if not running.256*/257goog.net.NetworkTester.prototype.stop = function() {258this.cleanupCallbacks_();259this.running_ = false;260};261262263/**264* Starts the next attempt to load an image.265* @private266*/267goog.net.NetworkTester.prototype.startNextAttempt_ = function() {268this.attempt_++;269270if (goog.net.NetworkTester.getNavigatorOffline_()) {271goog.log.info(this.logger_, 'Browser is set to work offline.');272// Call in a timeout to make async like the rest.273goog.Timer.callOnce(goog.bind(this.onResult, this, false), 0);274} else {275goog.log.info(276this.logger_,277'Loading image (attempt ' + this.attempt_ + ') at ' + this.uri_);278this.image_ = new Image();279this.image_.onload = goog.bind(this.onImageLoad_, this);280this.image_.onerror = goog.bind(this.onImageError_, this);281this.image_.onabort = goog.bind(this.onImageAbort_, this);282283this.timeoutTimer_ =284goog.Timer.callOnce(this.onImageTimeout_, this.timeoutMs_, this);285this.image_.src = String(this.uri_);286}287};288289290/**291* @return {boolean} Whether navigator.onLine returns false.292* @private293*/294goog.net.NetworkTester.getNavigatorOffline_ = function() {295return navigator !== null && 'onLine' in navigator && !navigator.onLine;296};297298299/**300* Callback for the image successfully loading.301* @private302*/303goog.net.NetworkTester.prototype.onImageLoad_ = function() {304goog.log.info(this.logger_, 'Image loaded');305this.onResult(true);306};307308309/**310* Callback for the image failing to load.311* @private312*/313goog.net.NetworkTester.prototype.onImageError_ = function() {314goog.log.info(this.logger_, 'Image load error');315this.onResult(false);316};317318319/**320* Callback for the image load being aborted.321* @private322*/323goog.net.NetworkTester.prototype.onImageAbort_ = function() {324goog.log.info(this.logger_, 'Image load aborted');325this.onResult(false);326};327328329/**330* Callback for the image load timing out.331* @private332*/333goog.net.NetworkTester.prototype.onImageTimeout_ = function() {334goog.log.info(this.logger_, 'Image load timed out');335this.onResult(false);336};337338339/**340* Handles a successful or failed result.341* @param {boolean} succeeded Whether the image load succeeded.342*/343goog.net.NetworkTester.prototype.onResult = function(succeeded) {344this.cleanupCallbacks_();345346if (succeeded) {347this.running_ = false;348this.callback_.call(this.handler_, true);349} else {350if (this.attempt_ <= this.retries_) {351if (this.pauseBetweenRetriesMs_) {352this.pauseTimer_ = goog.Timer.callOnce(353this.onPauseFinished_, this.pauseBetweenRetriesMs_, this);354} else {355this.startNextAttempt_();356}357} else {358this.running_ = false;359this.callback_.call(this.handler_, false);360}361}362};363364365/**366* Callback for the pause between retry timer.367* @private368*/369goog.net.NetworkTester.prototype.onPauseFinished_ = function() {370this.pauseTimer_ = null;371this.startNextAttempt_();372};373374375/**376* Cleans up the handlers and timer associated with the image.377* @private378*/379goog.net.NetworkTester.prototype.cleanupCallbacks_ = function() {380// clear handlers to avoid memory leaks381// NOTE(user): Nullified individually to avoid compiler warnings382// (BUG 658126)383if (this.image_) {384this.image_.onload = null;385this.image_.onerror = null;386this.image_.onabort = null;387this.image_ = null;388}389if (this.timeoutTimer_) {390goog.Timer.clear(this.timeoutTimer_);391this.timeoutTimer_ = null;392}393if (this.pauseTimer_) {394goog.Timer.clear(this.pauseTimer_);395this.pauseTimer_ = null;396}397};398399400