Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6522)

Unified Diff: chrome/browser/resources/hotword/state_manager.js

Issue 493203004: Add a StateManager for managing hotwording state based on various factors (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@hotword-nacl-manager
Patch Set: Rebase. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/resources/hotword/manifest.json ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
new file mode 100644
index 0000000000000000000000000000000000000000..4b2ae1316614d86cdb14e0b62cfc9bb18e0a2586
--- /dev/null
+++ b/chrome/browser/resources/hotword/state_manager.js
@@ -0,0 +1,195 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('hotword', function() {
+ 'use strict';
+
+ /**
+ * 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.
+ * @constructor
+ * @struct
+ */
+ function StateManager() {
+ /**
+ * Current state.
+ * @private {hotword.StateManager.State_}
+ */
+ this.state_ = State_.STOPPED;
+
+ /**
+ * Current hotwording status.
+ * @private {?chrome.hotwordPrivate.StatusDetails}
+ */
+ this.hotwordStatus_ = null;
+
+ /**
+ * NaCl plugin manager.
+ * @private {?hotword.NaClManager}
+ */
+ this.pluginManager_ = null;
+
+ // Get the initial status.
+ chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this));
+ }
+
+ /**
+ * @enum {number}
+ * @private
+ */
+ StateManager.State_ = {
+ STOPPED: 0,
+ STARTING: 1,
+ RUNNING: 2,
+ ERROR: 3,
+ };
+ var State_ = StateManager.State_;
+
+ StateManager.prototype = {
+ /**
+ * Request status details update. Intended to be called from the
+ * hotwordPrivate.onEnabledChanged() event.
+ */
+ updateStatus: function() {
+ chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this));
+ },
+
+ /**
+ * Callback for hotwordPrivate.getStatus() function.
+ * @param {chrome.hotwordPrivate.StatusDetails} status Current hotword
+ * status.
+ * @private
+ */
+ handleStatus_: function(status) {
+ this.hotwordStatus_ = status;
+ this.updateStateFromStatus_();
+ },
+
+ /**
+ * Updates state based on the current status.
+ * @private
+ */
+ updateStateFromStatus_: function() {
+ if (this.hotwordStatus_.enabled) {
+ // Hotwording is enabled.
+ // TODO(amistry): Have a separate alwaysOnEnabled flag. For now, treat
+ // "enabled" as "always on enabled".
+ this.startDetector_();
+ } else {
+ // Not enabled. Shut down if running.
+ this.shutdownDetector_();
+ }
+ },
+
+ /**
+ * Starts the hotword detector.
+ * @private
+ */
+ startDetector_: function() {
+ // Last attempt to start detector resulted in an error.
+ if (this.state_ == State_.ERROR) {
+ // TODO(amistry): Do some error rate tracking here and disable the
+ // extension if we error too often.
+ }
+
+ if (!this.pluginManager_) {
+ this.state_ = State_.STARTING;
+ this.pluginManager_ = new hotword.NaClManager();
+ this.pluginManager_.addEventListener(hotword.constants.Event.READY,
+ this.onReady_.bind(this));
+ this.pluginManager_.addEventListener(hotword.constants.Event.ERROR,
+ this.onError_.bind(this));
+ this.pluginManager_.addEventListener(hotword.constants.Event.TRIGGER,
+ this.onTrigger_.bind(this));
+ chrome.runtime.getPlatformInfo(function(platform) {
+ var naclArch = platform.nacl_arch;
+
+ // googDucking set to false so that audio output level from other tabs
+ // is not affected when hotword is enabled. https://crbug.com/357773
+ // content/common/media/media_stream_options.cc
+ var constraints = /** @type {googMediaStreamConstraints} */
+ ({audio: {optional: [{googDucking: false}]}});
+ navigator.webkitGetUserMedia(
+ /** @type {MediaStreamConstraints} */ (constraints),
+ function(stream) {
+ if (!this.pluginManager_.initialize(naclArch, stream)) {
+ this.state_ = State_.ERROR;
+ this.shutdownPluginManager_();
+ }
+ }.bind(this),
+ function(error) {
+ this.state_ = State_.ERROR;
+ this.pluginManager_ = null;
+ }.bind(this));
+ }.bind(this));
+ } else if (this.state_ != State_.STARTING) {
+ // Don't try to start a starting detector.
+ this.state_ = State_.RUNNING;
+ this.pluginManager_.startRecognizer();
+ }
+ },
+
+ /**
+ * Shuts down and removes the plugin manager, if it exists.
+ * @private
+ */
+ shutdownPluginManager_: function() {
+ if (this.pluginManager_) {
+ this.pluginManager_.shutdown();
+ this.pluginManager_ = null;
+ }
+ },
+
+ /**
+ * Shuts down the hotword detector.
+ * @private
+ */
+ shutdownDetector_: function() {
+ this.state_ = State_.STOPPED;
+ this.shutdownPluginManager_();
+ },
+
+ /**
+ * Handle the hotword plugin being ready to start.
+ * @private
+ */
+ onReady_: function() {
+ if (this.state_ != State_.STARTING) {
+ // At this point, we should not be in the RUNNING state. Doing so would
+ // imply the hotword detector was started without being ready.
+ assert(this.state_ != State_.RUNNING);
+ this.shutdownPluginManager_();
+ return;
+ }
+ this.state_ = State_.RUNNING;
+ this.pluginManager_.startRecognizer();
+ },
+
+ /**
+ * Handle an error from the hotword plugin.
+ * @private
+ */
+ onError_: function() {
+ this.state_ = State_.ERROR;
+ this.shutdownPluginManager_();
+ },
+
+ /**
+ * Handle hotword triggering.
+ * @private
+ */
+ onTrigger_: function() {
+ assert(this.pluginManager_);
+ // Detector implicitly stops when the hotword is detected.
+ this.state_ = State_.STOPPED;
+
+ chrome.hotwordPrivate.notifyHotwordRecognition('search', function() {});
+ }
+ };
+
+ return {
+ StateManager: StateManager
+ };
+});
« no previous file with comments | « chrome/browser/resources/hotword/manifest.json ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698