1 // Copyright 2013 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 cr
.define('mobile', function() {
7 // TODO(tbarzic): Share code with mobile_setup.js.
8 var EXTENSION_BASE_URL
=
9 'chrome-extension://iadeocfgjdjdmpenejdbfeaocpbikmab/';
10 var REDIRECT_POST_PAGE_URL
= EXTENSION_BASE_URL
+ 'redirect.html?autoPost=1';
11 var PORTAL_OFFLINE_PAGE_URL
= EXTENSION_BASE_URL
+ 'portal_offline.html';
12 var INVALID_DEVICE_INFO_PAGE_URL
=
13 EXTENSION_BASE_URL
+ 'invalid_device_info.html';
21 var CarrierPageType
= {
24 INVALID_DEVICE_INFO
: 2
27 var localStrings
= new LocalStrings();
29 function PortalImpl() {
30 // Mobile device information.
31 this.deviceInfo_
= null;
32 this.spinnerInt_
= -1;
33 this.networkState_
= NetworkState
.UNKNOWN
;
34 this.portalFrameSet_
= false;
35 this.carrierPageType_
= CarrierPageType
.NOT_SET
;
38 cr
.addSingletonGetter(PortalImpl
);
40 PortalImpl
.prototype = {
41 initialize: function() {
42 // Get network device info for which portal should be opened.
43 // For LTE networks, this will also start observing network connection
44 // state and raise |updatePortalReachability| messages when the portal
45 // reachability changes.
46 chrome
.send('getDeviceInfo');
49 updateDeviceInfo: function(deviceInfo
) {
50 this.deviceInfo_
= deviceInfo
;
54 updateNetworkState: function(networkState
) {
55 if (this.networkState_
== networkState
)
57 this.networkState_
= networkState
;
59 // If the device info is not yet set, the state will be updated on the
60 // device info update.
65 updateState_: function() {
66 if (!this.deviceInfo_
|| this.networkState_
== NetworkState
.UNKNOWN
)
69 if (!this.isDeviceInfoValid_()) {
70 // If the device info is not valid, hide portalFrame and show system
71 // status displaying 'invalid device info' page.
72 this.setCarrierPage_(CarrierPageType
.INVALID_DEVICE_INFO
);
73 $('portalFrame').hidden
= true;
74 $('systemStatus').hidden
= false;
75 } else if (this.networkState_
!= NetworkState
.PORTAL_REACHABLE
) {
76 // If the portal is not reachable, hide portalFrame and show system
77 // status displaying 'offline portal' page.
78 this.setCarrierPage_(CarrierPageType
.PORTAL_OFFLINE
);
79 $('portalFrame').hidden
= true;
80 $('systemStatus').hidden
= false;
82 // If the portal is reachable and device info is valid, set and show
83 // portalFrame; and hide system status displaying 'offline portal' page.
84 this.setPortalFrameIfNeeded_(this.deviceInfo_
);
85 $('portalFrame').hidden
= false;
86 $('systemStatus').hidden
= true;
91 setCarrierPage_: function(type
) {
92 // The page is already set, nothing to do.
93 if (type
== this.carrierPageType_
)
97 case CarrierPageType
.PORTAL_OFFLINE
:
98 $('carrierPage').contentWindow
.location
.href
=
99 PORTAL_OFFLINE_PAGE_URL
;
100 $('statusHeader').textContent
=
101 localStrings
.getString('portal_unreachable_header');
102 this.startSpinner_();
104 case CarrierPageType
.INVALID_DEVICE_INFO
:
105 $('carrierPage').contentWindow
.location
.href
=
106 INVALID_DEVICE_INFO_PAGE_URL
;
107 $('statusHeader').textContent
=
108 localStrings
.getString('invalid_device_info_header');
111 case CarrierPageType
.NOT_SET
:
112 $('carrierPage').contentWindow
.location
.href
= 'about:blank';
113 $('statusHeader').textContent
= '';
120 this.carrierPageType_
= type
;
123 setPortalFrameIfNeeded_: function(deviceInfo
) {
124 // The portal should be set only once.
125 if (this.portalFrameSet_
)
129 if (deviceInfo
.post_data
&& deviceInfo
.post_data
.length
)
130 postData
= '&post_data=' + encodeURIComponent(deviceInfo
.post_data
);
132 $('portalFrame').contentWindow
.location
.href
= REDIRECT_POST_PAGE_URL
+
133 postData
+ '&formUrl=' + encodeURIComponent(deviceInfo
.payment_url
);
135 this.portalFrameSet_
= true;
138 isDeviceInfoValid_: function() {
139 // Device info is valid if it has mdn which doesn't contain only '0's.
140 return this.deviceInfo_
&& this.deviceInfo_
.MDN
&&
141 this.deviceInfo_
.MDN
.match('[^0]');
144 startSpinner_: function() {
146 this.spinnerInt_
= setInterval(this.drawProgress_
.bind(this), 100);
149 stopSpinner_: function() {
150 if (this.spinnerInt_
!= -1) {
151 clearInterval(this.spinnerInt_
);
152 this.spinnerInt_
= -1;
154 // Clear the spinner canvas.
155 var ctx
= canvas
.getContext('2d');
156 ctx
.clearRect(0, 0, canvas
.width
, canvas
.height
);
159 drawProgress_: function() {
160 var ctx
= canvas
.getContext('2d');
161 ctx
.clearRect(0, 0, canvas
.width
, canvas
.height
);
163 var segmentCount
= Math
.min(12, canvas
.width
/ 1.6); // Number of segments
164 var rotation
= 0.75; // Counterclockwise rotation
166 // Rotate canvas over time
167 ctx
.translate(canvas
.width
/ 2, canvas
.height
/ 2);
168 ctx
.rotate(Math
.PI
* 2 / (segmentCount
+ rotation
));
169 ctx
.translate(-canvas
.width
/ 2, -canvas
.height
/ 2);
171 var gap
= canvas
.width
/ 24; // Gap between segments
172 var oRadius
= canvas
.width
/ 2; // Outer radius
173 var iRadius
= oRadius
* 0.618; // Inner radius
174 var oCircumference
= Math
.PI
* 2 * oRadius
; // Outer circumference
175 var iCircumference
= Math
.PI
* 2 * iRadius
; // Inner circumference
176 var oGap
= gap
/ oCircumference
; // Gap size as fraction of outer ring
177 var iGap
= gap
/ iCircumference
; // Gap size as fraction of inner ring
178 var oArc
= Math
.PI
* 2 * (1 / segmentCount
- oGap
); // Angle of outer arcs
179 var iArc
= Math
.PI
* 2 * (1 / segmentCount
- iGap
); // Angle of inner arcs
181 for (i
= 0; i
< segmentCount
; i
++) { // Draw each segment
182 var opacity
= Math
.pow(1.0 - i
/ segmentCount
, 3.0);
183 opacity
= (0.15 + opacity
* 0.8); // Vary from 0.15 to 0.95
184 var angle
= - Math
.PI
* 2 * i
/ segmentCount
;
187 ctx
.arc(canvas
.width
/ 2, canvas
.height
/ 2, oRadius
,
188 angle
- oArc
/ 2, angle
+ oArc
/ 2, false);
189 ctx
.arc(canvas
.width
/ 2, canvas
.height
/ 2, iRadius
,
190 angle
+ iArc
/ 2, angle
- iArc
/ 2, true);
192 ctx
.fillStyle
= 'rgba(240, 30, 29, ' + opacity
+ ')';
198 function MobileSetupPortal() {}
200 MobileSetupPortal
.loadPage = function() {
201 PortalImpl
.getInstance().initialize();
204 MobileSetupPortal
.onGotDeviceInfo = function(deviceInfo
) {
205 PortalImpl
.getInstance().updateDeviceInfo(deviceInfo
);
208 MobileSetupPortal
.onConnectivityChanged = function(portalReachable
) {
209 PortalImpl
.getInstance().updateNetworkState(
210 portalReachable
? NetworkState
.PORTAL_REACHABLE
:
211 NetworkState
.PORTAL_UNREACHABLE
);
216 MobileSetupPortal
: MobileSetupPortal
220 document
.addEventListener('DOMContentLoaded',
221 mobile
.MobileSetupPortal
.loadPage
);