chromium/chrome/services/sharing/nearby/platform/ble_medium.h

// 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 CHROME_SERVICES_SHARING_NEARBY_PLATFORM_BLE_MEDIUM_H_
#define CHROME_SERVICES_SHARING_NEARBY_PLATFORM_BLE_MEDIUM_H_

#include <string>

#include "chrome/services/sharing/nearby/platform/ble_peripheral.h"
#include "device/bluetooth/public/mojom/adapter.mojom.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/shared_remote.h"
#include "third_party/nearby/src/internal/platform/implementation/ble.h"

namespace nearby {
namespace chrome {

// Concrete BleMedium implementation.
// api::BleMedium is a synchronous interface, so this implementation consumes
// the synchronous signatures of bluetooth::mojom::Adapter methods.
class BleMedium : public api::BleMedium,
                  public bluetooth::mojom::AdapterObserver {
 public:
  explicit BleMedium(
      const mojo::SharedRemote<bluetooth::mojom::Adapter>& adapter);
  ~BleMedium() override;

  BleMedium(const BleMedium&) = delete;
  BleMedium& operator=(const BleMedium&) = delete;

  // api::BleMedium:
  bool StartAdvertising(
      const std::string& service_id,
      const ByteArray& advertisement,
      const std::string& fast_advertisement_service_uuid) override;
  bool StopAdvertising(const std::string& service_id) override;
  bool StartScanning(
      const std::string& service_id,
      const std::string& fast_advertisement_service_uuid,
      DiscoveredPeripheralCallback discovered_peripheral_callback) override;
  bool StopScanning(const std::string& service_id) override;
  bool StartAcceptingConnections(
      const std::string& service_id,
      AcceptedConnectionCallback accepted_connection_callback) override;
  bool StopAcceptingConnections(const std::string& service_id) override;
  std::unique_ptr<api::BleSocket> Connect(
      api::BlePeripheral& ble_peripheral,
      const std::string& service_id,
      CancellationFlag* cancellation_flag) override;

 private:
  // bluetooth::mojom::AdapterObserver:
  void PresentChanged(bool present) override;
  void PoweredChanged(bool powered) override;
  void DiscoverableChanged(bool discoverable) override;
  void DiscoveringChanged(bool discovering) override;
  void DeviceAdded(bluetooth::mojom::DeviceInfoPtr device) override;
  void DeviceChanged(bluetooth::mojom::DeviceInfoPtr device) override;
  void DeviceRemoved(bluetooth::mojom::DeviceInfoPtr device) override;

  // A bluetooth::mojom::Advertisement message pipe was destroyed.
  void AdvertisementReleased(const device::BluetoothUUID& service_uuid);

  // Query if any service IDs are being scanned for.
  bool IsScanning();

  // End discovery for all requested services.
  void StopScanning();

  // Returns nullptr if no BlePeripheral at |address| exists.
  chrome::BlePeripheral* GetDiscoveredBlePeripheral(const std::string& address);

  mojo::SharedRemote<bluetooth::mojom::Adapter> adapter_;

  // |adapter_observer_| is only set and bound during active discovery so that
  // events we don't care about outside of discovery don't pile up.
  mojo::Receiver<bluetooth::mojom::AdapterObserver> adapter_observer_{this};

  // A map of service IDs (e.g., "NearbySharing") to their respective fast
  // advertisement UUIDs, as informed by active registered advertisements.
  std::map<std::string, device::BluetoothUUID>
      registered_service_id_to_fast_advertisement_service_uuid_map_;

  // Keyed by service UUID of the advertisement.
  std::map<device::BluetoothUUID, mojo::Remote<bluetooth::mojom::Advertisement>>
      registered_advertisements_map_;

  // A map of service IDs (e.g., "NearbySharing") to their respective fast
  // advertisement UUIDs used to filter incoming BLE advertisements during
  // scanning. We assume that the mapping is one-to-one. Insertions and
  // deletions mirror those of |discovered_peripheral_callbacks_map_|.
  std::map<std::string, device::BluetoothUUID>
      discovery_service_id_to_fast_advertisement_service_uuid_map_;

  // Keyed by requested service UUID. Discovery is active as long as this map is
  // non-empty.
  std::map<device::BluetoothUUID, DiscoveredPeripheralCallback>
      discovered_peripheral_callbacks_map_;

  // Only set while discovery is active.
  mojo::Remote<bluetooth::mojom::DiscoverySession> discovery_session_;

  // Keyed by address of advertising remote device. Note: References to these
  // BlePeripherals are passed to Nearby Connections. This is safe because, for
  // std::map, insert/emplace do not invalidate references, and the erase
  // operation only invalidates the reference to the erased element.
  std::map<std::string, chrome::BlePeripheral> discovered_ble_peripherals_map_;
};

}  // namespace chrome
}  // namespace nearby

#endif  // CHROME_SERVICES_SHARING_NEARBY_PLATFORM_BLE_MEDIUM_H_