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

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/cvox2/background/media_automation_handler.js

Issue 2563013003: Support audio ducking and suspension in ChromeVox (Closed)
Patch Set: Support audio ducking and suspension in ChromeVox Created 4 years 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 /** 5 /**
6 * @fileoverview Handles media events automation. 6 * @fileoverview Handles media events automation.
7 */ 7 */
8 8
9 goog.provide('MediaAutomationHandler'); 9 goog.provide('MediaAutomationHandler');
10 10
11 goog.require('BaseAutomationHandler'); 11 goog.require('BaseAutomationHandler');
12 goog.require('cvox.TtsCapturingEventListener');
12 13
13 goog.scope(function() { 14 goog.scope(function() {
14 var AutomationEvent = chrome.automation.AutomationEvent; 15 var AutomationEvent = chrome.automation.AutomationEvent;
15 var AutomationNode = chrome.automation.AutomationNode; 16 var AutomationNode = chrome.automation.AutomationNode;
16 var EventType = chrome.automation.EventType; 17 var EventType = chrome.automation.EventType;
17 var RoleType = chrome.automation.RoleType; 18 var RoleType = chrome.automation.RoleType;
18 19
19 /** 20 /**
20 * @param {!AutomationNode} node The root to observe media changes.
21 * @constructor 21 * @constructor
22 * @extends {BaseAutomationHandler} 22 * @extends {BaseAutomationHandler}
23 * @implements {cvox.TtsCapturingEventListener}
23 */ 24 */
24 MediaAutomationHandler = function(node) { 25 MediaAutomationHandler = function() {
25 BaseAutomationHandler.call(this, node); 26 /** @type {!Set<AutomationNode>} @private */
27 this.mediaRoots_ = new Set();
26 28
27 var e = EventType; 29 /** @type {Date} @private */
28 this.addListener_(e.mediaStartedPlaying, this.onMediaStartedPlaying); 30 this.lastTtsEvent_ = new Date();
29 this.addListener_(e.mediaStoppedPlaying, this.onMediaStoppedPlaying); 31
32 cvox.ChromeVox.tts.addCapturingEventListener(this);
33
34 chrome.automation.getDesktop(function(node) {
35 BaseAutomationHandler.call(this, node);
36 node.findAll({role: RoleType.rootWebArea}).forEach(function(r) {
37 if (localStorage['useAudioDucking'] == 'true')
dmazzoni 2016/12/09 18:30:10 It doesn't make sense to me to do both. I'd prefer
38 r.startDuckingMedia()();
39 if (localStorage['useAudioSuspension'] == 'true')
40 r.suspendMedia()();
41 });
42
43 var e = EventType;
44 this.addListener_(e.mediaStartedPlaying, this.onMediaStartedPlaying);
45 this.addListener_(e.mediaStoppedPlaying, this.onMediaStoppedPlaying);
46 }.bind(this));
30 }; 47 };
31 48
49 /** @type {number} */
50 MediaAutomationHandler.MIN_WAITTIME_MS = 1000;
51
32 MediaAutomationHandler.prototype = { 52 MediaAutomationHandler.prototype = {
33 __proto__: BaseAutomationHandler.prototype, 53 __proto__: BaseAutomationHandler.prototype,
34 54
55 /** @override */
56 onTtsStart: function() {
57 this.lastTtsEvent_ = new Date();
58 if (localStorage['useAudioDucking'] == 'true')
59 this.update_({duck: true});
60 if (localStorage['useAudioSuspension'] == 'true')
61 this.update_({suspend: true});
62 },
63
64 /** @override */
65 onTtsEnd: function() {
66 var now = new Date();
67 setTimeout(function() {
68 var then = this.lastTtsEvent_;
69 if (now < then)
70 return;
71 this.lastTtsEvent_ = now;
72 if (localStorage['useAudioDucking'] == 'true')
73 this.update_({unduck: true});
74 if (localStorage['useAudioSuspension'] == 'true')
75 this.update_({resume: true});
76 }.bind(this), MediaAutomationHandler.MIN_WAITTIME_MS);
77 },
78
35 /** 79 /**
36 * @param {!AutomationEvent} evt 80 * @param {!AutomationEvent} evt
37 */ 81 */
38 onMediaStartedPlaying: function(evt) { 82 onMediaStartedPlaying: function(evt) {
83 if (cvox.ChromeVox.tts.isSpeaking())
84 evt.target.startDuckingMedia();
85
86 this.mediaRoots_.add(evt.target);
39 }, 87 },
40 88
41 /** 89 /**
42 * @param {!AutomationEvent} evt 90 * @param {!AutomationEvent} evt
43 */ 91 */
44 onMediaStoppedPlaying: function(evt) { 92 onMediaStoppedPlaying: function(evt) {
93 // Intentionally does nothing (to cover resume).
94 },
95
96 /**
97 * Updates the media state for all observed automation roots.
98 * Does not check options.
99 * @param {{duck: (boolean|undefined),
100 * unduck: (boolean|undefined),
101 * resume: (boolean|undefined),
102 * suspend: (boolean|undefined)}} options
103 * @private
104 */
105 update_: function(options) {
106 var it = this.mediaRoots_.values();
107 var item = it.next();
108 while (!item.done) {
109 var root = item.value;
110 if (options.duck)
111 root.startDuckingMedia();
112 if (options.unduck)
113 root.stopDuckingMedia();
114 if (options.resume)
115 root.resumeMedia();
116 if (options.suspend)
117 root.suspendMedia();
118 item = it.next();
119 }
45 } 120 }
46 }; 121 };
47 122
48 }); // goog.scope 123 }); // goog.scope
124
125 new MediaAutomationHandler();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698