Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / mobile_setup_portal.js
blob53808d1a19720e66e3da7b657b3127ca64b07402
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';
15   var NetworkState = {
16     UNKNOWN: 0,
17     PORTAL_REACHABLE: 1,
18     PORTAL_UNREACHABLE: 2
19   };
21   var CarrierPageType = {
22     NOT_SET: 0,
23     PORTAL_OFFLINE: 1,
24     INVALID_DEVICE_INFO: 2
25   };
27   function PortalImpl() {
28     // Mobile device information.
29     this.deviceInfo_ = null;
30     this.spinnerInt_ = -1;
31     this.networkState_ = NetworkState.UNKNOWN;
32     this.portalFrameSet_ = false;
33     this.carrierPageType_ = CarrierPageType.NOT_SET;
34   }
36   cr.addSingletonGetter(PortalImpl);
38   PortalImpl.prototype = {
39     initialize: function() {
40       // Get network device info for which portal should be opened.
41       // For LTE networks, this will also start observing network connection
42       // state and raise |updatePortalReachability| messages when the portal
43       // reachability changes.
44       chrome.send('getDeviceInfo');
45     },
47     updateDeviceInfo: function(deviceInfo) {
48       this.deviceInfo_ = deviceInfo;
49       this.updateState_();
50     },
52     updateNetworkState: function(networkState) {
53       if (this.networkState_ == networkState)
54         return;
55       this.networkState_ = networkState;
57       // If the device info is not yet set, the state will be updated on the
58       // device info update.
59       if (this.deviceInfo_)
60         this.updateState_();
61     },
63     updateState_: function() {
64       if (!this.deviceInfo_ || this.networkState_ == NetworkState.UNKNOWN)
65         return;
67       if (!this.isDeviceInfoValid_()) {
68         // If the device info is not valid, hide portalFrame and show system
69         // status displaying 'invalid device info' page.
70         this.setCarrierPage_(CarrierPageType.INVALID_DEVICE_INFO);
71         $('portalFrame').hidden = true;
72         $('systemStatus').hidden = false;
73       } else if (this.networkState_ != NetworkState.PORTAL_REACHABLE) {
74         // If the portal is not reachable, hide portalFrame and show system
75         // status displaying 'offline portal' page.
76         this.setCarrierPage_(CarrierPageType.PORTAL_OFFLINE);
77         $('portalFrame').hidden = true;
78         $('systemStatus').hidden = false;
79      } else {
80         // If the portal is reachable and device info is valid, set and show
81         // portalFrame; and hide system status displaying 'offline portal' page.
82         this.setPortalFrameIfNeeded_(this.deviceInfo_);
83         $('portalFrame').hidden = false;
84         $('systemStatus').hidden = true;
85         this.stopSpinner_();
86       }
87     },
89     setCarrierPage_: function(type) {
90       // The page is already set, nothing to do.
91       if (type == this.carrierPageType_)
92         return;
94       switch (type) {
95         case CarrierPageType.PORTAL_OFFLINE:
96           $('carrierPage').contentWindow.location.href =
97               PORTAL_OFFLINE_PAGE_URL;
98           $('statusHeader').textContent =
99               loadTimeData.getString('portal_unreachable_header');
100           this.startSpinner_();
101           break;
102         case CarrierPageType.INVALID_DEVICE_INFO:
103           $('carrierPage').contentWindow.location.href =
104               INVALID_DEVICE_INFO_PAGE_URL;
105           $('statusHeader').textContent =
106               loadTimeData.getString('invalid_device_info_header');
107           this.stopSpinner_();
108           break;
109         case CarrierPageType.NOT_SET:
110           $('carrierPage').contentWindow.location.href = 'about:blank';
111           $('statusHeader').textContent = '';
112           this.stopSpinner_();
113           break;
114         default:
115           break;
116       }
118       this.carrierPageType_ = type;
119     },
121     setPortalFrameIfNeeded_: function(deviceInfo) {
122       // The portal should be set only once.
123       if (this.portalFrameSet_)
124         return;
126       var postData = '';
127       if (deviceInfo.post_data && deviceInfo.post_data.length)
128         postData = '&post_data=' + encodeURIComponent(deviceInfo.post_data);
130       $('portalFrame').contentWindow.location.href = REDIRECT_POST_PAGE_URL +
131           postData + '&formUrl=' + encodeURIComponent(deviceInfo.payment_url);
133       this.portalFrameSet_ = true;
134     },
136     isDeviceInfoValid_: function() {
137       // Device info is valid if it has mdn which doesn't contain only '0's.
138       return this.deviceInfo_ && this.deviceInfo_.MDN &&
139           this.deviceInfo_.MDN.match('[^0]');
140     },
142     startSpinner_: function() {
143       this.stopSpinner_();
144       this.spinnerInt_ = setInterval(this.drawProgress_.bind(this), 100);
145     },
147     stopSpinner_: function() {
148       if (this.spinnerInt_ != -1) {
149         clearInterval(this.spinnerInt_);
150         this.spinnerInt_ = -1;
151       }
152       // Clear the spinner canvas.
153       var ctx = canvas.getContext('2d');
154       ctx.clearRect(0, 0, canvas.width, canvas.height);
155     },
157     drawProgress_: function() {
158       var ctx = canvas.getContext('2d');
159       ctx.clearRect(0, 0, canvas.width, canvas.height);
161       var segmentCount = Math.min(12, canvas.width / 1.6); // Number of segments
162       var rotation = 0.75; // Counterclockwise rotation
164       // Rotate canvas over time
165       ctx.translate(canvas.width / 2, canvas.height / 2);
166       ctx.rotate(Math.PI * 2 / (segmentCount + rotation));
167       ctx.translate(-canvas.width / 2, -canvas.height / 2);
169       var gap = canvas.width / 24; // Gap between segments
170       var oRadius = canvas.width / 2; // Outer radius
171       var iRadius = oRadius * 0.618; // Inner radius
172       var oCircumference = Math.PI * 2 * oRadius; // Outer circumference
173       var iCircumference = Math.PI * 2 * iRadius; // Inner circumference
174       var oGap = gap / oCircumference; // Gap size as fraction of  outer ring
175       var iGap = gap / iCircumference; // Gap size as fraction of  inner ring
176       var oArc = Math.PI * 2 * (1 / segmentCount - oGap); // Angle of outer arcs
177       var iArc = Math.PI * 2 * (1 / segmentCount - iGap); // Angle of inner arcs
179       for (i = 0; i < segmentCount; i++) { // Draw each segment
180         var opacity = Math.pow(1.0 - i / segmentCount, 3.0);
181         opacity = (0.15 + opacity * 0.8); // Vary from 0.15 to 0.95
182         var angle = - Math.PI * 2 * i / segmentCount;
184         ctx.beginPath();
185         ctx.arc(canvas.width / 2, canvas.height / 2, oRadius,
186             angle - oArc / 2, angle + oArc / 2, false);
187         ctx.arc(canvas.width / 2, canvas.height / 2, iRadius,
188             angle + iArc / 2, angle - iArc / 2, true);
189         ctx.closePath();
190         ctx.fillStyle = 'rgba(240, 30, 29, ' + opacity + ')';
191         ctx.fill();
192       }
193     }
194   };
196   function MobileSetupPortal() {}
198   MobileSetupPortal.loadPage = function() {
199     PortalImpl.getInstance().initialize();
200   };
202   MobileSetupPortal.onGotDeviceInfo = function(deviceInfo) {
203     PortalImpl.getInstance().updateDeviceInfo(deviceInfo);
204   };
206   MobileSetupPortal.onConnectivityChanged = function(portalReachable) {
207     PortalImpl.getInstance().updateNetworkState(
208         portalReachable ? NetworkState.PORTAL_REACHABLE :
209                           NetworkState.PORTAL_UNREACHABLE);
210   };
212   // Export
213   return {
214     MobileSetupPortal: MobileSetupPortal
215   };
218 document.addEventListener('DOMContentLoaded',
219                           mobile.MobileSetupPortal.loadPage);