Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / chromeos / mobile_setup.js
1 // Copyright (c) 2012 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.
4
5
6 cr.define('mobile', function() {
7
8   function MobileSetup() {
9   }
10
11   cr.addSingletonGetter(MobileSetup);
12
13   MobileSetup.PLAN_ACTIVATION_UNKNOWN = -2;
14   MobileSetup.PLAN_ACTIVATION_PAGE_LOADING = -1;
15   MobileSetup.PLAN_ACTIVATION_START = 0;
16   MobileSetup.PLAN_ACTIVATION_TRYING_OTASP = 1;
17   MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION = 3;
18   MobileSetup.PLAN_ACTIVATION_RECONNECTING = 4;
19   MobileSetup.PLAN_ACTIVATION_WAITING_FOR_CONNECTION = 5;
20   MobileSetup.PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING = 6;
21   MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT = 7;
22   MobileSetup.PLAN_ACTIVATION_RECONNECTING_PAYMENT = 8;
23   MobileSetup.PLAN_ACTIVATION_DELAY_OTASP = 9;
24   MobileSetup.PLAN_ACTIVATION_START_OTASP = 10;
25   MobileSetup.PLAN_ACTIVATION_OTASP = 11;
26   MobileSetup.PLAN_ACTIVATION_DONE = 12;
27   MobileSetup.PLAN_ACTIVATION_ERROR = 0xFF;
28
29   MobileSetup.EXTENSION_PAGE_URL =
30       'chrome-extension://iadeocfgjdjdmpenejdbfeaocpbikmab';
31   MobileSetup.ACTIVATION_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
32                                     '/activation.html';
33   MobileSetup.PORTAL_OFFLINE_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
34                                         '/portal_offline.html';
35   MobileSetup.REDIRECT_POST_PAGE_URL = MobileSetup.EXTENSION_PAGE_URL +
36                                        '/redirect.html';
37
38   MobileSetup.localStrings_ = new LocalStrings();
39
40   MobileSetup.prototype = {
41     // Mobile device information.
42     deviceInfo_: null,
43     frameName_: '',
44     initialized_: false,
45     fakedTransaction_: false,
46     paymentShown_: false,
47     frameLoadError_: 0,
48     frameLoadIgnored_: true,
49     carrierPageUrl_: null,
50     spinnerInt_: -1,
51     // UI states.
52     state_: MobileSetup.PLAN_ACTIVATION_UNKNOWN,
53     STATE_UNKNOWN_: 'unknown',
54     STATE_CONNECTING_: 'connecting',
55     STATE_ERROR_: 'error',
56     STATE_PAYMENT_: 'payment',
57     STATE_ACTIVATING_: 'activating',
58     STATE_CONNECTED_: 'connected',
59
60     initialize: function(frame_name, carrierPage) {
61       if (this.initialized_) {
62         console.log('calling initialize() again?');
63         return;
64       }
65       this.initialized_ = true;
66       self = this;
67       this.frameName_ = frame_name;
68
69       cr.ui.dialogs.BaseDialog.OK_LABEL =
70         MobileSetup.localStrings_.getString('ok_button');
71       cr.ui.dialogs.BaseDialog.CANCEL_LABEL =
72           MobileSetup.localStrings_.getString('cancel_button');
73       this.confirm_ = new cr.ui.dialogs.ConfirmDialog(document.body);
74
75       window.addEventListener('message', function(e) {
76           self.onMessageReceived_(e);
77       });
78
79       $('closeButton').addEventListener('click', function(e) {
80         $('finalStatus').classList.add('hidden');
81       });
82
83       // Kick off activation process.
84       chrome.send('startActivation');
85     },
86
87     startSpinner_: function() {
88       this.stopSpinner_();
89       this.spinnerInt_ = setInterval(mobile.MobileSetup.drawProgress, 100);
90     },
91
92     stopSpinner_: function() {
93       if (this.spinnerInt_ != -1) {
94         clearInterval(this.spinnerInt_);
95         this.spinnerInt_ = -1;
96       }
97     },
98
99     onFrameLoaded_: function(success) {
100       chrome.send('paymentPortalLoad', [success ? 'ok' : 'failed']);
101     },
102
103     loadPaymentFrame_: function(deviceInfo) {
104       if (deviceInfo) {
105         this.frameLoadError_ = 0;
106         this.deviceInfo_ = deviceInfo;
107         if (deviceInfo.post_data && deviceInfo.post_data.length) {
108           this.frameLoadIgnored_ = true;
109           $(this.frameName_).contentWindow.location.href =
110               MobileSetup.REDIRECT_POST_PAGE_URL +
111               '?post_data=' + escape(deviceInfo.post_data) +
112               '&formUrl=' + escape(deviceInfo.payment_url);
113         } else {
114           this.frameLoadIgnored_ = false;
115           $(this.frameName_).contentWindow.location.href =
116               deviceInfo.payment_url;
117         }
118       }
119     },
120
121     onMessageReceived_: function(e) {
122       if (e.origin !=
123               this.deviceInfo_.payment_url.substring(0, e.origin.length) &&
124           e.origin != MobileSetup.EXTENSION_PAGE_URL)
125         return;
126
127       if (e.data.type == 'requestDeviceInfoMsg') {
128         this.sendDeviceInfo_();
129       } else if (e.data.type == 'framePostReady') {
130         this.frameLoadIgnored_ = false;
131         this.sendPostFrame_(e.origin);
132       } else if (e.data.type == 'reportTransactionStatusMsg') {
133         console.log('calling setTransactionStatus from onMessageReceived_');
134         chrome.send('setTransactionStatus', [e.data.status]);
135       }
136     },
137
138     changeState_: function(deviceInfo) {
139       var newState = deviceInfo.state;
140       if (this.state_ == newState)
141         return;
142
143       // The mobile setup is already in its final state.
144       if (this.state_ == MobileSetup.PLAN_ACTIVATION_DONE ||
145           this.state_ == MobileSetup.PLAN_ACTIVATION_ERROR) {
146         return;
147       }
148
149       // Map handler state to UX.
150       var simpleActivationFlow =
151           (deviceInfo.activation_type == 'NonCellular' ||
152            deviceInfo.activation_type == 'OTA');
153       switch (newState) {
154         case MobileSetup.PLAN_ACTIVATION_PAGE_LOADING:
155         case MobileSetup.PLAN_ACTIVATION_START:
156         case MobileSetup.PLAN_ACTIVATION_DELAY_OTASP:
157         case MobileSetup.PLAN_ACTIVATION_START_OTASP:
158         case MobileSetup.PLAN_ACTIVATION_RECONNECTING:
159         case MobileSetup.PLAN_ACTIVATION_RECONNECTING_PAYMENT:
160           // Activation page should not be shown for the simple activation flow.
161           if (simpleActivationFlow)
162             break;
163
164           $('statusHeader').textContent =
165               MobileSetup.localStrings_.getString('connecting_header');
166           $('auxHeader').textContent =
167               MobileSetup.localStrings_.getString('please_wait');
168           $('paymentForm').classList.add('hidden');
169           $('finalStatus').classList.add('hidden');
170           this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
171           $('systemStatus').classList.remove('hidden');
172           $('canvas').classList.remove('hidden');
173           this.startSpinner_();
174           break;
175         case MobileSetup.PLAN_ACTIVATION_TRYING_OTASP:
176         case MobileSetup.PLAN_ACTIVATION_INITIATING_ACTIVATION:
177         case MobileSetup.PLAN_ACTIVATION_OTASP:
178           // Activation page should not be shown for the simple activation flow.
179           if (simpleActivationFlow)
180             break;
181
182           $('statusHeader').textContent =
183               MobileSetup.localStrings_.getString('activating_header');
184           $('auxHeader').textContent =
185               MobileSetup.localStrings_.getString('please_wait');
186           $('paymentForm').classList.add('hidden');
187           $('finalStatus').classList.add('hidden');
188           this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
189           $('systemStatus').classList.remove('hidden');
190           $('canvas').classList.remove('hidden');
191           this.startSpinner_();
192           break;
193         case MobileSetup.PLAN_ACTIVATION_PAYMENT_PORTAL_LOADING:
194           // Activation page should not be shown for the simple activation flow.
195           if (!simpleActivationFlow) {
196             $('statusHeader').textContent =
197                 MobileSetup.localStrings_.getString('connecting_header');
198             $('auxHeader').textContent = '';
199             $('paymentForm').classList.add('hidden');
200             $('finalStatus').classList.add('hidden');
201             this.setCarrierPage_(MobileSetup.ACTIVATION_PAGE_URL);
202             $('systemStatus').classList.remove('hidden');
203             $('canvas').classList.remove('hidden');
204           }
205           this.loadPaymentFrame_(deviceInfo);
206           break;
207         case MobileSetup.PLAN_ACTIVATION_WAITING_FOR_CONNECTION:
208           var statusHeaderText;
209           var carrierPage;
210           if (deviceInfo.activation_type == 'NonCellular') {
211             statusHeaderText = MobileSetup.localStrings_.getString(
212                 'portal_unreachable_header');
213             carrierPage = MobileSetup.PORTAL_OFFLINE_PAGE_URL;
214           } else if (deviceInfo.activation_type == 'OTA') {
215             statusHeaderText =
216                 MobileSetup.localStrings_.getString('connecting_header');
217             carrierPage = MobileSetup.ACTIVATION_PAGE_URL;
218           }
219           $('statusHeader').textContent = statusHeaderText;
220           $('auxHeader').textContent = '';
221           $('auxHeader').classList.add('hidden');
222           $('paymentForm').classList.add('hidden');
223           $('finalStatus').classList.add('hidden');
224           $('systemStatus').classList.remove('hidden');
225           this.setCarrierPage_(carrierPage);
226           $('canvas').classList.remove('hidden');
227           this.startSpinner_();
228           break;
229         case MobileSetup.PLAN_ACTIVATION_SHOWING_PAYMENT:
230           $('statusHeader').textContent = '';
231           $('auxHeader').textContent = '';
232           $('finalStatus').classList.add('hidden');
233           $('systemStatus').classList.add('hidden');
234           $('paymentForm').classList.remove('hidden');
235           $('canvas').classList.add('hidden');
236           this.stopSpinner_();
237           this.paymentShown_ = true;
238           break;
239         case MobileSetup.PLAN_ACTIVATION_DONE:
240           $('statusHeader').textContent = '';
241           $('auxHeader').textContent = '';
242           $('finalHeader').textContent =
243               MobileSetup.localStrings_.getString('completed_header');
244           $('finalMessage').textContent =
245               MobileSetup.localStrings_.getString('completed_text');
246           $('systemStatus').classList.add('hidden');
247           $('closeButton').classList.remove('hidden');
248           $('finalStatus').classList.remove('hidden');
249           $('canvas').classList.add('hidden');
250           $('closeButton').classList.toggle('hidden', !this.paymentShown_);
251           $('paymentForm').classList.toggle('hidden', !this.paymentShown_);
252           this.stopSpinner_();
253           break;
254         case MobileSetup.PLAN_ACTIVATION_ERROR:
255           $('statusHeader').textContent = '';
256           $('auxHeader').textContent = '';
257           $('finalHeader').textContent =
258               MobileSetup.localStrings_.getString('error_header');
259           $('finalMessage').textContent = deviceInfo.error;
260           $('systemStatus').classList.add('hidden');
261           $('canvas').classList.add('hidden');
262           $('closeButton').classList.toggle('hidden', !this.paymentShown_);
263           $('paymentForm').classList.toggle('hidden', !this.paymentShown_);
264           $('finalStatus').classList.remove('hidden');
265           this.stopSpinner_();
266           break;
267       }
268       this.state_ = newState;
269     },
270
271     setCarrierPage_: function(url) {
272       if (this.carrierPageUrl_ == url)
273         return;
274       this.carrierPageUrl_ = url;
275       $('carrierPage').contentWindow.location.href = url;
276     },
277
278     updateDeviceStatus_: function(deviceInfo) {
279       this.changeState_(deviceInfo);
280     },
281
282     portalFrameLoadError_: function(errorCode) {
283       if (this.frameLoadIgnored_)
284         return;
285       console.log('Portal frame load error detected: ', errorCode);
286       this.frameLoadError_ = errorCode;
287     },
288
289     portalFrameLoadCompleted_: function() {
290       if (this.frameLoadIgnored_)
291         return;
292       console.log('Portal frame load completed!');
293       this.onFrameLoaded_(this.frameLoadError_ == 0);
294     },
295
296     sendPostFrame_: function(frameUrl) {
297       var msg = { type: 'postFrame' };
298       $(this.frameName_).contentWindow.postMessage(msg, frameUrl);
299     },
300
301     sendDeviceInfo_: function() {
302       var msg = {
303         type: 'deviceInfoMsg',
304         domain: document.location,
305         payload: {
306           'carrier': this.deviceInfo_.carrier,
307           'MEID': this.deviceInfo_.MEID,
308           'IMEI': this.deviceInfo_.IMEI,
309           'MDN': this.deviceInfo_.MDN
310         }
311       };
312       $(this.frameName_).contentWindow.postMessage(msg,
313           this.deviceInfo_.payment_url);
314     }
315
316   };
317
318   MobileSetup.drawProgress = function() {
319     var ctx = canvas.getContext('2d');
320     ctx.clearRect(0, 0, canvas.width, canvas.height);
321
322     var segmentCount = Math.min(12, canvas.width / 1.6); // Number of segments
323     var rotation = 0.75; // Counterclockwise rotation
324
325     // Rotate canvas over time
326     ctx.translate(canvas.width / 2, canvas.height / 2);
327     ctx.rotate(Math.PI * 2 / (segmentCount + rotation));
328     ctx.translate(-canvas.width / 2, -canvas.height / 2);
329
330     var gap = canvas.width / 24; // Gap between segments
331     var oRadius = canvas.width / 2; // Outer radius
332     var iRadius = oRadius * 0.618; // Inner radius
333     var oCircumference = Math.PI * 2 * oRadius; // Outer circumference
334     var iCircumference = Math.PI * 2 * iRadius; // Inner circumference
335     var oGap = gap / oCircumference; // Gap size as fraction of  outer ring
336     var iGap = gap / iCircumference; // Gap size as fraction of  inner ring
337     var oArc = Math.PI * 2 * (1 / segmentCount - oGap); // Angle of outer arcs
338     var iArc = Math.PI * 2 * (1 / segmentCount - iGap); // Angle of inner arcs
339
340     for (i = 0; i < segmentCount; i++) { // Draw each segment
341       var opacity = Math.pow(1.0 - i / segmentCount, 3.0);
342       opacity = (0.15 + opacity * 0.8); // Vary from 0.15 to 0.95
343       var angle = - Math.PI * 2 * i / segmentCount;
344
345       ctx.beginPath();
346       ctx.arc(canvas.width / 2, canvas.height / 2, oRadius,
347         angle - oArc / 2, angle + oArc / 2, false);
348       ctx.arc(canvas.width / 2, canvas.height / 2, iRadius,
349         angle + iArc / 2, angle - iArc / 2, true);
350       ctx.closePath();
351       ctx.fillStyle = 'rgba(240, 30, 29, ' + opacity + ')';
352       ctx.fill();
353     }
354   };
355
356   MobileSetup.deviceStateChanged = function(deviceInfo) {
357     MobileSetup.getInstance().updateDeviceStatus_(deviceInfo);
358   };
359
360   MobileSetup.portalFrameLoadError = function(errorCode) {
361     MobileSetup.getInstance().portalFrameLoadError_(errorCode);
362   };
363
364   MobileSetup.portalFrameLoadCompleted = function() {
365     MobileSetup.getInstance().portalFrameLoadCompleted_();
366   };
367
368   MobileSetup.loadPage = function() {
369     mobile.MobileSetup.getInstance().initialize('paymentForm',
370         mobile.MobileSetup.ACTIVATION_PAGE_URL);
371   };
372
373   // Export
374   return {
375     MobileSetup: MobileSetup
376   };
377 });
378
379 document.addEventListener('DOMContentLoaded', mobile.MobileSetup.loadPage);