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

Side by Side Diff: chrome/browser/resources/hotword_audio_verification/flow.js

Issue 693433002: Hotword Audio Verification App: update training UI on hotword trigger. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@tp3-api
Patch Set: Created 6 years, 1 month 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 unified diff | Download patch
« no previous file with comments | « no previous file | chrome/browser/resources/hotword_audio_verification/main.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 (function() { 5 (function() {
6 6
7 // Correspond to steps in the hotword opt-in flow. 7 // Correspond to steps in the hotword opt-in flow.
8 /** @const */ var HOTWORD_AUDIO_HISTORY = 'hotword-audio-history-container'; 8 /** @const */ var HOTWORD_AUDIO_HISTORY = 'hotword-audio-history-container';
9 /** @const */ var HOTWORD_ONLY_START = 'hotword-only-container'; 9 /** @const */ var HOTWORD_ONLY_START = 'hotword-only-container';
10 /** @const */ var AUDIO_HISTORY_START = 'audio-history-container'; 10 /** @const */ var AUDIO_HISTORY_START = 'audio-history-container';
11 /** @const */ var SPEECH_TRAINING = 'speech-training-container'; 11 /** @const */ var SPEECH_TRAINING = 'speech-training-container';
12 /** @const */ var FINISHED = 'finished-container'; 12 /** @const */ var FINISHED = 'finished-container';
13 13
14 /** 14 /**
15 * These flows correspond to the three LaunchModes as defined in 15 * These flows correspond to the three LaunchModes as defined in
16 * chrome/browser/search/hotword_service.h and should be kept in sync 16 * chrome/browser/search/hotword_service.h and should be kept in sync
17 * with them. 17 * with them.
18 * @const 18 * @const
19 */ 19 */
20 var FLOWS = [ 20 var FLOWS = [
21 // TODO(kcarattini): Remove the first flow, since we will not be
22 // managing the Audio History Setting in Chrome anymore.
23 [AUDIO_HISTORY_START],
24 [HOTWORD_ONLY_START, FINISHED], 21 [HOTWORD_ONLY_START, FINISHED],
25 [HOTWORD_AUDIO_HISTORY, SPEECH_TRAINING, FINISHED], 22 [HOTWORD_AUDIO_HISTORY, SPEECH_TRAINING, FINISHED],
26 [SPEECH_TRAINING, FINISHED] 23 [SPEECH_TRAINING, FINISHED]
27 ]; 24 ];
28 25
29 /** 26 /**
27 * The launch mode. This enum needs to be kept in sync with that of
28 * the same name in hotword_service.h.
29 * @enum {number}
30 */
31 var LaunchMode = {
32 HOTWORD_ONLY: 0,
33 HOTWORD_AND_AUDIO_HISTORY: 1,
34 RETRAIN: 2
35 };
36
37 /**
30 * Class to control the page flow of the always-on hotword and 38 * Class to control the page flow of the always-on hotword and
31 * Audio History opt-in process. 39 * Audio History opt-in process.
32 * @constructor 40 * @constructor
33 */ 41 */
34 function Flow() { 42 function Flow() {
35 this.currentStepIndex_ = -1; 43 this.currentStepIndex_ = -1;
36 this.currentFlow_ = []; 44 this.currentFlow_ = [];
45
46 /**
47 * Whether this flow is currently in the process of training a voice model.
48 * @private {LaunchMode}
49 */
50 this.launchMode_ = LaunchMode.HOTWORD_AND_AUDIO_HISTORY;
51
52 /**
53 * Whether this flow is currently in the process of training a voice model.
54 * @private {boolean}
55 */
56 this.training_ = false;
57
58 /**
59 * Prefix of the element ids for the page that is currently training.
60 * @private {string}
61 */
62 this.trainingPagePrefix_ = '';
37 } 63 }
38 64
39 /** 65 /**
40 * Advances the current step. 66 * Advances the current step.
41 */ 67 */
42 Flow.prototype.advanceStep = function() { 68 Flow.prototype.advanceStep = function() {
Dan Beam 2014/10/30 02:57:55 what happens if this is called while training? do
kcarattini 2014/10/30 05:56:18 It shouldn't matter if this is called while traini
43 this.currentStepIndex_++; 69 this.currentStepIndex_++;
44 if (this.currentStepIndex_ < this.currentFlow_.length) 70 if (this.currentStepIndex_ < this.currentFlow_.length)
45 this.showStep_.apply(this); 71 this.showStep_.apply(this);
46 }; 72 };
47 73
48 /** 74 /**
49 * Gets the appropriate flow and displays its first page. 75 * Gets the appropriate flow and displays its first page.
50 */ 76 */
51 Flow.prototype.startFlow = function() { 77 Flow.prototype.startFlow = function() {
52 if (chrome.hotwordPrivate && chrome.hotwordPrivate.getLaunchState) 78 if (chrome.hotwordPrivate && chrome.hotwordPrivate.getLaunchState)
53 chrome.hotwordPrivate.getLaunchState(this.startFlowForMode_.bind(this)); 79 chrome.hotwordPrivate.getLaunchState(this.startFlowForMode_.bind(this));
54 }; 80 };
55 81
82 /**
83 * Starts the training process.
84 */
85 Flow.prototype.startTraining = function() {
Dan Beam 2014/10/30 02:57:54 should we check that !this.training_?
kcarattini 2014/10/30 05:56:17 Done.
86 this.training_ = true;
87 if (this.launchMode_ == LaunchMode.HOTWORD_ONLY ||
88 this.launchMode_ == LaunchMode.RETRAIN) {
89 this.trainingPagePrefix_ = 'hotword-only';
90 }
91 if (this.launchMode_ == LaunchMode.HOTWORD_AND_AUDIO_HISTORY)
92 this.trainingPagePrefix_ = 'speech-training';
93
94 if (chrome.hotwordPrivate.onHotwordTriggered)
Dan Beam 2014/10/30 02:57:55 curlies
kcarattini 2014/10/30 05:56:18 Done.
95 chrome.hotwordPrivate.onHotwordTriggered.addListener(
96 this.handleHotwordTrigger.bind(this));
97 if (chrome.hotwordPrivate.startTraining)
98 chrome.hotwordPrivate.startTraining();
99 };
100
101 /**
102 * Stops the training process.
103 */
104 Flow.prototype.stopTraining = function() {
Dan Beam 2014/10/30 02:57:54 should this actually be a check to ensure this.tra
kcarattini 2014/10/30 05:56:18 No, since this is called from all events that clos
105 if (this.training_) {
106 this.training_ = false;
107 if (chrome.hotwordPrivate.onHotwordTriggered) {
108 chrome.hotwordPrivate.onHotwordTriggered.
109 removeListener(this.handleHotwordTrigger);
110 }
111 if (chrome.hotwordPrivate.stopTraining)
112 chrome.hotwordPrivate.stopTraining();
113 }
114 };
115
116 /**
117 * Handles the speaker model finalized event.
118 */
119 Flow.prototype.onSpeakerModelFinalized = function() {
120 this.stopTraining();
121
122 if (chrome.hotwordPrivate.setAudioLoggingEnabled)
123 chrome.hotwordPrivate.setAudioLoggingEnabled(true, function() {});
124
125 if (chrome.hotwordPrivate.setHotwordAlwaysOnSearchEnabled) {
126 chrome.hotwordPrivate.setHotwordAlwaysOnSearchEnabled(true,
127 this.advanceStep.bind(this));
128 }
129 };
130
131 /**
132 * Completes the training process.
Dan Beam 2014/10/30 02:57:54 @private, finalizeSpeakerModel_
kcarattini 2014/10/30 05:56:17 Done.
133 */
134 Flow.prototype.finalizeSpeakerModel = function() {
135 if (this.training_) {
Dan Beam 2014/10/30 02:57:54 nit: if (!this.training_) return;
kcarattini 2014/10/30 05:56:18 Done.
136 if (chrome.hotwordPrivate.finalizeSpeakerModel)
137 chrome.hotwordPrivate.finalizeSpeakerModel();
138
139 // TODO(kcarattini): Implement a notification that speaker model has been
140 // finalized instead of setting a timeout.
141 setTimeout(this.onSpeakerModelFinalized.bind(this), 2000);
142 }
143 };
144
145 /**
146 * Handles a hotword trigger event and updates the training UI.
Dan Beam 2014/10/30 02:57:54 handleHotwordTrigger_, @private
kcarattini 2014/10/30 05:56:17 Done.
147 */
148 Flow.prototype.handleHotwordTrigger = function() {
149 var curStep =
150 $(this.trainingPagePrefix_ + '-training').querySelector('.listening');
151 // TODO(kcarattini): Localize this string.
152 curStep.querySelector('.text').textContent = 'Recorded';
153 curStep.classList.remove('listening');
154 curStep.classList.add('recorded');
155
156 var steps =
157 $(this.trainingPagePrefix_ + '-training').querySelectorAll('.train');
158 var index = Array.prototype.indexOf.call(steps, curStep);
159 if (steps[index + 1]) {
160 steps[index + 1].classList.remove('not-started');
161 steps[index + 1].classList.add('listening');
162 return;
163 }
Dan Beam 2014/10/30 02:57:54 // Only the last step makes it here. (or somethin
kcarattini 2014/10/30 05:56:17 Done.
164
165 // Update the 'Cancel' button.
166 var buttonElem = $(this.trainingPagePrefix_ + '-cancel-button');
167 // TODO(kcarattini): Localize this string.
168 buttonElem.textContent = 'Please wait ...';
169 buttonElem.classList.add('grayed-out');
170 buttonElem.classList.remove('finish-button');
171
172 this.finalizeSpeakerModel();
173 };
174
56 // ---- private methods: 175 // ---- private methods:
57 176
58 /** 177 /**
59 * Gets and starts the appropriate flow for the launch mode. 178 * Gets and starts the appropriate flow for the launch mode.
Dan Beam 2014/10/30 02:57:54 @param {WhateverTypeStateIs} state Doc comment abo
kcarattini 2014/10/30 05:56:18 Done.
60 * @private 179 * @private
61 */ 180 */
62 Flow.prototype.startFlowForMode_ = function(state) { 181 Flow.prototype.startFlowForMode_ = function(state) {
182 this.launchMode_ = state.launchMode;
63 assert(state.launchMode >= 0 && state.launchMode < FLOWS.length, 183 assert(state.launchMode >= 0 && state.launchMode < FLOWS.length,
64 'Invalid Launch Mode.'); 184 'Invalid Launch Mode.');
65 this.currentFlow_ = FLOWS[state.launchMode]; 185 this.currentFlow_ = FLOWS[state.launchMode];
66 this.advanceStep(); 186 this.advanceStep();
187 // If the flow begins with a a training step, then start the training flow.
188 if (state.launchMode == LaunchMode.HOTWORD_ONLY ||
189 state.launchMode == LaunchMode.SPEECH_TRAINING)
Dan Beam 2014/10/30 02:57:54 curlies
kcarattini 2014/10/30 05:56:17 Done.
190 this.startTraining();
67 }; 191 };
68 192
69 /** 193 /**
70 * Displays the current step. If the current step is not the first step, 194 * Displays the current step. If the current step is not the first step,
71 * also hides the previous step. 195 * also hides the previous step.
72 * @private 196 * @private
73 */ 197 */
74 Flow.prototype.showStep_ = function() { 198 Flow.prototype.showStep_ = function() {
75 var currentStep = this.currentFlow_[this.currentStepIndex_]; 199 var currentStep = this.currentFlow_[this.currentStepIndex_];
76 var previousStep = null; 200 var previousStep = null;
77 if (this.currentStepIndex_ > 0) 201 if (this.currentStepIndex_ > 0)
78 previousStep = this.currentFlow_[this.currentStepIndex_ - 1]; 202 previousStep = this.currentFlow_[this.currentStepIndex_ - 1];
79 203
80 if (previousStep) 204 if (previousStep)
81 document.getElementById(previousStep).hidden = true; 205 document.getElementById(previousStep).hidden = true;
82 206
83 document.getElementById(currentStep).hidden = false; 207 document.getElementById(currentStep).hidden = false;
84 }; 208 };
85 209
86 window.Flow = Flow; 210 window.Flow = Flow;
87 })(); 211 })();
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/hotword_audio_verification/main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698