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

Side by Side Diff: content/browser/media/capture/web_contents_audio_input_stream.cc

Issue 542863004: Site Isolation: RenderView-->RenderFrame for WebContentsVideoCaptureDevice and WebContentsAudioInpu… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months 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 (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 #include "content/browser/media/capture/web_contents_audio_input_stream.h" 5 #include "content/browser/media/capture/web_contents_audio_input_stream.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/threading/thread_checker.h" 13 #include "base/threading/thread_checker.h"
14 #include "content/browser/media/capture/audio_mirroring_manager.h" 14 #include "content/browser/media/capture/audio_mirroring_manager.h"
15 #include "content/browser/media/capture/web_contents_capture_util.h" 15 #include "content/browser/media/capture/web_contents_capture_util.h"
16 #include "content/browser/media/capture/web_contents_tracker.h" 16 #include "content/browser/media/capture/web_contents_tracker.h"
17 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "content/public/browser/render_frame_host.h"
19 #include "content/public/browser/web_contents.h"
18 #include "media/audio/virtual_audio_input_stream.h" 20 #include "media/audio/virtual_audio_input_stream.h"
19 #include "media/audio/virtual_audio_output_stream.h" 21 #include "media/audio/virtual_audio_output_stream.h"
22 #include "media/base/bind_to_current_loop.h"
20 23
21 namespace content { 24 namespace content {
22 25
23 class WebContentsAudioInputStream::Impl 26 class WebContentsAudioInputStream::Impl
24 : public base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>, 27 : public base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>,
25 public AudioMirroringManager::MirroringDestination { 28 public AudioMirroringManager::MirroringDestination {
26 public: 29 public:
27 // Takes ownership of |mixer_stream|. The rest outlive this instance. 30 // Takes ownership of |mixer_stream|. The rest outlive this instance.
28 Impl(int render_process_id, int main_render_frame_id, 31 Impl(int render_process_id, int main_render_frame_id,
29 AudioMirroringManager* mirroring_manager, 32 AudioMirroringManager* mirroring_manager,
(...skipping 15 matching lines...) Expand all
45 void Close(); 48 void Close();
46 49
47 // Accessor to underlying VirtualAudioInputStream. 50 // Accessor to underlying VirtualAudioInputStream.
48 media::VirtualAudioInputStream* mixer_stream() const { 51 media::VirtualAudioInputStream* mixer_stream() const {
49 return mixer_stream_.get(); 52 return mixer_stream_.get();
50 } 53 }
51 54
52 private: 55 private:
53 friend class base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>; 56 friend class base::RefCountedThreadSafe<WebContentsAudioInputStream::Impl>;
54 57
58 typedef AudioMirroringManager::SourceFrameRef SourceFrameRef;
59
55 enum State { 60 enum State {
56 CONSTRUCTED, 61 CONSTRUCTED,
57 OPENED, 62 OPENED,
58 MIRRORING, 63 MIRRORING,
59 CLOSED 64 CLOSED
60 }; 65 };
61 66
62 virtual ~Impl(); 67 virtual ~Impl();
63 68
64 // Returns true if the mirroring target has been permanently lost.
65 bool IsTargetLost() const;
66
67 // Notifies the consumer callback that the stream is now dead. 69 // Notifies the consumer callback that the stream is now dead.
68 void ReportError(); 70 void ReportError();
69 71
70 // Start/Stop mirroring by posting a call to AudioMirroringManager on the IO 72 // (Re-)Start/Stop mirroring by posting a call to AudioMirroringManager on the
71 // BrowserThread. 73 // IO BrowserThread.
72 void StartMirroring(); 74 void StartMirroring();
73 void StopMirroring(); 75 void StopMirroring();
74 76
75 // AudioMirroringManager::MirroringDestination implementation 77 // AudioMirroringManager::MirroringDestination implementation
78 virtual void QueryForMatches(
79 const std::set<SourceFrameRef>& candidates,
80 const MatchesCallback& results_callback) OVERRIDE;
81 void QueryForMatchesOnUIThread(const std::set<SourceFrameRef>& candidates,
82 const MatchesCallback& results_callback);
76 virtual media::AudioOutputStream* AddInput( 83 virtual media::AudioOutputStream* AddInput(
77 const media::AudioParameters& params) OVERRIDE; 84 const media::AudioParameters& params) OVERRIDE;
78 85
79 // Callback which is run when |stream| is closed. Deletes |stream|. 86 // Callback which is run when |stream| is closed. Deletes |stream|.
80 void ReleaseInput(media::VirtualAudioOutputStream* stream); 87 void ReleaseInput(media::VirtualAudioOutputStream* stream);
81 88
82 // Called by WebContentsTracker when the target of the audio mirroring has 89 // Called by WebContentsTracker when the target of the audio mirroring has
83 // changed. 90 // changed.
84 void OnTargetChanged(int render_process_id, int render_view_id); 91 void OnTargetChanged(RenderWidgetHost* target);
85 92
86 // Injected dependencies. 93 // Injected dependencies.
87 const int initial_render_process_id_; 94 const int initial_render_process_id_;
88 const int initial_main_render_frame_id_; 95 const int initial_main_render_frame_id_;
89 AudioMirroringManager* const mirroring_manager_; 96 AudioMirroringManager* const mirroring_manager_;
90 const scoped_refptr<WebContentsTracker> tracker_; 97 const scoped_refptr<WebContentsTracker> tracker_;
91 // The AudioInputStream implementation that handles the audio conversion and 98 // The AudioInputStream implementation that handles the audio conversion and
92 // mixing details. 99 // mixing details.
93 const scoped_ptr<media::VirtualAudioInputStream> mixer_stream_; 100 const scoped_ptr<media::VirtualAudioInputStream> mixer_stream_;
94 101
95 State state_; 102 State state_;
96 103
97 // Current audio mirroring target. 104 // Set to true if |tracker_| reports a NULL target, which indicates the target
98 bool target_identified_; 105 // is permanently lost.
99 int target_render_process_id_; 106 bool is_target_lost_;
100 int target_render_view_id_;
101 107
102 // Current callback used to consume the resulting mixed audio data. 108 // Current callback used to consume the resulting mixed audio data.
103 AudioInputCallback* callback_; 109 AudioInputCallback* callback_;
104 110
105 base::ThreadChecker thread_checker_; 111 base::ThreadChecker thread_checker_;
106 112
107 DISALLOW_COPY_AND_ASSIGN(Impl); 113 DISALLOW_COPY_AND_ASSIGN(Impl);
108 }; 114 };
109 115
110 WebContentsAudioInputStream::Impl::Impl( 116 WebContentsAudioInputStream::Impl::Impl(
111 int render_process_id, int main_render_frame_id, 117 int render_process_id, int main_render_frame_id,
112 AudioMirroringManager* mirroring_manager, 118 AudioMirroringManager* mirroring_manager,
113 const scoped_refptr<WebContentsTracker>& tracker, 119 const scoped_refptr<WebContentsTracker>& tracker,
114 media::VirtualAudioInputStream* mixer_stream) 120 media::VirtualAudioInputStream* mixer_stream)
115 : initial_render_process_id_(render_process_id), 121 : initial_render_process_id_(render_process_id),
116 initial_main_render_frame_id_(main_render_frame_id), 122 initial_main_render_frame_id_(main_render_frame_id),
117 mirroring_manager_(mirroring_manager), 123 mirroring_manager_(mirroring_manager),
118 tracker_(tracker), 124 tracker_(tracker),
119 mixer_stream_(mixer_stream), 125 mixer_stream_(mixer_stream),
120 state_(CONSTRUCTED), 126 state_(CONSTRUCTED),
121 target_identified_(false), 127 is_target_lost_(false),
122 target_render_process_id_(-1),
123 target_render_view_id_(-1),
124 callback_(NULL) { 128 callback_(NULL) {
125 DCHECK(mirroring_manager_); 129 DCHECK(mirroring_manager_);
126 DCHECK(tracker_.get()); 130 DCHECK(tracker_.get());
127 DCHECK(mixer_stream_.get()); 131 DCHECK(mixer_stream_.get());
128 132
129 // WAIS::Impl can be constructed on any thread, but will DCHECK that all 133 // WAIS::Impl can be constructed on any thread, but will DCHECK that all
130 // its methods from here on are called from the same thread. 134 // its methods from here on are called from the same thread.
131 thread_checker_.DetachFromThread(); 135 thread_checker_.DetachFromThread();
132 } 136 }
133 137
(...skipping 19 matching lines...) Expand all
153 } 157 }
154 158
155 void WebContentsAudioInputStream::Impl::Start(AudioInputCallback* callback) { 159 void WebContentsAudioInputStream::Impl::Start(AudioInputCallback* callback) {
156 DCHECK(thread_checker_.CalledOnValidThread()); 160 DCHECK(thread_checker_.CalledOnValidThread());
157 DCHECK(callback); 161 DCHECK(callback);
158 162
159 if (state_ != OPENED) 163 if (state_ != OPENED)
160 return; 164 return;
161 165
162 callback_ = callback; 166 callback_ = callback;
163 if (IsTargetLost()) { 167 if (is_target_lost_) {
164 ReportError(); 168 ReportError();
165 callback_ = NULL; 169 callback_ = NULL;
166 return; 170 return;
167 } 171 }
168 172
169 state_ = MIRRORING; 173 state_ = MIRRORING;
170 mixer_stream_->Start(callback); 174 mixer_stream_->Start(callback);
171 175
172 StartMirroring(); 176 StartMirroring();
173 } 177 }
174 178
175 void WebContentsAudioInputStream::Impl::Stop() { 179 void WebContentsAudioInputStream::Impl::Stop() {
176 DCHECK(thread_checker_.CalledOnValidThread()); 180 DCHECK(thread_checker_.CalledOnValidThread());
177 181
178 if (state_ != MIRRORING) 182 if (state_ != MIRRORING)
179 return; 183 return;
180 184
181 state_ = OPENED; 185 state_ = OPENED;
182 186
183 mixer_stream_->Stop(); 187 mixer_stream_->Stop();
184 callback_ = NULL; 188 callback_ = NULL;
185 189
186 if (!IsTargetLost()) 190 StopMirroring();
187 StopMirroring();
188 } 191 }
189 192
190 void WebContentsAudioInputStream::Impl::Close() { 193 void WebContentsAudioInputStream::Impl::Close() {
191 DCHECK(thread_checker_.CalledOnValidThread()); 194 DCHECK(thread_checker_.CalledOnValidThread());
192 195
193 Stop(); 196 Stop();
194 197
195 if (state_ == OPENED) { 198 if (state_ == OPENED) {
196 state_ = CONSTRUCTED; 199 state_ = CONSTRUCTED;
197 tracker_->Stop(); 200 tracker_->Stop();
198 mixer_stream_->Close(); 201 mixer_stream_->Close();
199 } 202 }
200 203
201 DCHECK_EQ(CONSTRUCTED, state_); 204 DCHECK_EQ(CONSTRUCTED, state_);
202 state_ = CLOSED; 205 state_ = CLOSED;
203 } 206 }
204 207
205 bool WebContentsAudioInputStream::Impl::IsTargetLost() const {
206 DCHECK(thread_checker_.CalledOnValidThread());
207 if (!target_identified_)
208 return false;
209 return target_render_process_id_ <= 0 || target_render_view_id_ <= 0;
210 }
211
212 void WebContentsAudioInputStream::Impl::ReportError() { 208 void WebContentsAudioInputStream::Impl::ReportError() {
213 DCHECK(thread_checker_.CalledOnValidThread()); 209 DCHECK(thread_checker_.CalledOnValidThread());
214 210
215 // TODO(miu): Need clean-up of AudioInputCallback interface in a future 211 // TODO(miu): Need clean-up of AudioInputCallback interface in a future
216 // change, since its only implementation ignores the first argument entirely 212 // change, since its only implementation ignores the first argument entirely
217 callback_->OnError(NULL); 213 callback_->OnError(NULL);
218 } 214 }
219 215
220 void WebContentsAudioInputStream::Impl::StartMirroring() { 216 void WebContentsAudioInputStream::Impl::StartMirroring() {
221 DCHECK(thread_checker_.CalledOnValidThread()); 217 DCHECK(thread_checker_.CalledOnValidThread());
222 218
223 BrowserThread::PostTask( 219 BrowserThread::PostTask(
224 BrowserThread::IO, 220 BrowserThread::IO,
225 FROM_HERE, 221 FROM_HERE,
226 base::Bind(&AudioMirroringManager::StartMirroring, 222 base::Bind(&AudioMirroringManager::StartMirroring,
227 base::Unretained(mirroring_manager_), 223 base::Unretained(mirroring_manager_),
228 target_render_process_id_, target_render_view_id_,
229 make_scoped_refptr(this))); 224 make_scoped_refptr(this)));
230 } 225 }
231 226
232 void WebContentsAudioInputStream::Impl::StopMirroring() { 227 void WebContentsAudioInputStream::Impl::StopMirroring() {
233 DCHECK(thread_checker_.CalledOnValidThread()); 228 DCHECK(thread_checker_.CalledOnValidThread());
234 229
235 BrowserThread::PostTask( 230 BrowserThread::PostTask(
236 BrowserThread::IO, 231 BrowserThread::IO,
237 FROM_HERE, 232 FROM_HERE,
238 base::Bind(&AudioMirroringManager::StopMirroring, 233 base::Bind(&AudioMirroringManager::StopMirroring,
239 base::Unretained(mirroring_manager_), 234 base::Unretained(mirroring_manager_),
240 target_render_process_id_, target_render_view_id_,
241 make_scoped_refptr(this))); 235 make_scoped_refptr(this)));
242 } 236 }
243 237
238 void WebContentsAudioInputStream::Impl::QueryForMatches(
239 const std::set<SourceFrameRef>& candidates,
240 const MatchesCallback& results_callback) {
241 BrowserThread::PostTask(
242 BrowserThread::UI,
243 FROM_HERE,
244 base::Bind(&Impl::QueryForMatchesOnUIThread,
245 this,
246 candidates,
247 media::BindToCurrentLoop(results_callback)));
248 }
249
250 void WebContentsAudioInputStream::Impl::QueryForMatchesOnUIThread(
251 const std::set<SourceFrameRef>& candidates,
252 const MatchesCallback& results_callback) {
253 DCHECK_CURRENTLY_ON(BrowserThread::UI);
254
255 std::set<SourceFrameRef> matches;
256 WebContents* const contents = tracker_->web_contents();
257 if (contents) {
258 // Add each ID to |matches| if it maps to a RenderFrameHost that maps to the
259 // currently-tracked WebContents.
260 for (std::set<SourceFrameRef>::const_iterator i = candidates.begin();
261 i != candidates.end(); ++i) {
262 WebContents* const contents_containing_frame =
263 WebContents::FromRenderFrameHost(
264 RenderFrameHost::FromID(i->first, i->second));
265 if (contents_containing_frame == contents)
266 matches.insert(*i);
267 }
268 }
269
270 results_callback.Run(matches);
271 }
272
244 media::AudioOutputStream* WebContentsAudioInputStream::Impl::AddInput( 273 media::AudioOutputStream* WebContentsAudioInputStream::Impl::AddInput(
245 const media::AudioParameters& params) { 274 const media::AudioParameters& params) {
246 // Note: The closure created here holds a reference to "this," which will 275 // Note: The closure created here holds a reference to "this," which will
247 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the 276 // guarantee the VirtualAudioInputStream (mixer_stream_) outlives the
248 // VirtualAudioOutputStream. 277 // VirtualAudioOutputStream.
249 return new media::VirtualAudioOutputStream( 278 return new media::VirtualAudioOutputStream(
250 params, 279 params,
251 mixer_stream_.get(), 280 mixer_stream_.get(),
252 base::Bind(&Impl::ReleaseInput, this)); 281 base::Bind(&Impl::ReleaseInput, this));
253 } 282 }
254 283
255 void WebContentsAudioInputStream::Impl::ReleaseInput( 284 void WebContentsAudioInputStream::Impl::ReleaseInput(
256 media::VirtualAudioOutputStream* stream) { 285 media::VirtualAudioOutputStream* stream) {
257 delete stream; 286 delete stream;
258 } 287 }
259 288
260 void WebContentsAudioInputStream::Impl::OnTargetChanged(int render_process_id, 289 void WebContentsAudioInputStream::Impl::OnTargetChanged(
261 int render_view_id) { 290 RenderWidgetHost* target) {
262 DCHECK(thread_checker_.CalledOnValidThread()); 291 DCHECK(thread_checker_.CalledOnValidThread());
263 292
264 if (target_identified_ && 293 is_target_lost_ = !target;
265 target_render_process_id_ == render_process_id &&
266 target_render_view_id_ == render_view_id) {
267 return;
268 }
269
270 DVLOG(1) << "Target RenderView has changed from "
271 << target_render_process_id_ << ':' << target_render_view_id_
272 << " to " << render_process_id << ':' << render_view_id;
273
274 if (state_ == MIRRORING)
275 StopMirroring();
276
277 target_identified_ = true;
278 target_render_process_id_ = render_process_id;
279 target_render_view_id_ = render_view_id;
280 294
281 if (state_ == MIRRORING) { 295 if (state_ == MIRRORING) {
282 if (IsTargetLost()) { 296 if (is_target_lost_) {
283 ReportError(); 297 ReportError();
284 Stop(); 298 Stop();
285 } else { 299 } else {
286 StartMirroring(); 300 StartMirroring();
287 } 301 }
288 } 302 }
289 } 303 }
290 304
291 // static 305 // static
292 WebContentsAudioInputStream* WebContentsAudioInputStream::Create( 306 WebContentsAudioInputStream* WebContentsAudioInputStream::Create(
293 const std::string& device_id, 307 const std::string& device_id,
294 const media::AudioParameters& params, 308 const media::AudioParameters& params,
295 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, 309 const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
296 AudioMirroringManager* audio_mirroring_manager) { 310 AudioMirroringManager* audio_mirroring_manager) {
297 int render_process_id; 311 int render_process_id;
298 int main_render_frame_id; 312 int main_render_frame_id;
299 if (!WebContentsCaptureUtil::ExtractTabCaptureTarget( 313 if (!WebContentsCaptureUtil::ExtractTabCaptureTarget(
300 device_id, &render_process_id, &main_render_frame_id)) { 314 device_id, &render_process_id, &main_render_frame_id)) {
301 return NULL; 315 return NULL;
302 } 316 }
303 317
304 return new WebContentsAudioInputStream( 318 return new WebContentsAudioInputStream(
305 render_process_id, main_render_frame_id, 319 render_process_id, main_render_frame_id,
306 audio_mirroring_manager, 320 audio_mirroring_manager,
307 new WebContentsTracker(), 321 new WebContentsTracker(false),
308 new media::VirtualAudioInputStream( 322 new media::VirtualAudioInputStream(
309 params, worker_task_runner, 323 params, worker_task_runner,
310 media::VirtualAudioInputStream::AfterCloseCallback())); 324 media::VirtualAudioInputStream::AfterCloseCallback()));
311 } 325 }
312 326
313 WebContentsAudioInputStream::WebContentsAudioInputStream( 327 WebContentsAudioInputStream::WebContentsAudioInputStream(
314 int render_process_id, int main_render_frame_id, 328 int render_process_id, int main_render_frame_id,
315 AudioMirroringManager* mirroring_manager, 329 AudioMirroringManager* mirroring_manager,
316 const scoped_refptr<WebContentsTracker>& tracker, 330 const scoped_refptr<WebContentsTracker>& tracker,
317 media::VirtualAudioInputStream* mixer_stream) 331 media::VirtualAudioInputStream* mixer_stream)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 365
352 void WebContentsAudioInputStream::SetAutomaticGainControl(bool enabled) { 366 void WebContentsAudioInputStream::SetAutomaticGainControl(bool enabled) {
353 impl_->mixer_stream()->SetAutomaticGainControl(enabled); 367 impl_->mixer_stream()->SetAutomaticGainControl(enabled);
354 } 368 }
355 369
356 bool WebContentsAudioInputStream::GetAutomaticGainControl() { 370 bool WebContentsAudioInputStream::GetAutomaticGainControl() {
357 return impl_->mixer_stream()->GetAutomaticGainControl(); 371 return impl_->mixer_stream()->GetAutomaticGainControl();
358 } 372 }
359 373
360 } // namespace content 374 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698