#ifndef COMPONENTS_PERMISSIONS_BLUETOOTH_DELEGATE_IMPL_H_
#define COMPONENTS_PERMISSIONS_BLUETOOTH_DELEGATE_IMPL_H_
#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "components/permissions/object_permission_context_base.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 content {
class RenderFrameHost;
}
namespace device {
class BluetoothDevice;
class BluetoothUUID;
}
namespace permissions {
class BluetoothChooserContext;
class BluetoothDelegateImpl : public content::BluetoothDelegate {
public:
class Client {
public:
Client() = default;
virtual ~Client() = default;
Client(const Client&) = delete;
Client& operator=(const Client&) = delete;
virtual permissions::BluetoothChooserContext* GetBluetoothChooserContext(
content::RenderFrameHost* frame) = 0;
virtual std::unique_ptr<content::BluetoothChooser> RunBluetoothChooser(
content::RenderFrameHost* frame,
const content::BluetoothChooser::EventHandler& event_handler) = 0;
virtual std::unique_ptr<content::BluetoothScanningPrompt>
ShowBluetoothScanningPrompt(
content::RenderFrameHost* frame,
const content::BluetoothScanningPrompt::EventHandler&
event_handler) = 0;
virtual void ShowBluetoothDevicePairDialog(
content::RenderFrameHost* frame,
const std::u16string& device_identifier,
content::BluetoothDelegate::PairPromptCallback callback,
content::BluetoothDelegate::PairingKind pairing_kind,
const absl::optional<std::u16string>& pin) = 0;
};
explicit BluetoothDelegateImpl(std::unique_ptr<Client> client);
~BluetoothDelegateImpl() override;
BluetoothDelegateImpl(const BluetoothDelegateImpl&) = delete;
BluetoothDelegateImpl& operator=(const BluetoothDelegateImpl&) = delete;
std::unique_ptr<content::BluetoothChooser> RunBluetoothChooser(
content::RenderFrameHost* frame,
const content::BluetoothChooser::EventHandler& event_handler) override;
std::unique_ptr<content::BluetoothScanningPrompt> ShowBluetoothScanningPrompt(
content::RenderFrameHost* frame,
const content::BluetoothScanningPrompt::EventHandler& event_handler)
override;
void ShowDevicePairPrompt(content::RenderFrameHost* frame,
const std::u16string& device_identifier,
PairPromptCallback callback,
PairingKind pairing_kind,
const absl::optional<std::u16string>& pin) override;
blink::WebBluetoothDeviceId GetWebBluetoothDeviceId(
content::RenderFrameHost* frame,
const std::string& device_address) override;
std::string GetDeviceAddress(
content::RenderFrameHost* frame,
const blink::WebBluetoothDeviceId& device_id) override;
blink::WebBluetoothDeviceId AddScannedDevice(
content::RenderFrameHost* frame,
const std::string& device_address) override;
blink::WebBluetoothDeviceId GrantServiceAccessPermission(
content::RenderFrameHost* frame,
const device::BluetoothDevice* device,
const blink::mojom::WebBluetoothRequestDeviceOptions* options) override;
bool HasDevicePermission(
content::RenderFrameHost* frame,
const blink::WebBluetoothDeviceId& device_id) override;
void RevokeDevicePermissionWebInitiated(
content::RenderFrameHost* frame,
const blink::WebBluetoothDeviceId& device_id) override;
bool IsAllowedToAccessService(content::RenderFrameHost* frame,
const blink::WebBluetoothDeviceId& device_id,
const device::BluetoothUUID& service) override;
bool IsAllowedToAccessAtLeastOneService(
content::RenderFrameHost* frame,
const blink::WebBluetoothDeviceId& device_id) override;
bool IsAllowedToAccessManufacturerData(
content::RenderFrameHost* frame,
const blink::WebBluetoothDeviceId& device_id,
uint16_t manufacturer_code) override;
std::vector<blink::mojom::WebBluetoothDevicePtr> GetPermittedDevices(
content::RenderFrameHost* frame) override;
void AddFramePermissionObserver(FramePermissionObserver* observer) override;
void RemoveFramePermissionObserver(
FramePermissionObserver* observer) override;
private:
class ChooserContextPermissionObserver
: public ObjectPermissionContextBase::PermissionObserver {
public:
explicit ChooserContextPermissionObserver(
BluetoothDelegateImpl* owning_delegate,
ObjectPermissionContextBase* context);
~ChooserContextPermissionObserver() override;
ChooserContextPermissionObserver(const ChooserContextPermissionObserver&) =
delete;
ChooserContextPermissionObserver& operator=(
const ChooserContextPermissionObserver) = delete;
void OnPermissionRevoked(const url::Origin& origin) override;
void AddFramePermissionObserver(FramePermissionObserver* observer);
void RemoveFramePermissionObserver(FramePermissionObserver* observer);
private:
raw_ptr<BluetoothDelegateImpl> owning_delegate_;
base::ObserverList<FramePermissionObserver> observer_list_;
std::list<FramePermissionObserver*> observers_pending_removal_;
bool is_traversing_observers_ = false;
base::ScopedObservation<ObjectPermissionContextBase,
ObjectPermissionContextBase::PermissionObserver>
observer_{this};
};
std::unique_ptr<Client> client_;
std::map<content::RenderFrameHost*,
std::unique_ptr<ChooserContextPermissionObserver>>
chooser_observers_;
};
}
#endif