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

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 automation events. Note that to perform any of
7 * the actions below such as ducking, and suspension of media sessions, the
8 * --enable-default-media-session flag must be passed at the command line.
7 */ 9 */
8 10
9 goog.provide('MediaAutomationHandler'); 11 goog.provide('MediaAutomationHandler');
10 12
11 goog.require('BaseAutomationHandler'); 13 goog.require('BaseAutomationHandler');
14 goog.require('cvox.TtsCapturingEventListener');
12 15
13 goog.scope(function() { 16 goog.scope(function() {
14 var AutomationEvent = chrome.automation.AutomationEvent; 17 var AutomationEvent = chrome.automation.AutomationEvent;
15 var AutomationNode = chrome.automation.AutomationNode; 18 var AutomationNode = chrome.automation.AutomationNode;
16 var EventType = chrome.automation.EventType; 19 var EventType = chrome.automation.EventType;
17 var RoleType = chrome.automation.RoleType; 20 var RoleType = chrome.automation.RoleType;
18 21
19 /** 22 /**
20 * @param {!AutomationNode} node The root to observe media changes.
21 * @constructor 23 * @constructor
22 * @extends {BaseAutomationHandler} 24 * @extends {BaseAutomationHandler}
25 * @implements {cvox.TtsCapturingEventListener}
23 */ 26 */
24 MediaAutomationHandler = function(node) { 27 MediaAutomationHandler = function() {
25 BaseAutomationHandler.call(this, node); 28 /** @type {!Set<AutomationNode>} @private */
29 this.mediaRoots_ = new Set();
26 30
27 var e = EventType; 31 /** @type {Date} @private */
28 this.addListener_(e.mediaStartedPlaying, this.onMediaStartedPlaying); 32 this.lastTtsEvent_ = new Date();
29 this.addListener_(e.mediaStoppedPlaying, this.onMediaStoppedPlaying); 33
34 cvox.ChromeVox.tts.addCapturingEventListener(this);
35
36 chrome.automation.getDesktop(function(node) {
37 BaseAutomationHandler.call(this, node);
38 this.setInitialState_(node);
39 var e = EventType;
40 this.addListener_(e.mediaStartedPlaying, this.onMediaStartedPlaying);
41 this.addListener_(e.mediaStoppedPlaying, this.onMediaStoppedPlaying);
42 }.bind(this));
30 }; 43 };
31 44
45 /** @type {number} */
46 MediaAutomationHandler.MIN_WAITTIME_MS = 1000;
47
32 MediaAutomationHandler.prototype = { 48 MediaAutomationHandler.prototype = {
33 __proto__: BaseAutomationHandler.prototype, 49 __proto__: BaseAutomationHandler.prototype,
34 50
51 /** @override */
52 onTtsStart: function() {
53 this.lastTtsEvent_ = new Date();
54 this.update_({start: true});
55 },
56
57 /** @override */
58 onTtsEnd: function() {
59 var now = new Date();
60 setTimeout(function() {
61 var then = this.lastTtsEvent_;
62 if (now < then)
63 return;
64 this.lastTtsEvent_ = now;
65 this.update_({end: true});
66 }.bind(this), MediaAutomationHandler.MIN_WAITTIME_MS);
67 },
68
35 /** 69 /**
36 * @param {!AutomationEvent} evt 70 * @param {!AutomationEvent} evt
37 */ 71 */
38 onMediaStartedPlaying: function(evt) { 72 onMediaStartedPlaying: function(evt) {
73 this.mediaRoots_.add(evt.target);
74 if (cvox.ChromeVox.tts.isSpeaking())
75 this.update_({start: true});
39 }, 76 },
40 77
41 /** 78 /**
42 * @param {!AutomationEvent} evt 79 * @param {!AutomationEvent} evt
43 */ 80 */
44 onMediaStoppedPlaying: function(evt) { 81 onMediaStoppedPlaying: function(evt) {
82 // Intentionally does nothing (to cover resume).
83 },
84
85 /**
86 * Sets the initial state of audio for all tabs.
87 * We do this on ChromeVox startup.
88 * @param {AutomationNode} node
89 */
90 setInitialState_: function(node) {
91 var roots = node.findAll({role: RoleType.rootWebArea});
92 if (!roots.length) {
93 var listener = this.setInitialState_.bind(this, node);
94 window.setTimeout(listener, 1000);
95 return;
96 }
97
98 roots.forEach(function(r) {
99 // Doing this allows us to get any currently playing media in our
100 // mediaStartedPlaying handler.
101 r.suspendMedia();
102 r.resumeMedia();
103 });
104 },
105
106 /**
107 * Updates the media state for all observed automation roots.
108 * @param {{start: (boolean|undefined),
109 * end: (boolean|undefined)}} options
110 * @private
111 */
112 update_: function(options) {
113 var it = this.mediaRoots_.values();
114 var item = it.next();
115 var audioStrategy = localStorage['audioStrategy'];
116 while (!item.done) {
117 var root = item.value;
118 if (options.start) {
119 if (audioStrategy == 'audioDuck')
120 root.startDuckingMedia();
121 else if (audioStrategy == 'audioSuspend')
122 root.suspendMedia();
123 } else if (options.end) {
124 if (audioStrategy == 'audioDuck')
125 root.stopDuckingMedia();
126 else if (audioStrategy == 'audioSuspend')
127 root.resumeMedia();
128 }
129 item = it.next();
130 }
45 } 131 }
46 }; 132 };
47 133
48 }); // goog.scope 134 }); // goog.scope
135
136 new MediaAutomationHandler();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698