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