OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 /** | |
6 * @fileoverview Class to manage hotwording state. | |
7 */ | |
8 | |
9 cr.define('hotword', function() { | |
10 '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.
| |
11 | |
12 /** | |
13 * @constructor | |
14 * @struct | |
15 */ | |
16 function StateManager() { | |
17 /** | |
18 * Current state. | |
19 * @private {hotword.StateManager.State_} | |
20 */ | |
21 this.state_ = State_.STOPPED; | |
22 | |
23 /** | |
24 * Current hotwording status. | |
25 * @private {chrome.hotwordPrivate.StatusDetails} | |
26 */ | |
27 this.hotwordStatus_ = null; | |
28 | |
29 /** | |
30 * NaCl plugin manager. | |
31 * @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.
| |
32 */ | |
33 this.pluginManager_ = null; | |
34 | |
35 // Get the initial status. | |
36 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); | |
37 } | |
38 | |
Dan Beam
2014/08/26 18:40:51
/**
* @enum {number}
* @private
*/
Anand Mistry (off Chromium)
2014/08/27 07:10:56
Done.
| |
39 StateManager.State_ = { | |
40 STOPPED: 0, | |
41 STARTING: 1, | |
42 RUNNING: 2, | |
43 ERROR: 3, | |
44 }; | |
45 var State_ = StateManager.State_; | |
46 | |
47 /** | |
48 * Request status details update. Intended to be called from the | |
49 * hotwordPrivate.onEnabledChanged() event. | |
50 */ | |
51 StateManager.prototype.updateStatus = function() { | |
52 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); | |
53 }; | |
54 | |
55 /** | |
56 * Callback for hotwordPrivate.getStatus() function. | |
57 * @param {chrome.hotwordPrivate.StatusDetails} status Current hotword status. | |
58 * @private | |
59 */ | |
60 StateManager.prototype.handleStatus_ = function(status) { | |
61 this.hotwordStatus_ = status; | |
62 this.updateStateFromStatus_(); | |
63 }; | |
64 | |
65 /** | |
66 * Updates state based on the current status. | |
67 * @private | |
68 */ | |
69 StateManager.prototype.updateStateFromStatus_ = function() { | |
70 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.
| |
71 // Hotwording is enabled. | |
72 // TODO(amistry): Have a separate alwaysOnEnabled flag. For now, treat | |
73 // "enabled" as "always on enabled". | |
74 this.startDetector_(); | |
75 } else { | |
76 // Not enabled. Shut down if running. | |
77 this.shutdownDetector_(); | |
78 } | |
79 }; | |
80 | |
81 /** | |
82 * Starts the hotword detector. | |
83 * @private | |
84 */ | |
85 StateManager.prototype.startDetector_ = function() { | |
86 // Last attempt to start detector resulted in an error. | |
87 if (this.state_ == State_.ERROR) { | |
88 // TODO(amistry): Do some error rate tracking here and disable the extension | |
89 // 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
| |
90 } | |
91 | |
92 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.
| |
93 this.state_ = State_.STARTING; | |
94 this.pluginManager_ = new hotword.NaClManager(); | |
95 this.pluginManager_.addEventListener(hotword.constants.Event.READY, | |
96 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.
| |
97 this.pluginManager_.addEventListener(hotword.constants.Event.ERROR, | |
98 this.onError_.bind(this)); | |
99 this.pluginManager_.addEventListener(hotword.constants.Event.TRIGGER, | |
100 this.onTrigger_.bind(this)); | |
101 chrome.runtime.getPlatformInfo(function(platform) { | |
102 var naclArch = platform.nacl_arch; | |
103 | |
104 // googDucking set to false so that audio output level from other tabs is | |
105 // not affected when hotword is enabled. https://crbug.com/357773 | |
106 // src.chromium.org/svn/trunk/src/content/common/media/media_stream_option s.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.
| |
107 var constraints = /** @type {googMediaStreamConstraints} */ | |
108 ({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.
| |
109 navigator.webkitGetUserMedia( | |
110 /** @type {MediaStreamConstraints} */ (constraints), | |
111 function(stream) { | |
112 if (!this.pluginManager_.initialize(naclArch, stream)) { | |
113 this.state_ = State_.ERROR; | |
114 this.pluginManager_.shutdown(); | |
115 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.
| |
116 } | |
117 }.bind(this), | |
118 function(error) { | |
119 this.state_ = State_.ERROR; | |
120 this.pluginManager_ = null; | |
121 }.bind(this)); | |
122 }.bind(this)); | |
123 } else if (this.state_ != State_.STARTING) { | |
124 // Don't try to start a starting detector. | |
125 this.state_ = State_.RUNNING; | |
126 this.pluginManager_.startRecognizer(); | |
127 } | |
128 }; | |
129 | |
130 /** | |
131 * Shuts down the hotword detector. | |
132 * @private | |
133 */ | |
134 StateManager.prototype.shutdownDetector_ = function() { | |
135 this.state_ = State_.STOPPED; | |
136 if (this.pluginManager_ != null) { | |
137 this.pluginManager_.shutdown(); | |
138 this.pluginManager_ = null; | |
139 } | |
140 }; | |
141 | |
142 /** | |
143 * Handle the hotword plugin being ready to start. | |
144 * @private | |
145 */ | |
146 StateManager.prototype.onReady_ = function() { | |
147 if (this.state_ != State_.STARTING) { | |
148 // Shouldn't be running while starting. | |
149 assert(this.state_ != State_.RUNNING); | |
150 this.pluginManager_.shutdown(); | |
151 this.pluginManager_ = null; | |
152 return; | |
153 } | |
154 this.state_ = State_.RUNNING; | |
155 this.pluginManager_.startRecognizer(); | |
156 }; | |
157 | |
158 /** | |
159 * Handle an error from the hotword plugin. | |
160 * @private | |
161 */ | |
162 StateManager.prototype.onError_ = function() { | |
163 this.state_ = State_.ERROR; | |
164 this.pluginManager_.shutdown(); | |
165 this.pluginManager_ = null; | |
166 }; | |
167 | |
168 /** | |
169 * Handle hotword triggering. | |
170 * @private | |
171 */ | |
172 StateManager.prototype.onTrigger_ = function() { | |
173 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.
| |
174 // Detector implicitly stops when the hotword is detected. | |
175 this.state_ = State_.STOPPED; | |
176 | |
177 chrome.hotwordPrivate.notifyHotwordRecognition('search', function() {}); | |
178 }; | |
179 | |
180 return { | |
181 StateManager: StateManager | |
182 }; | |
183 | |
184 }); | |
OLD | NEW |