// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_

#include <stdint.h>

#include <list>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_advertisement.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h"

namespace base {
class SingleThreadTaskRunner;
}  // namespace base

namespace device {

class BluetoothAdvertisement;
class BluetoothDiscoveryFilter;
class BluetoothDiscoverySession;
class BluetoothLocalGattService;
class BluetoothRemoteGattCharacteristic;
class BluetoothRemoteGattDescriptor;
class BluetoothRemoteGattService;
class BluetoothSocket;
class BluetoothUUID;
enum class UMABluetoothDiscoverySessionOutcome;

// BluetoothAdapter represents a local Bluetooth adapter which may be used to
// interact with remote Bluetooth devices. As well as providing support for
// determining whether an adapter is present and whether the radio is powered,
// this class also provides support for obtaining the list of remote devices
// known to the adapter, discovering new devices, and providing notification of
// updates to device information.
class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
    : public base::RefCounted<BluetoothAdapter> {
 public:
  // Interface for observing changes from bluetooth adapters.
  class DEVICE_BLUETOOTH_EXPORT Observer {
   public:
    virtual ~Observer() {}

    // Called when the presence of the adapter |adapter| changes. When |present|
    // is true the adapter is now present, false means the adapter has been
    // removed from the system.
    virtual void AdapterPresentChanged(BluetoothAdapter* adapter,
                                       bool present) {}

    // Called when the radio power state of the adapter |adapter| changes. When
    // |powered| is true the adapter radio is powered, false means the adapter
    // radio is off.
    virtual void AdapterPoweredChanged(BluetoothAdapter* adapter,
                                       bool powered) {}

    // Called when the discoverability state of the  adapter |adapter| changes.
    // When |discoverable| is true the adapter is discoverable by other devices,
    // false means the adapter is not discoverable.
    virtual void AdapterDiscoverableChanged(BluetoothAdapter* adapter,
                                           bool discoverable) {}

    // Called when the discovering state of the adapter |adapter| changes. When
    // |discovering| is true the adapter is seeking new devices, false means it
    // is not.
    virtual void AdapterDiscoveringChanged(BluetoothAdapter* adapter,
                                           bool discovering) {}

    // Called when a new device |device| is added to the adapter |adapter|,
    // either because it has been discovered or a connection made. |device|
    // should not be cached. Instead, copy its Bluetooth address.
    virtual void DeviceAdded(BluetoothAdapter* adapter,
                             BluetoothDevice* device) {}

    // Called when the result of one of the following methods of the device
    // |device| changes:
    //  * GetAddress()
    //  * GetAppearance()
    //  * GetName() (Chrome OS and Windows only)
    //  * GetBluetoothClass()
    //  * GetInquiryRSSI()
    //  * GetInquiryTxPower()
    //  * GetUUIDs()
    //  * GetServiceData()
    //  * GetServiceDataUUIDs()
    //  * GetServiceDataForUUID()
    //  * GetManufacturerData()
    //  * GetManufacturerDataIDs()
    //  * GetManufacturerDataForID()
    //  * GetAdvertisingDataFlags()
    //  * IsConnectable()
    //  * IsConnected()
    //  * IsConnecting()
    //  * IsGattConnected()
    //  * IsPaired()
    //
    // On Android and MacOS this method is called for each advertisement packet
    // received. On Chrome OS and Linux, we can't guarantee that this method
    // will be called for each Adv. Packet received but, because the RSSI is
    // always changing, it's very likely this method will be called for each
    // Adv. Packet.
    // |device| should not be cached. Instead, copy its Bluetooth address.
    virtual void DeviceChanged(BluetoothAdapter* adapter,
                               BluetoothDevice* device) {}

    // Called when address property of the device |device| known to the adapter
    // |adapter| change due to pairing.
    virtual void DeviceAddressChanged(BluetoothAdapter* adapter,
                                      BluetoothDevice* device,
                                      const std::string& old_address) {}

    // Called when advertisement is received.
    //
    // Override this function to observe LE advertisements. This function
    // returns the raw values that have been parsed from EIR.
    virtual void DeviceAdvertisementReceived(
        const std::string& device_address,
        const base::Optional<std::string>& device_name,
        const base::Optional<std::string>& advertisement_name,
        base::Optional<int8_t> rssi,
        base::Optional<int8_t> tx_power,
        base::Optional<uint16_t> appearance,
        const BluetoothDevice::UUIDList& advertised_uuids,
        const BluetoothDevice::ServiceDataMap& service_data_map,
        const BluetoothDevice::ManufacturerDataMap& manufacturer_data_map) {}

// TODO(crbug.com/732991): Update comment and fix redundant #ifs throughout.
#if defined(OS_CHROMEOS) || defined(OS_LINUX)
    // This function is implemented for ChromeOS only, and the support for
    // Android, MaxOS and Windows should be added on demand in the future.
    // Called when paired property of the device |device| known to the adapter
    // |adapter| changed.
    virtual void DevicePairedChanged(BluetoothAdapter* adapter,
                                     BluetoothDevice* device,
                                     bool new_paired_status) {}

    // This function is implemented for ChromeOS only.
    // Called when the MTU |mtu| (Bluetooth Spec Vol 3, Part F, 3.4.2) used in
    // ATT communication with device |device| known to the adapter |adapter|
    // changed.
    virtual void DeviceMTUChanged(BluetoothAdapter* adapter,
                                  BluetoothDevice* device,
                                  uint16_t mtu) {}

    // This function is implemented for ChromeOS only.
    // Called when advertisement is received from |device|. |eir| is the
    // extended inquiry response specified in Bluetooth Core Spec, Vol 3,
    // Part C, Section 11.
    //
    // Override this function to observe LE advertisements. Whenever |rssi| of
    // |device| changes, this function is called with the latest |eir| from
    // |device|. This function is never called on classic |device|.
    virtual void DeviceAdvertisementReceived(BluetoothAdapter* adapter,
                                             BluetoothDevice* device,
                                             int16_t rssi,
                                             const std::vector<uint8_t>& eir) {}

    // This function is implemented for ChromeOS only.
    // Called when |device|'s state has changed from connected to not connected
    // or vice versa.
    virtual void DeviceConnectedStateChanged(BluetoothAdapter* adapter,
                                             BluetoothDevice* device,
                                             bool is_now_connected) {}
#endif

    // Called when the device |device| is removed from the adapter |adapter|,
    // either as a result of a discovered device being lost between discovering
    // phases or pairing information deleted. |device| should not be
    // cached. Instead, copy its Bluetooth address.
    virtual void DeviceRemoved(BluetoothAdapter* adapter,
                               BluetoothDevice* device) {}

    // Deprecated GATT Added/Removed Events NOTE:
    //
    // The series of Observer methods for Service, Characteristic, & Descriptor
    // Added/Removed events should be removed.  They are rarely used and add
    // API & implementation complexity.  They are not reliable for cross
    // platform use, and devices that modify their attribute table have not been
    // tested or supported.
    //
    // New code should use Observer::GattServicesDiscovered and then call
    //   GetGattService(s)
    //   GetCharacteristic(s)
    //   GetDescriptor(s)
    //
    // TODO(710352): Remove Service, Characteristic, & Descriptor Added/Removed.

    // See "Deprecated GATT Added/Removed Events NOTE" above.
    //
    // Called when a new GATT service |service| is added to the device |device|,
    // as the service is received from the device. Don't cache |service|. Store
    // its identifier instead (i.e. BluetoothRemoteGattService::GetIdentifier).
    virtual void GattServiceAdded(BluetoothAdapter* adapter,
                                  BluetoothDevice* device,
                                  BluetoothRemoteGattService* service) {}

    // See "Deprecated GATT Added/Removed Events NOTE" above.
    //
    // Called when the GATT service |service| is removed from the device
    // |device|. This can happen if the attribute database of the remote device
    // changes or when |device| gets removed.
    virtual void GattServiceRemoved(BluetoothAdapter* adapter,
                                    BluetoothDevice* device,
                                    BluetoothRemoteGattService* service) {}

    // Called when the GATT discovery process has completed for all services,
    // characteristics, and descriptors in |device|.
    virtual void GattServicesDiscovered(BluetoothAdapter* adapter,
                                        BluetoothDevice* device) {}

    // TODO(782494): Deprecated & not functional on all platforms. Use
    // GattServicesDiscovered.
    //
    // Called when all characteristic and descriptor discovery procedures are
    // known to be completed for the GATT service |service|. This method will be
    // called after the initial discovery of a GATT service and will usually be
    // preceded by calls to GattCharacteristicAdded and GattDescriptorAdded.
    virtual void GattDiscoveryCompleteForService(
        BluetoothAdapter* adapter,
        BluetoothRemoteGattService* service) {}

    // See "Deprecated GATT Added/Removed Events NOTE" above.
    //
    // Called when properties of the remote GATT service |service| have changed.
    // This will get called for properties such as UUID, as well as for changes
    // to the list of known characteristics and included services. Observers
    // should read all GATT characteristic and descriptors objects and do any
    // necessary set up required for a changed service.
    virtual void GattServiceChanged(BluetoothAdapter* adapter,
                                    BluetoothRemoteGattService* service) {}

    // See "Deprecated GATT Added/Removed Events NOTE" above.
    //
    // Called when the remote GATT characteristic |characteristic| has been
    // discovered. Use this to issue any initial read/write requests to the
    // characteristic but don't cache the pointer as it may become invalid.
    // Instead, use the specially assigned identifier to obtain a characteristic
    // and cache that identifier as necessary, as it can be used to retrieve the
    // characteristic from its GATT service. The number of characteristics with
    // the same UUID belonging to a service depends on the particular profile
    // the remote device implements, hence the client of a GATT based profile
    // will usually operate on the whole set of characteristics and not just
    // one.
    virtual void GattCharacteristicAdded(
        BluetoothAdapter* adapter,
        BluetoothRemoteGattCharacteristic* characteristic) {}

    // See "Deprecated GATT Added/Removed Events NOTE" above.
    //
    // Called when a GATT characteristic |characteristic| has been removed from
    // the system.
    virtual void GattCharacteristicRemoved(
        BluetoothAdapter* adapter,
        BluetoothRemoteGattCharacteristic* characteristic) {}

    // See "Deprecated GATT Added/Removed Events NOTE" above.
    //
    // Called when the remote GATT characteristic descriptor |descriptor| has
    // been discovered. Don't cache the arguments as the pointers may become
    // invalid. Instead, use the specially assigned identifier to obtain a
    // descriptor and cache that identifier as necessary.
    virtual void GattDescriptorAdded(
        BluetoothAdapter* adapter,
        BluetoothRemoteGattDescriptor* descriptor) {}

    // See "Deprecated GATT Added/Removed Events NOTE" above.
    //
    // Called when a GATT characteristic descriptor |descriptor| has been
    // removed from the system.
    virtual void GattDescriptorRemoved(
        BluetoothAdapter* adapter,
        BluetoothRemoteGattDescriptor* descriptor) {}

    // Called when the value of a characteristic has changed. This might be a
    // result of a read/write request to, or a notification/indication from, a
    // remote GATT characteristic.
    virtual void GattCharacteristicValueChanged(
        BluetoothAdapter* adapter,
        BluetoothRemoteGattCharacteristic* characteristic,
        const std::vector<uint8_t>& value) {}

    // Called when the value of a characteristic descriptor has been updated.
    virtual void GattDescriptorValueChanged(
        BluetoothAdapter* adapter,
        BluetoothRemoteGattDescriptor* descriptor,
        const std::vector<uint8_t>& value) {}
  };

  // Used to configure a listening servie.
  struct DEVICE_BLUETOOTH_EXPORT ServiceOptions {
    ServiceOptions();
    ~ServiceOptions();

    std::unique_ptr<int> channel;
    std::unique_ptr<int> psm;
    std::unique_ptr<std::string> name;
  };

  // The ErrorCallback is used for methods that can fail in which case it is
  // called, in the success case the callback is simply not called.
  using ErrorCallback = base::Closure;

  // The InitCallback is used to trigger a callback after asynchronous
  // initialization, if initialization is asynchronous on the platform.
  using InitCallback = base::OnceClosure;

  using DiscoverySessionCallback =
      base::Callback<void(std::unique_ptr<BluetoothDiscoverySession>)>;
  using DeviceList = std::vector<BluetoothDevice*>;
  using ConstDeviceList = std::vector<const BluetoothDevice*>;
  using UUIDList = std::vector<BluetoothUUID>;
  using CreateServiceCallback =
      base::Callback<void(scoped_refptr<BluetoothSocket>)>;
  using CreateServiceErrorCallback =
      base::Callback<void(const std::string& message)>;
  using CreateAdvertisementCallback =
      base::Callback<void(scoped_refptr<BluetoothAdvertisement>)>;
  using AdvertisementErrorCallback =
      base::Callback<void(BluetoothAdvertisement::ErrorCode)>;
  using DiscoverySessionErrorCallback =
      base::OnceCallback<void(UMABluetoothDiscoverySessionOutcome)>;
  // The is_error bool is a flag to indicate if the result is an error(true)
  // or a success(false)
  // The Session Outcome is the result which could be success or some sort of
  // error.  However, this variable is ignored when the bool is false
  using DiscoverySessionResultCallback =
      base::OnceCallback<void(/*is_error*/ bool,
                              UMABluetoothDiscoverySessionOutcome)>;

  // Returns a weak pointer to a new adapter.  For platforms with asynchronous
  // initialization, the returned adapter will run the |init_callback| once
  // asynchronous initialization is complete.
  // Caution: The returned pointer also transfers ownership of the adapter.  The
  // caller is expected to call |AddRef()| on the returned pointer, typically by
  // storing it into a |scoped_refptr|.
  static base::WeakPtr<BluetoothAdapter> CreateAdapter(
      InitCallback init_callback);

  // Returns a weak pointer to an existing adapter for testing purposes only.
  base::WeakPtr<BluetoothAdapter> GetWeakPtrForTesting();

#if defined(OS_LINUX)
  // Shutdown the adapter: tear down and clean up all objects owned by
  // BluetoothAdapter. After this call, the BluetoothAdapter will behave as if
  // no Bluetooth controller exists in the local system. |IsPresent| will return
  // false.
  virtual void Shutdown();
#endif

  // Adds and removes observers for events on this bluetooth adapter. If
  // monitoring multiple adapters, check the |adapter| parameter of observer
  // methods to determine which adapter is issuing the event.
  virtual void AddObserver(BluetoothAdapter::Observer* observer);
  virtual void RemoveObserver(BluetoothAdapter::Observer* observer);
  virtual bool HasObserver(BluetoothAdapter::Observer* observer);

  // The address of this adapter. The address format is "XX:XX:XX:XX:XX:XX",
  // where each XX is a hexadecimal number.
  virtual std::string GetAddress() const = 0;

  // The name of the adapter.
  virtual std::string GetName() const = 0;

  // Set the human-readable name of the adapter to |name|. On success,
  // |callback| will be called. On failure, |error_callback| will be called.
  virtual void SetName(const std::string& name,
                       const base::Closure& callback,
                       const ErrorCallback& error_callback) = 0;

  // Indicates whether the adapter is initialized and ready to use.
  virtual bool IsInitialized() const = 0;

  // Indicates whether the adapter is actually present on the system. For the
  // default adapter, this indicates whether any adapter is present. An adapter
  // is only considered present if the address has been obtained.
  virtual bool IsPresent() const = 0;

  // Indicates whether the adapter radio can be powered. Defaults to
  // IsPresent(). Currently only overridden on Windows, where the adapter can be
  // present, but we might fail to get access to the underlying radio.
  virtual bool CanPower() const;

  // Indicates whether the adapter radio is powered.
  virtual bool IsPowered() const = 0;

  // Requests a change to the adapter radio power. Setting |powered| to true
  // will turn on the radio and false will turn it off. On success, |callback|
  // will be called. On failure, |error_callback| will be called.
  //
  // The default implementation is meant for platforms that don't have a
  // callback based API. It will store pending callbacks in
  // |set_powered_callbacks_| and invoke SetPoweredImpl(bool) which these
  // platforms need to implement. Pending callbacks are only run when
  // RunPendingPowerCallbacks() is invoked.
  //
  // Platforms that natively support a callback based API (e.g. BlueZ and Win)
  // should override this method and provide their own implementation instead.
  //
  // Due to an issue with non-native APIs on Windows 10, both IsPowered() and
  // SetPowered() don't work correctly when run from a x86 Chrome on a x64 CPU.
  // See https://github.com/Microsoft/cppwinrt/issues/47 for more details.
  virtual void SetPowered(bool powered,
                          const base::Closure& callback,
                          const ErrorCallback& error_callback);

  // Indicates whether the adapter radio is discoverable.
  virtual bool IsDiscoverable() const = 0;

  // Requests that the adapter change its discoverability state. If
  // |discoverable| is true, then it will be discoverable by other Bluetooth
  // devices. On successfully changing the adapter's discoverability, |callback|
  // will be called. On failure, |error_callback| will be called.
  virtual void SetDiscoverable(bool discoverable,
                               const base::Closure& callback,
                               const ErrorCallback& error_callback) = 0;

  // Indicates whether the adapter is currently discovering new devices.
  virtual bool IsDiscovering() const = 0;

  // Inserts all the devices that are connected by the operating system, and not
  // being connected by Chromium, into |devices_|. This method is useful since
  // a discovery session cannot find devices that are already connected to the
  // computer.
  // TODO(crbug.com/653032): Needs to be implemented for Android, ChromeOS and
  // Windows.
  virtual std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet>
  RetrieveGattConnectedDevicesWithDiscoveryFilter(
      const BluetoothDiscoveryFilter& discovery_filter);

  // Requests the adapter to start a new discovery session. On success, a new
  // instance of BluetoothDiscoverySession will be returned to the caller via
  // |callback| and the adapter will be discovering nearby Bluetooth devices.
  // The returned BluetoothDiscoverySession is owned by the caller and it's the
  // owner's responsibility to properly clean it up and stop the session when
  // device discovery is no longer needed.
  //
  // If clients desire device discovery to run, they should always call this
  // method and never make it conditional on the value of IsDiscovering(), as
  // another client might cause discovery to stop unexpectedly. Hence, clients
  // should always obtain a BluetoothDiscoverySession and call
  // BluetoothDiscoverySession::Stop when done. When this method gets called,
  // device discovery may actually be in progress. Clients can call GetDevices()
  // and check for those with IsPaired() as false to obtain the list of devices
  // that have been discovered so far. Otherwise, clients can be notified of all
  // new and lost devices by implementing the Observer methods "DeviceAdded" and
  // "DeviceRemoved".
  void StartDiscoverySession(const DiscoverySessionCallback& callback,
                             const ErrorCallback& error_callback);
  void StartDiscoverySessionWithFilter(
      std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
      const DiscoverySessionCallback& callback,
      const ErrorCallback& error_callback);

  // Return all discovery filters assigned to this adapter merged together.
  std::unique_ptr<BluetoothDiscoveryFilter> GetMergedDiscoveryFilter() const;

  // Works like GetMergedDiscoveryFilter, but doesn't take |masked_filter| into
  // account. |masked_filter| is compared by pointer, and must be a member of
  // active session.
  std::unique_ptr<BluetoothDiscoveryFilter> GetMergedDiscoveryFilterMasked(
      BluetoothDiscoveryFilter* masked_filter) const;

  // Requests the list of devices from the adapter. All devices are returned,
  // including those currently connected, those paired and all devices returned
  // by RetrieveGattConnectedDevicesWithDiscoveryFilter() (from the previous
  // call). Use the returned device pointers to determine which they are.
  virtual DeviceList GetDevices();
  virtual ConstDeviceList GetDevices() const;

  // Returns a pointer to the device with the given address |address| or NULL if
  // no such device is known.
  virtual BluetoothDevice* GetDevice(const std::string& address);
  virtual const BluetoothDevice* GetDevice(const std::string& address) const;

  // Returns a list of UUIDs for services registered on this adapter.
  // This may include UUIDs from standard profiles (e.g. A2DP) as well
  // as those created by CreateRfcommService and CreateL2capService.
  virtual UUIDList GetUUIDs() const = 0;

  // Possible priorities for AddPairingDelegate(), low is intended for
  // permanent UI and high is intended for interactive UI or applications.
  enum PairingDelegatePriority {
    PAIRING_DELEGATE_PRIORITY_LOW,
    PAIRING_DELEGATE_PRIORITY_HIGH
  };

  // Adds a default pairing delegate with priority |priority|. Method calls
  // will be made on |pairing_delegate| for incoming pairing requests if the
  // priority is higher than any other registered; or for those of the same
  // priority, the first registered.
  //
  // |pairing_delegate| must not be freed without first calling
  // RemovePairingDelegate().
  virtual void AddPairingDelegate(
      BluetoothDevice::PairingDelegate* pairing_delegate,
      PairingDelegatePriority priority);

  // Removes a previously added pairing delegate.
  virtual void RemovePairingDelegate(
      BluetoothDevice::PairingDelegate* pairing_delegate);

  // Returns the first registered pairing delegate with the highest priority,
  // or NULL if no delegate is registered. Used to select the delegate for
  // incoming pairing requests.
  virtual BluetoothDevice::PairingDelegate* DefaultPairingDelegate();

  // Creates an RFCOMM service on this adapter advertised with UUID |uuid|,
  // listening on channel |options.channel|, which may be left null to
  // automatically allocate one. The service will be advertised with
  // |options.name| as the English name of the service. |callback| will be
  // called on success with a BluetoothSocket instance that is to be owned by
  // the received.  |error_callback| will be called on failure with a message
  // indicating the cause.
  virtual void CreateRfcommService(
      const BluetoothUUID& uuid,
      const ServiceOptions& options,
      const CreateServiceCallback& callback,
      const CreateServiceErrorCallback& error_callback) = 0;

  // Creates an L2CAP service on this adapter advertised with UUID |uuid|,
  // listening on PSM |options.psm|, which may be left null to automatically
  // allocate one. The service will be advertised with |options.name| as the
  // English name of the service. |callback| will be called on success with a
  // BluetoothSocket instance that is to be owned by the received.
  // |error_callback| will be called on failure with a message indicating the
  // cause.
  virtual void CreateL2capService(
      const BluetoothUUID& uuid,
      const ServiceOptions& options,
      const CreateServiceCallback& callback,
      const CreateServiceErrorCallback& error_callback) = 0;

  // Creates and registers an advertisement for broadcast over the LE channel.
  // The created advertisement will be returned via the success callback. An
  // advertisement can unregister itself at any time by calling its unregister
  // function.
  virtual void RegisterAdvertisement(
      std::unique_ptr<BluetoothAdvertisement::Data> advertisement_data,
      const CreateAdvertisementCallback& callback,
      const AdvertisementErrorCallback& error_callback) = 0;

#if defined(OS_LINUX)
  // Sets the interval between two consecutive advertisements. Valid ranges
  // for the interval are from 20ms to 10.24 seconds, with min <= max.
  // Note: This is a best effort. The actual interval may vary non-trivially
  // from the requested intervals. On some hardware, there is a minimum
  // interval of 100ms. The minimum and maximum values are specified by the
  // Core 4.2 Spec, Vol 2, Part E, Section 7.8.5.
  virtual void SetAdvertisingInterval(
      const base::TimeDelta& min,
      const base::TimeDelta& max,
      const base::Closure& callback,
      const AdvertisementErrorCallback& error_callback) = 0;

  // Resets advertising on this adapter. This will unregister all existing
  // advertisements and will stop advertising them.
  virtual void ResetAdvertising(
      const base::Closure& callback,
      const AdvertisementErrorCallback& error_callback) = 0;
#endif

  // Returns the list of pending advertisements that are not registered yet.
  virtual std::vector<BluetoothAdvertisement*>
  GetPendingAdvertisementsForTesting() const;

  // Returns the local GATT services associated with this adapter with the
  // given identifier. Returns NULL if the service doesn't exist.
  virtual BluetoothLocalGattService* GetGattService(
      const std::string& identifier) const = 0;

  // The following methods are used to send various events to observers.
  void NotifyAdapterPoweredChanged(bool powered);
  void NotifyDeviceChanged(BluetoothDevice* device);

#if defined(OS_CHROMEOS) || defined(OS_LINUX)
  // This function is implemented for ChromeOS only, and the support on
  // Android, MaxOS and Windows should be added on demand in the future.
  void NotifyDevicePairedChanged(BluetoothDevice* device,
                                 bool new_paired_status);
#endif
  void NotifyGattServiceAdded(BluetoothRemoteGattService* service);
  void NotifyGattServiceRemoved(BluetoothRemoteGattService* service);
  void NotifyGattServiceChanged(BluetoothRemoteGattService* service);
  void NotifyGattServicesDiscovered(BluetoothDevice* device);
  void NotifyGattDiscoveryComplete(BluetoothRemoteGattService* service);
  void NotifyGattCharacteristicAdded(
      BluetoothRemoteGattCharacteristic* characteristic);
  void NotifyGattCharacteristicRemoved(
      BluetoothRemoteGattCharacteristic* characteristic);
  void NotifyGattDescriptorAdded(BluetoothRemoteGattDescriptor* descriptor);
  void NotifyGattDescriptorRemoved(BluetoothRemoteGattDescriptor* descriptor);
  void NotifyGattCharacteristicValueChanged(
      BluetoothRemoteGattCharacteristic* characteristic,
      const std::vector<uint8_t>& value);
  void NotifyGattDescriptorValueChanged(
      BluetoothRemoteGattDescriptor* descriptor,
      const std::vector<uint8_t>& value);

  // The timeout in seconds used by RemoveTimedOutDevices.
  static const base::TimeDelta timeoutSec;

 protected:
  friend class base::RefCounted<BluetoothAdapter>;
  friend class BluetoothDiscoverySession;
  friend class BluetoothTestBase;

  using DevicesMap =
      std::unordered_map<std::string, std::unique_ptr<BluetoothDevice>>;
  using PairingDelegatePair =
      std::pair<BluetoothDevice::PairingDelegate*, PairingDelegatePriority>;

  // Implementations on Android and macOS need to store pending SetPowered()
  // callbacks until an appropriate event is received, due to a lack of blocking
  // or callback supporting platform APIs. Declaring the struct here allows
  // Android and macOS to share the implementation.
  struct SetPoweredCallbacks {
    SetPoweredCallbacks();
    ~SetPoweredCallbacks();

    bool powered = false;
    base::OnceClosure callback;
    ErrorCallback error_callback;
  };

  BluetoothAdapter();
  virtual ~BluetoothAdapter();

  // This method calls into platform specific logic on macOS and Android where
  // pending SetPowered() callbacks need to be stored explicitly.
  virtual bool SetPoweredImpl(bool powered) = 0;

  // Called by macOS, Android and WinRT once the specific powered state events
  // are received or an error occurred. Clears out pending callbacks.
  void RunPendingPowerCallbacks();

  // Internal methods for initiating and terminating device discovery sessions.
  // An implementation of BluetoothAdapter keeps an internal reference count to
  // make sure that the underlying controller is constantly searching for nearby
  // devices and retrieving information from them as long as there are clients
  // who have requested discovery. These methods behave in the following way:
  //
  // On a call to StartScanWithFilter:
  //    - This should only be called when we get the first request to start the
  //      scan with only the initial filter in that request.
  //    - This function should do the OS specific things to get the filter
  //      started.
  //    - When finished it should callback with success or the appropriate
  //    Output for an error.
  // On a call to UpdateFilter:
  //    - The scan should already be started or at least starting.
  //    - This function takes in a filter and should do all the OS specifics
  //      needed to update the scan with the new filter.
  //    - When finished it should call the callback with success or the
  //      appropriate output for an error
  //
  // On a call to RemoveDiscoverySession:
  //    - If there is a pending request to the subsystem, queue this request to
  //      execute once the pending requests are done.
  //    - If the count is 0, return failure, as there is no active discovery
  //      session.
  //    - If the count is 1, issue a request to the subsystem to stop device
  //      discovery and decrement the count to 0 on success.
  //    - If the count is greater than 1, decrement the count and return
  //      success.
  //
  // |discovery_filter| passed to AddDiscoverySession and RemoveDiscoverySession
  // is owned by other objects and shall not be freed.  When the count is
  // greater than 0 and AddDiscoverySession or RemoveDiscoverySession is called
  // the filter being used by the underlying controller must be updated.
  //
  // These methods invoke |callback| for success and |error_callback| for
  // failures.
  virtual void StartScanWithFilter(
      std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
      DiscoverySessionResultCallback callback) = 0;
  virtual void UpdateFilter(
      std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
      DiscoverySessionResultCallback callback) = 0;
  virtual void RemoveDiscoverySession(
      BluetoothDiscoveryFilter* discovery_filter,
      const base::Closure& callback,
      DiscoverySessionErrorCallback error_callback) = 0;

  // Used to set and update the discovery filter used by the underlying
  // Bluetooth controller.
  virtual void SetDiscoveryFilter(
      std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter,
      const base::Closure& callback,
      DiscoverySessionErrorCallback error_callback) = 0;

  // Called by RemovePairingDelegate() in order to perform any class-specific
  // internal functionality necessary to remove the pairing delegate, such as
  // cleaning up ongoing pairings using it.
  virtual void RemovePairingDelegateInternal(
      BluetoothDevice::PairingDelegate* pairing_delegate) = 0;

  // Success callback passed to AddDiscoverySession by StartDiscoverySession.
  void OnStartDiscoverySession(
      std::unique_ptr<BluetoothDiscoverySession> discovery_session,
      const DiscoverySessionCallback& callback);

  // Error callback passed to AddDiscoverySession by StartDiscoverySession.
  void OnStartDiscoverySessionError(
      std::unique_ptr<BluetoothDiscoverySession> discovery_session,
      const ErrorCallback& callback,
      UMABluetoothDiscoverySessionOutcome outcome);

  // Marks all known DiscoverySession instances as inactive. Called by
  // BluetoothAdapter in the event that the adapter unexpectedly stops
  // discovering. This should be called by all platform implementations.
  void MarkDiscoverySessionsAsInactive();

  // Removes |discovery_session| from |discovery_sessions_|, if its in there.
  // Called by DiscoverySession when an instance is destroyed or becomes
  // inactive.
  void DiscoverySessionBecameInactive(
      BluetoothDiscoverySession* discovery_session);

  void DeleteDeviceForTesting(const std::string& address);

  // Removes from |devices_| any previously paired, connected or seen
  // devices which are no longer present. Notifies observers. Note:
  // this is only used by platforms where there is no notification of
  // lost devices.
  void RemoveTimedOutDevices();

  int NumDiscoverySessions() const;

  // UI thread task runner.
  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;

  // Observers of BluetoothAdapter, notified from implementation subclasses.
  base::ObserverList<device::BluetoothAdapter::Observer>::Unchecked observers_;

  // Devices paired with, connected to, discovered by, or visible to the
  // adapter. The key is the Bluetooth address of the device and the value is
  // the BluetoothDevice object whose lifetime is managed by the adapter
  // instance.
  DevicesMap devices_;

  // Default pairing delegates registered with the adapter.
  std::list<PairingDelegatePair> pairing_delegates_;

  // SetPowered() callbacks, only relevant for macOS and Android.
  std::unique_ptr<SetPoweredCallbacks> set_powered_callbacks_;

  // List of active DiscoverySession objects. This is used to notify sessions to
  // become inactive in case of an unexpected change to the adapter discovery
  // state. We keep raw pointers, with the invariant that a DiscoverySession
  // will remove itself from this list when it gets destroyed or becomes
  // inactive by calling DiscoverySessionBecameInactive(), hence no pointers to
  // deallocated sessions are kept.
  std::set<BluetoothDiscoverySession*> discovery_sessions_;

 private:
  // Histograms the result of StartDiscoverySession.
  static void RecordBluetoothDiscoverySessionStartOutcome(
      UMABluetoothDiscoverySessionOutcome outcome);

  // Histograms the result of BluetoothDiscoverySession::Stop.
  static void RecordBluetoothDiscoverySessionStopOutcome(
      UMABluetoothDiscoverySessionOutcome outcome);

  // An adapter between DiscoverySessionResultCallback and
  // DiscoverySessionCallback that calls either OnStartDiscoverySession() or
  // OnStartDiscoverySessionError() based on the outcome of starting
  // |discovery_session|.
  void OnStartDiscoverySessionCallback(
      std::unique_ptr<BluetoothDiscoverySession> discovery_session,
      const DiscoverySessionCallback& callback,
      const ErrorCallback& error_callback,
      bool is_error,
      UMABluetoothDiscoverySessionOutcome outcome);

  // Return all discovery filters assigned to this adapter merged together.
  // If |omit| is true, |discovery_filter| will not be processed.
  std::unique_ptr<BluetoothDiscoveryFilter> GetMergedDiscoveryFilterHelper(
      const BluetoothDiscoveryFilter* discovery_filter,
      bool omit) const;

  // Note: This should remain the last member so it'll be destroyed and
  // invalidate its weak pointers before any other members are destroyed.
  base::WeakPtrFactory<BluetoothAdapter> weak_ptr_factory_;
};

}  // namespace device

#endif  // DEVICE_BLUETOOTH_BLUETOOTH_ADAPTER_H_
