1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134

content / web_test / browser / fake_bluetooth_delegate.h [blame]

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_WEB_TEST_BROWSER_FAKE_BLUETOOTH_DELEGATE_H_
#define CONTENT_WEB_TEST_BROWSER_FAKE_BLUETOOTH_DELEGATE_H_

#include <map>
#include <string>
#include <utility>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "content/public/browser/bluetooth_delegate.h"
#include "third_party/blink/public/mojom/bluetooth/web_bluetooth.mojom-forward.h"

namespace blink {
class WebBluetoothDeviceId;
}  // namespace blink

namespace device {
class BluetoothDevice;
class BluetoothUUID;
}  // namespace device

namespace url {
class Origin;
}  // namespace url

namespace content {

class RenderFrameHost;

// Fakes Web Bluetooth permissions for web tests by emulating Chrome's
// implementation.
class FakeBluetoothDelegate : public BluetoothDelegate {
 public:
  FakeBluetoothDelegate();
  ~FakeBluetoothDelegate() override;

  // Move-only class.
  FakeBluetoothDelegate(const FakeBluetoothDelegate&) = delete;
  FakeBluetoothDelegate& operator=(const FakeBluetoothDelegate&) = delete;

  // BluetoothDelegate implementation:
  std::unique_ptr<BluetoothChooser> RunBluetoothChooser(
      RenderFrameHost* frame,
      const BluetoothChooser::EventHandler& event_handler) override;
  std::unique_ptr<BluetoothScanningPrompt> ShowBluetoothScanningPrompt(
      RenderFrameHost* frame,
      const BluetoothScanningPrompt::EventHandler& event_handler) override;

  void ShowDevicePairPrompt(RenderFrameHost* frame,
                            const std::u16string& device_identifier,
                            PairPromptCallback callback,
                            PairingKind pairing_kind,
                            const std::optional<std::u16string>& pin) override;

  blink::WebBluetoothDeviceId GetWebBluetoothDeviceId(
      RenderFrameHost* frame,
      const std::string& device_address) override;
  std::string GetDeviceAddress(RenderFrameHost* frame,
                               const blink::WebBluetoothDeviceId&) override;
  blink::WebBluetoothDeviceId AddScannedDevice(
      RenderFrameHost* frame,
      const std::string& device_address) override;
  blink::WebBluetoothDeviceId GrantServiceAccessPermission(
      RenderFrameHost* frame,
      const device::BluetoothDevice* device,
      const blink::mojom::WebBluetoothRequestDeviceOptions* options) override;
  bool HasDevicePermission(
      RenderFrameHost* frame,
      const blink::WebBluetoothDeviceId& device_id) override;
  void RevokeDevicePermissionWebInitiated(
      RenderFrameHost* frame,
      const blink::WebBluetoothDeviceId& device_id) override;
  bool MayUseBluetooth(RenderFrameHost* rfh) override;
  bool IsAllowedToAccessService(RenderFrameHost* frame,
                                const blink::WebBluetoothDeviceId& device_id,
                                const device::BluetoothUUID& service) override;
  bool IsAllowedToAccessAtLeastOneService(
      RenderFrameHost* frame,
      const blink::WebBluetoothDeviceId& device_id) override;
  bool IsAllowedToAccessManufacturerData(
      RenderFrameHost* frame,
      const blink::WebBluetoothDeviceId& device_id,
      const uint16_t manufacturer_code) override;
  std::vector<blink::mojom::WebBluetoothDevicePtr> GetPermittedDevices(
      RenderFrameHost* frame) override;
  void AddFramePermissionObserver(FramePermissionObserver* observer) override;
  void RemoveFramePermissionObserver(
      FramePermissionObserver* observer) override;

 private:
  using AddressToIdMap =
      base::flat_map<std::string, blink::WebBluetoothDeviceId>;
  using OriginPair = std::pair<url::Origin, url::Origin>;
  using IdToServicesMap = base::flat_map<blink::WebBluetoothDeviceId,
                                         base::flat_set<device::BluetoothUUID>>;
  using IdToNameMap = base::flat_map<blink::WebBluetoothDeviceId, std::string>;
  using IdToManufacturerCodesMap =
      base::flat_map<blink::WebBluetoothDeviceId, base::flat_set<uint16_t>>;

  // Finds an existing WebBluetoothDeviceId for |device_address| for |frame| or
  // creates a new ID for the Bluetooth device on the current frame.
  blink::WebBluetoothDeviceId GetOrCreateDeviceIdForDeviceAddress(
      RenderFrameHost* frame,
      const std::string& device_address);

  // Adds the union of |options->filters->services| and
  // |options->optional_services| to the allowed services for |device_id|.
  void GrantUnionOfServicesAndManufacturerDataForDevice(
      const blink::WebBluetoothDeviceId& device_id,
      const blink::mojom::WebBluetoothRequestDeviceOptions* options);
  AddressToIdMap& GetAddressToIdMapForOrigin(RenderFrameHost* frame);

  // Maps origins to their own maps of device address to device ID.
  // If a given origin and device address does not have an associated device ID,
  // then the origin does not have permission to access the device.
  std::map<OriginPair, AddressToIdMap> device_address_to_id_map_for_origin_;

  // These map device IDs to their set of allowed services and device names.
  // Since devices IDs are randomly generated, it is very unlikely that two
  // unique devices will share the same ID. Therefore, these maps contain all of
  // the service permissions and device names from all of the origins.
  IdToServicesMap device_id_to_services_map_;
  IdToNameMap device_id_to_name_map_;
  IdToManufacturerCodesMap device_id_to_manufacturer_code_map_;
};

}  // namespace content

#endif  // CONTENT_WEB_TEST_BROWSER_FAKE_BLUETOOTH_DELEGATE_H_