blob: eafd7a833b7ecb82462d4ec214388d397eacc751 [file] [log] [blame]
// Copyright 2014 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_BROWSER_DEVTOOLS_DEVICE_ANDROID_DEVICE_MANAGER_H_
#define CHROME_BROWSER_DEVTOOLS_DEVICE_ANDROID_DEVICE_MANAGER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_delete_on_sequence.h"
#include "base/memory/weak_ptr.h"
#include "base/no_destructor.h"
#include "base/sequence_checker.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "content/public/browser/browser_thread.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/device/public/mojom/usb_manager.mojom.h"
#include "ui/gfx/geometry/size.h"
namespace net {
class StreamSocket;
}
class AndroidDeviceManager {
public:
using CommandCallback = base::OnceCallback<void(int, const std::string&)>;
using SocketCallback =
base::OnceCallback<void(int result, std::unique_ptr<net::StreamSocket>)>;
// |body_head| should contain the body (WebSocket frame data) part that has
// been read during processing the header (WebSocket handshake).
using HttpUpgradeCallback =
base::OnceCallback<void(int result,
const std::string& extensions,
const std::string& body_head,
std::unique_ptr<net::StreamSocket>)>;
using SerialsCallback = base::OnceCallback<void(std::vector<std::string>)>;
struct BrowserInfo {
BrowserInfo();
BrowserInfo(const BrowserInfo& other);
BrowserInfo& operator=(const BrowserInfo& other);
enum Type {
kTypeChrome,
kTypeWebView,
kTypeOther
};
std::string socket_name;
std::string display_name;
std::string user;
Type type;
};
struct DeviceInfo {
DeviceInfo();
DeviceInfo(const DeviceInfo& other);
~DeviceInfo();
std::string model;
bool connected;
gfx::Size screen_size;
std::vector<BrowserInfo> browser_info;
};
using DeviceInfoCallback = base::OnceCallback<void(const DeviceInfo&)>;
class Device;
class AndroidWebSocket {
public:
class Delegate {
public:
virtual void OnSocketOpened() = 0;
virtual void OnFrameRead(const std::string& message) = 0;
virtual void OnSocketClosed() = 0;
protected:
virtual ~Delegate() = default;
};
AndroidWebSocket(const AndroidWebSocket&) = delete;
AndroidWebSocket& operator=(const AndroidWebSocket&) = delete;
~AndroidWebSocket();
void SendFrame(const std::string& message);
private:
friend class Device;
class WebSocketImpl;
AndroidWebSocket(
scoped_refptr<Device> device,
const std::string& socket_name,
const std::string& path,
AndroidWebSocket::Delegate* delegate);
void Connected(int result,
const std::string& extensions,
const std::string& body_head,
std::unique_ptr<net::StreamSocket> socket);
void OnFrameRead(const std::string& message);
void OnSocketClosed();
scoped_refptr<Device> device_;
std::unique_ptr<WebSocketImpl, base::OnTaskRunnerDeleter> socket_impl_;
raw_ptr<Delegate> delegate_;
base::WeakPtrFactory<AndroidWebSocket> weak_factory_{this};
};
class DeviceProvider;
class Device final : public base::RefCountedDeleteOnSequence<Device> {
public:
Device(const Device&) = delete;
Device& operator=(const Device&) = delete;
void QueryDeviceInfo(DeviceInfoCallback callback);
void OpenSocket(const std::string& socket_name, SocketCallback callback);
void SendJsonRequest(const std::string& socket_name,
const std::string& request,
CommandCallback callback);
void HttpUpgrade(const std::string& socket_name,
const std::string& path,
const std::string& extensions,
HttpUpgradeCallback callback);
AndroidWebSocket* CreateWebSocket(
const std::string& socket_name,
const std::string& path,
AndroidWebSocket::Delegate* delegate);
const std::string& serial() { return serial_; }
private:
friend class base::RefCountedDeleteOnSequence<Device>;
friend class base::DeleteHelper<Device>;
friend class AndroidDeviceManager;
friend class AndroidWebSocket;
Device(scoped_refptr<base::SingleThreadTaskRunner> device_task_runner,
scoped_refptr<DeviceProvider> provider,
const std::string& serial);
~Device();
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
scoped_refptr<DeviceProvider> provider_;
const std::string serial_;
base::WeakPtrFactory<Device> weak_factory_{this};
};
using Devices = std::vector<scoped_refptr<Device>>;
using DevicesCallback = base::OnceCallback<void(const Devices&)>;
class DeviceProvider : public base::RefCountedThreadSafe<DeviceProvider> {
public:
using SerialsCallback = AndroidDeviceManager::SerialsCallback;
using DeviceInfoCallback = AndroidDeviceManager::DeviceInfoCallback;
using SocketCallback = AndroidDeviceManager::SocketCallback;
using CommandCallback = AndroidDeviceManager::CommandCallback;
virtual void QueryDevices(SerialsCallback callback) = 0;
virtual void QueryDeviceInfo(const std::string& serial,
DeviceInfoCallback callback) = 0;
virtual void OpenSocket(const std::string& serial,
const std::string& socket_name,
SocketCallback callback) = 0;
void SendJsonRequest(const std::string& serial,
const std::string& socket_name,
const std::string& request,
CommandCallback callback);
virtual void HttpUpgrade(const std::string& serial,
const std::string& socket_name,
const std::string& path,
const std::string& extensions,
HttpUpgradeCallback callback);
virtual void ReleaseDevice(const std::string& serial);
protected:
friend class base::RefCountedThreadSafe<DeviceProvider>;
DeviceProvider();
virtual ~DeviceProvider();
};
typedef std::vector<scoped_refptr<DeviceProvider> > DeviceProviders;
virtual ~AndroidDeviceManager();
static std::unique_ptr<AndroidDeviceManager> Create();
void SetDeviceProviders(const DeviceProviders& providers);
void QueryDevices(DevicesCallback callback);
void CountDevices(base::OnceCallback<void(int)> callback);
void set_usb_device_manager_for_test(
mojo::PendingRemote<device::mojom::UsbDeviceManager> fake_usb_manager);
static std::string GetBrowserName(const std::string& socket,
const std::string& package);
using RunCommandCallback =
base::OnceCallback<void(const std::string&, CommandCallback)>;
static void QueryDeviceInfo(RunCommandCallback command_callback,
DeviceInfoCallback callback);
struct DeviceDescriptor {
DeviceDescriptor();
DeviceDescriptor(const DeviceDescriptor& other);
~DeviceDescriptor();
scoped_refptr<DeviceProvider> provider;
std::string serial;
};
typedef std::vector<DeviceDescriptor> DeviceDescriptors;
private:
class HandlerThread {
public:
static HandlerThread* GetInstance();
scoped_refptr<base::SingleThreadTaskRunner> message_loop();
private:
friend class base::NoDestructor<HandlerThread>;
static void StopThread(base::Thread* thread);
HandlerThread();
~HandlerThread();
raw_ptr<base::Thread> thread_;
};
AndroidDeviceManager();
void UpdateDevices(DevicesCallback callback,
std::unique_ptr<DeviceDescriptors> descriptors);
typedef std::map<std::string, base::WeakPtr<Device> > DeviceWeakMap;
raw_ptr<HandlerThread> handler_thread_;
DeviceProviders providers_;
DeviceWeakMap devices_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<AndroidDeviceManager> weak_factory_{this};
};
#endif // CHROME_BROWSER_DEVTOOLS_DEVICE_ANDROID_DEVICE_MANAGER_H_