OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 cr.define('hotword', function() { | 5 cr.define('hotword', function() { |
6 'use strict'; | 6 'use strict'; |
7 | 7 |
8 /** | 8 /** |
9 * Trivial container class for session information. | 9 * Trivial container class for session information. |
10 * @param {!hotword.constants.SessionSource} source Source of the hotword | 10 * @param {!hotword.constants.SessionSource} source Source of the hotword |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 */ | 94 */ |
95 this.chime_ = | 95 this.chime_ = |
96 /** @type {!HTMLAudioElement} */(document.createElement('audio')); | 96 /** @type {!HTMLAudioElement} */(document.createElement('audio')); |
97 | 97 |
98 /** | 98 /** |
99 * Chrome event listeners. Saved so that they can be de-registered when | 99 * Chrome event listeners. Saved so that they can be de-registered when |
100 * hotwording is disabled. | 100 * hotwording is disabled. |
101 * @private | 101 * @private |
102 */ | 102 */ |
103 this.idleStateChangedListener_ = this.handleIdleStateChanged_.bind(this); | 103 this.idleStateChangedListener_ = this.handleIdleStateChanged_.bind(this); |
| 104 this.startupListener_ = this.handleStartup_.bind(this); |
104 | 105 |
105 /** | 106 /** |
106 * Whether this user is locked. | 107 * Whether this user is locked. |
107 * @private {boolean} | 108 * @private {boolean} |
108 */ | 109 */ |
109 this.isLocked_ = false; | 110 this.isLocked_ = false; |
110 | 111 |
111 /** | 112 /** |
112 * Current state of audio logging. | 113 * Current state of audio logging. |
113 * This is tracked separately from hotwordStatus_ because we need to restart | 114 * This is tracked separately from hotwordStatus_ because we need to restart |
(...skipping 20 matching lines...) Expand all Loading... |
134 // Get the initial status. | 135 // Get the initial status. |
135 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); | 136 chrome.hotwordPrivate.getStatus(this.handleStatus_.bind(this)); |
136 | 137 |
137 // Setup the chime and insert into the page. | 138 // Setup the chime and insert into the page. |
138 // Set preload=none to prevent an audio output stream from being created | 139 // Set preload=none to prevent an audio output stream from being created |
139 // when the extension loads. | 140 // when the extension loads. |
140 this.chime_.preload = 'none'; | 141 this.chime_.preload = 'none'; |
141 this.chime_.src = chrome.extension.getURL( | 142 this.chime_.src = chrome.extension.getURL( |
142 hotword.constants.SHARED_MODULE_ROOT + '/audio/chime.wav'); | 143 hotword.constants.SHARED_MODULE_ROOT + '/audio/chime.wav'); |
143 document.body.appendChild(this.chime_); | 144 document.body.appendChild(this.chime_); |
| 145 |
| 146 // In order to remove this listener, it must first be added. This handles |
| 147 // the case on first Chrome startup where this event is never registered, |
| 148 // so can't be removed when it's determined that hotwording is disabled. |
| 149 // Why not only remove the listener if it exists? Extension API events have |
| 150 // two parts to them, the Javascript listeners, and a browser-side component |
| 151 // that wakes up the extension if it's an event page. The browser-side |
| 152 // wake-up event is only removed when the number of javascript listeners |
| 153 // becomes 0. To clear the browser wake-up event, a listener first needs to |
| 154 // be added, then removed in order to drop the count to 0 and remove the |
| 155 // event. |
| 156 chrome.runtime.onStartup.addListener(this.startupListener_); |
144 } | 157 } |
145 | 158 |
146 /** | 159 /** |
147 * @enum {number} | 160 * @enum {number} |
148 * @private | 161 * @private |
149 */ | 162 */ |
150 StateManager.State_ = { | 163 StateManager.State_ = { |
151 STOPPED: 0, | 164 STOPPED: 0, |
152 STARTING: 1, | 165 STARTING: 1, |
153 RUNNING: 2, | 166 RUNNING: 2, |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 this.startDetector_(); | 285 this.startDetector_(); |
273 } else { | 286 } else { |
274 this.shutdownDetector_(); | 287 this.shutdownDetector_(); |
275 } | 288 } |
276 | 289 |
277 if (!chrome.idle.onStateChanged.hasListener( | 290 if (!chrome.idle.onStateChanged.hasListener( |
278 this.idleStateChangedListener_)) { | 291 this.idleStateChangedListener_)) { |
279 chrome.idle.onStateChanged.addListener( | 292 chrome.idle.onStateChanged.addListener( |
280 this.idleStateChangedListener_); | 293 this.idleStateChangedListener_); |
281 } | 294 } |
| 295 if (!chrome.runtime.onStartup.hasListener(this.startupListener_)) |
| 296 chrome.runtime.onStartup.addListener(this.startupListener_); |
282 } else { | 297 } else { |
283 // Not enabled. Shut down if running. | 298 // Not enabled. Shut down if running. |
284 this.shutdownDetector_(); | 299 this.shutdownDetector_(); |
285 | 300 |
286 chrome.idle.onStateChanged.removeListener( | 301 chrome.idle.onStateChanged.removeListener( |
287 this.idleStateChangedListener_); | 302 this.idleStateChangedListener_); |
| 303 // If hotwording isn't enabled, don't start this component extension on |
| 304 // Chrome startup. If a user enables hotwording, the status change |
| 305 // event will be fired and the onStartup event will be registered. |
| 306 chrome.runtime.onStartup.removeListener(this.startupListener_); |
288 } | 307 } |
289 }, | 308 }, |
290 | 309 |
291 /** | 310 /** |
292 * Starts the hotword detector. | 311 * Starts the hotword detector. |
293 * @private | 312 * @private |
294 */ | 313 */ |
295 startDetector_: function() { | 314 startDetector_: function() { |
296 // Last attempt to start detector resulted in an error. | 315 // Last attempt to start detector resulted in an error. |
297 if (this.state_ == State_.ERROR) { | 316 if (this.state_ == State_.ERROR) { |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 handleIdleStateChanged_: function(state) { | 614 handleIdleStateChanged_: function(state) { |
596 hotword.debug('Idle state changed: ' + state); | 615 hotword.debug('Idle state changed: ' + state); |
597 var oldLocked = this.isLocked_; | 616 var oldLocked = this.isLocked_; |
598 if (state == 'locked') | 617 if (state == 'locked') |
599 this.isLocked_ = true; | 618 this.isLocked_ = true; |
600 else | 619 else |
601 this.isLocked_ = false; | 620 this.isLocked_ = false; |
602 | 621 |
603 if (oldLocked != this.isLocked_) | 622 if (oldLocked != this.isLocked_) |
604 this.updateStateFromStatus_(); | 623 this.updateStateFromStatus_(); |
| 624 }, |
| 625 |
| 626 /** |
| 627 * Handles a chrome.runtime.onStartup event. |
| 628 * @private |
| 629 */ |
| 630 handleStartup_: function() { |
| 631 updateStatus(); |
605 } | 632 } |
606 }; | 633 }; |
607 | 634 |
608 return { | 635 return { |
609 StateManager: StateManager | 636 StateManager: StateManager |
610 }; | 637 }; |
611 }); | 638 }); |
OLD | NEW |