• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5cr.define('mobile', function() {
6
7  function SimUnlock() {
8  }
9
10  cr.addSingletonGetter(SimUnlock);
11
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;
22
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;
28
29  // Error codes.
30  SimUnlock.ERROR_PIN = 'incorrectPin';
31  SimUnlock.ERROR_PUK = 'incorrectPuk';
32  SimUnlock.ERROR_OK = 'ok';
33
34  // Misc constants.
35  SimUnlock.PIN_MIN_LENGTH = 4;
36  SimUnlock.PUK_LENGTH = 8;
37
38  SimUnlock.localStrings_ = new LocalStrings();
39
40  SimUnlock.prototype = {
41    initialized_: false,
42    mode_: SimUnlock.SIM_DIALOG_UNLOCK,
43    pukValue_: '',
44    defaultDialogSize_: {
45      'width': window.innerWidth,
46      'height': window.innerHeight
47    },
48    state_: SimUnlock.SIM_UNLOCK_LOADING,
49
50    changeState_: function(simInfo) {
51      var newState = simInfo.state;
52      var error = simInfo.error;
53      var tries = simInfo.tries;
54      var pinMessage;
55      this.hideAll_();
56      switch (newState) {
57        case SimUnlock.SIM_UNLOCK_LOADING:
58          break;
59        case SimUnlock.SIM_ABSENT_NOT_LOCKED:
60          SimUnlock.close();
61          break;
62        case SimUnlock.SIM_LOCKED_PIN:
63          if (error == SimUnlock.ERROR_OK) {
64            pinMessage = SimUnlock.localStrings_.getStringF(
65                'enterPinTriesMessage', tries);
66            $('pin-error-msg').classList.remove('error');
67          } else if (error == SimUnlock.ERROR_PIN) {
68              pinMessage = SimUnlock.localStrings_.getStringF(
69                  'incorrectPinTriesMessage', tries);
70            $('pin-error-msg').classList.add('error');
71          }
72          $('pin-error-msg').textContent = pinMessage;
73          $('pin-input').value = '';
74          SimUnlock.enablePinDialog(true);
75          $('locked-pin-overlay').hidden = false;
76          $('pin-input').focus();
77          break;
78        case SimUnlock.SIM_NOT_LOCKED_ASK_PIN:
79          if (error == SimUnlock.ERROR_OK) {
80            pinMessage = SimUnlock.localStrings_.getString('enterPinMessage');
81            $('pin-error-msg').classList.remove('error');
82          } else if (error == SimUnlock.ERROR_PIN) {
83              pinMessage = SimUnlock.localStrings_.getStringF(
84                  'incorrectPinTriesMessage', tries);
85            $('pin-error-msg').classList.add('error');
86          }
87          $('pin-error-msg').textContent = pinMessage;
88          $('pin-input').value = '';
89          SimUnlock.enablePinDialog(true);
90          $('locked-pin-overlay').hidden = false;
91          $('pin-input').focus();
92          break;
93        case SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN:
94          SimUnlock.prepareChoosePinDialog(true);
95          if (error == SimUnlock.ERROR_OK) {
96            pinMessage = SimUnlock.localStrings_.getString('changePinMessage');
97            $('choose-pin-msg').classList.remove('error');
98          } else if (error == SimUnlock.ERROR_PIN) {
99              pinMessage = SimUnlock.localStrings_.getStringF(
100                  'incorrectPinTriesMessage', tries);
101            $('choose-pin-msg').classList.add('error');
102          }
103          $('choose-pin-msg').textContent = pinMessage;
104          $('old-pin-input').value = '';
105          $('new-pin-input').value = '';
106          $('retype-new-pin-input').value = '';
107          $('choose-pin-overlay').hidden = false;
108          SimUnlock.enableChoosePinDialog(true);
109          $('old-pin-input').focus();
110          break;
111        case SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT:
112          $('locked-pin-no-tries-overlay').hidden = false;
113          break;
114        case SimUnlock.SIM_LOCKED_PUK:
115          $('puk-input').value = '';
116          if (tries && tries >= 0) {
117            var pukMessage = SimUnlock.localStrings_.getStringF(
118                'enterPukWarning', tries);
119            $('puk-warning-msg').textContent = pukMessage;
120          }
121          $('enter-puk-confirm').disabled = true;
122          $('locked-puk-overlay').hidden = false;
123          $('puk-input').focus();
124
125          // Resize the dialog to accomodate the PUK contents.
126          this.updateDialogSize_(0, 45);
127          break;
128        case SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT:
129          $('locked-puk-no-tries-overlay').hidden = false;
130          break;
131        case SimUnlock.SIM_DISABLED:
132          $('sim-disabled-overlay').hidden = false;
133          break;
134      }
135      this.state_ = newState;
136    },
137
138    /**
139     * Returns current state of the dialog.
140     * @type {number} value of the state.
141     */
142    get state() {
143      return this.state_;
144    },
145
146    updateDialogSize_: function(deltaX, deltaY) {
147      window.resizeTo(this.defaultDialogSize_.width + deltaX,
148                      this.defaultDialogSize_.height + deltaY);
149    },
150
151    hideAll_: function() {
152      $('locked-pin-overlay').hidden = true;
153      $('locked-pin-no-tries-overlay').hidden = true;
154      $('locked-puk-overlay').hidden = true;
155      $('choose-pin-overlay').hidden = true;
156      $('locked-puk-no-tries-overlay').hidden = true;
157      $('sim-disabled-overlay').hidden = true;
158    },
159
160    newPinEntered_: function(newPin, newPin2) {
161      var changePinMode = this.state_ == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
162      if (newPin.length < SimUnlock.PIN_MIN_LENGTH ||
163          newPin2.length < SimUnlock.PIN_MIN_LENGTH ||
164             (changePinMode &&
165              $('old-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH)) {
166        return;
167      }
168      if (newPin != newPin2) {
169        $('choose-pin-error').hidden = false;
170        $('old-pin-input').value = '';
171        $('new-pin-input').value = '';
172        $('retype-new-pin-input').value = '';
173        if (changePinMode)
174          $('old-pin-input').focus();
175        else
176          $('new-pin-input').focus();
177      } else {
178        $('choose-pin-error').hidden = true;
179        SimUnlock.enableChoosePinDialog(false);
180        if (changePinMode) {
181          var oldPin = $('old-pin-input').value;
182          chrome.send('changePinCode', [oldPin, newPin]);
183        } else {
184          chrome.send('enterPukCode', [this.pukValue_, newPin]);
185          this.pukValue_ = '';
186        }
187      }
188    },
189
190    pukEntered_: function(pukValue) {
191      if (pukValue.length < SimUnlock.PUK_LENGTH)
192        return;
193      this.pukValue_ = pukValue;
194      this.hideAll_();
195      SimUnlock.prepareChoosePinDialog(false);
196      SimUnlock.enableChoosePinDialog(true);
197      $('new-pin-input').value = '';
198      $('retype-new-pin-input').value = '';
199      $('choose-pin-overlay').hidden = false;
200      $('new-pin-input').focus();
201      this.updateDialogSize_(0, 18);
202    },
203
204    updateSimStatus_: function(simInfo) {
205      this.changeState_(simInfo);
206    },
207  };
208
209  SimUnlock.cancel = function() {
210    chrome.send('cancel');
211    SimUnlock.close();
212  };
213
214  SimUnlock.close = function() {
215    window.close();
216  };
217
218  SimUnlock.initialize = function() {
219    this.initialized_ = true;
220
221    var modePattern = /(^\?|&)mode=([^&#]*)/;
222    var results = modePattern.exec(window.location.search);
223    if (results == null) {
224      this.mode_ = SimUnlock.SIM_DIALOG_UNLOCK;
225    } else {
226      var mode = results[2];
227      if (mode == 'change-pin')
228        this.mode_ = SimUnlock.SIM_DIALOG_CHANGE_PIN;
229      else if (mode == 'set-lock-on')
230        this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_ON;
231      else if (mode == 'set-lock-off')
232        this.mode_ = SimUnlock.SIM_DIALOG_SET_LOCK_OFF;
233    }
234
235    // PIN input screen.
236    $('pin-input').addEventListener('keydown', function(event) {
237      if (event.keyIdentifier == 'Enter') {
238        SimUnlock.submitPin();
239        return;
240      }
241    });
242    $('pin-input').addEventListener('keyup', function(event) {
243      $('enter-pin-confirm').disabled =
244          $('enter-pin-dismiss').disabled ||
245          this.value.length < SimUnlock.PIN_MIN_LENGTH;
246    });
247    $('pin-input').addEventListener('textInput',
248                                    SimUnlock.processInput.bind(this));
249    $('enter-pin-confirm').addEventListener('click', function(event) {
250      SimUnlock.submitPin();
251    });
252    $('enter-pin-dismiss').addEventListener('click', function(event) {
253      SimUnlock.cancel();
254    });
255
256    // No PIN retries left screen.
257    $('pin-no-tries-proceed').addEventListener('click', function(event) {
258      chrome.send('proceedToPukInput');
259    });
260    $('pin-no-tries-dismiss').addEventListener('click', function(event) {
261      SimUnlock.cancel();
262    });
263
264    // PUK input screen.
265    $('puk-input').addEventListener('keydown', function(event) {
266      if (event.keyIdentifier == 'Enter') {
267        SimUnlock.pukEntered($('puk-input').value);
268        return;
269      }
270    });
271    $('puk-input').addEventListener('keyup', function(event) {
272      $('enter-puk-confirm').disabled =
273          $('enter-puk-dismiss').disabled ||
274          this.value.length < SimUnlock.PUK_LENGTH;
275    });
276    $('puk-input').addEventListener('textInput',
277                                    SimUnlock.processInput.bind(this));
278    $('enter-puk-confirm').addEventListener('click', function(event) {
279      SimUnlock.pukEntered($('puk-input').value);
280    });
281    $('enter-puk-dismiss').addEventListener('click', function(event) {
282      SimUnlock.cancel();
283    });
284
285    // Change PIN / new PIN screen.
286    $('old-pin-input').addEventListener('keydown', function(event) {
287      if (event.keyIdentifier == 'Enter') {
288        if (this.value.length >= SimUnlock.PIN_MIN_LENGTH)
289          $('new-pin-input').focus();
290        return;
291      }
292    });
293    $('old-pin-input').addEventListener('keyup', function(event) {
294      $('choose-pin-confirm').disabled =
295          $('choose-pin-dismiss').disabled ||
296          this.value.length < SimUnlock.PIN_MIN_LENGTH ||
297          $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
298          $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH;
299    });
300    $('old-pin-input').addEventListener('textInput',
301                                        SimUnlock.processInput.bind(this));
302    $('new-pin-input').addEventListener('keydown', function(event) {
303      if (event.keyIdentifier == 'Enter') {
304        if (this.value.length >= SimUnlock.PIN_MIN_LENGTH)
305          $('retype-new-pin-input').focus();
306        return;
307      }
308    });
309    $('new-pin-input').addEventListener('keyup', function(event) {
310      var changePinMode =
311          SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
312      var oldPinLengthOk =
313          $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH;
314      var oldPinOk = !changePinMode || oldPinLengthOk;
315      $('choose-pin-confirm').disabled =
316          $('choose-pin-dismiss').disabled ||
317          this.value.length < SimUnlock.PIN_MIN_LENGTH ||
318          $('retype-new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
319          !oldPinOk;
320    });
321    $('new-pin-input').addEventListener('textInput',
322                                        SimUnlock.processInput.bind(this));
323    $('retype-new-pin-input').addEventListener('keyup', function(event) {
324      var changePinMode =
325          SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
326      var oldPinLengthOk =
327          $('old-pin-input').value.length >= SimUnlock.PIN_MIN_LENGTH;
328      var oldPinOk = !changePinMode || oldPinLengthOk;
329      $('choose-pin-confirm').disabled =
330          $('choose-pin-dismiss').disabled ||
331          this.value.length < SimUnlock.PIN_MIN_LENGTH ||
332          $('new-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH ||
333          !oldPinOk;
334    });
335    $('retype-new-pin-input').addEventListener('keydown', function(event) {
336      if (event.keyIdentifier == 'Enter') {
337        SimUnlock.newPinEntered($('new-pin-input').value,
338                                $('retype-new-pin-input').value);
339        return;
340      }
341    });
342    $('retype-new-pin-input').addEventListener('textInput',
343        SimUnlock.processInput.bind(this));
344    $('choose-pin-confirm').addEventListener('click', function(event) {
345      SimUnlock.newPinEntered($('new-pin-input').value,
346                              $('retype-new-pin-input').value);
347    });
348    $('choose-pin-dismiss').addEventListener('click', function(event) {
349      SimUnlock.cancel();
350    });
351
352    // SIM blocked screens.
353    $('puk-no-tries-confirm').addEventListener('click', function(event) {
354      SimUnlock.close();
355    });
356    $('sim-disabled-confirm').addEventListener('click', function(event) {
357      SimUnlock.close();
358    });
359    chrome.send('simStatusInitialize', [this.mode_]);
360  };
361
362  SimUnlock.enablePinDialog = function(enabled) {
363    $('pin-input').disabled = !enabled;
364    // Ok button is initially disabled.
365    $('enter-pin-confirm').disabled = true;
366    $('enter-pin-dismiss').disabled = !enabled;
367  };
368
369  SimUnlock.enableChoosePinDialog = function(enabled) {
370    $('old-pin-input').disabled = !enabled;
371    $('new-pin-input').disabled = !enabled;
372    $('retype-new-pin-input').disabled = !enabled;
373    // Ok button is initially disabled.
374    $('choose-pin-confirm').disabled = true;
375    $('choose-pin-dismiss').disabled = !enabled;
376  };
377
378  SimUnlock.submitPin = function() {
379    var pin = $('pin-input').value;
380    if (pin.length < SimUnlock.PIN_MIN_LENGTH)
381      return;
382    SimUnlock.enablePinDialog(false);
383    chrome.send('enterPinCode', [pin]);
384  };
385
386  SimUnlock.prepareChoosePinDialog = function(changePin) {
387    // Our dialog has different height than choose-pin step of the
388    // unlock process which we're reusing.
389    if (changePin) {
390      $('choose-pin-content-area').classList.remove('choose-pin-content-area');
391      $('choose-pin-content-area').classList.add('change-pin-content-area');
392      var title = SimUnlock.localStrings_.getString('changePinTitle');
393      $('choose-pin-title').textContent = title;
394    } else {
395      $('choose-pin-content-area').classList.remove('change-pin-content-area');
396      $('choose-pin-content-area').classList.add('choose-pin-content-area');
397      var pinMessage = SimUnlock.localStrings_.getString('choosePinMessage');
398      $('choose-pin-msg').classList.remove('error');
399      $('choose-pin-msg').textContent = pinMessage;
400      var title = SimUnlock.localStrings_.getString('choosePinTitle');
401      $('choose-pin-title').textContent = title;
402    }
403    $('old-pin-label').hidden = !changePin;
404    $('old-pin-input-area').hidden = !changePin;
405  };
406
407  SimUnlock.newPinEntered = function(newPin, newPin2) {
408    SimUnlock.getInstance().newPinEntered_(newPin, newPin2);
409  };
410
411  SimUnlock.pukEntered = function(pukValue) {
412    SimUnlock.getInstance().pukEntered_(pukValue);
413  };
414
415  /**
416   * Processes PIN/PUK fields input, restricting it to 0..9.
417   */
418  SimUnlock.processInput = function(event) {
419    if (/[^0-9]+/gi.test(event.data))
420      event.preventDefault();
421  };
422
423  SimUnlock.simStateChanged = function(simInfo) {
424    SimUnlock.getInstance().updateSimStatus_(simInfo);
425  };
426
427  // Export
428  return {
429    SimUnlock: SimUnlock
430  };
431
432});
433
434disableTextSelectAndDrag();
435