Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / hotword / training_manager.js
blob15752eb1590cb1c0fc5f4960e807c4d900ba18b9
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() {
6   'use strict';
8   /**
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
13    * @constructor
14    * @extends {hotword.BaseSessionManager}
15    */
16   function TrainingManager(stateManager) {
17     /**
18      * Chrome event listeners. Saved so that they can be de-registered when
19      * hotwording is disabled.
20      * @private
21      */
22     this.finalizedSpeakerModelListener_ =
23         this.handleFinalizeSpeakerModel_.bind(this);
25     hotword.BaseSessionManager.call(this,
26                                     stateManager,
27                                     hotword.constants.SessionSource.TRAINING);
28   }
30   /**
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.
34    * @private
35    */
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,
43           {create: false},
44           TrainingManager.deleteFile_, TrainingManager.fileErrorHandler_);
45     }
46   };
48   /**
49    * Deletes a file.
50    * @param {FileEntry} fileEntry The FileEntry object.
51    * @private
52    */
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);
59         });
60       }
61       fileEntry.remove(function() {
62           hotword.debug('File removed: ' + fileEntry.fullPath);
63       }, TrainingManager.fileErrorHandler_);
64     }
65   };
67   /**
68    * Handles a failure event on mounting the file system event.
69    * @param {FileError} e The FileError object.
70    * @private
71    */
72   TrainingManager.fileErrorHandler_ = function(e) {
73       hotword.debug('File error: ' + e.code);
74   };
76   /**
77    * Handles a failure event on checking for the existence of the speaker model.
78    * @param {FileError} e The FileError object.
79    * @private
80    */
81   TrainingManager.sendNoSpeakerModelResponse_ = function(e) {
82     chrome.hotwordPrivate.speakerModelExistsResult(false);
83   };
85   /**
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.
89    * @private
90    */
91   TrainingManager.speakerModelExists_ = function(fs) {
92     fs.root.getFile(hotword.constants.SPEAKER_MODEL_FILE_NAME, {create: false},
93         TrainingManager.sendSpeakerModelExistsResponse_,
94         TrainingManager.sendNoSpeakerModelResponse_);
95   };
97   /**
98    * Sends a response through the HotwordPrivateApi indicating whether
99    * the speaker model exists.
100    * @param {FileEntry} fileEntry The FileEntry object.
101    * @private
102    */
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);
109         });
110       }
111     }
112     chrome.hotwordPrivate.speakerModelExistsResult(fileEntry.isFile);
113   };
115   /**
116    * Handles a request to delete the speaker model.
117    */
118   TrainingManager.handleDeleteSpeakerModel = function() {
119     window.webkitRequestFileSystem(PERSISTENT,
120         hotword.constants.FILE_SYSTEM_SIZE_BYTES,
121         TrainingManager.deleteFiles_,
122         TrainingManager.fileErrorHandler_);
123   };
125   /**
126    * Handles a request for the speaker model existence.
127    */
128   TrainingManager.handleSpeakerModelExists = function() {
129     window.webkitRequestFileSystem(PERSISTENT,
130         hotword.constants.FILE_SYSTEM_SIZE_BYTES,
131         TrainingManager.speakerModelExists_,
132         TrainingManager.fileErrorHandler_);
133   };
135   TrainingManager.prototype = {
136     __proto__: hotword.BaseSessionManager.prototype,
138     /** @override */
139      enabled: function() {
140        return this.stateManager.isTrainingEnabled();
141      },
143     /** @override */
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_);
153         }
154         this.startSession(hotword.constants.RecognizerStartMode.NEW_MODEL);
155       } else {
156         chrome.hotwordPrivate.onFinalizeSpeakerModel.removeListener(
157             this.finalizedSpeakerModelListener_);
158       }
159     },
161     /** @override */
162     handleHotwordTrigger: function(log) {
163       if (this.enabled()) {
164         hotword.BaseSessionManager.prototype.handleHotwordTrigger.call(
165             this, log);
166         this.startSession(hotword.constants.RecognizerStartMode.ADAPT_MODEL);
167       }
168     },
170     /** @override */
171     startSession: function(opt_mode) {
172       this.stateManager.startSession(
173           this.sessionSource_,
174           function() {
175             chrome.hotwordPrivate.setHotwordSessionState(true, function() {});
176           },
177           this.handleHotwordTrigger.bind(this),
178           this.handleSpeakerModelSaved_.bind(this),
179           opt_mode);
180     },
182     /**
183      * Handles a hotwordPrivate.onFinalizeSpeakerModel event.
184      * @private
185      */
186     handleFinalizeSpeakerModel_: function() {
187       if (this.enabled())
188         this.stateManager.finalizeSpeakerModel();
189     },
191     /**
192      * Handles a hotwordPrivate.onFinalizeSpeakerModel event.
193      * @private
194      */
195     handleSpeakerModelSaved_: function() {
196       if (this.enabled())
197         chrome.hotwordPrivate.notifySpeakerModelSaved();
198     },
199   };
201   return {
202     TrainingManager: TrainingManager
203   };