OLD | NEW |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 cr.define('hotword', function() { | 5 cr.define('hotword', function() { |
6 'use strict'; | 6 'use strict'; |
7 | 7 |
8 /** | 8 /** |
9 * Class to manage hotwording state. Starts/stops the hotword detector based | 9 * Class to manage hotwording state. Starts/stops the hotword detector based |
10 * on user settings, session requests, and any other factors that play into | 10 * on user settings, session requests, and any other factors that play into |
(...skipping 13 matching lines...) Expand all Loading... |
24 * @private {?chrome.hotwordPrivate.StatusDetails} | 24 * @private {?chrome.hotwordPrivate.StatusDetails} |
25 */ | 25 */ |
26 this.hotwordStatus_ = null; | 26 this.hotwordStatus_ = null; |
27 | 27 |
28 /** | 28 /** |
29 * NaCl plugin manager. | 29 * NaCl plugin manager. |
30 * @private {?hotword.NaClManager} | 30 * @private {?hotword.NaClManager} |
31 */ | 31 */ |
32 this.pluginManager_ = null; | 32 this.pluginManager_ = null; |
33 | 33 |
| 34 /** |
| 35 * Source of the current hotword session. |
| 36 * @private {?hotword.constants.SessionSource} |
| 37 */ |
| 38 this.sessionSource_ = null; |
| 39 |
| 40 /** |
| 41 * Callback to run when the hotword detector has successfully started. |
| 42 * @private {!function()} |
| 43 */ |
| 44 this.sessionStartedCb_ = null; |
| 45 |
34 // Get the initial status. | 46 // Get the initial status. |
35 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); | 47 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); |
36 } | 48 } |
37 | 49 |
38 /** | 50 /** |
39 * @enum {number} | 51 * @enum {number} |
40 * @private | 52 * @private |
41 */ | 53 */ |
42 StateManager.State_ = { | 54 StateManager.State_ = { |
43 STOPPED: 0, | 55 STOPPED: 0, |
(...skipping 21 matching lines...) Expand all Loading... |
65 handleStatus_: function(status) { | 77 handleStatus_: function(status) { |
66 this.hotwordStatus_ = status; | 78 this.hotwordStatus_ = status; |
67 this.updateStateFromStatus_(); | 79 this.updateStateFromStatus_(); |
68 }, | 80 }, |
69 | 81 |
70 /** | 82 /** |
71 * Updates state based on the current status. | 83 * Updates state based on the current status. |
72 * @private | 84 * @private |
73 */ | 85 */ |
74 updateStateFromStatus_: function() { | 86 updateStateFromStatus_: function() { |
| 87 if (!this.hotwordStatus_) |
| 88 return; |
| 89 |
75 if (this.hotwordStatus_.enabled) { | 90 if (this.hotwordStatus_.enabled) { |
76 // Hotwording is enabled. | 91 // Start the detector if there's a session, and shut it down if there |
77 // TODO(amistry): Have a separate alwaysOnEnabled flag. For now, treat | 92 // isn't. |
78 // "enabled" as "always on enabled". | 93 // TODO(amistry): Support stacking sessions. This can happen when the |
79 this.startDetector_(); | 94 // user opens google.com or the NTP, then opens the launcher. Opening |
| 95 // google.com will create one session, and opening the launcher will |
| 96 // create the second. Closing the launcher should re-activate the |
| 97 // google.com session. |
| 98 // NOTE(amistry): With always-on, we want a different behaviour with |
| 99 // sessions since the detector should always be running. The exception |
| 100 // being when the user triggers by saying 'Ok Google'. In that case, the |
| 101 // detector stops, so starting/stopping the launcher session should |
| 102 // restart the detector. |
| 103 if (this.sessionSource_) |
| 104 this.startDetector_(); |
| 105 else |
| 106 this.shutdownDetector_(); |
80 } else { | 107 } else { |
81 // Not enabled. Shut down if running. | 108 // Not enabled. Shut down if running. |
82 this.shutdownDetector_(); | 109 this.shutdownDetector_(); |
83 } | 110 } |
84 }, | 111 }, |
85 | 112 |
86 /** | 113 /** |
87 * Starts the hotword detector. | 114 * Starts the hotword detector. |
88 * @private | 115 * @private |
89 */ | 116 */ |
(...skipping 29 matching lines...) Expand all Loading... |
119 this.shutdownPluginManager_(); | 146 this.shutdownPluginManager_(); |
120 } | 147 } |
121 }.bind(this), | 148 }.bind(this), |
122 function(error) { | 149 function(error) { |
123 this.state_ = State_.ERROR; | 150 this.state_ = State_.ERROR; |
124 this.pluginManager_ = null; | 151 this.pluginManager_ = null; |
125 }.bind(this)); | 152 }.bind(this)); |
126 }.bind(this)); | 153 }.bind(this)); |
127 } else if (this.state_ != State_.STARTING) { | 154 } else if (this.state_ != State_.STARTING) { |
128 // Don't try to start a starting detector. | 155 // Don't try to start a starting detector. |
129 this.state_ = State_.RUNNING; | 156 this.startRecognizer_(); |
130 this.pluginManager_.startRecognizer(); | |
131 } | 157 } |
132 }, | 158 }, |
133 | 159 |
134 /** | 160 /** |
| 161 * Start the recognizer plugin. Assumes the plugin has been loaded and is |
| 162 * ready to start. |
| 163 * @private |
| 164 */ |
| 165 startRecognizer_: function() { |
| 166 assert(this.pluginManager_); |
| 167 if (this.state_ != State_.RUNNING) { |
| 168 this.state_ = State_.RUNNING; |
| 169 this.pluginManager_.startRecognizer(); |
| 170 } |
| 171 if (this.sessionStartedCb_) { |
| 172 this.sessionStartedCb_(); |
| 173 this.sessionStartedCb_ = null; |
| 174 } |
| 175 }, |
| 176 |
| 177 /** |
135 * Shuts down and removes the plugin manager, if it exists. | 178 * Shuts down and removes the plugin manager, if it exists. |
136 * @private | 179 * @private |
137 */ | 180 */ |
138 shutdownPluginManager_: function() { | 181 shutdownPluginManager_: function() { |
139 if (this.pluginManager_) { | 182 if (this.pluginManager_) { |
140 this.pluginManager_.shutdown(); | 183 this.pluginManager_.shutdown(); |
141 this.pluginManager_ = null; | 184 this.pluginManager_ = null; |
142 } | 185 } |
143 }, | 186 }, |
144 | 187 |
(...skipping 11 matching lines...) Expand all Loading... |
156 * @private | 199 * @private |
157 */ | 200 */ |
158 onReady_: function() { | 201 onReady_: function() { |
159 if (this.state_ != State_.STARTING) { | 202 if (this.state_ != State_.STARTING) { |
160 // At this point, we should not be in the RUNNING state. Doing so would | 203 // At this point, we should not be in the RUNNING state. Doing so would |
161 // imply the hotword detector was started without being ready. | 204 // imply the hotword detector was started without being ready. |
162 assert(this.state_ != State_.RUNNING); | 205 assert(this.state_ != State_.RUNNING); |
163 this.shutdownPluginManager_(); | 206 this.shutdownPluginManager_(); |
164 return; | 207 return; |
165 } | 208 } |
166 this.state_ = State_.RUNNING; | 209 this.startRecognizer_(); |
167 this.pluginManager_.startRecognizer(); | |
168 }, | 210 }, |
169 | 211 |
170 /** | 212 /** |
171 * Handle an error from the hotword plugin. | 213 * Handle an error from the hotword plugin. |
172 * @private | 214 * @private |
173 */ | 215 */ |
174 onError_: function() { | 216 onError_: function() { |
175 this.state_ = State_.ERROR; | 217 this.state_ = State_.ERROR; |
176 this.shutdownPluginManager_(); | 218 this.shutdownPluginManager_(); |
177 }, | 219 }, |
178 | 220 |
179 /** | 221 /** |
180 * Handle hotword triggering. | 222 * Handle hotword triggering. |
181 * @private | 223 * @private |
182 */ | 224 */ |
183 onTrigger_: function() { | 225 onTrigger_: function() { |
184 assert(this.pluginManager_); | 226 assert(this.pluginManager_); |
185 // Detector implicitly stops when the hotword is detected. | 227 // Detector implicitly stops when the hotword is detected. |
186 this.state_ = State_.STOPPED; | 228 this.state_ = State_.STOPPED; |
187 | 229 |
188 chrome.hotwordPrivate.notifyHotwordRecognition('search', function() {}); | 230 chrome.hotwordPrivate.notifyHotwordRecognition('search', function() {}); |
| 231 |
| 232 // Implicitly clear the session. A session needs to be started in order to |
| 233 // restart the detector. |
| 234 this.sessionSource_ = null; |
| 235 this.sessionStartedCb_ = null; |
| 236 }, |
| 237 |
| 238 /** |
| 239 * Start a hotwording session. |
| 240 * @param {!hotword.constants.SessionSource} source Source of the hotword |
| 241 * session request. |
| 242 * @param {!function()} startedCb Callback invoked when the session has |
| 243 * been started successfully. |
| 244 */ |
| 245 startSession: function(source, startedCb) { |
| 246 this.sessionSource_ = source; |
| 247 this.sessionStartedCb_ = startedCb; |
| 248 this.updateStateFromStatus_(); |
| 249 }, |
| 250 |
| 251 /** |
| 252 * Stops a hotwording session. |
| 253 * @param {!hotword.constants.SessionSource} source Source of the hotword |
| 254 * session request. |
| 255 */ |
| 256 stopSession: function(source) { |
| 257 this.sessionSource_ = null; |
| 258 this.sessionStartedCb_ = null; |
| 259 this.updateStateFromStatus_(); |
189 } | 260 } |
190 }; | 261 }; |
191 | 262 |
192 return { | 263 return { |
193 StateManager: StateManager | 264 StateManager: StateManager |
194 }; | 265 }; |
195 }); | 266 }); |
OLD | NEW |