bluetooth_device.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "device/bluetooth/bluetooth_device.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "device/bluetooth/bluetooth_utils.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/device_bluetooth_strings.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace device {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BluetoothDevice::IsUUIDValid(const std::string& uuid) {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return !bluetooth_utils::CanonicalUuid(uuid).empty();
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)BluetoothDevice::BluetoothDevice() {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothDevice::~BluetoothDevice() {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BluetoothDevice::GetName() const {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string name = GetDeviceName();
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!name.empty()) {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::UTF8ToUTF16(name);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GetAddressWithLocalizedDeviceTypeName();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() const {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::string16 address_utf16 = base::UTF8ToUTF16(GetAddress());
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BluetoothDevice::DeviceType device_type = GetDeviceType();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (device_type) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_COMPUTER:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_COMPUTER,
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_PHONE:
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_PHONE,
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_MODEM:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MODEM,
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_AUDIO:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_AUDIO,
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_CAR_AUDIO:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_CAR_AUDIO,
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_VIDEO:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_VIDEO,
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_JOYSTICK:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_JOYSTICK,
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_GAMEPAD:
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_GAMEPAD,
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_KEYBOARD:
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_KEYBOARD,
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_MOUSE:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_MOUSE,
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_TABLET:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_TABLET,
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case DEVICE_KEYBOARD_MOUSE_COMBO:
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return l10n_util::GetStringFUTF16(
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          IDS_BLUETOOTH_DEVICE_KEYBOARD_MOUSE_COMBO, address_utf16);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return l10n_util::GetStringFUTF16(IDS_BLUETOOTH_DEVICE_UNKNOWN,
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        address_utf16);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BluetoothDevice::DeviceType BluetoothDevice::GetDeviceType() const {
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  uint32 bluetooth_class = GetBluetoothClass();
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch ((bluetooth_class & 0x1f00) >> 8) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x01:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Computer major device class.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return DEVICE_COMPUTER;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x02:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Phone major device class.
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switch ((bluetooth_class & 0xfc) >> 2) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x01:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x02:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x03:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Cellular, cordless and smart phones.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_PHONE;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x04:
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x05:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Modems: wired or voice gateway and common ISDN access.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_MODEM;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x04:
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Audio major device class.
105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switch ((bluetooth_class & 0xfc) >> 2) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x08:
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Car audio.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_CAR_AUDIO;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0b:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0c:
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0d:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0e:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x0f:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x010:
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Video devices.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_VIDEO;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_AUDIO;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 0x05:
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Peripheral major device class.
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      switch ((bluetooth_class & 0xc0) >> 6) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x00:
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // "Not a keyboard or pointing device."
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switch ((bluetooth_class & 0x01e) >> 2) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case 0x01:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Joystick.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_JOYSTICK;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case 0x02:
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Gamepad.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_GAMEPAD;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_PERIPHERAL;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x01:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Keyboard.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_KEYBOARD;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x02:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Pointing device.
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          switch ((bluetooth_class & 0x01e) >> 2) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case 0x05:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Digitizer tablet.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_TABLET;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            default:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              // Mouse.
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              return DEVICE_MOUSE;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case 0x03:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          // Combo device.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return DEVICE_KEYBOARD_MOUSE_COMBO;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return DEVICE_UNKNOWN;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool BluetoothDevice::IsPairable() const {
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeviceType type = GetDeviceType();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the vendor part of the address: "00:11:22" for "00:11:22:33:44:55"
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string vendor = GetAddress().substr(0, 8);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Verbatim "Bluetooth Mouse", model 96674
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if ((type == DEVICE_MOUSE && vendor == "00:12:A1") ||
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Microsoft "Microsoft Bluetooth Notebook Mouse 5000", model X807028-001
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      (type == DEVICE_MOUSE && vendor == "7C:ED:8D"))
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO: Move this database into a config file.
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool BluetoothDevice::ProvidesServiceWithUUID(
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& uuid) const {
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string canonical_uuid = bluetooth_utils::CanonicalUuid(uuid);
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  BluetoothDevice::ServiceList services = GetServices();
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (BluetoothDevice::ServiceList::const_iterator iter = services.begin();
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != services.end();
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++iter) {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (bluetooth_utils::CanonicalUuid(*iter) == canonical_uuid)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace device
191