Index: chrome/browser/resources/hotword_audio_verification/flow.js |
diff --git a/chrome/browser/resources/hotword_audio_verification/flow.js b/chrome/browser/resources/hotword_audio_verification/flow.js |
index 635456a06650e4a47640fa85cbcd4ad929572492..f6aff9958cf91284abfc816527003c38b4729afb 100644 |
--- a/chrome/browser/resources/hotword_audio_verification/flow.js |
+++ b/chrome/browser/resources/hotword_audio_verification/flow.js |
@@ -18,15 +18,23 @@ |
* @const |
*/ |
var FLOWS = [ |
- // TODO(kcarattini): Remove the first flow, since we will not be |
- // managing the Audio History Setting in Chrome anymore. |
- [AUDIO_HISTORY_START], |
[HOTWORD_ONLY_START, FINISHED], |
[HOTWORD_AUDIO_HISTORY, SPEECH_TRAINING, FINISHED], |
[SPEECH_TRAINING, FINISHED] |
]; |
/** |
+ * The launch mode. This enum needs to be kept in sync with that of |
+ * the same name in hotword_service.h. |
+ * @enum {number} |
+ */ |
+ var LaunchMode = { |
+ HOTWORD_ONLY: 0, |
+ HOTWORD_AND_AUDIO_HISTORY: 1, |
+ RETRAIN: 2 |
+ }; |
+ |
+ /** |
* Class to control the page flow of the always-on hotword and |
* Audio History opt-in process. |
* @constructor |
@@ -34,6 +42,24 @@ |
function Flow() { |
this.currentStepIndex_ = -1; |
this.currentFlow_ = []; |
+ |
+ /** |
+ * Whether this flow is currently in the process of training a voice model. |
+ * @private {LaunchMode} |
+ */ |
+ this.launchMode_ = LaunchMode.HOTWORD_AND_AUDIO_HISTORY; |
+ |
+ /** |
+ * Whether this flow is currently in the process of training a voice model. |
+ * @private {boolean} |
+ */ |
+ this.training_ = false; |
+ |
+ /** |
+ * Prefix of the element ids for the page that is currently training. |
+ * @private {string} |
+ */ |
+ this.trainingPagePrefix_ = ''; |
} |
/** |
@@ -53,17 +79,127 @@ |
chrome.hotwordPrivate.getLaunchState(this.startFlowForMode_.bind(this)); |
}; |
+ /** |
+ * Starts the training process. |
+ */ |
+ Flow.prototype.startTraining = function() { |
+ // Don't start a training session if one already exists. |
+ if (this.training_) |
+ return; |
+ |
+ this.training_ = true; |
+ if (this.launchMode_ == LaunchMode.HOTWORD_ONLY || |
+ this.launchMode_ == LaunchMode.RETRAIN) { |
+ this.trainingPagePrefix_ = 'hotword-only'; |
+ } |
+ if (this.launchMode_ == LaunchMode.HOTWORD_AND_AUDIO_HISTORY) |
+ this.trainingPagePrefix_ = 'speech-training'; |
Dan Beam
2014/10/30 22:25:35
maybe this code should be:
switch (this.launchM
kcarattini
2014/10/31 00:00:43
Done.
|
+ |
+ if (chrome.hotwordPrivate.onHotwordTriggered) { |
+ chrome.hotwordPrivate.onHotwordTriggered.addListener( |
+ this.handleHotwordTrigger_.bind(this)); |
+ } |
+ if (chrome.hotwordPrivate.startTraining) |
+ chrome.hotwordPrivate.startTraining(); |
+ }; |
+ |
+ /** |
+ * Stops the training process. |
+ */ |
+ Flow.prototype.stopTraining = function() { |
+ if (!this.training_) |
+ return; |
+ |
+ this.training_ = false; |
+ if (chrome.hotwordPrivate.onHotwordTriggered) { |
+ chrome.hotwordPrivate.onHotwordTriggered. |
+ removeListener(this.handleHotwordTrigger_); |
+ } |
+ if (chrome.hotwordPrivate.stopTraining) |
+ chrome.hotwordPrivate.stopTraining(); |
rpetterson
2014/10/30 17:13:13
indent
kcarattini
2014/10/31 00:00:43
Done.
|
+ }; |
+ |
+ /** |
+ * Handles the speaker model finalized event. |
+ */ |
+ Flow.prototype.onSpeakerModelFinalized = function() { |
+ this.stopTraining(); |
+ |
+ if (chrome.hotwordPrivate.setAudioLoggingEnabled) |
+ chrome.hotwordPrivate.setAudioLoggingEnabled(true, function() {}); |
rpetterson
2014/10/30 17:13:13
indent
kcarattini
2014/10/31 00:00:43
Done.
|
+ |
+ if (chrome.hotwordPrivate.setHotwordAlwaysOnSearchEnabled) { |
+ chrome.hotwordPrivate.setHotwordAlwaysOnSearchEnabled(true, |
+ this.advanceStep.bind(this)); |
+ } |
+ }; |
+ |
// ---- private methods: |
/** |
+ * Completes the training process. |
+ * @private |
+ */ |
+ Flow.prototype.finalizeSpeakerModel_ = function() { |
+ if (!this.training_) |
+ return; |
+ |
+ if (chrome.hotwordPrivate.finalizeSpeakerModel) |
+ chrome.hotwordPrivate.finalizeSpeakerModel(); |
+ |
+ // TODO(kcarattini): Implement a notification that speaker model has been |
+ // finalized instead of setting a timeout. |
+ setTimeout(this.onSpeakerModelFinalized.bind(this), 2000); |
+ }; |
+ |
+ /** |
+ * Handles a hotword trigger event and updates the training UI. |
+ * @private |
+ */ |
+ Flow.prototype.handleHotwordTrigger_ = function() { |
+ var curStep = |
+ $(this.trainingPagePrefix_ + '-training').querySelector('.listening'); |
+ // TODO(kcarattini): Localize this string. |
+ curStep.querySelector('.text').textContent = 'Recorded'; |
+ curStep.classList.remove('listening'); |
+ curStep.classList.add('recorded'); |
+ |
+ var steps = |
+ $(this.trainingPagePrefix_ + '-training').querySelectorAll('.train'); |
+ var index = Array.prototype.indexOf.call(steps, curStep); |
+ if (steps[index + 1]) { |
+ steps[index + 1].classList.remove('not-started'); |
+ steps[index + 1].classList.add('listening'); |
+ return; |
+ } |
+ |
+ // Only the last step makes it here. |
+ var buttonElem = $(this.trainingPagePrefix_ + '-cancel-button'); |
+ // TODO(kcarattini): Localize this string. |
+ buttonElem.textContent = 'Please wait ...'; |
+ buttonElem.classList.add('grayed-out'); |
+ buttonElem.classList.remove('finish-button'); |
+ |
+ this.finalizeSpeakerModel_(); |
+ }; |
+ |
+ /** |
* Gets and starts the appropriate flow for the launch mode. |
+ * @param {chrome.hotwordPrivate.LaunchState} state Launch state of the |
+ * Hotword Audio Verification App. |
* @private |
*/ |
Flow.prototype.startFlowForMode_ = function(state) { |
+ this.launchMode_ = state.launchMode; |
assert(state.launchMode >= 0 && state.launchMode < FLOWS.length, |
'Invalid Launch Mode.'); |
this.currentFlow_ = FLOWS[state.launchMode]; |
this.advanceStep(); |
+ // If the flow begins with a a training step, then start the training flow. |
+ if (state.launchMode == LaunchMode.HOTWORD_ONLY || |
+ state.launchMode == LaunchMode.SPEECH_TRAINING) { |
+ this.startTraining(); |
+ } |
}; |
/** |