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

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: Address review comments. Created 6 years, 4 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
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..25000e8c7cec198931b915321c4e59f871ae5cd5
--- /dev/null
+++ b/chrome/browser/resources/hotword/state_manager.js
@@ -0,0 +1,193 @@
+// 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.
+
+/**
+ * @fileoverview Class to manage hotwording state.
Dan Beam 2014/08/27 20:08:37 nit: if it fits, one-liner -- /** ... */
Dan Beam 2014/08/27 20:08:37 this isn't a particularly useful comment and shoul
Anand Mistry (off Chromium) 2014/08/28 00:59:26 Done.
+ */
+
Dan Beam 2014/08/27 20:08:37 remove \n
Anand Mistry (off Chromium) 2014/08/28 00:59:26 Done.
+cr.define('hotword', function() {
+ 'use strict';
+
+ /**
+ * @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_;
+
+ /**
+ * Request status details update. Intended to be called from the
+ * hotwordPrivate.onEnabledChanged() event.
+ */
+ StateManager.prototype.updateStatus = function() {
Dan Beam 2014/08/27 20:08:37 nit: just assign whole prototype StateManager.p
Anand Mistry (off Chromium) 2014/08/28 00:59:25 Done.
+ chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this));
+ };
+
+ /**
+ * Callback for hotwordPrivate.getStatus() function.
+ * @param {chrome.hotwordPrivate.StatusDetails} status Current hotword status.
+ * @private
+ */
+ StateManager.prototype.handleStatus_ = function(status) {
+ this.hotwordStatus_ = status;
+ this.updateStateFromStatus_();
+ };
+
+ /**
+ * Updates state based on the current status.
+ * @private
+ */
+ StateManager.prototype.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
+ */
+ StateManager.prototype.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
+ */
+ StateManager.prototype.shutdownPluginManager_ = function() {
+ if (this.pluginManager_) {
+ this.pluginManager_.shutdown();
+ this.pluginManager_ = null;
+ }
+ };
+
+ /**
+ * Shuts down the hotword detector.
+ * @private
+ */
+ StateManager.prototype.shutdownDetector_ = function() {
+ this.state_ = State_.STOPPED;
+ this.shutdownPluginManager_();
+ };
+
+ /**
+ * Handle the hotword plugin being ready to start.
+ * @private
+ */
+ StateManager.prototype.onReady_ = function() {
+ if (this.state_ != State_.STARTING) {
+ // Shouldn't be running while starting.
Dan Beam 2014/08/27 20:08:37 this comment is confusing because you say the code
Anand Mistry (off Chromium) 2014/08/28 00:59:26 Done.
+ assert(this.state_ != State_.RUNNING);
+ this.shutdownPluginManager_();
+ return;
+ }
+ this.state_ = State_.RUNNING;
+ this.pluginManager_.startRecognizer();
+ };
+
+ /**
+ * Handle an error from the hotword plugin.
+ * @private
+ */
+ StateManager.prototype.onError_ = function() {
+ this.state_ = State_.ERROR;
+ this.shutdownPluginManager_();
+ };
+
+ /**
+ * Handle hotword triggering.
+ * @private
+ */
+ StateManager.prototype.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
+ };
+
Dan Beam 2014/08/27 20:08:37 nit: remove \n
Anand Mistry (off Chromium) 2014/08/28 00:59:25 Done.
+});
« chrome/browser/resources/hotword/manager.js ('K') | « chrome/browser/resources/hotword/manifest.json ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698