| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 * Trivial container class for session information. | 9 * Trivial container class for session information. |
| 10 * @param {!hotword.constants.SessionSource} source Source of the hotword | 10 * @param {!hotword.constants.SessionSource} source Source of the hotword |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 * @private | 95 * @private |
| 96 */ | 96 */ |
| 97 StateManager.State_ = { | 97 StateManager.State_ = { |
| 98 STOPPED: 0, | 98 STOPPED: 0, |
| 99 STARTING: 1, | 99 STARTING: 1, |
| 100 RUNNING: 2, | 100 RUNNING: 2, |
| 101 ERROR: 3, | 101 ERROR: 3, |
| 102 }; | 102 }; |
| 103 var State_ = StateManager.State_; | 103 var State_ = StateManager.State_; |
| 104 | 104 |
| 105 var UmaMediaStreamOpenResults_ = { |
| 106 // These first error are defined by the MediaStream spec: |
| 107 // http://w3c.github.io/mediacapture-main/getusermedia.html#idl-def-MediaStr
eamError |
| 108 'NotSupportedError': |
| 109 hotword.constants.UmaMediaStreamOpenResult.NOT_SUPPORTED, |
| 110 'PermissionDeniedError': |
| 111 hotword.constants.UmaMediaStreamOpenResult.PERMISSION_DENIED, |
| 112 'ConstraintNotSatisfiedError': |
| 113 hotword.constants.UmaMediaStreamOpenResult.CONSTRAINT_NOT_SATISFIED, |
| 114 'OverconstrainedError': |
| 115 hotword.constants.UmaMediaStreamOpenResult.OVERCONSTRAINED, |
| 116 'NotFoundError': hotword.constants.UmaMediaStreamOpenResult.NOT_FOUND, |
| 117 'AbortError': hotword.constants.UmaMediaStreamOpenResult.ABORT, |
| 118 'SourceUnavailableError': |
| 119 hotword.constants.UmaMediaStreamOpenResult.SOURCE_UNAVAILABLE, |
| 120 // The next few errors are chrome-specific. See: |
| 121 // content/renderer/media/user_media_client_impl.cc |
| 122 // (UserMediaClientImpl::GetUserMediaRequestFailed) |
| 123 'PermissionDismissedError': |
| 124 hotword.constants.UmaMediaStreamOpenResult.PERMISSION_DISMISSED, |
| 125 'InvalidStateError': |
| 126 hotword.constants.UmaMediaStreamOpenResult.INVALID_STATE, |
| 127 'DevicesNotFoundError': |
| 128 hotword.constants.UmaMediaStreamOpenResult.DEVICES_NOT_FOUND, |
| 129 'InvalidSecurityOriginError': |
| 130 hotword.constants.UmaMediaStreamOpenResult.INVALID_SECURITY_ORIGIN |
| 131 }; |
| 132 |
| 105 StateManager.prototype = { | 133 StateManager.prototype = { |
| 106 /** | 134 /** |
| 107 * Request status details update. Intended to be called from the | 135 * Request status details update. Intended to be called from the |
| 108 * hotwordPrivate.onEnabledChanged() event. | 136 * hotwordPrivate.onEnabledChanged() event. |
| 109 */ | 137 */ |
| 110 updateStatus: function() { | 138 updateStatus: function() { |
| 111 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); | 139 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); |
| 112 }, | 140 }, |
| 113 | 141 |
| 114 /** | 142 /** |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 var naclArch = platform.nacl_arch; | 220 var naclArch = platform.nacl_arch; |
| 193 | 221 |
| 194 // googDucking set to false so that audio output level from other tabs | 222 // googDucking set to false so that audio output level from other tabs |
| 195 // is not affected when hotword is enabled. https://crbug.com/357773 | 223 // is not affected when hotword is enabled. https://crbug.com/357773 |
| 196 // content/common/media/media_stream_options.cc | 224 // content/common/media/media_stream_options.cc |
| 197 var constraints = /** @type {googMediaStreamConstraints} */ | 225 var constraints = /** @type {googMediaStreamConstraints} */ |
| 198 ({audio: {optional: [{googDucking: false}]}}); | 226 ({audio: {optional: [{googDucking: false}]}}); |
| 199 navigator.webkitGetUserMedia( | 227 navigator.webkitGetUserMedia( |
| 200 /** @type {MediaStreamConstraints} */ (constraints), | 228 /** @type {MediaStreamConstraints} */ (constraints), |
| 201 function(stream) { | 229 function(stream) { |
| 230 hotword.metrics.recordEnum( |
| 231 hotword.constants.UmaMetrics.MEDIA_STREAM_RESULT, |
| 232 hotword.constants.UmaMediaStreamOpenResult.SUCCESS, |
| 233 hotword.constants.UmaMediaStreamOpenResult.MAX); |
| 202 if (!this.pluginManager_.initialize(naclArch, stream)) { | 234 if (!this.pluginManager_.initialize(naclArch, stream)) { |
| 203 this.state_ = State_.ERROR; | 235 this.state_ = State_.ERROR; |
| 204 this.shutdownPluginManager_(); | 236 this.shutdownPluginManager_(); |
| 205 } | 237 } |
| 206 }.bind(this), | 238 }.bind(this), |
| 207 function(error) { | 239 function(error) { |
| 240 if (error.name in UmaMediaStreamOpenResults_) { |
| 241 var metricValue = UmaMediaStreamOpenResults_[error.name]; |
| 242 } else { |
| 243 var metricValue = |
| 244 hotword.constants.UmaMediaStreamOpenResult.UNKNOWN; |
| 245 } |
| 246 hotword.metrics.recordEnum( |
| 247 hotword.constants.UmaMetrics.MEDIA_STREAM_RESULT, |
| 248 metricValue, |
| 249 hotword.constants.UmaMediaStreamOpenResult.MAX); |
| 208 this.state_ = State_.ERROR; | 250 this.state_ = State_.ERROR; |
| 209 this.pluginManager_ = null; | 251 this.pluginManager_ = null; |
| 210 }.bind(this)); | 252 }.bind(this)); |
| 211 }.bind(this)); | 253 }.bind(this)); |
| 212 } else if (this.state_ != State_.STARTING) { | 254 } else if (this.state_ != State_.STARTING) { |
| 213 // Don't try to start a starting detector. | 255 // Don't try to start a starting detector. |
| 214 this.startRecognizer_(); | 256 this.startRecognizer_(); |
| 215 } | 257 } |
| 216 }, | 258 }, |
| 217 | 259 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 this.state_ = State_.ERROR; | 320 this.state_ = State_.ERROR; |
| 279 this.shutdownPluginManager_(); | 321 this.shutdownPluginManager_(); |
| 280 }, | 322 }, |
| 281 | 323 |
| 282 /** | 324 /** |
| 283 * Handle hotword triggering. | 325 * Handle hotword triggering. |
| 284 * @private | 326 * @private |
| 285 */ | 327 */ |
| 286 onTrigger_: function() { | 328 onTrigger_: function() { |
| 287 hotword.debug('Hotword triggered!'); | 329 hotword.debug('Hotword triggered!'); |
| 330 chrome.metricsPrivate.recordUserAction( |
| 331 hotword.constants.UmaMetrics.TRIGGER); |
| 288 assert(this.pluginManager_, 'No NaCl plugin loaded on trigger'); | 332 assert(this.pluginManager_, 'No NaCl plugin loaded on trigger'); |
| 289 // Detector implicitly stops when the hotword is detected. | 333 // Detector implicitly stops when the hotword is detected. |
| 290 this.state_ = State_.STOPPED; | 334 this.state_ = State_.STOPPED; |
| 291 | 335 |
| 292 // Play the chime. | 336 // Play the chime. |
| 293 this.chime_.play(); | 337 this.chime_.play(); |
| 294 | 338 |
| 295 // Implicitly clear the top session. A session needs to be started in | 339 // Implicitly clear the top session. A session needs to be started in |
| 296 // order to restart the detector. | 340 // order to restart the detector. |
| 297 if (this.sessions_.length) { | 341 if (this.sessions_.length) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 hotword.debug('Stopping session for source: ' + source); | 385 hotword.debug('Stopping session for source: ' + source); |
| 342 this.removeSession_(source); | 386 this.removeSession_(source); |
| 343 this.updateStateFromStatus_(); | 387 this.updateStateFromStatus_(); |
| 344 } | 388 } |
| 345 }; | 389 }; |
| 346 | 390 |
| 347 return { | 391 return { |
| 348 StateManager: StateManager | 392 StateManager: StateManager |
| 349 }; | 393 }; |
| 350 }); | 394 }); |
| OLD | NEW |