blob: 854b507e7c9c56e90b122449cd6800eae1dc3ac7 [file] [log] [blame]
// Copyright 2013 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.
cr.define('mobile', function() {
// TODO(tbarzic): Share code with mobile_setup.js.
var EXTENSION_BASE_URL =
'chrome-extension://iadeocfgjdjdmpenejdbfeaocpbikmab/';
var REDIRECT_POST_PAGE_URL = EXTENSION_BASE_URL + 'redirect.html?autoPost=1';
var PORTAL_OFFLINE_PAGE_URL = EXTENSION_BASE_URL + 'portal_offline.html';
var INVALID_DEVICE_INFO_PAGE_URL =
EXTENSION_BASE_URL + 'invalid_device_info.html';
var NetworkState = {
UNKNOWN: 0,
PORTAL_REACHABLE: 1,
PORTAL_UNREACHABLE: 2
};
var CarrierPageType = {
NOT_SET: 0,
PORTAL_OFFLINE: 1,
INVALID_DEVICE_INFO: 2
};
var localStrings = new LocalStrings();
function PortalImpl() {
// Mobile device information.
this.deviceInfo_ = null;
this.spinnerInt_ = -1;
this.networkState_ = NetworkState.UNKNOWN;
this.portalFrameSet_ = false;
this.carrierPageType_ = CarrierPageType.NOT_SET;
}
cr.addSingletonGetter(PortalImpl);
PortalImpl.prototype = {
initialize: function() {
// Get network device info for which portal should be opened.
// For LTE networks, this will also start observing network connection
// state and raise |updatePortalReachability| messages when the portal
// reachability changes.
chrome.send('getDeviceInfo');
},
updateDeviceInfo: function(deviceInfo) {
this.deviceInfo_ = deviceInfo;
this.updateState_();
},
updateNetworkState: function(networkState) {
if (this.networkState_ == networkState)
return;
this.networkState_ = networkState;
// If the device info is not yet set, the state will be updated on the
// device info update.
if (this.deviceInfo_)
this.updateState_();
},
updateState_: function() {
if (!this.deviceInfo_ || this.networkState_ == NetworkState.UNKNOWN)
return;
if (!this.isDeviceInfoValid_()) {
// If the device info is not valid, hide portalFrame and show system
// status displaying 'invalid device info' page.
this.setCarrierPage_(CarrierPageType.INVALID_DEVICE_INFO);
$('portalFrame').hidden = true;
$('systemStatus').hidden = false;
} else if (this.networkState_ != NetworkState.PORTAL_REACHABLE) {
// If the portal is not reachable, hide portalFrame and show system
// status displaying 'offline portal' page.
this.setCarrierPage_(CarrierPageType.PORTAL_OFFLINE);
$('portalFrame').hidden = true;
$('systemStatus').hidden = false;
} else {
// If the portal is reachable and device info is valid, set and show
// portalFrame; and hide system status displaying 'offline portal' page.
this.setPortalFrameIfNeeded_(this.deviceInfo_);
$('portalFrame').hidden = false;
$('systemStatus').hidden = true;
this.stopSpinner_();
}
},
setCarrierPage_: function(type) {
// The page is already set, nothing to do.
if (type == this.carrierPageType_)
return;
switch (type) {
case CarrierPageType.PORTAL_OFFLINE:
$('carrierPage').contentWindow.location.href =
PORTAL_OFFLINE_PAGE_URL;
$('statusHeader').textContent =
localStrings.getString('portal_unreachable_header');
this.startSpinner_();
break;
case CarrierPageType.INVALID_DEVICE_INFO:
$('carrierPage').contentWindow.location.href =
INVALID_DEVICE_INFO_PAGE_URL;
$('statusHeader').textContent =
localStrings.getString('invalid_device_info_header');
this.stopSpinner_();
break;
case CarrierPageType.NOT_SET:
$('carrierPage').contentWindow.location.href = 'about:blank';
$('statusHeader').textContent = '';
this.stopSpinner_();
break;
default:
break;
}
this.carrierPageType_ = type;
},
setPortalFrameIfNeeded_: function(deviceInfo) {
// The portal should be set only once.
if (this.portalFrameSet_)
return;
var postData = '';
if (deviceInfo.post_data && deviceInfo.post_data.length)
postData = '&post_data=' + encodeURIComponent(deviceInfo.post_data);
$('portalFrame').contentWindow.location.href = REDIRECT_POST_PAGE_URL +
postData + '&formUrl=' + encodeURIComponent(deviceInfo.payment_url);
this.portalFrameSet_ = true;
},
isDeviceInfoValid_: function() {
// Device info is valid if it has mdn which doesn't contain only '0's.
return this.deviceInfo_ && this.deviceInfo_.MDN &&
this.deviceInfo_.MDN.match('[^0]');
},
startSpinner_: function() {
this.stopSpinner_();
this.spinnerInt_ = setInterval(this.drawProgress_.bind(this), 100);
},
stopSpinner_: function() {
if (this.spinnerInt_ != -1) {
clearInterval(this.spinnerInt_);
this.spinnerInt_ = -1;
}
// Clear the spinner canvas.
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
},
drawProgress_: function() {
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
var segmentCount = Math.min(12, canvas.width / 1.6); // Number of segments
var rotation = 0.75; // Counterclockwise rotation
// Rotate canvas over time
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(Math.PI * 2 / (segmentCount + rotation));
ctx.translate(-canvas.width / 2, -canvas.height / 2);
var gap = canvas.width / 24; // Gap between segments
var oRadius = canvas.width / 2; // Outer radius
var iRadius = oRadius * 0.618; // Inner radius
var oCircumference = Math.PI * 2 * oRadius; // Outer circumference
var iCircumference = Math.PI * 2 * iRadius; // Inner circumference
var oGap = gap / oCircumference; // Gap size as fraction of outer ring
var iGap = gap / iCircumference; // Gap size as fraction of inner ring
var oArc = Math.PI * 2 * (1 / segmentCount - oGap); // Angle of outer arcs
var iArc = Math.PI * 2 * (1 / segmentCount - iGap); // Angle of inner arcs
for (i = 0; i < segmentCount; i++) { // Draw each segment
var opacity = Math.pow(1.0 - i / segmentCount, 3.0);
opacity = (0.15 + opacity * 0.8); // Vary from 0.15 to 0.95
var angle = - Math.PI * 2 * i / segmentCount;
ctx.beginPath();
ctx.arc(canvas.width / 2, canvas.height / 2, oRadius,
angle - oArc / 2, angle + oArc / 2, false);
ctx.arc(canvas.width / 2, canvas.height / 2, iRadius,
angle + iArc / 2, angle - iArc / 2, true);
ctx.closePath();
ctx.fillStyle = 'rgba(240, 30, 29, ' + opacity + ')';
ctx.fill();
}
}
};
function MobileSetupPortal() {}
MobileSetupPortal.loadPage = function() {
PortalImpl.getInstance().initialize();
};
MobileSetupPortal.onGotDeviceInfo = function(deviceInfo) {
PortalImpl.getInstance().updateDeviceInfo(deviceInfo);
};
MobileSetupPortal.onConnectivityChanged = function(portalReachable) {
PortalImpl.getInstance().updateNetworkState(
portalReachable ? NetworkState.PORTAL_REACHABLE :
NetworkState.PORTAL_UNREACHABLE);
};
// Export
return {
MobileSetupPortal: MobileSetupPortal
};
});
document.addEventListener('DOMContentLoaded',
mobile.MobileSetupPortal.loadPage);