Chromium Code Reviews| Index: chrome/browser/resources/hotword/state_manager.js |
| diff --git a/chrome/browser/resources/hotword/state_manager.js b/chrome/browser/resources/hotword/state_manager.js |
| index 39e176b278571580e1788d7458b88931c38ac542..8c994c6b52552cfb50833150a1a1bf3a035bcdd6 100644 |
| --- a/chrome/browser/resources/hotword/state_manager.js |
| +++ b/chrome/browser/resources/hotword/state_manager.js |
| @@ -6,6 +6,32 @@ cr.define('hotword', function() { |
| 'use strict'; |
| /** |
| + * Trivial container class for session information. |
|
Dan Beam
2014/10/11 00:54:36
@param x 3
Anand Mistry (off Chromium)
2014/10/13 19:30:21
Done.
|
| + * @constructor |
| + * @struct |
| + * @private |
| + */ |
| + function Session_(source, triggerCb, startedCb) { |
| + /** |
| + * Source of the hotword session request. |
| + * @protected {!hotword.constants.SessionSource} |
|
Dan Beam
2014/10/11 00:54:35
nit: ehhh, I'd just make this @private if it's onl
Anand Mistry (off Chromium)
2014/10/13 19:30:21
Done.
|
| + */ |
| + this.source = source; |
| + |
| + /** |
| + * Callback invoked when the hotword has triggered. |
| + * @protected {!function()} |
| + */ |
| + this.triggerCb = triggerCb; |
| + |
| + /** |
| + * Callback invoked when the session has been started successfully. |
| + * @protected {?function()} |
| + */ |
| + this.startedCb = startedCb; |
| + } |
| + |
| + /** |
| * Class to manage hotwording state. Starts/stops the hotword detector based |
| * on user settings, session requests, and any other factors that play into |
| * whether or not hotwording should be running. |
| @@ -32,16 +58,15 @@ cr.define('hotword', function() { |
| this.pluginManager_ = null; |
| /** |
| - * Source of the current hotword session. |
| - * @private {?hotword.constants.SessionSource} |
| + * Currently active hotwording sessions. |
| + * @private {!Array.<hotword.Session_>} |
| */ |
| - this.sessionSource_ = null; |
| + this.sessions_ = []; |
| /** |
| - * Callback to run when the hotword detector has successfully started. |
| - * @private {!function()} |
| + * Event that fires when the hotwording status has changed. |
|
Dan Beam
2014/10/11 00:54:36
@type
Anand Mistry (off Chromium)
2014/10/13 19:30:21
Done.
|
| */ |
| - this.sessionStartedCb_ = null; |
| + this.onStatusChanged = new chrome.Event(); |
| /** |
| * Hotword trigger audio notification... a.k.a The Chime (tm). |
| @@ -80,6 +105,23 @@ cr.define('hotword', function() { |
| }, |
| /** |
| + * @return {boolean} True if hotwording is enabled. |
| + */ |
| + isEnabled: function() { |
| + assert(this.hotwordStatus_); |
| + return this.hotwordStatus_.enabled; |
| + }, |
| + |
| + /** |
| + * @return {boolean} True if always-on hotwording is enabled. |
| + */ |
| + isAlwaysOnEnabled: function() { |
| + assert(this.hotwordStatus_); |
| + return this.hotwordStatus_.enabled && |
| + this.hotwordStatus_.alwaysOnEnabled; |
| + }, |
| + |
| + /** |
| * Callback for hotwordPrivate.getStatus() function. |
| * @param {chrome.hotwordPrivate.StatusDetails} status Current hotword |
| * status. |
| @@ -89,6 +131,8 @@ cr.define('hotword', function() { |
| hotword.debug('New hotword status', status); |
| this.hotwordStatus_ = status; |
| this.updateStateFromStatus_(); |
| + |
| + this.onStatusChanged.dispatch(); |
| }, |
| /** |
| @@ -102,17 +146,12 @@ cr.define('hotword', function() { |
| if (this.hotwordStatus_.enabled) { |
| // Start the detector if there's a session, and shut it down if there |
| // isn't. |
| - // TODO(amistry): Support stacking sessions. This can happen when the |
| - // user opens google.com or the NTP, then opens the launcher. Opening |
| - // google.com will create one session, and opening the launcher will |
| - // create the second. Closing the launcher should re-activate the |
| - // google.com session. |
| // NOTE(amistry): With always-on, we want a different behaviour with |
| // sessions since the detector should always be running. The exception |
| // being when the user triggers by saying 'Ok Google'. In that case, the |
| // detector stops, so starting/stopping the launcher session should |
| // restart the detector. |
| - if (this.sessionSource_) |
| + if (this.sessions_.length) |
| this.startDetector_(); |
| else |
| this.shutdownDetector_(); |
| @@ -180,9 +219,12 @@ cr.define('hotword', function() { |
| this.state_ = State_.RUNNING; |
| this.pluginManager_.startRecognizer(); |
| } |
| - if (this.sessionStartedCb_) { |
| - this.sessionStartedCb_(); |
| - this.sessionStartedCb_ = null; |
| + for (var i = 0; i < this.sessions_.length; i++) { |
| + var session = this.sessions_[i]; |
| + if (session.startedCb) { |
| + session.startedCb(); |
| + session.startedCb = null; |
| + } |
| } |
| }, |
| @@ -243,12 +285,28 @@ cr.define('hotword', function() { |
| // Play the chime. |
| this.chime_.play(); |
| - chrome.hotwordPrivate.notifyHotwordRecognition('search', function() {}); |
| + // Implicitly clear the top session. A session needs to be started in |
| + // order to restart the detector. |
| + if (this.sessions_.length) { |
| + var session = this.sessions_.pop(); |
| + if (session.triggerCb) |
| + session.triggerCb(); |
| + } |
| + }, |
| - // Implicitly clear the session. A session needs to be started in order to |
| - // restart the detector. |
| - this.sessionSource_ = null; |
| - this.sessionStartedCb_ = null; |
| + /** |
| + * Remove a hotwording session from the given source. |
| + * @param {!hotword.constants.SessionSource} source Source of the hotword |
| + * session request. |
| + * @private |
| + */ |
| + removeSession_: function(source) { |
| + for (var i = 0; i < this.sessions_.length; i++) { |
| + if (this.sessions_[i].source == source) { |
| + this.sessions_.splice(i, 1); |
| + break; |
| + } |
| + } |
| }, |
| /** |
| @@ -257,11 +315,13 @@ cr.define('hotword', function() { |
| * session request. |
| * @param {!function()} startedCb Callback invoked when the session has |
| * been started successfully. |
| + * @param {!function()} triggerCb Callback invoked when the hotword has |
| + * triggered. |
| */ |
| - startSession: function(source, startedCb) { |
| + startSession: function(source, startedCb, triggerCb) { |
| hotword.debug('Starting session for source: ' + source); |
| - this.sessionSource_ = source; |
| - this.sessionStartedCb_ = startedCb; |
| + this.removeSession_(source); |
| + this.sessions_.push(new Session_(source, triggerCb, startedCb)); |
| this.updateStateFromStatus_(); |
| }, |
| @@ -272,8 +332,7 @@ cr.define('hotword', function() { |
| */ |
| stopSession: function(source) { |
| hotword.debug('Stopping session for source: ' + source); |
| - this.sessionSource_ = null; |
| - this.sessionStartedCb_ = null; |
| + this.removeSession_(source); |
| this.updateStateFromStatus_(); |
| } |
| }; |