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

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: 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..964e7dcf04abeb26bb26b57e7f31506253f9f33a
--- /dev/null
+++ b/chrome/browser/resources/hotword/state_manager.js
@@ -0,0 +1,184 @@
+// 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.
+ */
+
+cr.define('hotword', function() {
+'use strict';
Dan Beam 2014/08/26 18:40:51 this code should probably be indented because it's
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+
+/**
+ * @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}
Dan Beam 2014/08/26 18:40:51 add ? to |this.hotwordStatus_|'s type or remove fr
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+ */
+ this.pluginManager_ = null;
+
+ // Get the initial status.
+ chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this));
+}
+
Dan Beam 2014/08/26 18:40:51 /** * @enum {number} * @private */
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+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() {
+ 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) {
Dan Beam 2014/08/26 18:40:52 indent off (needs 1 more space)
Anand Mistry (off Chromium) 2014/08/27 07:10:56 WTF? How did that end up there? Done.
+ // 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.
Dan Beam 2014/08/26 18:40:52 is there some code you meant to put here?
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Not yet. I'm not ready to fill in that kind of det
+ }
+
+ if (this.pluginManager_ == null) {
Dan Beam 2014/08/26 18:40:52 if (!this.pluginManager_) {
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+ this.state_ = State_.STARTING;
+ this.pluginManager_ = new hotword.NaClManager();
+ this.pluginManager_.addEventListener(hotword.constants.Event.READY,
+ this.onReady_.bind(this));
Dan Beam 2014/08/26 18:40:52 indent off x 3
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+ 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
+ // src.chromium.org/svn/trunk/src/content/common/media/media_stream_options.cc
Dan Beam 2014/08/26 18:40:52 use bit.ly or just put local path.
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+ var constraints = /** @type {googMediaStreamConstraints} */
+ ({audio: {optional: [{ googDucking: false}] }});
Dan Beam 2014/08/26 18:40:52 no \s after { or }
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+ navigator.webkitGetUserMedia(
+ /** @type {MediaStreamConstraints} */ (constraints),
+ function(stream) {
+ if (!this.pluginManager_.initialize(naclArch, stream)) {
+ this.state_ = State_.ERROR;
+ this.pluginManager_.shutdown();
+ this.pluginManager_ = null;
Dan Beam 2014/08/26 18:40:51 nit: this code seems to be repeated a lot: this
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+ }
+ }.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 the hotword detector.
+ * @private
+ */
+StateManager.prototype.shutdownDetector_ = function() {
+ this.state_ = State_.STOPPED;
+ if (this.pluginManager_ != null) {
+ this.pluginManager_.shutdown();
+ this.pluginManager_ = null;
+ }
+};
+
+/**
+ * Handle the hotword plugin being ready to start.
+ * @private
+ */
+StateManager.prototype.onReady_ = function() {
+ if (this.state_ != State_.STARTING) {
+ // Shouldn't be running while starting.
+ assert(this.state_ != State_.RUNNING);
+ this.pluginManager_.shutdown();
+ this.pluginManager_ = null;
+ 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.pluginManager_.shutdown();
+ this.pluginManager_ = null;
+};
+
+/**
+ * Handle hotword triggering.
+ * @private
+ */
+StateManager.prototype.onTrigger_ = function() {
+ assert(this.pluginManager_ != null);
Dan Beam 2014/08/26 18:40:52 assert(this.pluginManager_)
Anand Mistry (off Chromium) 2014/08/27 07:10:56 Done.
+ // Detector implicitly stops when the hotword is detected.
+ this.state_ = State_.STOPPED;
+
+ chrome.hotwordPrivate.notifyHotwordRecognition('search', function() {});
+};
+
+return {
+ StateManager: StateManager
+};
+
+});

Powered by Google App Engine
This is Rietveld 408576698