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
3 // found in the LICENSE file.
5 cr.define('hotword', function() {
9 * Class used to manage speaker training. Starts a hotwording session
10 * if training is on, and automatically restarts the detector when a
11 * a hotword is triggered.
12 * @param {!hotword.StateManager} stateManager
14 * @extends {hotword.BaseSessionManager}
16 function TrainingManager(stateManager) {
18 * Chrome event listeners. Saved so that they can be de-registered when
19 * hotwording is disabled.
22 this.finalizedSpeakerModelListener_ =
23 this.handleFinalizeSpeakerModel_.bind(this);
25 hotword.BaseSessionManager.call(this,
27 hotword.constants.SessionSource.TRAINING);
31 * Handles a success event on mounting the file system event and deletes
32 * the user data files.
33 * @param {FileSystem} fs The FileSystem object.
36 TrainingManager.deleteFiles_ = function(fs) {
37 fs.root.getFile(hotword.constants.SPEAKER_MODEL_FILE_NAME, {create: false},
38 TrainingManager.deleteFile_, TrainingManager.fileErrorHandler_);
40 for (var i = 0; i < hotword.constants.NUM_TRAINING_UTTERANCES; ++i) {
41 fs.root.getFile(hotword.constants.UTTERANCE_FILE_PREFIX + i +
42 hotword.constants.UTTERANCE_FILE_EXTENSION,
44 TrainingManager.deleteFile_, TrainingManager.fileErrorHandler_);
50 * @param {FileEntry} fileEntry The FileEntry object.
53 TrainingManager.deleteFile_ = function(fileEntry) {
54 if (fileEntry.isFile) {
55 hotword.debug('File found: ' + fileEntry.fullPath);
56 if (hotword.DEBUG || window.localStorage['hotword.DEBUG']) {
57 fileEntry.getMetadata(function(md) {
58 hotword.debug('File size: ' + md.size);
61 fileEntry.remove(function() {
62 hotword.debug('File removed: ' + fileEntry.fullPath);
63 }, TrainingManager.fileErrorHandler_);
68 * Handles a failure event on mounting the file system event.
69 * @param {FileError} e The FileError object.
72 TrainingManager.fileErrorHandler_ = function(e) {
73 hotword.debug('File error: ' + e.code);
77 * Handles a failure event on checking for the existence of the speaker model.
78 * @param {FileError} e The FileError object.
81 TrainingManager.sendNoSpeakerModelResponse_ = function(e) {
82 chrome.hotwordPrivate.speakerModelExistsResult(false);
86 * Handles a success event on mounting the file system and checks for the
87 * existence of the speaker model.
88 * @param {FileSystem} fs The FileSystem object.
91 TrainingManager.speakerModelExists_ = function(fs) {
92 fs.root.getFile(hotword.constants.SPEAKER_MODEL_FILE_NAME, {create: false},
93 TrainingManager.sendSpeakerModelExistsResponse_,
94 TrainingManager.sendNoSpeakerModelResponse_);
98 * Sends a response through the HotwordPrivateApi indicating whether
99 * the speaker model exists.
100 * @param {FileEntry} fileEntry The FileEntry object.
103 TrainingManager.sendSpeakerModelExistsResponse_ = function(fileEntry) {
104 if (fileEntry.isFile) {
105 hotword.debug('File found: ' + fileEntry.fullPath);
106 if (hotword.DEBUG || window.localStorage['hotword.DEBUG']) {
107 fileEntry.getMetadata(function(md) {
108 hotword.debug('File size: ' + md.size);
112 chrome.hotwordPrivate.speakerModelExistsResult(fileEntry.isFile);
116 * Handles a request to delete the speaker model.
118 TrainingManager.handleDeleteSpeakerModel = function() {
119 window.webkitRequestFileSystem(PERSISTENT,
120 hotword.constants.FILE_SYSTEM_SIZE_BYTES,
121 TrainingManager.deleteFiles_,
122 TrainingManager.fileErrorHandler_);
126 * Handles a request for the speaker model existence.
128 TrainingManager.handleSpeakerModelExists = function() {
129 window.webkitRequestFileSystem(PERSISTENT,
130 hotword.constants.FILE_SYSTEM_SIZE_BYTES,
131 TrainingManager.speakerModelExists_,
132 TrainingManager.fileErrorHandler_);
135 TrainingManager.prototype = {
136 __proto__: hotword.BaseSessionManager.prototype,
139 enabled: function() {
140 return this.stateManager.isTrainingEnabled();
144 updateListeners: function() {
145 hotword.BaseSessionManager.prototype.updateListeners.call(this);
147 if (this.enabled()) {
148 // Detect when the speaker model needs to be finalized.
149 if (!chrome.hotwordPrivate.onFinalizeSpeakerModel.hasListener(
150 this.finalizedSpeakerModelListener_)) {
151 chrome.hotwordPrivate.onFinalizeSpeakerModel.addListener(
152 this.finalizedSpeakerModelListener_);
154 this.startSession(hotword.constants.RecognizerStartMode.NEW_MODEL);
156 chrome.hotwordPrivate.onFinalizeSpeakerModel.removeListener(
157 this.finalizedSpeakerModelListener_);
162 handleHotwordTrigger: function(log) {
163 if (this.enabled()) {
164 hotword.BaseSessionManager.prototype.handleHotwordTrigger.call(
166 this.startSession(hotword.constants.RecognizerStartMode.ADAPT_MODEL);
171 startSession: function(opt_mode) {
172 this.stateManager.startSession(
175 chrome.hotwordPrivate.setHotwordSessionState(true, function() {});
177 this.handleHotwordTrigger.bind(this),
178 this.handleSpeakerModelSaved_.bind(this),
183 * Handles a hotwordPrivate.onFinalizeSpeakerModel event.
186 handleFinalizeSpeakerModel_: function() {
188 this.stateManager.finalizeSpeakerModel();
192 * Handles a hotwordPrivate.onFinalizeSpeakerModel event.
195 handleSpeakerModelSaved_: function() {
197 chrome.hotwordPrivate.notifySpeakerModelSaved();
202 TrainingManager: TrainingManager