| 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..bed945af65adcfad7090dc088e6b5851a17799b0 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.
|
| + * @constructor
|
| + * @struct
|
| + * @private
|
| + */
|
| + function Session_(source, triggerCb, startedCb) {
|
| + /**
|
| + * Source of the hotword session request.
|
| + * @protected {!hotword.constants.SessionSource}
|
| + */
|
| + 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.
|
| */
|
| - 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.
|
| @@ -88,6 +130,8 @@ cr.define('hotword', function() {
|
| handleStatus_: function(status) {
|
| this.hotwordStatus_ = status;
|
| this.updateStateFromStatus_();
|
| +
|
| + this.onStatusChanged.dispatch();
|
| },
|
|
|
| /**
|
| @@ -101,17 +145,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,9 +218,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;
|
| + }
|
| }
|
| },
|
|
|
| @@ -241,12 +283,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;
|
| + }
|
| + }
|
| },
|
|
|
| /**
|
| @@ -255,10 +313,12 @@ 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) {
|
| - this.sessionSource_ = source;
|
| - this.sessionStartedCb_ = startedCb;
|
| + startSession: function(source, startedCb, triggerCb) {
|
| + this.removeSession_(source);
|
| + this.sessions_.push(new Session_(source, triggerCb, startedCb));
|
| this.updateStateFromStatus_();
|
| },
|
|
|
| @@ -268,8 +328,7 @@ cr.define('hotword', function() {
|
| * session request.
|
| */
|
| stopSession: function(source) {
|
| - this.sessionSource_ = null;
|
| - this.sessionStartedCb_ = null;
|
| + this.removeSession_(source);
|
| this.updateStateFromStatus_();
|
| }
|
| };
|
|
|