Commit e5a389c2 authored by sammiequon's avatar sammiequon Committed by Commit bot

Added uma for pin unlock set up.

BUG=621548
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:closure_compilation

Review-Url: https://codereview.chromium.org/2313103002
Cr-Commit-Position: refs/heads/master@{#439836}
parent 4234d3c6
<if expr="chromeos">
<link rel="import" href="/people_page/lock_screen_constants.html">
</if>
<div id="settings" class="page" hidden>
<header>
<h1 i18n-content="settingsTitle"></h1>
......
......@@ -441,6 +441,8 @@ cr.define('options', function() {
if (loadTimeData.getBoolean('showQuickUnlockSettings')) {
$('manage-screenlock').onclick = function(event) {
PageManager.showPageByName('quickUnlockConfigureOverlay');
settings.recordLockScreenProgress(
LockScreenProgress.START_SCREEN_LOCK);
};
$('manage-screenlock').hidden = false;
}
......
......@@ -45,6 +45,7 @@
'../../../../chrome/browser/resources/chromeos/keyboard/keyboard_utils.js',
'../../../../ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
'../settings/compiled_resources2.gyp:route',
'../settings/people_page/compiled_resources2.gyp:lock_screen_constants',
'../settings/people_page/compiled_resources2.gyp:lock_state_behavior',
'../settings/people_page/compiled_resources2.gyp:password_prompt_dialog',
'../settings/people_page/compiled_resources2.gyp:lock_screen',
......
......@@ -40,6 +40,14 @@
type="chrome_html"
flattenhtml="true"
allowexternalscript="true" />
<structure name="IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_JS"
file="settings/people_page/lock_screen_constants.js"
type="chrome_html" />
<structure name="IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_HTML"
file="settings/people_page/lock_screen_constants.html"
type="chrome_html"
flattenhtml="true"
allowexternalscript="true" />
<structure name="IDR_OPTIONS_LOCK_STATE_BEHAVIOR_JS"
file="settings/people_page/lock_state_behavior.js"
type="chrome_html" />
......
......@@ -80,6 +80,7 @@
'dependencies': [
'../compiled_resources2.gyp:route',
'<(EXTERNS_GYP):quick_unlock_private',
'lock_screen_constants',
],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
},
......@@ -95,6 +96,7 @@
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior',
'easy_unlock_browser_proxy',
'easy_unlock_turn_off_dialog',
'lock_screen_constants',
'lock_state_behavior',
'profile_info_browser_proxy',
'sync_browser_proxy',
......@@ -116,10 +118,18 @@
],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
'target_name': 'lock_screen_constants',
'dependencies': [
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
],
'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
},
{
'target_name': 'lock_screen',
'dependencies': [
'../compiled_resources2.gyp:route',
'lock_screen_constants',
'lock_state_behavior',
'password_prompt_dialog',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
......@@ -130,6 +140,7 @@
'target_name': 'setup_pin_dialog',
'dependencies': [
'../compiled_resources2.gyp:route',
'lock_screen_constants',
'password_prompt_dialog',
'<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
],
......
......@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-radio-group/paper-radio-group.html">
<link rel="import" href="/people_page/lock_screen_constants.html">
<link rel="import" href="/people_page/lock_state_behavior.html">
<link rel="import" href="/people_page/password_prompt_dialog.html">
<link rel="import" href="/people_page/setup_pin_dialog.html">
......
......@@ -37,6 +37,18 @@ Polymer({
type: Object,
observer: 'onSetModesChanged_'
},
/**
* writeUma_ is a function that handles writing uma stats. It may be
* overridden for tests.
*
* @type {Function}
* @private
*/
writeUma_: {
type: Object,
value: function() { return settings.recordLockScreenProgress; }
}
},
/** selectedUnlockType is defined in LockStateBehavior. */
......@@ -125,5 +137,6 @@ Polymer({
onConfigurePin_: function(e) {
e.preventDefault();
this.$.setupPin.open();
this.writeUma_(LockScreenProgress.CHOOSE_PIN_OR_PASSWORD);
},
});
<script src="/people_page/lock_screen_constants.js"></script>
// 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 Constants used for logging the pin unlock setup uma.
*/
/**
* Name of the pin unlock setup uma histogram.
* @type {string}
*/
var PinUnlockUmaHistogramName = 'Settings.PinUnlockSetup';
/**
* Stages the user can enter while setting up pin unlock.
* @enum {number}
*/
var LockScreenProgress = {
START_SCREEN_LOCK: 0,
ENTER_PASSWORD_CORRECTLY: 1,
CHOOSE_PIN_OR_PASSWORD: 2,
ENTER_PIN: 3,
CONFIRM_PIN: 4,
MAX_BUCKET: 5
};
cr.define('settings', function() {
/**
* Helper function to send the progress of the pin setup to be recorded in the
* histogram.
* @param {LockScreenProgress} currentProgress
*/
var recordLockScreenProgress = function(currentProgress) {
if (currentProgress >= LockScreenProgress.MAX_BUCKET) {
console.error('Expected a enumeration value of ' +
LockScreenProgress.MAX_BUCKET + ' or lower: Received ' +
currentProgress + '.');
return;
}
chrome.send('metricsHandler:recordInHistogram',
[PinUnlockUmaHistogramName, currentProgress,
LockScreenProgress.MAX_BUCKET]);
};
return {
recordLockScreenProgress: recordLockScreenProgress
};
});
......@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/html/polymer.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
<link rel="import" href="/people_page/lock_screen_constants.html">
<link rel="import" href="/settings_shared_css.html">
<link rel="import" href="/settings_shared_css.html">
......
......@@ -71,6 +71,18 @@ Polymer({
value: chrome.quickUnlockPrivate
},
/**
* writeUma_ is a function that handles writing uma stats. It may be
* overridden for tests.
*
* @type {Function}
* @private
*/
writeUma_: {
type: Object,
value: function() { return settings.recordLockScreenProgress; }
},
/**
* PASSWORD_ACTIVE_DURATION_MS value. May be overridden by tests.
* @private
......@@ -96,6 +108,7 @@ Polymer({
if (this.$.dialog.open)
return;
this.writeUma_(LockScreenProgress.START_SCREEN_LOCK);
this.$.dialog.showModal();
},
......@@ -163,6 +176,8 @@ Polymer({
this.password_ = '';
if (this.$.dialog.open)
this.$.dialog.close();
this.writeUma_(LockScreenProgress.ENTER_PASSWORD_CORRECTLY);
}
}
......
......@@ -2,6 +2,7 @@
<link rel="import" href="chrome://resources/html/i18n_behavior.html">
<link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
<link rel="import" href="/icons.html">
<link rel="import" href="/people_page/lock_screen_constants.html">
<link rel="import" href="/people_page/pin_keyboard.html">
<link rel="import" href="/settings_shared_css.html">
......
......@@ -60,6 +60,18 @@ Polymer({
*/
enableSubmit_: Boolean,
/**
* writeUma_ is a function that handles writing uma stats. It may be
* overridden for tests.
*
* @type {Function}
* @private
*/
writeUma_: {
type: Object,
value: function() { return settings.recordLockScreenProgress; }
},
/**
* The current step/subpage we are on.
* @private
......@@ -210,6 +222,7 @@ Polymer({
this.isConfirmStep_ = true;
this.onPinChange_();
this.$.pinKeyboard.focus();
this.writeUma_(LockScreenProgress.ENTER_PIN);
}
} else {
// onPinSubmit_ gets called if the user hits enter on the PIN keyboard.
......@@ -234,6 +247,7 @@ Polymer({
[chrome.quickUnlockPrivate.QuickUnlockMode.PIN],
[this.pinKeyboardValue_],
onSetModesCompleted.bind(this));
this.writeUma_(LockScreenProgress.CONFIRM_PIN);
}
},
......
......@@ -1160,6 +1160,14 @@
type="chrome_html"
flattenhtml="true"
allowexternalscript="true" />
<structure name="IDR_SETTINGS_PEOPLE_LOCK_SCREEN_CONSTANTS_JS"
file="people_page/lock_screen_constants.js"
type="chrome_html" />
<structure name="IDR_SETTINGS_PEOPLE_LOCK_SCREEN_CONSTANTS_HTML"
file="people_page/lock_screen_constants.html"
type="chrome_html"
flattenhtml="true"
allowexternalscript="true" />
<structure name="IDR_SETTINGS_PEOPLE_LOCK_STATE_BEHAVIOR_JS"
file="people_page/lock_state_behavior.js"
type="chrome_html" />
......
......@@ -125,6 +125,10 @@ constexpr char kPasswordPromptDialogHTMLPath[] =
"people_page/password_prompt_dialog.html";
constexpr char kPasswordPromptDialogJSPath[] =
"people_page/password_prompt_dialog.js";
constexpr char kLockScreenConstantsHTMLPath[] =
"people_page/lock_screen_constants.html";
constexpr char kLockScreenConstantsJSPath[] =
"people_page/lock_screen_constants.js";
constexpr char kLockStateBehaviorHTMLPath[] =
"people_page/lock_state_behavior.html";
constexpr char kLockStateBehaviorJSPath[] =
......@@ -257,6 +261,10 @@ void OptionsUIHTMLSource::CreateDataSourceMap() {
IDR_OPTIONS_PASSWORD_PROMPT_DIALOG_HTML;
path_to_idr_map_[kPasswordPromptDialogJSPath] =
IDR_OPTIONS_PASSWORD_PROMPT_DIALOG_JS;
path_to_idr_map_[kLockScreenConstantsHTMLPath] =
IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_HTML;
path_to_idr_map_[kLockScreenConstantsJSPath] =
IDR_OPTIONS_LOCK_SCREEN_CONSTANTS_JS;
path_to_idr_map_[kLockStateBehaviorHTMLPath] =
IDR_OPTIONS_LOCK_STATE_BEHAVIOR_HTML;
path_to_idr_map_[kLockStateBehaviorJSPath] =
......
......@@ -10,6 +10,7 @@
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/metrics_handler.h"
#include "chrome/browser/ui/webui/settings/about_handler.h"
#include "chrome/browser/ui/webui/settings/appearance_handler.h"
#include "chrome/browser/ui/webui/settings/browser_lifetime_handler.h"
......@@ -147,6 +148,9 @@ MdSettingsUI::MdSettingsUI(content::WebUI* web_ui, const GURL& url)
AddSettingsPageUIHandler(AboutHandler::Create(html_source, profile));
AddSettingsPageUIHandler(ResetSettingsHandler::Create(html_source, profile));
// Add the metrics handler to write uma stats.
web_ui->AddMessageHandler(new MetricsHandler());
// Add all settings resources.
for (size_t i = 0; i < kSettingsResourcesSize; ++i) {
html_source->AddResourcePath(kSettingsResources[i].name,
......
......@@ -197,6 +197,7 @@ CrSettingsPeoplePageQuickUnlockAuthenticateTest.prototype = {
extraLibraries: CrSettingsBrowserTest.prototype.extraLibraries.concat([
'../fake_chrome_event.js',
'fake_quick_unlock_private.js',
'fake_quick_unlock_uma.js',
'quick_unlock_authenticate_browsertest_chromeos.js'
]),
};
......@@ -227,6 +228,7 @@ CrSettingsPeoplePageLockScreenTest.prototype = {
'../fake_chrome_event.js',
'fake_quick_unlock_private.js',
'fake_settings_private.js',
'fake_quick_unlock_uma.js',
'quick_unlock_authenticate_browsertest_chromeos.js'
]),
};
......@@ -257,6 +259,7 @@ CrSettingsPeoplePageSetupPinDialogTest.prototype = {
'../fake_chrome_event.js',
'fake_quick_unlock_private.js',
'fake_settings_private.js',
'fake_quick_unlock_uma.js',
'quick_unlock_authenticate_browsertest_chromeos.js'
]),
};
......
// 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 Fake implementation of chrome histogram recording for testing.
*/
cr.define('settings', function() {
/**
* Fake of the chrome.quickUnlockUma.
* @constructor
*/
function FakeQuickUnlockUma() {
this.histogram = {};
for (var key in LockScreenProgress)
this.histogram[LockScreenProgress[key]] = 0;
}
FakeQuickUnlockUma.prototype = {
/**
* Update the histgoram at |key| by one.
* @param {LockScreenProgress} key
*/
recordProgress: function(key) {
if (!(key in this.histogram))
this.histogram[key] = 0;
this.histogram[key]++;
},
/**
* Get the value of the uma histogram at |key|.
* @param {LockScreenProgress} key
* @return {Number}
*/
getHistogramValue: function(key) {
return this.histogram[key];
}
};
return {FakeQuickUnlockUma: FakeQuickUnlockUma};
});
......@@ -6,6 +6,7 @@ cr.define('settings_people_page_quick_unlock', function() {
var element = null;
var quickUnlockPrivateApi = null;
var QuickUnlockMode = chrome.quickUnlockPrivate.QuickUnlockMode;
var fakeUma = null;
/**
* Returns if the element is visible.
......@@ -61,9 +62,11 @@ cr.define('settings_people_page_quick_unlock', function() {
PolymerTest.clearBody();
quickUnlockPrivateApi = new settings.FakeQuickUnlockPrivate();
fakeUma = new settings.FakeQuickUnlockUma();
element = document.createElement('settings-password-prompt-dialog');
element.quickUnlockPrivate_ = quickUnlockPrivateApi;
element.writeUma_ = fakeUma.recordProgress.bind(fakeUma);
document.body.appendChild(element);
passwordElement = getFromElement('#passwordInput');
......@@ -86,23 +89,29 @@ cr.define('settings_people_page_quick_unlock', function() {
assertDeepEquals([''], quickUnlockPrivateApi.credentials);
});
// A bad password does not provide an authenticated setModes object.
// A bad password does not provide an authenticated setModes object, and a
// entered password correctly uma should not be recorded.
test('InvalidPasswordDoesNotProvideAuthentication', function() {
quickUnlockPrivateApi.accountPassword = 'bar';
passwordElement.value = 'foo';
element.submitPassword_();
assertEquals(0, fakeUma.getHistogramValue(
LockScreenProgress.ENTER_PASSWORD_CORRECTLY));
assertFalse(!!element.setModes);
});
// A valid password provides an authenticated setModes object.
// A valid password provides an authenticated setModes object, and a
// entered password correctly uma should be recorded.
test('ValidPasswordProvidesAuthentication', function() {
quickUnlockPrivateApi.accountPassword = 'foo';
passwordElement.value = 'foo';
element.submitPassword_();
assertEquals(1, fakeUma.getHistogramValue(
LockScreenProgress.ENTER_PASSWORD_CORRECTLY));
assertTrue(!!element.setModes);
});
......@@ -198,6 +207,7 @@ cr.define('settings_people_page_quick_unlock', function() {
value: true
}];
fakeSettings = new settings.FakeSettingsPrivate(fakePrefs);
fakeUma = new settings.FakeQuickUnlockUma();
setLockScreenPref(true);
var prefElement = document.createElement('settings-prefs');
prefElement.initialize(fakeSettings);
......@@ -215,6 +225,7 @@ cr.define('settings_people_page_quick_unlock', function() {
element.settingsPrivate_ = fakeSettings;
element.quickUnlockPrivate_ = quickUnlockPrivateApi;
element.prefs = prefElement.prefs;
element.writeUma_ = fakeUma.recordProgress.bind(fakeUma);
document.body.appendChild(element);
Polymer.dom.flush();
......@@ -285,8 +296,11 @@ cr.define('settings_people_page_quick_unlock', function() {
assertDeepEquals([], quickUnlockPrivateApi.activeModes);
});
// Tapping the PIN configure button opens up the setup PIN dialog.
// Tapping the PIN configure button opens up the setup PIN dialog, and
// records a chose pin or password uma.
test('TappingConfigureOpensSetupPin', function() {
assertEquals(0, fakeUma.getHistogramValue(
LockScreenProgress.CHOOSE_PIN_OR_PASSWORD));
assertRadioButtonActive(passwordRadioButton);
MockInteractions.tap(pinPasswordRadioButton);
......@@ -296,6 +310,8 @@ cr.define('settings_people_page_quick_unlock', function() {
MockInteractions.tap(configureButton);
var setupPinDialog = getFromElement('#setupPin');
assertTrue(setupPinDialog.$.dialog.open);
assertEquals(1, fakeUma.getHistogramValue(
LockScreenProgress.CHOOSE_PIN_OR_PASSWORD));
});
});
}
......@@ -317,11 +333,13 @@ cr.define('settings_people_page_quick_unlock', function() {
PolymerTest.clearBody();
quickUnlockPrivateApi = new settings.FakeQuickUnlockPrivate();
fakeUma = new settings.FakeQuickUnlockUma();
// Create setup-pin element.
element = document.createElement('settings-setup-pin-dialog');
element.setModes =
quickUnlockPrivateApi.setModes.bind(quickUnlockPrivateApi, '');
element.writeUma_ = fakeUma.recordProgress.bind(fakeUma);
document.body.appendChild(element);
Polymer.dom.flush();
......@@ -438,14 +456,24 @@ cr.define('settings_people_page_quick_unlock', function() {
});
// Completing the flow results in a call to the quick unlock private API.
// Check that uma stats are called as expected.
test('SubmittingPinCallsQuickUnlockApi', function() {
// Entering the same (even weak) pin twice calls the quick unlock API
// and sets up a PIN.
assertEquals(0, fakeUma.getHistogramValue(
LockScreenProgress.ENTER_PIN));
assertEquals(0, fakeUma.getHistogramValue(
LockScreenProgress.CONFIRM_PIN));
pinKeyboard.value = '1111';
MockInteractions.tap(continueButton);
assertEquals(1, fakeUma.getHistogramValue(
LockScreenProgress.ENTER_PIN));
pinKeyboard.value = '1111';
MockInteractions.tap(continueButton);
assertEquals(1, fakeUma.getHistogramValue(
LockScreenProgress.CONFIRM_PIN));
assertDeepEquals(['PIN'], quickUnlockPrivateApi.activeModes);
assertDeepEquals(['1111'], quickUnlockPrivateApi.credentials);
});
......
......@@ -59950,6 +59950,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
<summary>The number of pinned tabs opened when a profile is loaded.</summary>
</histogram>
<histogram name="Settings.PinUnlockSetup" enum="LockScreenProgress">
<owner>sammiequon@chromium.org</owner>
<summary>
The users progress through the pin unlock setup wizard. Each type
corresponds to the user completeing a different stage of the setup wizard.
</summary>
</histogram>
<histogram name="Settings.RegisterProfilePrefsTime" units="ms">
<owner>rkaplow@chromium.org</owner>
<summary>
......@@ -93280,6 +93288,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
<int value="1" label="SinkNeverStarted"/>
</enum>
<enum name="LockScreenProgress" type="int">
<int value="0" label="Start screen lock"/>
<int value="1" label="Enter password correctly"/>
<int value="2" label="Choose pin or password"/>
<int value="3" label="Enter pin"/>
<int value="4" label="Confirm pin"/>
</enum>
<enum name="LoginConsumerWhitelist" type="int">
<int value="0" label="ANY_USER_ALLOWED">Any user can sign in</int>
<int value="1" label="ONLY_WHITELISTED_ALLOWED">Whitelisted users only</int>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment