1 // Copyright (c) 2012 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 "extensions/browser/api/bluetooth/bluetooth_api_utils.h"
6 
7 #include "base/strings/utf_string_conversions.h"
8 #include "base/values.h"
9 #include "build/chromeos_buildflags.h"
10 #include "device/bluetooth/bluetooth_adapter.h"
11 #include "device/bluetooth/bluetooth_common.h"
12 #include "device/bluetooth/bluetooth_device.h"
13 #include "extensions/common/api/bluetooth.h"
14 
15 namespace bluetooth = extensions::api::bluetooth;
16 
17 using bluetooth::VendorIdSource;
18 using device::BluetoothDevice;
19 using device::BluetoothDeviceType;
20 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
21 using device::BluetoothTransport;
22 #endif
23 
24 namespace {
25 
ConvertVendorIDSourceToApi(const BluetoothDevice::VendorIDSource & input,bluetooth::VendorIdSource * output)26 bool ConvertVendorIDSourceToApi(const BluetoothDevice::VendorIDSource& input,
27                                 bluetooth::VendorIdSource* output) {
28   switch (input) {
29     case BluetoothDevice::VENDOR_ID_UNKNOWN:
30       *output = bluetooth::VENDOR_ID_SOURCE_NONE;
31       return true;
32     case BluetoothDevice::VENDOR_ID_BLUETOOTH:
33       *output = bluetooth::VENDOR_ID_SOURCE_BLUETOOTH;
34       return true;
35     case BluetoothDevice::VENDOR_ID_USB:
36       *output = bluetooth::VENDOR_ID_SOURCE_USB;
37       return true;
38     default:
39       NOTREACHED();
40       return false;
41   }
42 }
43 
ConvertDeviceTypeToApi(const BluetoothDeviceType & input,bluetooth::DeviceType * output)44 bool ConvertDeviceTypeToApi(const BluetoothDeviceType& input,
45                             bluetooth::DeviceType* output) {
46   switch (input) {
47     case BluetoothDeviceType::UNKNOWN:
48       *output = bluetooth::DEVICE_TYPE_NONE;
49       return true;
50     case BluetoothDeviceType::COMPUTER:
51       *output = bluetooth::DEVICE_TYPE_COMPUTER;
52       return true;
53     case BluetoothDeviceType::PHONE:
54       *output = bluetooth::DEVICE_TYPE_PHONE;
55       return true;
56     case BluetoothDeviceType::MODEM:
57       *output = bluetooth::DEVICE_TYPE_MODEM;
58       return true;
59     case BluetoothDeviceType::AUDIO:
60       *output = bluetooth::DEVICE_TYPE_AUDIO;
61       return true;
62     case BluetoothDeviceType::CAR_AUDIO:
63       *output = bluetooth::DEVICE_TYPE_CARAUDIO;
64       return true;
65     case BluetoothDeviceType::VIDEO:
66       *output = bluetooth::DEVICE_TYPE_VIDEO;
67       return true;
68     case BluetoothDeviceType::PERIPHERAL:
69       *output = bluetooth::DEVICE_TYPE_PERIPHERAL;
70       return true;
71     case BluetoothDeviceType::JOYSTICK:
72       *output = bluetooth::DEVICE_TYPE_JOYSTICK;
73       return true;
74     case BluetoothDeviceType::GAMEPAD:
75       *output = bluetooth::DEVICE_TYPE_GAMEPAD;
76       return true;
77     case BluetoothDeviceType::KEYBOARD:
78       *output = bluetooth::DEVICE_TYPE_KEYBOARD;
79       return true;
80     case BluetoothDeviceType::MOUSE:
81       *output = bluetooth::DEVICE_TYPE_MOUSE;
82       return true;
83     case BluetoothDeviceType::TABLET:
84       *output = bluetooth::DEVICE_TYPE_TABLET;
85       return true;
86     case BluetoothDeviceType::KEYBOARD_MOUSE_COMBO:
87       *output = bluetooth::DEVICE_TYPE_KEYBOARDMOUSECOMBO;
88       return true;
89     default:
90       return false;
91   }
92 }
93 
94 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
ConvertTransportToApi(const BluetoothTransport & input,bluetooth::Transport * output)95 bool ConvertTransportToApi(const BluetoothTransport& input,
96                            bluetooth::Transport* output) {
97   switch (input) {
98     case BluetoothTransport::BLUETOOTH_TRANSPORT_INVALID:
99       *output = bluetooth::TRANSPORT_INVALID;
100       return true;
101     case BluetoothTransport::BLUETOOTH_TRANSPORT_CLASSIC:
102       *output = bluetooth::TRANSPORT_CLASSIC;
103       return true;
104     case BluetoothTransport::BLUETOOTH_TRANSPORT_LE:
105       *output = bluetooth::TRANSPORT_LE;
106       return true;
107     case BluetoothTransport::BLUETOOTH_TRANSPORT_DUAL:
108       *output = bluetooth::TRANSPORT_DUAL;
109       return true;
110     default:
111       return false;
112   }
113 }
114 #endif
115 
116 }  // namespace
117 
118 namespace extensions {
119 namespace api {
120 namespace bluetooth {
121 
BluetoothDeviceToApiDevice(const device::BluetoothDevice & device,Device * out)122 void BluetoothDeviceToApiDevice(const device::BluetoothDevice& device,
123                                 Device* out) {
124   out->address = device.GetAddress();
125   out->name.reset(
126       new std::string(base::UTF16ToUTF8(device.GetNameForDisplay())));
127   out->device_class.reset(new int(device.GetBluetoothClass()));
128 
129   // Only include the Device ID members when one exists for the device, and
130   // always include all or none.
131   if (ConvertVendorIDSourceToApi(device.GetVendorIDSource(),
132                                  &(out->vendor_id_source)) &&
133       out->vendor_id_source != VENDOR_ID_SOURCE_NONE) {
134     out->vendor_id.reset(new int(device.GetVendorID()));
135     out->product_id.reset(new int(device.GetProductID()));
136     out->device_id.reset(new int(device.GetDeviceID()));
137   }
138 
139   ConvertDeviceTypeToApi(device.GetDeviceType(), &(out->type));
140 
141   out->paired.reset(new bool(device.IsPaired()));
142   out->connected.reset(new bool(device.IsConnected()));
143   out->connecting.reset(new bool(device.IsConnecting()));
144   out->connectable.reset(new bool(device.IsConnectable()));
145 
146   std::vector<std::string>* string_uuids = new std::vector<std::string>();
147   const device::BluetoothDevice::UUIDSet& uuids = device.GetUUIDs();
148   for (const auto& uuid : uuids) {
149     string_uuids->push_back(uuid.canonical_value());
150   }
151   out->uuids.reset(string_uuids);
152 
153   if (device.GetInquiryRSSI())
154     out->inquiry_rssi.reset(new int(device.GetInquiryRSSI().value()));
155   else
156     out->inquiry_rssi.reset();
157 
158   if (device.GetInquiryTxPower())
159     out->inquiry_tx_power.reset(new int(device.GetInquiryTxPower().value()));
160   else
161     out->inquiry_tx_power.reset();
162 
163 #if BUILDFLAG(IS_CHROMEOS_ASH)
164   if (device.battery_percentage())
165     out->battery_percentage.reset(new int(device.battery_percentage().value()));
166   else
167     out->battery_percentage.reset();
168 #endif
169 
170 #if defined(OS_LINUX) || defined(OS_CHROMEOS)
171   ConvertTransportToApi(device.GetType(), &(out->transport));
172 #endif
173 }
174 
PopulateAdapterState(const device::BluetoothAdapter & adapter,AdapterState * out)175 void PopulateAdapterState(const device::BluetoothAdapter& adapter,
176                           AdapterState* out) {
177   out->discovering = adapter.IsDiscovering();
178   out->available = adapter.IsPresent();
179   out->powered = adapter.IsPowered();
180   out->name = adapter.GetName();
181   out->address = adapter.GetAddress();
182 }
183 
184 #if BUILDFLAG(IS_CHROMEOS_ASH)
ToBluetoothDeviceFilterType(FilterType type)185 device::BluetoothFilterType ToBluetoothDeviceFilterType(FilterType type) {
186   switch (type) {
187     case FilterType::FILTER_TYPE_NONE:
188     case FilterType::FILTER_TYPE_ALL:
189       return device::BluetoothFilterType::ALL;
190     case FilterType::FILTER_TYPE_KNOWN:
191       return device::BluetoothFilterType::KNOWN;
192     default:
193       NOTREACHED();
194   }
195 }
196 #endif
197 
198 }  // namespace bluetooth
199 }  // namespace api
200 }  // namespace extensions
201