Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(676)

Unified Diff: chrome/browser/resources/settings/people_page/quick_unlock_setup_pin.js

Issue 2098663002: Add settings screen that lets a user setup a PIN to unlock their device with. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pin-unlock-settings-choose-method
Patch Set: Rebase account for parent CL changes Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/settings/people_page/quick_unlock_setup_pin.js
diff --git a/chrome/browser/resources/settings/people_page/quick_unlock_setup_pin.js b/chrome/browser/resources/settings/people_page/quick_unlock_setup_pin.js
new file mode 100644
index 0000000000000000000000000000000000000000..881190f41d027ad96465aecb0e51208fee7cd28d
--- /dev/null
+++ b/chrome/browser/resources/settings/people_page/quick_unlock_setup_pin.js
@@ -0,0 +1,335 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * @fileoverview
+ * 'settings-quick-unlock-setup-pin' is the settings page for choosing a PIN.
+ *
+ * Example:
+ *
+ * <settings-quick-unlock-setup-pin
+ * set-modes="[[quickUnlockSetModes]]"
+ * current-route="{{currentRoute}}">
+ * </settings-quick-unlock-setup-pin>
+ */
+
+(function() {
+'use strict';
+
+/**
+ * The step in the setup PIN flow.
+ * @const
+ */
+var QuickUnlockSetupPinStep = {
tommycli 2016/07/13 19:31:11 I think the confirm/choose stuff could be simplifi
jdufault 2016/07/13 20:38:13 Done.
+ CHOOSE_PIN: 'choose-pin',
+ CONFIRM_PIN: 'confirm-pin'
+};
+
+/**
+ * The type of problem message to display. Each entry contains the i18n message
+ * id and the associated css class to display the problem with. At most one
+ * problem can be shown at a time.
+ * @const
+ */
+var QuickUnlockSetupPinProblemType = {
tommycli 2016/07/13 19:31:12 If there's not going to be more than 3 errors, I t
jdufault 2016/07/13 20:38:13 I've done some renaming, but this makes the showPr
tommycli 2016/07/13 20:57:10 Okay, sounds good. Thanks for trying it.
+ TOO_SHORT: {
+ messageId: 'quickUnlockConfigurePinChoosePinTooShort',
+ class: 'error'
+ },
+ WEAK: {
+ messageId: 'quickUnlockConfigurePinChoosePinWeakPinWarning',
+ class: 'warning'
+ },
+ MISMATCHED: {
+ messageId: 'quickUnlockConfigurePinMismatchedPins',
+ class: 'error'
+ }
+};
+
+/**
+ * A list of the top-10 most commmonly used PINs. This list is taken from
+ * www.datagenetics.com/blog/september32012/.
+ * @const
+ */
+var WEAK_PINS = [
+ '1234', '1111', '0000', '1212', '7777', '1004', '2000', '4444', '2222',
+ '6969'
+];
+
+/**
+ * When the user should be shown an error/warning, wait for this long until
+ * showing them the problem, to give them a chance to stop typing.
+ * @const
+ */
+var SHOW_PROBLEM_DELAY_IN_MS = 500;
tommycli 2016/07/13 19:31:12 Is the delay mechanism a requirement? Because othe
jdufault 2016/07/13 20:38:13 Without the delay, as you type the PIN you'll imme
+
+Polymer({
+ is: 'settings-quick-unlock-setup-pin',
+
+ behaviors: [
tommycli 2016/07/13 19:31:12 formatting seems odd here
jdufault 2016/07/13 20:38:13 I've added a newline. I'm not sure otherwise what
+ QuickUnlockPasswordDetectBehavior, I18nBehavior
+ ],
+
+ properties: {
+ /**
+ * The current PIN keyboard value.
+ * @private
+ */
+ pinKeyboardValue_: String,
+
+ /**
+ * Stores the initial PIN value so it can be confirmed.
+ * @private
+ */
+ initialPin_: String,
+
+ /**
+ * String content of the title element.
+ * @private
+ */
+ titleMessage_: String,
tommycli 2016/07/13 19:31:11 Instead of a message variable, how about two dom-i
jdufault 2016/07/13 20:38:13 Done, I like this better.
+
+ /**
+ * String content of the continue/save button.
+ * @private
+ */
+ continueMessage_: String,
tommycli 2016/07/13 19:31:11 Ditto here.
jdufault 2016/07/13 20:38:13 Done.
+
+ /**
+ * Should the step-specific problem message be displayed?
+ * @private
+ */
+ showProblem_: Boolean,
tommycli 2016/07/13 19:31:12 I think you can axe this boolean and just make int
jdufault 2016/07/13 20:38:13 Done.
+
+ /**
+ * The actual problem message to display.
+ * @private
+ */
+ problemMessage_: String,
+
+ /**
+ * The type of problem class to show (warning or error).
+ */
+ problemClass_: String,
+
+ /**
+ * Should the step-specific submit button be displayed?
+ * @private
+ */
+ enableSubmit_: Boolean,
+
+ /**
+ * The current step/subpage we are on.
+ * @private
+ */
+ step_: {
+ type: String,
+ value: QuickUnlockSetupPinStep.CHOOSE_PIN,
+ },
+ },
+
+ observers: [
+ 'onRouteChanged_(currentRoute)',
+ 'onSetModesChanged_(setModes)'
+ ],
+
+ /** @override */
+ attached: function() {
+ this.resetState_();
+ this.askForPasswordIfUnset();
+ },
+
+ /** @private */
+ onRouteChanged_: function(currentRoute) {
+ if (this.isScreenActive(QuickUnlockScreen.SETUP_PIN)) {
+ this.askForPasswordIfUnset();
+ } else {
+ // If the user hits the back button, they can leave the element
+ // half-completed; therefore, reset state if the element is not active.
+ this.resetState_();
+ }
+ },
+
+ /** @private */
+ onSetModesChanged_: function() {
+ if (this.isScreenActive(QuickUnlockScreen.SETUP_PIN))
+ this.askForPasswordIfUnset();
+ },
+
+ /**
+ * Resets the element to the initial state.
+ * @private
+ */
+ resetState_: function() {
+ this.initialPin_ = '';
+ this.pinKeyboardValue_ = '';
+ this.showProblem_ = false;
+ this.enableSubmit_ = false;
+ this.setStep_(QuickUnlockSetupPinStep.CHOOSE_PIN);
+ this.onPinChange_();
+ },
+
+ /**
+ * Returns true if the given PIN is likely easy to guess.
+ * @private
+ */
+ isPinWeak_: function(pin) {
+ // Warn if it's a top-10 pin.
+ if (WEAK_PINS.includes(pin))
+ return true;
+
+ // Warn if the PIN is consecutive digits.
+ var delta = 0;
+ for (var i = 1; i < pin.length; ++i) {
+ var prev = Number(pin[i - 1]);
+ var num = Number(pin[i]);
+ if (Number.isNaN(prev) || Number.isNaN(num))
+ return false;
+ delta = Math.max(delta, Math.abs(num - prev));
+ }
+
+ return delta <= 1;
+ },
+
+ /**
+ * Returns true if the given PIN matches PIN requirements, such as minimum
+ * length.
+ * @private
+ */
+ isPinLongEnough_: function(pin) {
+ return pin.length >= 4;
+ },
+
+ /**
+ * Returns true if the PIN is ready to be changed to a new value.
+ * @private
+ */
+ canSubmit_: function() {
+ return this.isPinLongEnough_(this.pinKeyboardValue_) &&
+ this.initialPin_ == this.pinKeyboardValue_;
+ },
+
+ /**
+ * Notify the user about a problem. The problem will be shown after
+ * SHOW_PROBLEM_DELAY_IN_MS. The problem show can be cancelled by calling
+ * |this.cancelPendingProblem_()|.
+ * @private
+ */
+ postProblem_: function(problemType) {
+ function activateProblem() {
+ this.showProblem_ = true;
+ this.problemMessage_ = this.i18n(problemType.messageId);
+ this.problemClass_ = problemType.class;
+ setTimeout(this.updateStyles.bind(this));
tommycli 2016/07/13 19:31:11 Hmm... does it not work without this call? I've ne
jdufault 2016/07/13 20:38:13 The icon color is not updated without the call. I'
tommycli 2016/07/13 20:57:09 Cool. Getting rid of the setTimeout makes it much
+ }
+
+ this.cancelPendingProblem_();
+ this.pendingProblem_ = setTimeout(activateProblem.bind(this),
+ SHOW_PROBLEM_DELAY_IN_MS);
+ },
+
+ /** @private */
+ cancelPendingProblem_: function() {
+ if (this.pendingProblem_) {
+ clearTimeout(this.pendingProblem_);
+ delete this.pendingProblem_;
+ }
+ },
+
+ /** @private */
+ onPinChange_: function() {
+ // If the user typed, we want to reset the show problem timeout.
+ this.cancelPendingProblem_();
+
+ if (this.isChooseStep_()) {
+ var isPinLongEnough = this.isPinLongEnough_(this.pinKeyboardValue_);
+ var isWeak = isPinLongEnough && this.isPinWeak_(this.pinKeyboardValue_);
+
+ if (!isPinLongEnough && this.pinKeyboardValue_)
+ this.postProblem_(QuickUnlockSetupPinProblemType.TOO_SHORT);
+ else if (isWeak)
+ this.postProblem_(QuickUnlockSetupPinProblemType.WEAK);
+ else
+ this.showProblem_ = false;
+
+ this.enableSubmit_ = isPinLongEnough;
+
+ } else if (this.isConfirmStep_()) {
+ var canSubmit = this.canSubmit_();
+
+ if (!canSubmit && this.pinKeyboardValue_)
+ this.postProblem_(QuickUnlockSetupPinProblemType.MISMATCHED);
+ else
+ this.showProblem_ = false;
+
+ this.enableSubmit_ = canSubmit;
+ }
+ },
+
+ /** @private */
+ onPinSubmit_: function() {
+ if (this.isChooseStep_()) {
+ if (this.isPinLongEnough_(this.pinKeyboardValue_)) {
+ this.initialPin_ = this.pinKeyboardValue_;
+ this.pinKeyboardValue_ = '';
+ this.setStep_(QuickUnlockSetupPinStep.CONFIRM_PIN);
+ this.onPinChange_();
+ }
+ } else if (this.isConfirmStep_()) {
+ // onPinSubmit_ gets called if the user hits enter on the PIN keyboard.
+ // The PIN is not guaranteed to be valid in that case.
+ if (!this.canSubmit_())
+ return;
+
+ function onSetModesCompleted(didSet) {
+ if (!didSet) {
+ console.error('Failed to update pin');
+ return;
+ }
+
+ this.resetState_();
+ this.currentRoute = {
+ page: 'basic',
+ section: 'people',
+ subpage: [QuickUnlockScreen.CHOOSE_METHOD]
+ };
+ }
+
+ this.setModes.call(
+ null,
+ [chrome.quickUnlockPrivate.QuickUnlockMode.PIN],
+ [this.pinKeyboardValue_],
+ onSetModesCompleted.bind(this));
+ }
+ },
+
+ /** @private */
+ setStep_: function(step) {
+ this.step_ = step;
+ switch (this.step_) {
+ case QuickUnlockSetupPinStep.CHOOSE_PIN:
+ this.titleMessage_ = this.i18n('quickUnlockConfigurePinChoosePinTitle');
+ this.continueMessage_ =
+ this.i18n('quickUnlockConfigurePinContinueButton');
+ break;
+ case QuickUnlockSetupPinStep.CONFIRM_PIN:
+ this.titleMessage_ =
+ this.i18n('quickUnlockConfigurePinConfirmPinTitle');
+ this.continueMessage_ = this.i18n('save');
+ break;
+ }
+ },
+
+ /** @private */
+ isChooseStep_: function() {
+ return this.step_ == QuickUnlockSetupPinStep.CHOOSE_PIN;
+ },
+
+ /** @private */
+ isConfirmStep_: function() {
+ return this.step_ == QuickUnlockSetupPinStep.CONFIRM_PIN;
+ },
+});
+
+})();

Powered by Google App Engine
This is Rietveld 408576698