OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "content/renderer/media/audio_ipc_factory.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/memory/ptr_util.h" | |
11 #include "base/single_thread_task_runner.h" | |
12 #include "content/renderer/media/audio_message_filter.h" | |
13 #include "content/renderer/media/mojo_audio_output_ipc.h" | |
14 #include "services/service_manager/public/cpp/interface_provider.h" | |
15 | |
16 namespace content { | |
17 | |
18 AudioIPCFactory* AudioIPCFactory::instance_ = nullptr; | |
19 | |
20 AudioIPCFactory::AudioIPCFactory( | |
21 const scoped_refptr<AudioMessageFilter>& audio_message_filter, | |
22 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) | |
23 : audio_message_filter_(audio_message_filter), | |
24 io_task_runner_(io_task_runner) { | |
25 // TODO(maxmorin): In the future, use a feature to control whether | |
26 // audio_message_filter should be used. | |
27 DCHECK(!instance_); | |
28 instance_ = this; | |
29 } | |
30 | |
31 AudioIPCFactory::~AudioIPCFactory() { | |
32 // Allow destruction in tests. | |
33 DCHECK_EQ(instance_, this); | |
34 instance_ = nullptr; | |
35 } | |
36 | |
37 std::unique_ptr<media::AudioOutputIPC> AudioIPCFactory::CreateAudioOutputIPC( | |
38 int frame_id) const { | |
39 if (UsingMojoFactories()) { | |
40 // Unretained is safe due to the contract at the top of the header file. | |
41 return base::MakeUnique<MojoAudioOutputIPC>(base::BindRepeating( | |
42 &AudioIPCFactory::GetRemoteFactory, base::Unretained(this), frame_id)); | |
43 } | |
44 return audio_message_filter_->CreateAudioOutputIPC(frame_id); | |
45 } | |
46 | |
47 void AudioIPCFactory::MaybeRegisterRemoteFactory( | |
48 int frame_id, | |
49 service_manager::InterfaceProvider* interface_provider) { | |
50 if (!UsingMojoFactories()) | |
51 return; | |
52 mojom::RendererAudioOutputStreamFactoryPtr factory_ptr; | |
53 interface_provider->GetInterface(&factory_ptr); | |
54 // PassInterface unbinds the message pipe from the current thread. This | |
55 // allows us to bind it to the IO thread. | |
56 // Unretained is safe due to the contract at the top of the header file. | |
57 io_task_runner_->PostTask( | |
58 FROM_HERE, | |
59 base::BindOnce(&AudioIPCFactory::RegisterRemoteFactoryOnIOThread, | |
60 base::Unretained(this), frame_id, | |
61 factory_ptr.PassInterface())); | |
62 } | |
63 | |
64 void AudioIPCFactory::MaybeDeregisterRemoteFactory(int frame_id) { | |
65 if (!UsingMojoFactories()) | |
66 return; | |
67 if (!io_task_runner_->BelongsToCurrentThread()) { | |
DaleCurtis
2017/05/31 20:48:09
Since MaybeRegisterRemoteFactory() doesn't add the
Max Morin
2017/06/01 13:58:42
Hmm, this is only called from the main thread in p
| |
68 // Unretained is safe due to the contract at the top of the header file. | |
69 io_task_runner_->PostTask( | |
70 FROM_HERE, | |
71 base::BindOnce(&AudioIPCFactory::MaybeDeregisterRemoteFactory, | |
72 base::Unretained(this), frame_id)); | |
73 return; | |
74 } | |
75 factory_ptrs_.erase(frame_id); | |
76 } | |
77 | |
78 mojom::RendererAudioOutputStreamFactory* AudioIPCFactory::GetRemoteFactory( | |
79 int frame_id) const { | |
80 DCHECK(io_task_runner_->BelongsToCurrentThread()); | |
81 DCHECK(UsingMojoFactories()); | |
82 auto it = factory_ptrs_.find(frame_id); | |
83 return it == factory_ptrs_.end() ? nullptr : it->second.get(); | |
84 } | |
85 | |
86 void AudioIPCFactory::RegisterRemoteFactoryOnIOThread( | |
87 int frame_id, | |
88 mojom::RendererAudioOutputStreamFactoryPtrInfo factory_ptr_info) { | |
89 DCHECK(io_task_runner_->BelongsToCurrentThread()); | |
90 DCHECK(UsingMojoFactories()); | |
91 std::pair<StreamFactoryMap::iterator, bool> emplace_result = | |
92 factory_ptrs_.emplace(frame_id, | |
93 mojo::MakeProxy(std::move(factory_ptr_info))); | |
94 | |
95 DCHECK(emplace_result.second) << "Attempt to register a factory for a " | |
96 "frame which already has a factory " | |
97 "registered."; | |
98 | |
99 auto& emplaced_factory = emplace_result.first->second; | |
100 DCHECK(emplaced_factory.is_bound()) | |
101 << "Factory is not bound to a remote implementation."; | |
102 | |
103 // Unretained is safe because |this| owns the binding, so a connection error | |
104 // cannot trigger after destruction. | |
105 emplaced_factory.set_connection_error_handler( | |
106 base::Bind(&AudioIPCFactory::MaybeDeregisterRemoteFactory, | |
107 base::Unretained(this), frame_id)); | |
108 } | |
109 | |
110 bool AudioIPCFactory::UsingMojoFactories() const { | |
111 return audio_message_filter_ == nullptr; | |
112 } | |
113 | |
114 } // namespace content | |
OLD | NEW |