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 764d2c099dd202f5b81f9d123d2a4195da6d1373..c9a328e99307b3a2b1a684258a88a209db207f42 100644 |
| --- a/chrome/browser/resources/hotword/state_manager.js |
| +++ b/chrome/browser/resources/hotword/state_manager.js |
| @@ -6,6 +6,17 @@ cr.define('hotword', function() { |
| 'use strict'; |
| /** |
| + * Trivial container class for session information. |
| + * @constructor |
| + * @struct |
| + * @private |
| + */ |
| + function Session_(source, triggerCb) { |
| + this.source = source; |
| + this.triggerCb = triggerCb; |
| + } |
| + |
| + /** |
| * 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 +43,21 @@ 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()} |
| + * Callbacks to run when the hotword detector has successfully started. |
| + * @private {!Array.<function()>} |
| */ |
| - this.sessionStartedCb_ = null; |
| + this.sessionStartedCbs_ = []; |
|
rpetterson
2014/09/25 02:23:38
why aren't these stored in the Session_ type?
Anand Mistry (off Chromium)
2014/09/25 05:23:42
There could be cases where you have several of the
|
| + |
| + /** |
| + * Event that fires when the hotwording status has changed. |
| + */ |
| + this.onStatusChanged = new chrome.Event(); |
| /** |
| * Hotword trigger audio notification... a.k.a The Chime (tm). |
| @@ -80,6 +96,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. |
| @@ -88,6 +121,8 @@ cr.define('hotword', function() { |
| handleStatus_: function(status) { |
| this.hotwordStatus_ = status; |
| this.updateStateFromStatus_(); |
| + |
| + this.onStatusChanged.dispatch(); |
| }, |
| /** |
| @@ -101,17 +136,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_(); |
| @@ -179,10 +209,10 @@ 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.sessionStartedCbs_.length; i++) { |
| + this.sessionStartedCbs_[i](); |
| } |
| + this.sessionStartedCbs_ = []; |
| }, |
| /** |
| @@ -241,12 +271,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; |
| + } |
| + } |
| }, |
| /** |
| @@ -256,9 +302,10 @@ cr.define('hotword', function() { |
| * @param {!function()} startedCb Callback invoked when the session has |
| * been started successfully. |
| */ |
| - startSession: function(source, startedCb) { |
| - this.sessionSource_ = source; |
| - this.sessionStartedCb_ = startedCb; |
| + startSession: function(source, startedCb, triggerCb) { |
| + this.removeSession_(source); |
| + this.sessions_.push(new Session_(source, triggerCb)); |
| + this.sessionStartedCbs_.push(startedCb); |
| this.updateStateFromStatus_(); |
| }, |
| @@ -268,8 +315,7 @@ cr.define('hotword', function() { |
| * session request. |
| */ |
| stopSession: function(source) { |
| - this.sessionSource_ = null; |
| - this.sessionStartedCb_ = null; |
| + this.removeSession_(source); |
| this.updateStateFromStatus_(); |
| } |
| }; |