Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / services / device / serial / serial_port_manager_impl.cc
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.
4
5 #include "services/device/serial/serial_port_manager_impl.h"
6
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "device/bluetooth/bluetooth_adapter_factory.h"
15 #include "services/device/public/cpp/serial/serial_switches.h"
16 #include "services/device/serial/bluetooth_serial_device_enumerator.h"
17 #include "services/device/serial/bluetooth_serial_port_impl.h"
18 #include "services/device/serial/serial_device_enumerator.h"
19 #include "services/device/serial/serial_port_impl.h"
20
21 namespace device {
22
23 namespace {
24
25 void OnPortOpened(mojom::SerialPortManager::OpenPortCallback callback,
26                   const scoped_refptr<base::TaskRunner>& task_runner,
27                   mojo::PendingRemote<mojom::SerialPort> port) {
28   task_runner->PostTask(FROM_HERE,
29                         base::BindOnce(std::move(callback), std::move(port)));
30 }
31
32 }  // namespace
33
34 SerialPortManagerImpl::SerialPortManagerImpl(
35     scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
36     scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
37     : io_task_runner_(std::move(io_task_runner)),
38       ui_task_runner_(std::move(ui_task_runner)) {
39   DETACH_FROM_SEQUENCE(sequence_checker_);
40 }
41
42 SerialPortManagerImpl::~SerialPortManagerImpl() {
43   // Intentionally do not check sequence. See class comment doc for more info.
44 }
45
46 void SerialPortManagerImpl::Bind(
47     mojo::PendingReceiver<mojom::SerialPortManager> receiver) {
48   receivers_.Add(this, std::move(receiver));
49 }
50
51 void SerialPortManagerImpl::SetSerialEnumeratorForTesting(
52     std::unique_ptr<SerialDeviceEnumerator> fake_enumerator) {
53   DCHECK(fake_enumerator);
54   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
55   enumerator_ = std::move(fake_enumerator);
56   observed_enumerator_.AddObservation(enumerator_.get());
57 }
58
59 void SerialPortManagerImpl::SetBluetoothSerialEnumeratorForTesting(
60     std::unique_ptr<BluetoothSerialDeviceEnumerator>
61         fake_bluetooth_enumerator) {
62   DCHECK(fake_bluetooth_enumerator);
63   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
64   bluetooth_enumerator_ = std::move(fake_bluetooth_enumerator);
65   observed_enumerator_.AddObservation(bluetooth_enumerator_.get());
66 }
67
68 void SerialPortManagerImpl::SetClient(
69     mojo::PendingRemote<mojom::SerialPortManagerClient> client) {
70   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
71   clients_.Add(std::move(client));
72 }
73
74 void SerialPortManagerImpl::GetDevices(GetDevicesCallback callback) {
75   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
76   if (!enumerator_) {
77     enumerator_ = SerialDeviceEnumerator::Create(ui_task_runner_);
78     observed_enumerator_.AddObservation(enumerator_.get());
79   }
80   auto devices = enumerator_->GetDevices();
81   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
82           switches::kEnableBluetoothSerialPortProfileInSerialApi)) {
83     if (!bluetooth_enumerator_) {
84       bluetooth_enumerator_ =
85           std::make_unique<BluetoothSerialDeviceEnumerator>(ui_task_runner_);
86       observed_enumerator_.AddObservation(bluetooth_enumerator_.get());
87     }
88     auto bluetooth_devices = bluetooth_enumerator_->GetDevices();
89     devices.insert(devices.end(),
90                    std::make_move_iterator(bluetooth_devices.begin()),
91                    std::make_move_iterator(bluetooth_devices.end()));
92   }
93
94   std::move(callback).Run(std::move(devices));
95 }
96
97 void SerialPortManagerImpl::OpenPort(
98     const base::UnguessableToken& token,
99     bool use_alternate_path,
100     device::mojom::SerialConnectionOptionsPtr options,
101     mojo::PendingRemote<mojom::SerialPortClient> client,
102     mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher,
103     OpenPortCallback callback) {
104   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
105   if (!enumerator_) {
106     enumerator_ = SerialDeviceEnumerator::Create(ui_task_runner_);
107     observed_enumerator_.AddObservation(enumerator_.get());
108   }
109   absl::optional<base::FilePath> path =
110       enumerator_->GetPathFromToken(token, use_alternate_path);
111   if (path) {
112     io_task_runner_->PostTask(
113         FROM_HERE,
114         base::BindOnce(&SerialPortImpl::Open, *path, std::move(options),
115                        std::move(client), std::move(watcher), ui_task_runner_,
116                        base::BindOnce(&OnPortOpened, std::move(callback),
117                                       base::SequencedTaskRunnerHandle::Get())));
118     return;
119   }
120
121   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
122           switches::kEnableBluetoothSerialPortProfileInSerialApi)) {
123     if (!bluetooth_enumerator_) {
124       bluetooth_enumerator_ =
125           std::make_unique<BluetoothSerialDeviceEnumerator>(ui_task_runner_);
126       observed_enumerator_.AddObservation(bluetooth_enumerator_.get());
127     }
128     absl::optional<std::string> address =
129         bluetooth_enumerator_->GetAddressFromToken(token);
130     if (address) {
131       const BluetoothUUID service_class_id =
132           bluetooth_enumerator_->GetServiceClassIdFromToken(token);
133       ui_task_runner_->PostTask(
134           FROM_HERE,
135           base::BindOnce(
136               &SerialPortManagerImpl::OpenBluetoothSerialPortOnUI,
137               weak_factory_.GetWeakPtr(), *address, service_class_id,
138               std::move(options), std::move(client), std::move(watcher),
139               base::BindOnce(&OnPortOpened, std::move(callback),
140                              base::SequencedTaskRunnerHandle::Get())));
141       return;
142     }
143   }
144
145   std::move(callback).Run(mojo::NullRemote());
146 }
147
148 void SerialPortManagerImpl::OpenBluetoothSerialPortOnUI(
149     const std::string& address,
150     const BluetoothUUID& service_class_id,
151     mojom::SerialConnectionOptionsPtr options,
152     mojo::PendingRemote<mojom::SerialPortClient> client,
153     mojo::PendingRemote<mojom::SerialPortConnectionWatcher> watcher,
154     BluetoothSerialPortImpl::OpenCallback callback) {
155   BluetoothSerialPortImpl::Open(bluetooth_enumerator_->GetAdapter(), address,
156                                 service_class_id, std::move(options),
157                                 std::move(client), std::move(watcher),
158                                 std::move(callback));
159 }
160
161 void SerialPortManagerImpl::OnPortAdded(const mojom::SerialPortInfo& port) {
162   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
163   for (auto& client : clients_)
164     client->OnPortAdded(port.Clone());
165 }
166
167 void SerialPortManagerImpl::OnPortRemoved(const mojom::SerialPortInfo& port) {
168   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
169   for (auto& client : clients_)
170     client->OnPortRemoved(port.Clone());
171 }
172
173 }  // namespace device