1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/mojo/services/mojo_audio_input_stream.h"
10 #include "base/functional/bind.h"
11 #include "base/functional/callback_helpers.h"
12 #include "base/memory/read_only_shared_memory_region.h"
13 #include "base/sync_socket.h"
14 #include "base/task/single_thread_task_runner.h"
15 #include "mojo/public/cpp/system/platform_handle.h"
16 #include "third_party/abseil-cpp/absl/utility/utility.h"
20 MojoAudioInputStream::MojoAudioInputStream(
21 mojo::PendingReceiver<mojom::AudioInputStream> receiver,
22 mojo::PendingRemote<mojom::AudioInputStreamClient> client,
23 CreateDelegateCallback create_delegate_callback,
24 StreamCreatedCallback stream_created_callback,
25 base::OnceClosure deleter_callback)
26 : stream_created_callback_(std::move(stream_created_callback)),
27 deleter_callback_(std::move(deleter_callback)),
28 receiver_(this, std::move(receiver)),
29 client_(std::move(client)) {
30 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
31 DCHECK(stream_created_callback_);
32 DCHECK(deleter_callback_);
33 // |this| owns |receiver_|, so unretained is safe.
34 receiver_.set_disconnect_handler(
35 base::BindOnce(&MojoAudioInputStream::OnError, base::Unretained(this)));
36 client_.set_disconnect_handler(
37 base::BindOnce(&MojoAudioInputStream::OnError, base::Unretained(this)));
38 delegate_ = std::move(create_delegate_callback).Run(this);
40 // Failed to initialize the stream. We cannot call |deleter_callback_| yet,
41 // since construction isn't done.
43 base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
45 base::BindOnce(&MojoAudioInputStream::OnStreamError,
46 weak_factory_.GetWeakPtr(), /* not used */ 0));
50 MojoAudioInputStream::~MojoAudioInputStream() {
51 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
54 void MojoAudioInputStream::SetOutputDeviceForAec(
55 const std::string& raw_output_device_id) {
56 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
57 delegate_->OnSetOutputDeviceForAec(raw_output_device_id);
60 void MojoAudioInputStream::Record() {
61 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
62 delegate_->OnRecordStream();
65 void MojoAudioInputStream::SetVolume(double volume) {
66 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
67 if (volume < 0 || volume > 1) {
68 LOG(ERROR) << "MojoAudioInputStream::SetVolume(" << volume
70 OnStreamError(/*not used*/ 0);
73 delegate_->OnSetVolume(volume);
76 void MojoAudioInputStream::OnStreamCreated(
78 base::ReadOnlySharedMemoryRegion shared_memory_region,
79 std::unique_ptr<base::CancelableSyncSocket> foreign_socket,
80 bool initially_muted) {
81 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
82 DCHECK(stream_created_callback_);
83 DCHECK(foreign_socket);
85 if (!shared_memory_region.IsValid()) {
86 OnStreamError(/*not used*/ 0);
90 DCHECK(foreign_socket->IsValid());
91 mojo::PlatformHandle socket_handle(foreign_socket->Take());
93 std::move(stream_created_callback_)
94 .Run({absl::in_place, std::move(shared_memory_region),
95 std::move(socket_handle)},
99 void MojoAudioInputStream::OnStreamError(int stream_id) {
100 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
101 client_->OnError(mojom::InputStreamErrorCode::kUnknown);
105 void MojoAudioInputStream::OnError() {
106 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
107 DCHECK(deleter_callback_);
108 std::move(deleter_callback_).Run(); // Deletes |this|.