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.
5 cr.define('mobile', function() {
10 cr.addSingletonGetter(SimUnlock);
12 // State of the dialog.
13 SimUnlock.SIM_UNLOCK_LOADING = -1;
14 SimUnlock.SIM_ABSENT_NOT_LOCKED = 0,
15 SimUnlock.SIM_NOT_LOCKED_ASK_PIN = 1;
16 SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN = 2;
17 SimUnlock.SIM_LOCKED_PIN = 3;
18 SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT = 4;
19 SimUnlock.SIM_LOCKED_PUK = 5;
20 SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT = 6;
21 SimUnlock.SIM_DISABLED = 7;
23 // Mode of the dialog.
24 SimUnlock.SIM_DIALOG_UNLOCK = 0;
25 SimUnlock.SIM_DIALOG_CHANGE_PIN = 1;
26 SimUnlock.SIM_DIALOG_SET_LOCK_ON = 2;
27 SimUnlock.SIM_DIALOG_SET_LOCK_OFF = 3;
30 SimUnlock.ERROR_PIN = 'incorrectPin';
31 SimUnlock.ERROR_PUK = 'incorrectPuk';
32 SimUnlock.ERROR_OK = 'ok';
35 SimUnlock.PIN_MIN_LENGTH = 4;
36 SimUnlock.PUK_LENGTH = 8;
38 SimUnlock.prototype = {
40 mode_: SimUnlock.SIM_DIALOG_UNLOCK,
43 'width': window.innerWidth,
44 'height': window.innerHeight
46 state_: SimUnlock.SIM_UNLOCK_LOADING,
48 changeState_: function(simInfo) {
49 var newState = simInfo.state;
50 var error = simInfo.error;
51 var tries = simInfo.tries;
55 case SimUnlock.SIM_UNLOCK_LOADING:
57 case SimUnlock.SIM_ABSENT_NOT_LOCKED:
60 case SimUnlock.SIM_LOCKED_PIN:
61 if (error == SimUnlock.ERROR_OK) {
62 pinMessage = loadTimeData.getStringF('enterPinTriesMessage', tries);
63 $('pin-error-msg').classList.remove('error');
64 } else if (error == SimUnlock.ERROR_PIN) {
65 pinMessage = loadTimeData.getStringF(
66 'incorrectPinTriesMessage', tries);
67 $('pin-error-msg').classList.add('error');
69 $('pin-error-msg').textContent = pinMessage;
70 $('pin-input').value = '';
71 SimUnlock.enablePinDialog(true);
72 $('locked-pin-overlay').hidden = false;
73 $('pin-input').focus();
75 case SimUnlock.SIM_NOT_LOCKED_ASK_PIN:
76 if (error == SimUnlock.ERROR_OK) {
77 pinMessage = loadTimeData.getString('enterPinMessage');
78 $('pin-error-msg').classList.remove('error');
79 } else if (error == SimUnlock.ERROR_PIN) {
80 pinMessage = loadTimeData.getStringF(
81 'incorrectPinTriesMessage', tries);
82 $('pin-error-msg').classList.add('error');
84 $('pin-error-msg').textContent = pinMessage;
85 $('pin-input').value = '';
86 SimUnlock.enablePinDialog(true);
87 $('locked-pin-overlay').hidden = false;
88 $('pin-input').focus();
90 case SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN:
91 SimUnlock.prepareChoosePinDialog(true);
92 if (error == SimUnlock.ERROR_OK) {
93 pinMessage = loadTimeData.getString('changePinMessage');
94 $('choose-pin-msg').classList.remove('error');
95 } else if (error == SimUnlock.ERROR_PIN) {
96 pinMessage = loadTimeData.getStringF(
97 'incorrectPinTriesMessage', tries);
98 $('choose-pin-msg').classList.add('error');
100 $('choose-pin-msg').textContent = pinMessage;
101 $('old-pin-input').value = '';
102 $('new-pin-input').value = '';
103 $('retype-new-pin-input').value = '';
104 $('choose-pin-overlay').hidden = false;
105 SimUnlock.enableChoosePinDialog(true);
106 $('old-pin-input').focus();
108 case SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT:
109 $('locked-pin-no-tries-overlay').hidden = false;
111 case SimUnlock.SIM_LOCKED_PUK:
112 $('puk-input').value = '';
113 if (tries && tries >= 0) {
114 var pukMessage = loadTimeData.getStringF('enterPukWarning', tries);
115 $('puk-warning-msg').textContent = pukMessage;
117 $('enter-puk-confirm').disabled = true;
118 $('locked-puk-overlay').hidden = false;
119 $('puk-input').focus();
121 // Resize the dialog to accomodate the PUK contents.
122 this.updateDialogSize_(0, 45);
124 case SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT:
125 $('locked-puk-no-tries-overlay').hidden = false;
127 case SimUnlock.SIM_DISABLED:
128 $('sim-disabled-overlay').hidden = false;
131 this.state_ = newState;
135 * Returns current state of the dialog.
136 * @type {number} value of the state.
142 updateDialogSize_: function(deltaX, deltaY) {
143 window.resizeTo(this.defaultDialogSize_.width + deltaX,
144 this.defaultDialogSize_.height + deltaY);
147 hideAll_: function() {
148 $('locked-pin-overlay').hidden = true;
149 $('locked-pin-no-tries-overlay').hidden = true;
150 $('locked-puk-overlay').hidden = true;
151 $('choose-pin-overlay').hidden = true;
152 $('locked-puk-no-tries-overlay').hidden = true;
153 $('sim-disabled-overlay').hidden = true;
156 newPinEntered_: function(newPin, newPin2) {
157 var changePinMode = this.state_ == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
158 if (newPin.length < SimUnlock.PIN_MIN_LENGTH ||
159 newPin2.length < SimUnlock.PIN_MIN_LENGTH ||
161 $('old-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH)) {
164 if (newPin != newPin2) {
165 $('choose-pin-error').hidden = false;
166 $('old-pin-input').value = '';
167 $('new-pin-input').value = '';
168 $('retype-new-pin-input').value = '';
170 $('old-pin-input').focus();
172 $('new-pin-input').focus();
174 $('choose-pin-error').hidden = true;
175 SimUnlock.enableChoosePinDialog(false);
177 var oldPin = $('old-pin-input').value;
178 chrome.send('changePinCode', [oldPin, newPin]);
180 chrome.send('enterPukCode', [this.pukValue_, newPin]);
186 pukEntered_: function(pukValue) {
187 if (pukValue.length < SimUnlock.PUK_LENGTH)
189 this.pukValue_ = pukValue;
191 SimUnlock.prepareChoosePinDialog(false);
192 SimUnlock.enableChoosePinDialog(true);
193 $('new-pin-input').value = '';
194 $('retype-new-pin-input').value = '';
195 $('choose-pin-overlay').hidden = false;
196 $('new-pin-input').focus();
197 this.updateDialogSize_(0, 18);
200 updateSimStatus_: function(simInfo) {
201 this.changeState_(simInfo);
205 SimUnlock.cancel = function() {
209 SimUnlock.close = function() {
213 SimUnlock.initialize = function() {
214 this.initialized_ = true;
216 var modePattern = /(^\?|&)mode=([^&#]*)/;
217 var results = modePattern.exec(window.location.search);
218 if (results == null) {
219 this.mode_ = SimUnlock.SIM_DIALOG_UNLOCK;
221 var mode = results[2];
222 if (mode == 'change-pin')
223 this.mode_ = SimUnlock.SIM_DIALOG_CHANGE_PIN;
224 else if (mode == 'set-lock-on')
225 this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_ON;
226 else if (mode == 'set-lock-off')
227 this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_OFF;
231 $('pin-input').addEventListener('keydown', function(event) {
232 if (event.keyIdentifier == 'Enter') {
233 SimUnlock.submitPin();
237 $('pin-input').addEventListener('keyup', function(event) {
238 $('enter-pin-confirm').disabled =
239 $('enter-pin-dismiss').disabled ||
240 this.value.length < SimUnlock.PIN_MIN_LENGTH;
242 $('pin-input').addEventListener('textInput',
243 SimUnlock.processInput.bind(this));
244 $('enter-pin-confirm').addEventListener('click', function(event) {
245 SimUnlock.submitPin();
247 $('enter-pin-dismiss').addEventListener('click', function(event) {
251 // No PIN retries left screen.
252 $('pin-no-tries-proceed').addEventListener('click', function(event) {
253 chrome.send('proceedToPukInput');
255 $('pin-no-tries-dismiss').addEventListener('click', function(event) {
260 $('puk-input').addEventListener('keydown', function(event) {
261 if (event.keyIdentifier == 'Enter') {
262 SimUnlock.pukEntered($('puk-input').value);
266 $('puk-input').addEventListener('keyup', function(event) {
267 $('enter-puk-confirm').disabled =
268 $('enter-puk-dismiss').disabled ||
269 this.value.length < SimUnlock.PUK_LENGTH;
271 $('puk-input').addEventListener('textInput',
272 SimUnlock.processInput.bind(this));
273 $('enter-puk-confirm').addEventListener('click', function(event) {
274 SimUnlock.pukEntered($('puk-input').value);
276 $('enter-puk-dismiss').addEventListener('click', function(event) {
280 // Change PIN / new PIN screen.
281 $('old-pin-input').addEventListener('keydown', function(event) {
282 if (event.keyIdentifier == 'Enter') {
283 if (this.value.length >= SimUnlock.PIN_MIN_LENGTH)
284 $('new-pin-input').focus();
288 $('old-pin-input').addEventListener('keyup', function(event) {
289 $('choose-pin-confirm').disabled =
290 $('choose-pin-dismiss').disabled ||
291 this.value.length < SimUnlock.PIN_MIN_LENGTH ||
292 $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
293 $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH;
295 $('old-pin-input').addEventListener('textInput',
296 SimUnlock.processInput.bind(this));
297 $('new-pin-input').addEventListener('keydown', function(event) {
298 if (event.keyIdentifier == 'Enter') {
299 if (this.value.length >= SimUnlock.PIN_MIN_LENGTH)
300 $('retype-new-pin-input').focus();
304 $('new-pin-input').addEventListener('keyup', function(event) {
306 SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
308 $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH;
309 var oldPinOk = !changePinMode || oldPinLengthOk;
310 $('choose-pin-confirm').disabled =
311 $('choose-pin-dismiss').disabled ||
312 this.value.length < SimUnlock.PIN_MIN_LENGTH ||
313 $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
316 $('new-pin-input').addEventListener('textInput',
317 SimUnlock.processInput.bind(this));
318 $('retype-new-pin-input').addEventListener('keyup', function(event) {
320 SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
322 $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH;
323 var oldPinOk = !changePinMode || oldPinLengthOk;
324 $('choose-pin-confirm').disabled =
325 $('choose-pin-dismiss').disabled ||
326 this.value.length < SimUnlock.PIN_MIN_LENGTH ||
327 $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
330 $('retype-new-pin-input').addEventListener('keydown', function(event) {
331 if (event.keyIdentifier == 'Enter') {
332 SimUnlock.newPinEntered($('new-pin-input').value,
333 $('retype-new-pin-input').value);
337 $('retype-new-pin-input').addEventListener('textInput',
338 SimUnlock.processInput.bind(this));
339 $('choose-pin-confirm').addEventListener('click', function(event) {
340 SimUnlock.newPinEntered($('new-pin-input').value,
341 $('retype-new-pin-input').value);
343 $('choose-pin-dismiss').addEventListener('click', function(event) {
347 // SIM blocked screens.
348 $('puk-no-tries-confirm').addEventListener('click', function(event) {
351 $('sim-disabled-confirm').addEventListener('click', function(event) {
354 chrome.send('simStatusInitialize', [this.mode_]);
357 SimUnlock.enablePinDialog = function(enabled) {
358 $('pin-input').disabled = !enabled;
359 // Ok button is initially disabled.
360 $('enter-pin-confirm').disabled = true;
361 $('enter-pin-dismiss').disabled = !enabled;
364 SimUnlock.enableChoosePinDialog = function(enabled) {
365 $('old-pin-input').disabled = !enabled;
366 $('new-pin-input').disabled = !enabled;
367 $('retype-new-pin-input').disabled = !enabled;
368 // Ok button is initially disabled.
369 $('choose-pin-confirm').disabled = true;
370 $('choose-pin-dismiss').disabled = !enabled;
373 SimUnlock.submitPin = function() {
374 var pin = $('pin-input').value;
375 if (pin.length < SimUnlock.PIN_MIN_LENGTH)
377 SimUnlock.enablePinDialog(false);
378 chrome.send('enterPinCode', [pin]);
381 SimUnlock.prepareChoosePinDialog = function(changePin) {
382 // Our dialog has different height than choose-pin step of the
383 // unlock process which we're reusing.
385 $('choose-pin-content-area').classList.remove('choose-pin-content-area');
386 $('choose-pin-content-area').classList.add('change-pin-content-area');
387 var title = loadTimeData.getString('changePinTitle');
388 $('choose-pin-title').textContent = title;
390 $('choose-pin-content-area').classList.remove('change-pin-content-area');
391 $('choose-pin-content-area').classList.add('choose-pin-content-area');
392 var pinMessage = loadTimeData.getString('choosePinMessage');
393 $('choose-pin-msg').classList.remove('error');
394 $('choose-pin-msg').textContent = pinMessage;
395 var title = loadTimeData.getString('choosePinTitle');
396 $('choose-pin-title').textContent = title;
398 $('old-pin-label').hidden = !changePin;
399 $('old-pin-input-area').hidden = !changePin;
402 SimUnlock.newPinEntered = function(newPin, newPin2) {
403 SimUnlock.getInstance().newPinEntered_(newPin, newPin2);
406 SimUnlock.pukEntered = function(pukValue) {
407 SimUnlock.getInstance().pukEntered_(pukValue);
411 * Processes PIN/PUK fields input, restricting it to 0..9.
413 SimUnlock.processInput = function(event) {
414 if (/[^0-9]+/gi.test(event.data))
415 event.preventDefault();
418 SimUnlock.simStateChanged = function(simInfo) {
419 SimUnlock.getInstance().updateSimStatus_(simInfo);
429 disableTextSelectAndDrag();