blob: afd59fa93aba5519d436f48764f1e1aaf7931190 [file] [log] [blame]
// 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.
cr.define('mobile', function() {
function MobileSetup() {
}
cr.addSingletonGetter(MobileSetup);
MobileSetup.PLAN_ACTIVATION_UNKNOWN = -2;
MobileSetup.PLAN_ACTIVATION_PAGE_LOADING = -1;
MobileSetup.PLAN_ACTIVATION_START = 0;
MobileSetup.PLAN_ACTIVATION_TRYING_OTASP = 1;
MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION = 3;
MobileSetup.PLAN_ACTIVATION_RECONNECTING = 4;
MobileSetup.PLAN_ACTIVATION_WAITING_FOR_CONNECTION = 5;
MobileSetup.PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING = 6;
MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT = 7;
MobileSetup.PLAN_ACTIVATION_RECONNECTING_PAYMENT = 8;
MobileSetup.PLAN_ACTIVATION_DELAY_OTASP = 9;
MobileSetup.PLAN_ACTIVATION_START_OTASP = 10;
MobileSetup.PLAN_ACTIVATION_OTASP = 11;
MobileSetup.PLAN_ACTIVATION_DONE = 12;
MobileSetup.PLAN_ACTIVATION_ERROR = 0xFF;
MobileSetup.EXTENSION_PAGE_URL =
'chrome-extension://iadeocfgjdjdmpenejdbfeaocpbikmab';
MobileSetup.ACTIVATION_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
'/activation.html';
MobileSetup.PORTAL_OFFLINE_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
'/portal_offline.html';
MobileSetup.REDIRECT_POST_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
'/redirect.html';
MobileSetup.localStrings_ = new LocalStrings();
MobileSetup.prototype = {
// Mobile device information.
deviceInfo_: null,
frameName_: '',
initialized_: false,
fakedTransaction_: false,
paymentShown_: false,
frameLoadError_: 0,
frameLoadIgnored_: true,
carrierPageUrl_: null,
spinnerInt_: -1,
// UI states.
state_: MobileSetup.PLAN_ACTIVATION_UNKNOWN,
STATE_UNKNOWN_: 'unknown',
STATE_CONNECTING_: 'connecting',
STATE_ERROR_: 'error',
STATE_PAYMENT_: 'payment',
STATE_ACTIVATING_: 'activating',
STATE_CONNECTED_: 'connected',
initialize: function(frame_name, carrierPage) {
if (this.initialized_) {
console.log('calling initialize() again?');
return;
}
this.initialized_ = true;
self = this;
this.frameName_ = frame_name;
cr.ui.dialogs.BaseDialog.OK_LABEL =
MobileSetup.localStrings_.getString('ok_button');
cr.ui.dialogs.BaseDialog.CANCEL_LABEL =
MobileSetup.localStrings_.getString('cancel_button');
this.confirm_ = new cr.ui.dialogs.ConfirmDialog(document.body);
window.addEventListener('message', function(e) {
self.onMessageReceived_(e);
});
$('closeButton').addEventListener('click', function(e) {
$('finalStatus').classList.add('hidden');
});
// Kick off activation process.
chrome.send('startActivation');
},
startSpinner_: function() {
this.stopSpinner_();
this.spinnerInt_ = setInterval(mobile.MobileSetup.drawProgress, 100);
},
stopSpinner_: function() {
if (this.spinnerInt_ != -1) {
clearInterval(this.spinnerInt_);
this.spinnerInt_ = -1;
}
},
onFrameLoaded_: function(success) {
chrome.send('paymentPortalLoad', [success ? 'ok' : 'failed']);
},
loadPaymentFrame_: function(deviceInfo) {
if (deviceInfo) {
this.frameLoadError_ = 0;
this.deviceInfo_ = deviceInfo;
if (deviceInfo.post_data && deviceInfo.post_data.length) {
this.frameLoadIgnored_ = true;
$(this.frameName_).contentWindow.location.href =
MobileSetup.REDIRECT_POST_PAGE_URL +
'?post_data=' + escape(deviceInfo.post_data) +
'&formUrl=' + escape(deviceInfo.payment_url);
} else {
this.frameLoadIgnored_ = false;
$(this.frameName_).contentWindow.location.href =
deviceInfo.payment_url;
}
}
},
onMessageReceived_: function(e) {
if (e.origin !=
this.deviceInfo_.payment_url.substring(0, e.origin.length) &&
e.origin != MobileSetup.EXTENSION_PAGE_URL)
return;
if (e.data.type == 'requestDeviceInfoMsg') {
this.sendDeviceInfo_();
} else if (e.data.type == 'framePostReady') {
this.frameLoadIgnored_ = false;
this.sendPostFrame_(e.origin);
} else if (e.data.type == 'reportTransactionStatusMsg') {
console.log('calling setTransactionStatus from onMessageReceived_');
chrome.send('setTransactionStatus', [e.data.status]);
}
},
changeState_: function(deviceInfo) {
var newState = deviceInfo.state;
if (this.state_ == newState)
return;
// The mobile setup is already in its final state.
if (this.state_ == MobileSetup.PLAN_ACTIVATION_DONE ||
this.state_ == MobileSetup.PLAN_ACTIVATION_ERROR) {
return;
}
// Map handler state to UX.
switch (newState) {
case MobileSetup.PLAN_ACTIVATION_PAGE_LOADING:
case MobileSetup.PLAN_ACTIVATION_START:
case MobileSetup.PLAN_ACTIVATION_DELAY_OTASP:
case MobileSetup.PLAN_ACTIVATION_START_OTASP:
case MobileSetup.PLAN_ACTIVATION_RECONNECTING:
case MobileSetup.PLAN_ACTIVATION_RECONNECTING_PAYMENT:
// Activation page should not be shown for devices that are activated
// over non cellular network.
if (deviceInfo.activate_over_non_cellular_network)
break;
$('statusHeader').textContent =
MobileSetup.localStrings_.getString('connecting_header');
$('auxHeader').textContent =
MobileSetup.localStrings_.getString('please_wait');
$('paymentForm').classList.add('hidden');
$('finalStatus').classList.add('hidden');
this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
$('systemStatus').classList.remove('hidden');
$('canvas').classList.remove('hidden');
this.startSpinner_();
break;
case MobileSetup.PLAN_ACTIVATION_TRYING_OTASP:
case MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION:
case MobileSetup.PLAN_ACTIVATION_OTASP:
// Activation page should not be shown for devices that are activated
// over non cellular network.
if (deviceInfo.activate_over_non_cellular_network)
break;
$('statusHeader').textContent =
MobileSetup.localStrings_.getString('activating_header');
$('auxHeader').textContent =
MobileSetup.localStrings_.getString('please_wait');
$('paymentForm').classList.add('hidden');
$('finalStatus').classList.add('hidden');
this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
$('systemStatus').classList.remove('hidden');
$('canvas').classList.remove('hidden');
this.startSpinner_();
break;
case MobileSetup.PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
// Activation page should not be shown for devices that are activated
// over non cellular network.
if (!deviceInfo.activate_over_non_cellular_network) {
$('statusHeader').textContent =
MobileSetup.localStrings_.getString('connecting_header');
$('auxHeader').textContent = '';
$('paymentForm').classList.add('hidden');
$('finalStatus').classList.add('hidden');
this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
$('systemStatus').classList.remove('hidden');
$('canvas').classList.remove('hidden');
}
this.loadPaymentFrame_(deviceInfo);
break;
case MobileSetup.PLAN_ACTIVATION_WAITING_FOR_CONNECTION:
$('statusHeader').textContent =
MobileSetup.localStrings_.getString('portal_unreachable_header');
$('auxHeader').textContent = '';
$('auxHeader').classList.add('hidden');
$('paymentForm').classList.add('hidden');
$('finalStatus').classList.add('hidden');
$('systemStatus').classList.remove('hidden');
this.setCarrierPage_(MobileSetup.PORTAL_OFFLINE_PAGE_URL);
$('canvas').classList.remove('hidden');
this.startSpinner_();
break;
case MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT:
$('statusHeader').textContent = '';
$('auxHeader').textContent = '';
$('finalStatus').classList.add('hidden');
$('systemStatus').classList.add('hidden');
$('paymentForm').classList.remove('hidden');
$('canvas').classList.add('hidden');
this.stopSpinner_();
this.paymentShown_ = true;
break;
case MobileSetup.PLAN_ACTIVATION_DONE:
$('statusHeader').textContent = '';
$('auxHeader').textContent = '';
$('finalHeader').textContent =
MobileSetup.localStrings_.getString('completed_header');
$('finalMessage').textContent =
MobileSetup.localStrings_.getString('completed_text');
$('systemStatus').classList.add('hidden');
$('closeButton').classList.remove('hidden');
$('finalStatus').classList.remove('hidden');
$('canvas').classList.add('hidden');
$('closeButton').classList.toggle('hidden', !this.paymentShown_);
$('paymentForm').classList.toggle('hidden', !this.paymentShown_);
this.stopSpinner_();
break;
case MobileSetup.PLAN_ACTIVATION_ERROR:
$('statusHeader').textContent = '';
$('auxHeader').textContent = '';
$('finalHeader').textContent =
MobileSetup.localStrings_.getString('error_header');
$('finalMessage').textContent = deviceInfo.error;
$('systemStatus').classList.add('hidden');
$('canvas').classList.add('hidden');
$('closeButton').classList.toggle('hidden', !this.paymentShown_);
$('paymentForm').classList.toggle('hidden', !this.paymentShown_);
$('finalStatus').classList.remove('hidden');
this.stopSpinner_();
break;
}
this.state_ = newState;
},
setCarrierPage_: function(url) {
if (this.carrierPageUrl_ == url)
return;
this.carrierPageUrl_ = url;
$('carrierPage').contentWindow.location.href = url;
},
updateDeviceStatus_: function(deviceInfo) {
this.changeState_(deviceInfo);
},
portalFrameLoadError_: function(errorCode) {
if (this.frameLoadIgnored_)
return;
console.log('Portal frame load error detected: ', errorCode);
this.frameLoadError_ = errorCode;
},
portalFrameLoadCompleted_: function() {
if (this.frameLoadIgnored_)
return;
console.log('Portal frame load completed!');
this.onFrameLoaded_(this.frameLoadError_ == 0);
},
sendPostFrame_: function(frameUrl) {
var msg = { type: 'postFrame' };
$(this.frameName_).contentWindow.postMessage(msg, frameUrl);
},
sendDeviceInfo_: function() {
var msg = {
type: 'deviceInfoMsg',
domain: document.location,
payload: {
'carrier': this.deviceInfo_.carrier,
'MEID': this.deviceInfo_.MEID,
'IMEI': this.deviceInfo_.IMEI,
'MDN': this.deviceInfo_.MDN
}
};
$(this.frameName_).contentWindow.postMessage(msg,
this.deviceInfo_.payment_url);
}
};
MobileSetup.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();
}
};
MobileSetup.deviceStateChanged = function(deviceInfo) {
MobileSetup.getInstance().updateDeviceStatus_(deviceInfo);
};
MobileSetup.portalFrameLoadError = function(errorCode) {
MobileSetup.getInstance().portalFrameLoadError_(errorCode);
};
MobileSetup.portalFrameLoadCompleted = function() {
MobileSetup.getInstance().portalFrameLoadCompleted_();
};
MobileSetup.loadPage = function() {
mobile.MobileSetup.getInstance().initialize('paymentForm',
mobile.MobileSetup.ACTIVATION_PAGE_URL);
};
// Export
return {
MobileSetup: MobileSetup
};
});
document.addEventListener('DOMContentLoaded', mobile.MobileSetup.loadPage);