• 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.prototype = {
39    initialized_: false,
40    mode_: SimUnlock.SIM_DIALOG_UNLOCK,
41    pukValue_: '',
42    defaultDialogSize_: {
43      'width': window.innerWidth,
44      'height': window.innerHeight
45    },
46    state_: SimUnlock.SIM_UNLOCK_LOADING,
47
48    changeState_: function(simInfo) {
49      var newState = simInfo.state;
50      var error = simInfo.error;
51      var tries = simInfo.tries;
52      var pinMessage;
53      this.hideAll_();
54      switch (newState) {
55        case SimUnlock.SIM_UNLOCK_LOADING:
56          break;
57        case SimUnlock.SIM_ABSENT_NOT_LOCKED:
58          SimUnlock.close();
59          break;
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');
68          }
69          $('pin-error-msg').textContent = pinMessage;
70          $('pin-input').value = '';
71          SimUnlock.enablePinDialog(true);
72          $('locked-pin-overlay').hidden = false;
73          $('pin-input').focus();
74          break;
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');
83          }
84          $('pin-error-msg').textContent = pinMessage;
85          $('pin-input').value = '';
86          SimUnlock.enablePinDialog(true);
87          $('locked-pin-overlay').hidden = false;
88          $('pin-input').focus();
89          break;
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');
99          }
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();
107          break;
108        case SimUnlock.SIM_LOCKED_NO_PIN_TRIES_LEFT:
109          $('locked-pin-no-tries-overlay').hidden = false;
110          break;
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;
116          }
117          $('enter-puk-confirm').disabled = true;
118          $('locked-puk-overlay').hidden = false;
119          $('puk-input').focus();
120
121          // Resize the dialog to accomodate the PUK contents.
122          this.updateDialogSize_(0, 45);
123          break;
124        case SimUnlock.SIM_LOCKED_NO_PUK_TRIES_LEFT:
125          $('locked-puk-no-tries-overlay').hidden = false;
126          break;
127        case SimUnlock.SIM_DISABLED:
128          $('sim-disabled-overlay').hidden = false;
129          break;
130      }
131      this.state_ = newState;
132    },
133
134    /**
135     * Returns current state of the dialog.
136     * @type {number} value of the state.
137     */
138    get state() {
139      return this.state_;
140    },
141
142    updateDialogSize_: function(deltaX, deltaY) {
143      window.resizeTo(this.defaultDialogSize_.width + deltaX,
144                      this.defaultDialogSize_.height + deltaY);
145    },
146
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;
154    },
155
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 ||
160             (changePinMode &&
161              $('old-pin-input').value.length < SimUnlock.PIN_MIN_LENGTH)) {
162        return;
163      }
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 = '';
169        if (changePinMode)
170          $('old-pin-input').focus();
171        else
172          $('new-pin-input').focus();
173      } else {
174        $('choose-pin-error').hidden = true;
175        SimUnlock.enableChoosePinDialog(false);
176        if (changePinMode) {
177          var oldPin = $('old-pin-input').value;
178          chrome.send('changePinCode', [oldPin, newPin]);
179        } else {
180          chrome.send('enterPukCode', [this.pukValue_, newPin]);
181          this.pukValue_ = '';
182        }
183      }
184    },
185
186    pukEntered_: function(pukValue) {
187      if (pukValue.length < SimUnlock.PUK_LENGTH)
188        return;
189      this.pukValue_ = pukValue;
190      this.hideAll_();
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);
198    },
199
200    updateSimStatus_: function(simInfo) {
201      this.changeState_(simInfo);
202    },
203  };
204
205  SimUnlock.cancel = function() {
206    SimUnlock.close();
207  };
208
209  SimUnlock.close = function() {
210    window.close();
211  };
212
213  SimUnlock.initialize = function() {
214    this.initialized_ = true;
215
216    var modePattern = /(^\?|&)mode=([^&#]*)/;
217    var results = modePattern.exec(window.location.search);
218    if (results == null) {
219      this.mode_ = SimUnlock.SIM_DIALOG_UNLOCK;
220    } else {
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;
228    }
229
230    // PIN input screen.
231    $('pin-input').addEventListener('keydown', function(event) {
232      if (event.keyIdentifier == 'Enter') {
233        SimUnlock.submitPin();
234        return;
235      }
236    });
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;
241    });
242    $('pin-input').addEventListener('textInput',
243                                    SimUnlock.processInput.bind(this));
244    $('enter-pin-confirm').addEventListener('click', function(event) {
245      SimUnlock.submitPin();
246    });
247    $('enter-pin-dismiss').addEventListener('click', function(event) {
248      SimUnlock.cancel();
249    });
250
251    // No PIN retries left screen.
252    $('pin-no-tries-proceed').addEventListener('click', function(event) {
253      chrome.send('proceedToPukInput');
254    });
255    $('pin-no-tries-dismiss').addEventListener('click', function(event) {
256      SimUnlock.cancel();
257    });
258
259    // PUK input screen.
260    $('puk-input').addEventListener('keydown', function(event) {
261      if (event.keyIdentifier == 'Enter') {
262        SimUnlock.pukEntered($('puk-input').value);
263        return;
264      }
265    });
266    $('puk-input').addEventListener('keyup', function(event) {
267      $('enter-puk-confirm').disabled =
268          $('enter-puk-dismiss').disabled ||
269          this.value.length < SimUnlock.PUK_LENGTH;
270    });
271    $('puk-input').addEventListener('textInput',
272                                    SimUnlock.processInput.bind(this));
273    $('enter-puk-confirm').addEventListener('click', function(event) {
274      SimUnlock.pukEntered($('puk-input').value);
275    });
276    $('enter-puk-dismiss').addEventListener('click', function(event) {
277      SimUnlock.cancel();
278    });
279
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();
285        return;
286      }
287    });
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;
294    });
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();
301        return;
302      }
303    });
304    $('new-pin-input').addEventListener('keyup', function(event) {
305      var changePinMode =
306          SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
307      var oldPinLengthOk =
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 ||
314          !oldPinOk;
315    });
316    $('new-pin-input').addEventListener('textInput',
317                                        SimUnlock.processInput.bind(this));
318    $('retype-new-pin-input').addEventListener('keyup', function(event) {
319      var changePinMode =
320          SimUnlock.getInstance().state == SimUnlock.SIM_NOT_LOCKED_CHANGE_PIN;
321      var oldPinLengthOk =
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 ||
328          !oldPinOk;
329    });
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);
334        return;
335      }
336    });
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);
342    });
343    $('choose-pin-dismiss').addEventListener('click', function(event) {
344      SimUnlock.cancel();
345    });
346
347    // SIM blocked screens.
348    $('puk-no-tries-confirm').addEventListener('click', function(event) {
349      SimUnlock.close();
350    });
351    $('sim-disabled-confirm').addEventListener('click', function(event) {
352      SimUnlock.close();
353    });
354    chrome.send('simStatusInitialize', [this.mode_]);
355  };
356
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;
362  };
363
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;
371  };
372
373  SimUnlock.submitPin = function() {
374    var pin = $('pin-input').value;
375    if (pin.length < SimUnlock.PIN_MIN_LENGTH)
376      return;
377    SimUnlock.enablePinDialog(false);
378    chrome.send('enterPinCode', [pin]);
379  };
380
381  SimUnlock.prepareChoosePinDialog = function(changePin) {
382    // Our dialog has different height than choose-pin step of the
383    // unlock process which we're reusing.
384    if (changePin) {
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;
389    } else {
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;
397    }
398    $('old-pin-label').hidden = !changePin;
399    $('old-pin-input-area').hidden = !changePin;
400  };
401
402  SimUnlock.newPinEntered = function(newPin, newPin2) {
403    SimUnlock.getInstance().newPinEntered_(newPin, newPin2);
404  };
405
406  SimUnlock.pukEntered = function(pukValue) {
407    SimUnlock.getInstance().pukEntered_(pukValue);
408  };
409
410  /**
411   * Processes PIN/PUK fields input, restricting it to 0..9.
412   */
413  SimUnlock.processInput = function(event) {
414    if (/[^0-9]+/gi.test(event.data))
415      event.preventDefault();
416  };
417
418  SimUnlock.simStateChanged = function(simInfo) {
419    SimUnlock.getInstance().updateSimStatus_(simInfo);
420  };
421
422  // Export
423  return {
424    SimUnlock: SimUnlock
425  };
426
427});
428
429disableTextSelectAndDrag();
430