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

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

Powered by Google App Engine
This is Rietveld 408576698