DevTools: Partially redesigned DevToolsAndroidBridge and AndroidDeviceManager.

Review URL: https://codereview.chromium.org/287643002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274211 0039d316-1c4b-4281-b951-d872f2087c98
parent d9250e7f
...@@ -34,6 +34,7 @@ class AdbClientSocketTest : public InProcessBrowserTest, ...@@ -34,6 +34,7 @@ class AdbClientSocketTest : public InProcessBrowserTest,
device_providers.push_back(new AdbDeviceProvider()); device_providers.push_back(new AdbDeviceProvider());
android_bridge_->set_device_providers_for_test(device_providers); android_bridge_->set_device_providers_for_test(device_providers);
android_bridge_->AddDeviceListListener(this); android_bridge_->AddDeviceListListener(this);
content::RunMessageLoop();
} }
virtual void DeviceListChanged( virtual void DeviceListChanged(
...@@ -125,7 +126,6 @@ class AdbClientSocketTest : public InProcessBrowserTest, ...@@ -125,7 +126,6 @@ class AdbClientSocketTest : public InProcessBrowserTest,
IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, TestAdbClientSocket) { IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, TestAdbClientSocket) {
StartMockAdbServer(); StartMockAdbServer();
StartTest(); StartTest();
content::RunMessageLoop();
CheckDevices(); CheckDevices();
StopMockAdbServer(); StopMockAdbServer();
} }
...@@ -209,6 +209,7 @@ void AdbDeviceInfoQuery::ReceivedModel(int result, ...@@ -209,6 +209,7 @@ void AdbDeviceInfoQuery::ReceivedModel(int result,
return; return;
} }
device_info_.model = response; device_info_.model = response;
device_info_.connected = true;
command_callback_.Run( command_callback_.Run(
kDumpsysCommand, kDumpsysCommand,
base::Bind(&AdbDeviceInfoQuery::ReceivedDumpsys, base::Unretained(this))); base::Bind(&AdbDeviceInfoQuery::ReceivedDumpsys, base::Unretained(this)));
......
...@@ -17,68 +17,48 @@ const char kLocalAbstractCommand[] = "localabstract:%s"; ...@@ -17,68 +17,48 @@ const char kLocalAbstractCommand[] = "localabstract:%s";
const int kAdbPort = 5037; const int kAdbPort = 5037;
class AdbDeviceImpl : public AndroidDeviceManager::Device { static void RunCommand(const std::string& serial,
public: const std::string& command,
AdbDeviceImpl(const std::string& serial, bool is_connected); const AdbDeviceProvider::CommandCallback& callback) {
virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) OVERRIDE; std::string query = base::StringPrintf(
kHostTransportCommand, serial.c_str(), command.c_str());
virtual void OpenSocket(const std::string& name,
const SocketCallback& callback) OVERRIDE;
private:
virtual ~AdbDeviceImpl() {}
void RunCommand(const std::string& command,
const CommandCallback& callback);
};
AdbDeviceImpl::AdbDeviceImpl(const std::string& serial, bool is_connected)
: Device(serial, is_connected) {
}
void AdbDeviceImpl::QueryDeviceInfo(const DeviceInfoCallback& callback) {
AdbDeviceInfoQuery::Start(
base::Bind(&AdbDeviceImpl::RunCommand, this), callback);
}
void AdbDeviceImpl::OpenSocket(const std::string& name,
const SocketCallback& callback) {
DCHECK(CalledOnValidThread());
std::string socket_name =
base::StringPrintf(kLocalAbstractCommand, name.c_str());
AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback);
}
void AdbDeviceImpl::RunCommand(const std::string& command,
const CommandCallback& callback) {
DCHECK(CalledOnValidThread());
std::string query = base::StringPrintf(kHostTransportCommand,
serial().c_str(), command.c_str());
AdbClientSocket::AdbQuery(kAdbPort, query, callback); AdbClientSocket::AdbQuery(kAdbPort, query, callback);
} }
// static static void ReceivedAdbDevices(
void ReceivedAdbDevices( const AdbDeviceProvider::SerialsCallback& callback,
const AdbDeviceProvider::QueryDevicesCallback& callback,
int result_code, int result_code,
const std::string& response) { const std::string& response) {
AndroidDeviceManager::Devices result; std::vector<std::string> result;
std::vector<std::string> serials; std::vector<std::string> serials;
Tokenize(response, "\n", &serials); Tokenize(response, "\n", &serials);
for (size_t i = 0; i < serials.size(); ++i) { for (size_t i = 0; i < serials.size(); ++i) {
std::vector<std::string> tokens; std::vector<std::string> tokens;
Tokenize(serials[i], "\t ", &tokens); Tokenize(serials[i], "\t ", &tokens);
bool offline = tokens.size() > 1 && tokens[1] == "offline"; result.push_back(tokens[0]);
result.push_back(new AdbDeviceImpl(tokens[0], !offline));
} }
callback.Run(result); callback.Run(result);
} }
} // namespace } // namespace
AdbDeviceProvider::~AdbDeviceProvider() { void AdbDeviceProvider::QueryDevices(const SerialsCallback& callback) {
}
void AdbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
AdbClientSocket::AdbQuery( AdbClientSocket::AdbQuery(
kAdbPort, kHostDevicesCommand, base::Bind(&ReceivedAdbDevices, callback)); kAdbPort, kHostDevicesCommand, base::Bind(&ReceivedAdbDevices, callback));
} }
void AdbDeviceProvider::QueryDeviceInfo(const std::string& serial,
const DeviceInfoCallback& callback) {
AdbDeviceInfoQuery::Start(base::Bind(&RunCommand, serial), callback);
}
void AdbDeviceProvider::OpenSocket(const std::string& serial,
const std::string& socket_name,
const SocketCallback& callback) {
std::string request =
base::StringPrintf(kLocalAbstractCommand, socket_name.c_str());
AdbClientSocket::TransportQuery(kAdbPort, serial, request, callback);
}
AdbDeviceProvider::~AdbDeviceProvider() {
}
...@@ -9,9 +9,14 @@ ...@@ -9,9 +9,14 @@
class AdbDeviceProvider : public AndroidDeviceManager::DeviceProvider { class AdbDeviceProvider : public AndroidDeviceManager::DeviceProvider {
public: public:
typedef DeviceProvider::QueryDevicesCallback QueryDevicesCallback; virtual void QueryDevices(const SerialsCallback& callback) OVERRIDE;
virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE; virtual void QueryDeviceInfo(const std::string& serial,
const DeviceInfoCallback& callback) OVERRIDE;
virtual void OpenSocket(const std::string& serial,
const std::string& socket_name,
const SocketCallback& callback) OVERRIDE;
private: private:
virtual ~AdbDeviceProvider(); virtual ~AdbDeviceProvider();
......
...@@ -463,7 +463,7 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -463,7 +463,7 @@ class MockAdbServer : SingleConnectionServer::Parser,
selected_device_ = command.substr(strlen(kHostTransportPrefix)); selected_device_ = command.substr(strlen(kHostTransportPrefix));
SendResponse(""); SendResponse("");
} else if (selected_device_ != kSerialOnline) { } else if (selected_device_ != kSerialOnline) {
NOTREACHED() << "Unknown device - " << selected_device_; Send("FAIL", "device offline (x)");
} else if (command == kDeviceModelCommand) { } else if (command == kDeviceModelCommand) {
SendResponse(kDeviceModel); SendResponse(kDeviceModel);
} else if (command == kOpenedUnixSocketsCommand) { } else if (command == kOpenedUnixSocketsCommand) {
...@@ -480,10 +480,14 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -480,10 +480,14 @@ class MockAdbServer : SingleConnectionServer::Parser,
} }
} }
void SendResponse(const std::string& response) { void SendResponse(const std::string& response) { Send("OKAY", response); }
void Send(const std::string& status, const std::string& response) {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
CHECK_EQ(4U, status.size());
std::stringstream response_stream; std::stringstream response_stream;
response_stream << "OKAY"; response_stream << status;
int size = response.size(); int size = response.size();
if (size > 0) { if (size > 0) {
......
...@@ -11,10 +11,16 @@ ...@@ -11,10 +11,16 @@
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/socket/stream_socket.h" #include "net/socket/stream_socket.h"
using content::BrowserThread;
namespace { namespace {
const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread";
const int kBufferSize = 16 * 1024; const int kBufferSize = 16 * 1024;
static const char kModelOffline[] = "Offline";
static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n"; static const char kHttpGetRequest[] = "GET %s HTTP/1.1\r\n\r\n";
static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n"
...@@ -24,6 +30,31 @@ static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n" ...@@ -24,6 +30,31 @@ static const char kWebSocketUpgradeRequest[] = "GET %s HTTP/1.1\r\n"
"Sec-WebSocket-Version: 13\r\n" "Sec-WebSocket-Version: 13\r\n"
"\r\n"; "\r\n";
static void PostDeviceInfoCallback(
scoped_refptr<base::MessageLoopProxy> response_message_loop,
const AndroidDeviceManager::DeviceInfoCallback& callback,
const AndroidDeviceManager::DeviceInfo& device_info) {
response_message_loop->PostTask(FROM_HERE, base::Bind(callback, device_info));
}
static void PostCommandCallback(
scoped_refptr<base::MessageLoopProxy> response_message_loop,
const AndroidDeviceManager::CommandCallback& callback,
int result,
const std::string& response) {
response_message_loop->PostTask(FROM_HERE,
base::Bind(callback, result, response));
}
static void PostSocketCallback(
scoped_refptr<base::MessageLoopProxy> response_message_loop,
const AndroidDeviceManager::SocketCallback& callback,
int result,
net::StreamSocket* socket) {
response_message_loop->PostTask(FROM_HERE,
base::Bind(callback, result, socket));
}
class HttpRequest { class HttpRequest {
public: public:
typedef AndroidDeviceManager::CommandCallback CommandCallback; typedef AndroidDeviceManager::CommandCallback CommandCallback;
...@@ -53,11 +84,9 @@ class HttpRequest { ...@@ -53,11 +84,9 @@ class HttpRequest {
private: private:
HttpRequest(net::StreamSocket* socket, HttpRequest(net::StreamSocket* socket,
const std::string& request, const std::string& request,
const CommandCallback& callback) const CommandCallback& callback)
: socket_(socket), : socket_(socket), command_callback_(callback), body_pos_(0) {
command_callback_(callback),
body_pos_(0) {
SendRequest(request); SendRequest(request);
} }
...@@ -174,33 +203,117 @@ class HttpRequest { ...@@ -174,33 +203,117 @@ class HttpRequest {
size_t body_pos_; size_t body_pos_;
}; };
class DevicesRequest : public base::RefCountedThreadSafe<DevicesRequest> {
public:
typedef AndroidDeviceManager::DeviceInfo DeviceInfo;
typedef AndroidDeviceManager::DeviceProvider DeviceProvider;
typedef AndroidDeviceManager::DeviceProviders DeviceProviders;
typedef AndroidDeviceManager::DeviceDescriptors DeviceDescriptors;
typedef base::Callback<void(DeviceDescriptors*)>
DescriptorsCallback;
static void Start(scoped_refptr<base::MessageLoopProxy> device_message_loop,
const DeviceProviders& providers,
const DescriptorsCallback& callback) {
// Don't keep counted reference on calling thread;
DevicesRequest* request = new DevicesRequest(callback);
// Avoid destruction while sending requests
request->AddRef();
for (DeviceProviders::const_iterator it = providers.begin();
it != providers.end(); ++it) {
device_message_loop->PostTask(
FROM_HERE,
base::Bind(
&DeviceProvider::QueryDevices,
*it,
base::Bind(&DevicesRequest::ProcessSerials, request, *it)));
}
device_message_loop->ReleaseSoon(FROM_HERE, request);
}
private:
explicit DevicesRequest(const DescriptorsCallback& callback)
: response_message_loop_(base::MessageLoopProxy::current()),
callback_(callback),
descriptors_(new DeviceDescriptors()) {
}
friend class base::RefCountedThreadSafe<DevicesRequest>;
~DevicesRequest() {
response_message_loop_->PostTask(FROM_HERE,
base::Bind(callback_, descriptors_.release()));
}
typedef std::vector<std::string> Serials;
void ProcessSerials(scoped_refptr<DeviceProvider> provider,
const Serials& serials) {
for (Serials::const_iterator it = serials.begin(); it != serials.end();
++it) {
descriptors_->resize(descriptors_->size() + 1);
descriptors_->back().provider = provider;
descriptors_->back().serial = *it;
}
}
scoped_refptr<base::MessageLoopProxy> response_message_loop_;
DescriptorsCallback callback_;
scoped_ptr<DeviceDescriptors> descriptors_;
};
void ReleaseDeviceAndProvider(
AndroidDeviceManager::DeviceProvider* provider,
const std::string& serial) {
provider->ReleaseDevice(serial);
provider->Release();
}
} // namespace } // namespace
AndroidDeviceManager::BrowserInfo::BrowserInfo() AndroidDeviceManager::BrowserInfo::BrowserInfo()
: type(kTypeOther) { : type(kTypeOther) {
} }
AndroidDeviceManager::DeviceInfo::DeviceInfo() { AndroidDeviceManager::DeviceInfo::DeviceInfo()
: model(kModelOffline), connected(false) {
} }
AndroidDeviceManager::DeviceInfo::~DeviceInfo() { AndroidDeviceManager::DeviceInfo::~DeviceInfo() {
} }
AndroidDeviceManager::Device::Device(const std::string& serial, AndroidDeviceManager::DeviceDescriptor::DeviceDescriptor() {
bool is_connected)
: serial_(serial),
is_connected_(is_connected) {
} }
void AndroidDeviceManager::Device::HttpQuery(const std::string& socket_name, AndroidDeviceManager::DeviceDescriptor::~DeviceDescriptor() {
const std::string& path,
const CommandCallback& callback) {
std::string request(base::StringPrintf(kHttpGetRequest, path.c_str()));
OpenSocket(socket_name,
base::Bind(&HttpRequest::CommandRequest, request, callback));
} }
AndroidDeviceManager::Device::~Device() { void AndroidDeviceManager::DeviceProvider::SendJsonRequest(
const std::string& serial,
const std::string& socket_name,
const std::string& request,
const CommandCallback& callback) {
OpenSocket(serial,
socket_name,
base::Bind(&HttpRequest::CommandRequest,
base::StringPrintf(kHttpGetRequest, request.c_str()),
callback));
}
void AndroidDeviceManager::DeviceProvider::HttpUpgrade(
const std::string& serial,
const std::string& socket_name,
const std::string& url,
const SocketCallback& callback) {
OpenSocket(
serial,
socket_name,
base::Bind(&HttpRequest::SocketRequest,
base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()),
callback));
}
void AndroidDeviceManager::DeviceProvider::ReleaseDevice(
const std::string& serial) {
} }
AndroidDeviceManager::DeviceProvider::DeviceProvider() { AndroidDeviceManager::DeviceProvider::DeviceProvider() {
...@@ -209,131 +322,181 @@ AndroidDeviceManager::DeviceProvider::DeviceProvider() { ...@@ -209,131 +322,181 @@ AndroidDeviceManager::DeviceProvider::DeviceProvider() {
AndroidDeviceManager::DeviceProvider::~DeviceProvider() { AndroidDeviceManager::DeviceProvider::~DeviceProvider() {
} }
// static void AndroidDeviceManager::Device::QueryDeviceInfo(
scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() { const DeviceInfoCallback& callback) {
return new AndroidDeviceManager(); device_message_loop_->PostTask(
FROM_HERE,
base::Bind(&DeviceProvider::QueryDeviceInfo,
provider_,
serial_,
base::Bind(&PostDeviceInfoCallback,
base::MessageLoopProxy::current(),
callback)));
} }
void AndroidDeviceManager::QueryDevices( void AndroidDeviceManager::Device::OpenSocket(const std::string& socket_name,
const DeviceProviders& providers, const SocketCallback& callback) {
const QueryDevicesCallback& callback) { device_message_loop_->PostTask(
DCHECK(CalledOnValidThread()); FROM_HERE,
stopped_ = false; base::Bind(&DeviceProvider::OpenSocket,
Devices empty; provider_,
QueryNextProvider(callback, providers, empty, empty); serial_,
socket_name,
callback));
} }
void AndroidDeviceManager::Stop() { void AndroidDeviceManager::Device::SendJsonRequest(
DCHECK(CalledOnValidThread()); const std::string& socket_name,
stopped_ = true; const std::string& request,
devices_.clear(); const CommandCallback& callback) {
device_message_loop_->PostTask(
FROM_HERE,
base::Bind(&DeviceProvider::SendJsonRequest,
provider_,
serial_,
socket_name,
request,
base::Bind(&PostCommandCallback,
base::MessageLoopProxy::current(),
callback)));
} }
bool AndroidDeviceManager::IsConnected(const std::string& serial) { void AndroidDeviceManager::Device::HttpUpgrade(const std::string& socket_name,
DCHECK(CalledOnValidThread()); const std::string& url,
Device* device = FindDevice(serial); const SocketCallback& callback) {
return device && device->is_connected(); device_message_loop_->PostTask(
FROM_HERE,
base::Bind(&DeviceProvider::HttpUpgrade,
provider_,
serial_,
socket_name,
url,
base::Bind(&PostSocketCallback,
base::MessageLoopProxy::current(),
callback)));
} }
void AndroidDeviceManager::QueryDeviceInfo(const std::string& serial, AndroidDeviceManager::Device::Device(
const DeviceInfoCallback& callback) { scoped_refptr<base::MessageLoopProxy> device_message_loop,
DCHECK(CalledOnValidThread()); scoped_refptr<DeviceProvider> provider,
Device* device = FindDevice(serial); const std::string& serial)
if (device) : device_message_loop_(device_message_loop),
device->QueryDeviceInfo(callback); provider_(provider),
else serial_(serial),
callback.Run(DeviceInfo()); weak_factory_(this) {
} }
void AndroidDeviceManager::OpenSocket( AndroidDeviceManager::Device::~Device() {
const std::string& serial, provider_->AddRef();
const std::string& socket_name, DeviceProvider* raw_ptr = provider_.get();
const SocketCallback& callback) { provider_ = NULL;
DCHECK(CalledOnValidThread()); device_message_loop_->PostTask(
Device* device = FindDevice(serial); FROM_HERE,
if (device) base::Bind(&ReleaseDeviceAndProvider,
device->OpenSocket(socket_name, callback); base::Unretained(raw_ptr),
else serial_));
callback.Run(net::ERR_CONNECTION_FAILED, NULL);
} }
void AndroidDeviceManager::HttpQuery( AndroidDeviceManager::HandlerThread*
const std::string& serial, AndroidDeviceManager::HandlerThread::instance_ = NULL;
const std::string& socket_name,
const std::string& request, // static
const CommandCallback& callback) { scoped_refptr<AndroidDeviceManager::HandlerThread>
DCHECK(CalledOnValidThread()); AndroidDeviceManager::HandlerThread::GetInstance() {
Device* device = FindDevice(serial); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (device) if (!instance_)
device->HttpQuery(socket_name, request, callback); new HandlerThread();
else return instance_;
callback.Run(net::ERR_CONNECTION_FAILED, std::string());
} }
void AndroidDeviceManager::HttpUpgrade( AndroidDeviceManager::HandlerThread::HandlerThread() {
const std::string& serial, DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const std::string& socket_name, instance_ = this;
const std::string& url, thread_ = new base::Thread(kDevToolsAdbBridgeThreadName);
const SocketCallback& callback) { base::Thread::Options options;
DCHECK(CalledOnValidThread()); options.message_loop_type = base::MessageLoop::TYPE_IO;
Device* device = FindDevice(serial); if (!thread_->StartWithOptions(options)) {
if (device) { delete thread_;
device->OpenSocket( thread_ = NULL;
socket_name,
base::Bind(&HttpRequest::SocketRequest,
base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()),
callback));
} else {
callback.Run(net::ERR_CONNECTION_FAILED, NULL);
} }
} }
AndroidDeviceManager::AndroidDeviceManager() scoped_refptr<base::MessageLoopProxy>
: stopped_(false) { AndroidDeviceManager::HandlerThread::message_loop() {
return thread_ ? thread_->message_loop_proxy() : NULL;
} }
AndroidDeviceManager::~AndroidDeviceManager() { // static
void AndroidDeviceManager::HandlerThread::StopThread(
base::Thread* thread) {
thread->Stop();
} }
void AndroidDeviceManager::QueryNextProvider( AndroidDeviceManager::HandlerThread::~HandlerThread() {
const QueryDevicesCallback& callback, DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const DeviceProviders& providers, instance_ = NULL;
const Devices& total_devices, if (!thread_)
const Devices& new_devices) {
DCHECK(CalledOnValidThread());
if (stopped_)
return; return;
// Shut down thread on FILE thread to join into IO.
content::BrowserThread::PostTask(
content::BrowserThread::FILE, FROM_HERE,
base::Bind(&HandlerThread::StopThread, thread_));
}
Devices more_devices(total_devices); // static
more_devices.insert( scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() {
more_devices.end(), new_devices.begin(), new_devices.end()); return new AndroidDeviceManager();
}
if (providers.empty()) {
std::vector<std::string> serials; void AndroidDeviceManager::SetDeviceProviders(
devices_.clear(); const DeviceProviders& providers) {
for (Devices::const_iterator it = more_devices.begin(); for (DeviceProviders::iterator it = providers_.begin();
it != more_devices.end(); ++it) { it != providers_.end(); ++it) {
devices_[(*it)->serial()] = *it; (*it)->AddRef();
serials.push_back((*it)->serial()); DeviceProvider* raw_ptr = it->get();
} *it = NULL;
callback.Run(serials); handler_thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr);
return;
} }
providers_ = providers;
}
void AndroidDeviceManager::QueryDevices(const DevicesCallback& callback) {
DevicesRequest::Start(handler_thread_->message_loop(),
providers_,
base::Bind(&AndroidDeviceManager::UpdateDevices,
this,
callback));
}
AndroidDeviceManager::AndroidDeviceManager()
: handler_thread_(HandlerThread::GetInstance()) {
}
scoped_refptr<DeviceProvider> current_provider = providers.back(); AndroidDeviceManager::~AndroidDeviceManager() {
DeviceProviders less_providers = providers; SetDeviceProviders(DeviceProviders());
less_providers.pop_back();
current_provider->QueryDevices(
base::Bind(&AndroidDeviceManager::QueryNextProvider,
this, callback, less_providers, more_devices));
} }
AndroidDeviceManager::Device* void AndroidDeviceManager::UpdateDevices(
AndroidDeviceManager::FindDevice(const std::string& serial) { const DevicesCallback& callback,
DCHECK(CalledOnValidThread()); DeviceDescriptors* descriptors_raw) {
DeviceMap::const_iterator it = devices_.find(serial); scoped_ptr<DeviceDescriptors> descriptors(descriptors_raw);
if (it == devices_.end()) Devices response;
return NULL; DeviceWeakMap new_devices;
return (*it).second.get(); for (DeviceDescriptors::const_iterator it = descriptors->begin();
it != descriptors->end();
++it) {
DeviceWeakMap::iterator found = devices_.find(it->serial);
scoped_refptr<Device> device;
if (found == devices_.end() || !found->second
|| found->second->provider_ != it->provider) {
device = new Device(handler_thread_->message_loop(),
it->provider, it->serial);
} else {
device = found->second.get();
}
response.push_back(device);
new_devices[it->serial] = device->weak_factory_.GetWeakPtr();
}
devices_.swap(new_devices);
callback.Run(response);
} }
...@@ -23,6 +23,7 @@ class AndroidDeviceManager ...@@ -23,6 +23,7 @@ class AndroidDeviceManager
public: public:
typedef base::Callback<void(int, const std::string&)> CommandCallback; typedef base::Callback<void(int, const std::string&)> CommandCallback;
typedef base::Callback<void(int result, net::StreamSocket*)> SocketCallback; typedef base::Callback<void(int result, net::StreamSocket*)> SocketCallback;
typedef base::Callback<void(const std::vector<std::string>&)> SerialsCallback;
struct BrowserInfo { struct BrowserInfo {
BrowserInfo(); BrowserInfo();
...@@ -43,117 +44,170 @@ class AndroidDeviceManager ...@@ -43,117 +44,170 @@ class AndroidDeviceManager
~DeviceInfo(); ~DeviceInfo();
std::string model; std::string model;
bool connected;
gfx::Size screen_size; gfx::Size screen_size;
std::vector<BrowserInfo> browser_info; std::vector<BrowserInfo> browser_info;
}; };
typedef base::Callback<void(const DeviceInfo&)> DeviceInfoCallback; typedef base::Callback<void(const DeviceInfo&)> DeviceInfoCallback;
class Device : public base::RefCounted<Device>, class AndroidWebSocket : public base::RefCountedThreadSafe<AndroidWebSocket> {
public base::NonThreadSafe { public:
class Delegate {
public:
virtual void OnSocketOpened() = 0;
virtual void OnFrameRead(const std::string& message) = 0;
virtual void OnSocketClosed(bool closed_by_device) = 0;
protected:
virtual ~Delegate() {}
};
AndroidWebSocket() {}
virtual void Connect() = 0;
virtual void Disconnect() = 0;
virtual void SendFrame(const std::string& message) = 0;
virtual void ClearDelegate() = 0;
protected: protected:
friend class AndroidDeviceManager; virtual ~AndroidWebSocket() {}
private:
friend class base::RefCountedThreadSafe<AndroidWebSocket>;
DISALLOW_COPY_AND_ASSIGN(AndroidWebSocket);
};
class DeviceProvider;
class Device : public base::RefCountedThreadSafe<Device>,
public base::NonThreadSafe {
public:
typedef AndroidDeviceManager::DeviceInfoCallback DeviceInfoCallback;
typedef AndroidDeviceManager::CommandCallback CommandCallback; typedef AndroidDeviceManager::CommandCallback CommandCallback;
typedef AndroidDeviceManager::SocketCallback SocketCallback; typedef AndroidDeviceManager::SocketCallback SocketCallback;
typedef AndroidDeviceManager::DeviceInfoCallback DeviceInfoCallback;
Device(const std::string& serial, bool is_connected); void QueryDeviceInfo(const DeviceInfoCallback& callback);
virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) = 0; void OpenSocket(const std::string& socket_name,
const SocketCallback& callback);
virtual void OpenSocket(const std::string& socket_name, void SendJsonRequest(const std::string& socket_name,
const SocketCallback& callback) = 0; const std::string& request,
const CommandCallback& callback);
void HttpUpgrade(const std::string& socket_name,
const std::string& url,
const SocketCallback& callback);
virtual void HttpQuery(const std::string& socket_name, scoped_refptr<AndroidWebSocket> CreateWebSocket(
const std::string& request, const std::string& socket_name,
const CommandCallback& callback); const std::string& url,
AndroidWebSocket::Delegate* delegate);
std::string serial() { return serial_; } std::string serial() { return serial_; }
bool is_connected() { return is_connected_; }
friend class base::RefCounted<Device>; private:
friend class AndroidDeviceManager;
Device(scoped_refptr<base::MessageLoopProxy> device_message_loop,
scoped_refptr<DeviceProvider> provider,
const std::string& serial);
friend class base::RefCountedThreadSafe<Device>;
virtual ~Device(); virtual ~Device();
private: scoped_refptr<base::MessageLoopProxy> device_message_loop_;
const std::string serial_; scoped_refptr<DeviceProvider> provider_;
const bool is_connected_; std::string serial_;
base::WeakPtrFactory<Device> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Device); DISALLOW_COPY_AND_ASSIGN(Device);
}; };
typedef std::vector<scoped_refptr<Device> > Devices; typedef std::vector<scoped_refptr<Device> > Devices;
typedef base::Callback<void(const Devices&)> DevicesCallback;
class DeviceProvider class DeviceProvider : public base::RefCountedThreadSafe<DeviceProvider> {
: public base::RefCountedThreadSafe< public:
DeviceProvider, typedef AndroidDeviceManager::SerialsCallback SerialsCallback;
content::BrowserThread::DeleteOnUIThread> { typedef AndroidDeviceManager::DeviceInfoCallback DeviceInfoCallback;
protected: typedef AndroidDeviceManager::SocketCallback SocketCallback;
friend class AndroidDeviceManager; typedef AndroidDeviceManager::CommandCallback CommandCallback;
typedef base::Callback<void(const Devices&)> QueryDevicesCallback; virtual void QueryDevices(const SerialsCallback& callback) = 0;
virtual void QueryDevices(const QueryDevicesCallback& callback) = 0; virtual void QueryDeviceInfo(const std::string& serial,
const DeviceInfoCallback& callback) = 0;
protected: virtual void OpenSocket(const std::string& serial,
friend struct const std::string& socket_name,
content::BrowserThread::DeleteOnThread<content::BrowserThread::UI>; const SocketCallback& callback) = 0;
friend class base::DeleteHelper<DeviceProvider>;
virtual void SendJsonRequest(const std::string& serial,
const std::string& socket_name,
const std::string& request,
const CommandCallback& callback);
virtual void HttpUpgrade(const std::string& serial,
const std::string& socket_name,
const std::string& url,
const SocketCallback& callback);
virtual void ReleaseDevice(const std::string& serial);
protected:
friend class base::RefCountedThreadSafe<DeviceProvider>;
DeviceProvider(); DeviceProvider();
virtual ~DeviceProvider(); virtual ~DeviceProvider();
}; };
public:
static scoped_refptr<AndroidDeviceManager> Create();
typedef std::vector<scoped_refptr<DeviceProvider> > DeviceProviders; typedef std::vector<scoped_refptr<DeviceProvider> > DeviceProviders;
typedef base::Callback<void (const std::vector<std::string>&)>
QueryDevicesCallback;
void QueryDevices(const DeviceProviders& providers, static scoped_refptr<AndroidDeviceManager> Create();
const QueryDevicesCallback& callback);
void Stop();
bool IsConnected(const std::string& serial); void SetDeviceProviders(const DeviceProviders& providers);
void QueryDeviceInfo(const std::string& serial, void QueryDevices(const DevicesCallback& callback);
const DeviceInfoCallback& callback);
void OpenSocket(const std::string& serial, struct DeviceDescriptor {
const std::string& socket_name, DeviceDescriptor();
const SocketCallback& callback); ~DeviceDescriptor();
void HttpQuery(const std::string& serial, scoped_refptr<DeviceProvider> provider;
const std::string& socket_name, std::string serial;
const std::string& request, };
const CommandCallback& callback);
void HttpUpgrade(const std::string& serial, typedef std::vector<DeviceDescriptor> DeviceDescriptors;
const std::string& socket_name,
const std::string& url,
const SocketCallback& callback);
private: private:
AndroidDeviceManager(); class HandlerThread : public base::RefCountedThreadSafe<HandlerThread> {
public:
static scoped_refptr<HandlerThread> GetInstance();
scoped_refptr<base::MessageLoopProxy> message_loop();
friend class base::RefCountedThreadSafe<AndroidDeviceManager>; private:
friend class base::RefCountedThreadSafe<HandlerThread>;
static HandlerThread* instance_;
static void StopThread(base::Thread* thread);
virtual ~AndroidDeviceManager(); HandlerThread();
virtual ~HandlerThread();
base::Thread* thread_;
};
void QueryNextProvider( friend class base::RefCountedThreadSafe<AndroidDeviceManager>;
const QueryDevicesCallback& callback, AndroidDeviceManager();
const DeviceProviders& providers, virtual ~AndroidDeviceManager();
const Devices& total_devices,
const Devices& new_devices);
Device* FindDevice(const std::string& serial); void UpdateDevices(const DevicesCallback& callback,
DeviceDescriptors* descriptors);
typedef std::map<std::string, scoped_refptr<Device> > DeviceMap; typedef std::map<std::string, base::WeakPtr<Device> > DeviceWeakMap;
DeviceMap devices_;
bool stopped_; scoped_refptr<HandlerThread> handler_thread_;
DeviceProviders providers_;
DeviceWeakMap devices_;
}; };
#endif // CHROME_BROWSER_DEVTOOLS_DEVICE_ANDROID_DEVICE_MANAGER_H_ #endif // CHROME_BROWSER_DEVTOOLS_DEVICE_ANDROID_DEVICE_MANAGER_H_
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "chrome/browser/devtools/device/devtools_android_bridge.h" #include "chrome/browser/devtools/device/android_device_manager.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "net/base/io_buffer.h" #include "net/base/io_buffer.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
...@@ -18,15 +18,14 @@ namespace { ...@@ -18,15 +18,14 @@ namespace {
const int kBufferSize = 16 * 1024; const int kBufferSize = 16 * 1024;
class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket { class WebSocketImpl : public AndroidDeviceManager::AndroidWebSocket {
public: public:
WebSocketImpl(scoped_refptr<DevToolsAndroidBridge> android_bridge, typedef AndroidDeviceManager::Device Device;
AndroidDeviceManager* device_manager, WebSocketImpl(scoped_refptr<base::MessageLoopProxy> device_message_loop,
base::MessageLoop* device_message_loop, scoped_refptr<Device> device,
const std::string& serial, const std::string& socket_name,
const std::string& socket_name, const std::string& url,
const std::string& url, Delegate* delegate);
Delegate* delegate);
virtual void Connect() OVERRIDE; virtual void Connect() OVERRIDE;
virtual void Disconnect() OVERRIDE; virtual void Disconnect() OVERRIDE;
...@@ -38,8 +37,7 @@ class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket { ...@@ -38,8 +37,7 @@ class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket {
virtual ~WebSocketImpl(); virtual ~WebSocketImpl();
void ConnectOnHandlerThread(); void Connected(int result, net::StreamSocket* socket);
void ConnectedOnHandlerThread(int result, net::StreamSocket* socket);
void StartListeningOnHandlerThread(); void StartListeningOnHandlerThread();
void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result); void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result);
void SendFrameOnHandlerThread(const std::string& message); void SendFrameOnHandlerThread(const std::string& message);
...@@ -50,10 +48,8 @@ class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket { ...@@ -50,10 +48,8 @@ class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket {
void OnFrameRead(const std::string& message); void OnFrameRead(const std::string& message);
void OnSocketClosed(bool closed_by_device); void OnSocketClosed(bool closed_by_device);
scoped_refptr<DevToolsAndroidBridge> android_bridge_; scoped_refptr<base::MessageLoopProxy> device_message_loop_;
AndroidDeviceManager* device_manager_; scoped_refptr<Device> device_;
base::MessageLoop* device_message_loop_;
std::string serial_;
std::string socket_name_; std::string socket_name_;
std::string url_; std::string url_;
scoped_ptr<net::StreamSocket> socket_; scoped_ptr<net::StreamSocket> socket_;
...@@ -63,17 +59,13 @@ class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket { ...@@ -63,17 +59,13 @@ class WebSocketImpl : public DevToolsAndroidBridge::AndroidWebSocket {
}; };
WebSocketImpl::WebSocketImpl( WebSocketImpl::WebSocketImpl(
scoped_refptr<DevToolsAndroidBridge> android_bridge, scoped_refptr<base::MessageLoopProxy> device_message_loop,
AndroidDeviceManager* device_manager, scoped_refptr<Device> device,
base::MessageLoop* device_message_loop,
const std::string& serial,
const std::string& socket_name, const std::string& socket_name,
const std::string& url, const std::string& url,
Delegate* delegate) Delegate* delegate)
: android_bridge_(android_bridge), : device_message_loop_(device_message_loop),
device_manager_(device_manager), device_(device),
device_message_loop_(device_message_loop),
serial_(serial),
socket_name_(socket_name), socket_name_(socket_name),
url_(url), url_(url),
delegate_(delegate) { delegate_(delegate) {
...@@ -81,11 +73,12 @@ WebSocketImpl::WebSocketImpl( ...@@ -81,11 +73,12 @@ WebSocketImpl::WebSocketImpl(
void WebSocketImpl::Connect() { void WebSocketImpl::Connect() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
device_message_loop_->PostTask( device_->HttpUpgrade(
FROM_HERE, base::Bind(&WebSocketImpl::ConnectOnHandlerThread, this)); socket_name_, url_, base::Bind(&WebSocketImpl::Connected, this));
} }
void WebSocketImpl::Disconnect() { void WebSocketImpl::Disconnect() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
device_message_loop_->PostTask( device_message_loop_->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&WebSocketImpl::DisconnectOnHandlerThread, this, false)); base::Bind(&WebSocketImpl::DisconnectOnHandlerThread, this, false));
...@@ -103,6 +96,7 @@ void WebSocketImpl::ClearDelegate() { ...@@ -103,6 +96,7 @@ void WebSocketImpl::ClearDelegate() {
} }
void WebSocketImpl::SendFrameOnHandlerThread(const std::string& message) { void WebSocketImpl::SendFrameOnHandlerThread(const std::string& message) {
DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
int mask = base::RandInt(0, 0x7FFFFFFF); int mask = base::RandInt(0, 0x7FFFFFFF);
std::string encoded_frame = WebSocket::EncodeFrameHybi17(message, mask); std::string encoded_frame = WebSocket::EncodeFrameHybi17(message, mask);
request_buffer_ += encoded_frame; request_buffer_ += encoded_frame;
...@@ -110,30 +104,25 @@ void WebSocketImpl::SendFrameOnHandlerThread(const std::string& message) { ...@@ -110,30 +104,25 @@ void WebSocketImpl::SendFrameOnHandlerThread(const std::string& message) {
SendPendingRequests(0); SendPendingRequests(0);
} }
WebSocketImpl::~WebSocketImpl() {} WebSocketImpl::~WebSocketImpl() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
void WebSocketImpl::ConnectOnHandlerThread() {
device_manager_->HttpUpgrade(
serial_,
socket_name_,
url_,
base::Bind(&WebSocketImpl::ConnectedOnHandlerThread, this));
} }
void WebSocketImpl::ConnectedOnHandlerThread( void WebSocketImpl::Connected(int result, net::StreamSocket* socket) {
int result, net::StreamSocket* socket) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (result != net::OK || socket == NULL) { if (result != net::OK || socket == NULL) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, OnSocketClosed(true);
base::Bind(&WebSocketImpl::OnSocketClosed, this, true));
return; return;
} }
socket_.reset(socket); socket_.reset(socket);
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, device_message_loop_->PostTask(
base::Bind(&WebSocketImpl::OnSocketOpened, this)); FROM_HERE,
StartListeningOnHandlerThread(); base::Bind(&WebSocketImpl::StartListeningOnHandlerThread, this));
OnSocketOpened();
} }
void WebSocketImpl::StartListeningOnHandlerThread() { void WebSocketImpl::StartListeningOnHandlerThread() {
DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
scoped_refptr<net::IOBuffer> response_buffer = scoped_refptr<net::IOBuffer> response_buffer =
new net::IOBuffer(kBufferSize); new net::IOBuffer(kBufferSize);
int result = socket_->Read( int result = socket_->Read(
...@@ -146,6 +135,7 @@ void WebSocketImpl::StartListeningOnHandlerThread() { ...@@ -146,6 +135,7 @@ void WebSocketImpl::StartListeningOnHandlerThread() {
void WebSocketImpl::OnBytesRead( void WebSocketImpl::OnBytesRead(
scoped_refptr<net::IOBuffer> response_buffer, int result) { scoped_refptr<net::IOBuffer> response_buffer, int result) {
DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
if (!socket_) if (!socket_)
return; return;
...@@ -185,6 +175,7 @@ void WebSocketImpl::OnBytesRead( ...@@ -185,6 +175,7 @@ void WebSocketImpl::OnBytesRead(
} }
void WebSocketImpl::SendPendingRequests(int result) { void WebSocketImpl::SendPendingRequests(int result) {
DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
if (!socket_) if (!socket_)
return; return;
if (result < 0) { if (result < 0) {
...@@ -205,6 +196,7 @@ void WebSocketImpl::SendPendingRequests(int result) { ...@@ -205,6 +196,7 @@ void WebSocketImpl::SendPendingRequests(int result) {
} }
void WebSocketImpl::DisconnectOnHandlerThread(bool closed_by_device) { void WebSocketImpl::DisconnectOnHandlerThread(bool closed_by_device) {
DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
if (!socket_) if (!socket_)
return; return;
// Wipe out socket_ first since Disconnect can re-enter this method. // Wipe out socket_ first since Disconnect can re-enter this method.
...@@ -231,13 +223,10 @@ void WebSocketImpl::OnSocketClosed(bool closed_by_device) { ...@@ -231,13 +223,10 @@ void WebSocketImpl::OnSocketClosed(bool closed_by_device) {
} // namespace } // namespace
scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> scoped_refptr<AndroidDeviceManager::AndroidWebSocket>
DevToolsAndroidBridge::RemoteBrowser::CreateWebSocket( AndroidDeviceManager::Device::CreateWebSocket(
const std::string& socket,
const std::string& url, const std::string& url,
DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate) { AndroidDeviceManager::AndroidWebSocket::Delegate* delegate) {
return new WebSocketImpl( return new WebSocketImpl(device_message_loop_, this, socket, url, delegate);
android_bridge_,
android_bridge_->device_manager(),
android_bridge_->device_message_loop(),
serial_, socket_, url, delegate);
} }
...@@ -41,8 +41,6 @@ using content::BrowserThread; ...@@ -41,8 +41,6 @@ using content::BrowserThread;
namespace { namespace {
const char kModelOffline[] = "Offline";
const char kPageListRequest[] = "/json"; const char kPageListRequest[] = "/json";
const char kVersionRequest[] = "/json/version"; const char kVersionRequest[] = "/json/version";
const char kClosePageRequest[] = "/json/close/%s"; const char kClosePageRequest[] = "/json/close/%s";
...@@ -65,14 +63,14 @@ class DiscoveryRequest : public base::RefCountedThreadSafe< ...@@ -65,14 +63,14 @@ class DiscoveryRequest : public base::RefCountedThreadSafe<
DiscoveryRequest, DiscoveryRequest,
BrowserThread::DeleteOnUIThread> { BrowserThread::DeleteOnUIThread> {
public: public:
typedef base::Callback<void(DevToolsAndroidBridge::RemoteDevices*)> Callback; typedef base::Callback<void(scoped_ptr<DevToolsAndroidBridge::RemoteDevices>)>
DiscoveryCallback;
typedef AndroidDeviceManager::Device Device;
typedef AndroidDeviceManager::Devices Devices;
DiscoveryRequest( DiscoveryRequest(
scoped_refptr<DevToolsAndroidBridge> android_bridge,
AndroidDeviceManager* device_manager, AndroidDeviceManager* device_manager,
base::MessageLoop* device_message_loop, const DiscoveryCallback& callback);
const AndroidDeviceManager::DeviceProviders& device_providers,
const Callback& callback);
private: private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
...@@ -80,14 +78,14 @@ class DiscoveryRequest : public base::RefCountedThreadSafe< ...@@ -80,14 +78,14 @@ class DiscoveryRequest : public base::RefCountedThreadSafe<
virtual ~DiscoveryRequest(); virtual ~DiscoveryRequest();
void ReceivedSerials(const std::vector<std::string>& serials); void ReceivedDevices(const Devices& devices);
void ProcessSerials(); void ProcessDevices();
void ReceivedDeviceInfo(const AndroidDeviceManager::DeviceInfo& device_info); void ReceivedDeviceInfo(const AndroidDeviceManager::DeviceInfo& device_info);
void ProcessSockets(); void ProcessSockets();
void ReceivedVersion(int result, const std::string& response); void ReceivedVersion(int result, const std::string& response);
void ReceivedPages(int result, const std::string& response); void ReceivedPages(int result, const std::string& response);
std::string current_serial() const { return serials_.back(); } scoped_refptr<Device> current_device() { return devices_.back(); }
scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> current_browser() const { scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> current_browser() const {
return browsers_.back(); return browsers_.back();
...@@ -98,84 +96,59 @@ class DiscoveryRequest : public base::RefCountedThreadSafe< ...@@ -98,84 +96,59 @@ class DiscoveryRequest : public base::RefCountedThreadSafe<
void Respond(); void Respond();
scoped_refptr<DevToolsAndroidBridge> android_bridge_; DiscoveryCallback callback_;
AndroidDeviceManager* device_manager_; Devices devices_;
base::MessageLoop* device_message_loop_;
Callback callback_;
std::vector<std::string> serials_;
DevToolsAndroidBridge::RemoteBrowsers browsers_; DevToolsAndroidBridge::RemoteBrowsers browsers_;
scoped_ptr<DevToolsAndroidBridge::RemoteDevices> remote_devices_; scoped_ptr<DevToolsAndroidBridge::RemoteDevices> remote_devices_;
}; };
DiscoveryRequest::DiscoveryRequest( DiscoveryRequest::DiscoveryRequest(
scoped_refptr<DevToolsAndroidBridge> android_bridge,
AndroidDeviceManager* device_manager, AndroidDeviceManager* device_manager,
base::MessageLoop* device_message_loop, const DiscoveryCallback& callback)
const AndroidDeviceManager::DeviceProviders& device_providers, : callback_(callback) {
const Callback& callback) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
: android_bridge_(android_bridge),
device_manager_(device_manager),
device_message_loop_(device_message_loop),
callback_(callback) {
remote_devices_.reset(new DevToolsAndroidBridge::RemoteDevices()); remote_devices_.reset(new DevToolsAndroidBridge::RemoteDevices());
device_message_loop_->PostTask( device_manager->QueryDevices(
FROM_HERE, base::Bind( base::Bind(&DiscoveryRequest::ReceivedDevices, this));
&AndroidDeviceManager::QueryDevices,
device_manager_,
device_providers,
base::Bind(&DiscoveryRequest::ReceivedSerials, this)));
} }
DiscoveryRequest::~DiscoveryRequest() { DiscoveryRequest::~DiscoveryRequest() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
} }
void DiscoveryRequest::ReceivedSerials( void DiscoveryRequest::ReceivedDevices(const Devices& devices) {
const std::vector<std::string>& serials) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); devices_ = devices;
serials_ = serials; ProcessDevices();
ProcessSerials();
} }
void DiscoveryRequest::ProcessSerials() { void DiscoveryRequest::ProcessDevices() {
DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); if (devices_.size() == 0) {
if (serials_.size() == 0) { Respond();
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&DiscoveryRequest::Respond, this));
return; return;
} }
if (device_manager_->IsConnected(current_serial())) { current_device()->QueryDeviceInfo(
device_manager_->QueryDeviceInfo(current_serial(), base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this));
base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this));
} else {
AndroidDeviceManager::DeviceInfo offline_info;
offline_info.model = kModelOffline;
remote_devices_->push_back(new DevToolsAndroidBridge::RemoteDevice(
android_bridge_, current_serial(), offline_info, false));
NextDevice();
}
} }
void DiscoveryRequest::ReceivedDeviceInfo( void DiscoveryRequest::ReceivedDeviceInfo(
const AndroidDeviceManager::DeviceInfo& device_info) { const AndroidDeviceManager::DeviceInfo& device_info) {
remote_devices_->push_back(new DevToolsAndroidBridge::RemoteDevice( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
android_bridge_, current_serial(), device_info, true)); remote_devices_->push_back(
new DevToolsAndroidBridge::RemoteDevice(current_device(), device_info));
browsers_ = remote_devices_->back()->browsers(); browsers_ = remote_devices_->back()->browsers();
ProcessSockets(); ProcessSockets();
} }
void DiscoveryRequest::ProcessSockets() { void DiscoveryRequest::ProcessSockets() {
DCHECK_EQ(device_message_loop_, base::MessageLoop::current());
if (browsers_.size() == 0) { if (browsers_.size() == 0) {
NextDevice(); NextDevice();
return; return;
} }
device_manager_->HttpQuery( current_device()->SendJsonRequest(
current_serial(),
current_browser()->socket(), current_browser()->socket(),
kVersionRequest, kVersionRequest,
base::Bind(&DiscoveryRequest::ReceivedVersion, this)); base::Bind(&DiscoveryRequest::ReceivedVersion, this));
...@@ -183,7 +156,7 @@ void DiscoveryRequest::ProcessSockets() { ...@@ -183,7 +156,7 @@ void DiscoveryRequest::ProcessSockets() {
void DiscoveryRequest::ReceivedVersion(int result, void DiscoveryRequest::ReceivedVersion(int result,
const std::string& response) { const std::string& response) {
DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (result < 0) { if (result < 0) {
NextBrowser(); NextBrowser();
return; return;
...@@ -210,8 +183,7 @@ void DiscoveryRequest::ReceivedVersion(int result, ...@@ -210,8 +183,7 @@ void DiscoveryRequest::ReceivedVersion(int result,
} }
} }
device_manager_->HttpQuery( current_device()->SendJsonRequest(
current_serial(),
current_browser()->socket(), current_browser()->socket(),
kPageListRequest, kPageListRequest,
base::Bind(&DiscoveryRequest::ReceivedPages, this)); base::Bind(&DiscoveryRequest::ReceivedPages, this));
...@@ -219,7 +191,7 @@ void DiscoveryRequest::ReceivedVersion(int result, ...@@ -219,7 +191,7 @@ void DiscoveryRequest::ReceivedVersion(int result,
void DiscoveryRequest::ReceivedPages(int result, void DiscoveryRequest::ReceivedPages(int result,
const std::string& response) { const std::string& response) {
DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (result >= 0) { if (result >= 0) {
scoped_ptr<base::Value> value(base::JSONReader::Read(response)); scoped_ptr<base::Value> value(base::JSONReader::Read(response));
base::ListValue* list_value; base::ListValue* list_value;
...@@ -235,12 +207,12 @@ void DiscoveryRequest::NextBrowser() { ...@@ -235,12 +207,12 @@ void DiscoveryRequest::NextBrowser() {
} }
void DiscoveryRequest::NextDevice() { void DiscoveryRequest::NextDevice() {
serials_.pop_back(); devices_.pop_back();
ProcessSerials(); ProcessDevices();
} }
void DiscoveryRequest::Respond() { void DiscoveryRequest::Respond() {
callback_.Run(remote_devices_.release()); callback_.Run(remote_devices_.Pass());
} }
// ProtocolCommand ------------------------------------------------------------ // ProtocolCommand ------------------------------------------------------------
...@@ -588,11 +560,9 @@ void RemotePageTarget::Navigate(const std::string& url, ...@@ -588,11 +560,9 @@ void RemotePageTarget::Navigate(const std::string& url,
// DevToolsAndroidBridge::RemoteBrowser --------------------------------------- // DevToolsAndroidBridge::RemoteBrowser ---------------------------------------
DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser( DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser(
scoped_refptr<DevToolsAndroidBridge> android_bridge, scoped_refptr<Device> device,
const std::string& serial,
const AndroidDeviceManager::BrowserInfo& browser_info) const AndroidDeviceManager::BrowserInfo& browser_info)
: android_bridge_(android_bridge), : device_(device),
serial_(serial),
socket_(browser_info.socket_name), socket_(browser_info.socket_name),
display_name_(browser_info.display_name), display_name_(browser_info.display_name),
type_(browser_info.type), type_(browser_info.type),
...@@ -642,7 +612,7 @@ void DevToolsAndroidBridge::RemoteBrowser::SetPageDescriptors( ...@@ -642,7 +612,7 @@ void DevToolsAndroidBridge::RemoteBrowser::SetPageDescriptors(
} }
static void RespondOnUIThread( static void RespondOnUIThread(
const DevToolsAndroidBridge::RemoteBrowser::JsonRequestCallback& callback, const DevToolsAndroidBridge::JsonRequestCallback& callback,
int result, int result,
const std::string& response) { const std::string& response) {
if (callback.is_null()) if (callback.is_null())
...@@ -653,12 +623,7 @@ static void RespondOnUIThread( ...@@ -653,12 +623,7 @@ static void RespondOnUIThread(
void DevToolsAndroidBridge::RemoteBrowser::SendJsonRequest( void DevToolsAndroidBridge::RemoteBrowser::SendJsonRequest(
const std::string& request, const JsonRequestCallback& callback) { const std::string& request, const JsonRequestCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); device_->SendJsonRequest(socket_, request, callback);
android_bridge_->device_message_loop()->PostTask(
FROM_HERE,
base::Bind(&AndroidDeviceManager::HttpQuery,
android_bridge_->device_manager(), serial_, socket_, request,
base::Bind(&RespondOnUIThread, callback)));
} }
void DevToolsAndroidBridge::RemoteBrowser::SendProtocolCommand( void DevToolsAndroidBridge::RemoteBrowser::SendProtocolCommand(
...@@ -684,7 +649,14 @@ void DevToolsAndroidBridge::RemoteBrowser::Open( ...@@ -684,7 +649,14 @@ void DevToolsAndroidBridge::RemoteBrowser::Open(
scoped_refptr<content::DevToolsAgentHost> scoped_refptr<content::DevToolsAgentHost>
DevToolsAndroidBridge::RemoteBrowser::GetAgentHost() { DevToolsAndroidBridge::RemoteBrowser::GetAgentHost() {
return AgentHostDelegate::GetOrCreateAgentHost( return AgentHostDelegate::GetOrCreateAgentHost(
"adb:" + serial_ + ":" + socket_, this, kBrowserTargetSocket); "adb:" + device_->serial() + ":" + socket_, this, kBrowserTargetSocket);
}
scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket>
DevToolsAndroidBridge::RemoteBrowser::CreateWebSocket(
const std::string& url,
DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate) {
return device_->CreateWebSocket(socket_, url, delegate);
} }
void DevToolsAndroidBridge::RemoteBrowser::RespondToOpenOnUIThread( void DevToolsAndroidBridge::RemoteBrowser::RespondToOpenOnUIThread(
...@@ -764,113 +736,50 @@ void DevToolsAndroidBridge::RemoteBrowser::NavigatePageOnUIThread( ...@@ -764,113 +736,50 @@ void DevToolsAndroidBridge::RemoteBrowser::NavigatePageOnUIThread(
DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() { DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() {
} }
// DevToolsAndroidBridge::RemoteDevice ---------------------------------------- // DevToolsAndroidBridge::RemoteDevice ----------------------------------------
DevToolsAndroidBridge::RemoteDevice::RemoteDevice( DevToolsAndroidBridge::RemoteDevice::RemoteDevice(
scoped_refptr<DevToolsAndroidBridge> android_bridge, scoped_refptr<AndroidDeviceManager::Device> device,
const std::string& serial, const AndroidDeviceManager::DeviceInfo& device_info)
const AndroidDeviceManager::DeviceInfo& device_info, : device_(device),
bool connected)
: android_bridge_(android_bridge),
serial_(serial),
model_(device_info.model), model_(device_info.model),
connected_(connected), connected_(device_info.connected),
screen_size_(device_info.screen_size) { screen_size_(device_info.screen_size) {
for (std::vector<AndroidDeviceManager::BrowserInfo>::const_iterator it = for (std::vector<AndroidDeviceManager::BrowserInfo>::const_iterator it =
device_info.browser_info.begin(); device_info.browser_info.begin();
it != device_info.browser_info.end(); it != device_info.browser_info.end();
++it) { ++it) {
browsers_.push_back(new DevToolsAndroidBridge::RemoteBrowser( browsers_.push_back(new DevToolsAndroidBridge::RemoteBrowser(device, *it));
android_bridge_, serial_, *it));
} }
} }
void DevToolsAndroidBridge::RemoteDevice::OpenSocket( void DevToolsAndroidBridge::RemoteDevice::OpenSocket(
const std::string& socket_name, const std::string& socket_name,
const AndroidDeviceManager::SocketCallback& callback) { const AndroidDeviceManager::SocketCallback& callback) {
android_bridge_->device_message_loop()->PostTask(FROM_HERE, device_->OpenSocket(socket_name, callback);
base::Bind(&AndroidDeviceManager::OpenSocket,
android_bridge_->device_manager(),
serial_,
socket_name,
callback));
} }
DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() { DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() {
} }
// DevToolsAndroidBridge::HandlerThread ---------------------------------
const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread";
DevToolsAndroidBridge::HandlerThread*
DevToolsAndroidBridge::HandlerThread::instance_ = NULL;
// static
scoped_refptr<DevToolsAndroidBridge::HandlerThread>
DevToolsAndroidBridge::HandlerThread::GetInstance() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!instance_)
new HandlerThread();
return instance_;
}
DevToolsAndroidBridge::HandlerThread::HandlerThread() {
instance_ = this;
thread_ = new base::Thread(kDevToolsAdbBridgeThreadName);
base::Thread::Options options;
options.message_loop_type = base::MessageLoop::TYPE_IO;
if (!thread_->StartWithOptions(options)) {
delete thread_;
thread_ = NULL;
}
}
base::MessageLoop* DevToolsAndroidBridge::HandlerThread::message_loop() {
return thread_ ? thread_->message_loop() : NULL;
}
// static
void DevToolsAndroidBridge::HandlerThread::StopThread(
base::Thread* thread) {
thread->Stop();
}
DevToolsAndroidBridge::HandlerThread::~HandlerThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
instance_ = NULL;
if (!thread_)
return;
// Shut down thread on FILE thread to join into IO.
BrowserThread::PostTask(
BrowserThread::FILE, FROM_HERE,
base::Bind(&HandlerThread::StopThread, thread_));
}
// DevToolsAndroidBridge ------------------------------------------------------ // DevToolsAndroidBridge ------------------------------------------------------
DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile) DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile)
: profile_(profile), : profile_(profile),
handler_thread_(HandlerThread::GetInstance()) { device_manager_(AndroidDeviceManager::Create()) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
pref_change_registrar_.Init(profile_->GetPrefs()); pref_change_registrar_.Init(profile_->GetPrefs());
pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled, pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled,
base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders, base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
base::Unretained(this))); base::Unretained(this)));
CreateDeviceProviders(); CreateDeviceProviders();
base::PostTaskAndReplyWithResult(
device_message_loop()->message_loop_proxy(),
FROM_HERE,
base::Bind(&AndroidDeviceManager::Create),
base::Bind(&DevToolsAndroidBridge::CreatedDeviceManager, this));
} }
void DevToolsAndroidBridge::AddDeviceListListener( void DevToolsAndroidBridge::AddDeviceListListener(
DeviceListListener* listener) { DeviceListListener* listener) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
device_list_listeners_.push_back(listener); device_list_listeners_.push_back(listener);
if (device_list_listeners_.size() == 1 && device_manager_) if (device_list_listeners_.size() == 1)
RequestDeviceList(); RequestDeviceList();
} }
...@@ -881,16 +790,14 @@ void DevToolsAndroidBridge::RemoveDeviceListListener( ...@@ -881,16 +790,14 @@ void DevToolsAndroidBridge::RemoveDeviceListListener(
device_list_listeners_.begin(), device_list_listeners_.end(), listener); device_list_listeners_.begin(), device_list_listeners_.end(), listener);
DCHECK(it != device_list_listeners_.end()); DCHECK(it != device_list_listeners_.end());
device_list_listeners_.erase(it); device_list_listeners_.erase(it);
if (device_list_listeners_.empty() && device_manager_) { if (device_list_listeners_.empty())
device_message_loop()->PostTask(FROM_HERE, devices_.clear();
base::Bind(&AndroidDeviceManager::Stop, device_manager_));
}
} }
void DevToolsAndroidBridge::AddDeviceCountListener( void DevToolsAndroidBridge::AddDeviceCountListener(
DeviceCountListener* listener) { DeviceCountListener* listener) {
device_count_listeners_.push_back(listener); device_count_listeners_.push_back(listener);
if (device_count_listeners_.size() == 1 && device_manager_) if (device_count_listeners_.size() == 1)
RequestDeviceCount(); RequestDeviceCount();
} }
...@@ -913,47 +820,28 @@ DevToolsAndroidBridge::~DevToolsAndroidBridge() { ...@@ -913,47 +820,28 @@ DevToolsAndroidBridge::~DevToolsAndroidBridge() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(device_list_listeners_.empty()); DCHECK(device_list_listeners_.empty());
DCHECK(device_count_listeners_.empty()); DCHECK(device_count_listeners_.empty());
if (device_manager_) {
AndroidDeviceManager* raw_ptr = device_manager_.get();
device_manager_->AddRef();
device_manager_ = NULL;
device_message_loop()->ReleaseSoon(FROM_HERE, raw_ptr);
}
} }
void DevToolsAndroidBridge::RequestDeviceList() { void DevToolsAndroidBridge::RequestDeviceList() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(device_manager_);
if (device_list_listeners_.empty()) if (device_list_listeners_.empty())
return; return;
new DiscoveryRequest( new DiscoveryRequest(
this, device_manager_.get(),
device_manager(),
device_message_loop(),
device_providers_,
base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this)); base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this));
} }
void DevToolsAndroidBridge::CreatedDeviceManager( void DevToolsAndroidBridge::ReceivedDeviceList(
scoped_refptr<AndroidDeviceManager> device_manager) { scoped_ptr<RemoteDevices> devices) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
device_manager_ = device_manager;
if (!device_list_listeners_.empty())
RequestDeviceList();
if (!device_count_listeners_.empty())
RequestDeviceCount();
}
void DevToolsAndroidBridge::ReceivedDeviceList(RemoteDevices* devices_ptr) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
scoped_ptr<RemoteDevices> devices(devices_ptr);
if (device_list_listeners_.empty()) if (device_list_listeners_.empty())
return; return;
devices_ = *devices;
DeviceListListeners copy(device_list_listeners_); DeviceListListeners copy(device_list_listeners_);
for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it) for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it)
(*it)->DeviceListChanged(*devices.get()); (*it)->DeviceListChanged(*devices.get());
...@@ -967,7 +855,6 @@ void DevToolsAndroidBridge::ReceivedDeviceList(RemoteDevices* devices_ptr) { ...@@ -967,7 +855,6 @@ void DevToolsAndroidBridge::ReceivedDeviceList(RemoteDevices* devices_ptr) {
void DevToolsAndroidBridge::RequestDeviceCount() { void DevToolsAndroidBridge::RequestDeviceCount() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(device_manager_);
if (device_count_listeners_.empty()) if (device_count_listeners_.empty())
return; return;
...@@ -994,15 +881,15 @@ void DevToolsAndroidBridge::ReceivedDeviceCount(int count) { ...@@ -994,15 +881,15 @@ void DevToolsAndroidBridge::ReceivedDeviceCount(int count) {
} }
void DevToolsAndroidBridge::CreateDeviceProviders() { void DevToolsAndroidBridge::CreateDeviceProviders() {
device_providers_.clear(); AndroidDeviceManager::DeviceProviders device_providers;
#if defined(DEBUG_DEVTOOLS) #if defined(DEBUG_DEVTOOLS)
BrowserListTabContentsProvider::EnableTethering(); BrowserListTabContentsProvider::EnableTethering();
// We cannot rely on command line switch here as we might want to connect // We cannot rely on command line switch here as we might want to connect
// to another instance of Chrome. Using hard-coded port number instead. // to another instance of Chrome. Using hard-coded port number instead.
const int kDefaultDebuggingPort = 9222; const int kDefaultDebuggingPort = 9222;
device_providers_.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort)); device_providers.push_back(new SelfAsDeviceProvider(kDefaultDebuggingPort));
#endif #endif
device_providers_.push_back(new AdbDeviceProvider()); device_providers.push_back(new AdbDeviceProvider());
PrefService* service = profile_->GetPrefs(); PrefService* service = profile_->GetPrefs();
const PrefService::Preference* pref = const PrefService::Preference* pref =
...@@ -1011,6 +898,7 @@ void DevToolsAndroidBridge::CreateDeviceProviders() { ...@@ -1011,6 +898,7 @@ void DevToolsAndroidBridge::CreateDeviceProviders() {
bool enabled; bool enabled;
if (pref_value->GetAsBoolean(&enabled) && enabled) { if (pref_value->GetAsBoolean(&enabled) && enabled) {
device_providers_.push_back(new UsbDeviceProvider(profile_)); device_providers.push_back(new UsbDeviceProvider(profile_));
} }
device_manager_->SetDeviceProviders(device_providers);
} }
...@@ -72,34 +72,6 @@ class DevToolsAndroidBridge ...@@ -72,34 +72,6 @@ class DevToolsAndroidBridge
DISALLOW_COPY_AND_ASSIGN(Factory); DISALLOW_COPY_AND_ASSIGN(Factory);
}; };
class AndroidWebSocket : public base::RefCountedThreadSafe<AndroidWebSocket> {
public:
class Delegate {
public:
virtual void OnSocketOpened() = 0;
virtual void OnFrameRead(const std::string& message) = 0;
virtual void OnSocketClosed(bool closed_by_device) = 0;
protected:
virtual ~Delegate() {}
};
AndroidWebSocket() {}
virtual void Connect() = 0;
virtual void Disconnect() = 0;
virtual void SendFrame(const std::string& message) = 0;
virtual void ClearDelegate() = 0;
protected:
virtual ~AndroidWebSocket() {}
private:
friend class base::RefCountedThreadSafe<AndroidWebSocket>;
DISALLOW_COPY_AND_ASSIGN(AndroidWebSocket);
};
class RemotePage { class RemotePage {
public: public:
virtual ~RemotePage() {} virtual ~RemotePage() {}
...@@ -108,15 +80,16 @@ class DevToolsAndroidBridge ...@@ -108,15 +80,16 @@ class DevToolsAndroidBridge
}; };
typedef base::Callback<void(RemotePage*)> RemotePageCallback; typedef base::Callback<void(RemotePage*)> RemotePageCallback;
typedef base::Callback<void(int, const std::string&)> JsonRequestCallback;
typedef AndroidDeviceManager::Device Device;
typedef AndroidDeviceManager::AndroidWebSocket AndroidWebSocket;
class RemoteBrowser : public base::RefCounted<RemoteBrowser> { class RemoteBrowser : public base::RefCounted<RemoteBrowser> {
public: public:
RemoteBrowser( RemoteBrowser(scoped_refptr<Device> device,
scoped_refptr<DevToolsAndroidBridge> android_bridge, const AndroidDeviceManager::BrowserInfo& browser_info);
const std::string& serial,
const AndroidDeviceManager::BrowserInfo& browser_info);
std::string serial() { return serial_; } std::string serial() { return device_->serial(); }
std::string socket() { return socket_; } std::string socket() { return socket_; }
std::string display_name() { return display_name_; } std::string display_name() { return display_name_; }
...@@ -134,9 +107,9 @@ class DevToolsAndroidBridge ...@@ -134,9 +107,9 @@ class DevToolsAndroidBridge
std::vector<RemotePage*> CreatePages(); std::vector<RemotePage*> CreatePages();
void SetPageDescriptors(const base::ListValue&); void SetPageDescriptors(const base::ListValue&);
typedef base::Callback<void(int, const std::string&)> JsonRequestCallback;
void SendJsonRequest(const std::string& request, void SendJsonRequest(const std::string& request,
const JsonRequestCallback& callback); const JsonRequestCallback& callback);
void SendProtocolCommand(const std::string& debug_url, void SendProtocolCommand(const std::string& debug_url,
const std::string& method, const std::string& method,
base::DictionaryValue* params, base::DictionaryValue* params,
...@@ -172,8 +145,7 @@ class DevToolsAndroidBridge ...@@ -172,8 +145,7 @@ class DevToolsAndroidBridge
int result, int result,
const std::string& response); const std::string& response);
scoped_refptr<DevToolsAndroidBridge> android_bridge_; scoped_refptr<Device> device_;
const std::string serial_;
const std::string socket_; const std::string socket_;
std::string display_name_; std::string display_name_;
const AndroidDeviceManager::BrowserInfo::Type type_; const AndroidDeviceManager::BrowserInfo::Type type_;
...@@ -187,12 +159,10 @@ class DevToolsAndroidBridge ...@@ -187,12 +159,10 @@ class DevToolsAndroidBridge
class RemoteDevice : public base::RefCounted<RemoteDevice> { class RemoteDevice : public base::RefCounted<RemoteDevice> {
public: public:
RemoteDevice(scoped_refptr<DevToolsAndroidBridge> android_bridge, RemoteDevice(scoped_refptr<Device> device,
const std::string& serial, const AndroidDeviceManager::DeviceInfo& device_info);
const AndroidDeviceManager::DeviceInfo& device_info,
bool connected);
std::string serial() { return serial_; } std::string serial() { return device_->serial(); }
std::string model() { return model_; } std::string model() { return model_; }
bool is_connected() { return connected_; } bool is_connected() { return connected_; }
RemoteBrowsers& browsers() { return browsers_; } RemoteBrowsers& browsers() { return browsers_; }
...@@ -205,8 +175,7 @@ class DevToolsAndroidBridge ...@@ -205,8 +175,7 @@ class DevToolsAndroidBridge
friend class base::RefCounted<RemoteDevice>; friend class base::RefCounted<RemoteDevice>;
virtual ~RemoteDevice(); virtual ~RemoteDevice();
scoped_refptr<DevToolsAndroidBridge> android_bridge_; scoped_refptr<Device> device_;
std::string serial_;
std::string model_; std::string model_;
bool connected_; bool connected_;
RemoteBrowsers browsers_; RemoteBrowsers browsers_;
...@@ -240,7 +209,7 @@ class DevToolsAndroidBridge ...@@ -240,7 +209,7 @@ class DevToolsAndroidBridge
void set_device_providers_for_test( void set_device_providers_for_test(
const AndroidDeviceManager::DeviceProviders& device_providers) { const AndroidDeviceManager::DeviceProviders& device_providers) {
device_providers_ = device_providers; device_manager_->SetDeviceProviders(device_providers);
} }
static bool HasDevToolsWindow(const std::string& agent_id); static bool HasDevToolsWindow(const std::string& agent_id);
...@@ -250,43 +219,18 @@ class DevToolsAndroidBridge ...@@ -250,43 +219,18 @@ class DevToolsAndroidBridge
content::BrowserThread::UI>; content::BrowserThread::UI>;
friend class base::DeleteHelper<DevToolsAndroidBridge>; friend class base::DeleteHelper<DevToolsAndroidBridge>;
class HandlerThread : public base::RefCountedThreadSafe<HandlerThread> {
public:
static scoped_refptr<HandlerThread> GetInstance();
base::MessageLoop* message_loop();
private:
friend class base::RefCountedThreadSafe<HandlerThread>;
static HandlerThread* instance_;
static void StopThread(base::Thread* thread);
HandlerThread();
virtual ~HandlerThread();
base::Thread* thread_;
};
virtual ~DevToolsAndroidBridge(); virtual ~DevToolsAndroidBridge();
base::MessageLoop* device_message_loop() {
return handler_thread_->message_loop();
}
AndroidDeviceManager* device_manager() {
return device_manager_.get();
}
void CreatedDeviceManager(scoped_refptr<AndroidDeviceManager> device_manager);
void RequestDeviceList(); void RequestDeviceList();
void ReceivedDeviceList(RemoteDevices* devices); void ReceivedDeviceList(scoped_ptr<RemoteDevices> devices);
void RequestDeviceCount(); void RequestDeviceCount();
void ReceivedDeviceCount(int count); void ReceivedDeviceCount(int count);
void CreateDeviceProviders(); void CreateDeviceProviders();
Profile* profile_; Profile* profile_;
scoped_refptr<HandlerThread> handler_thread_;
scoped_refptr<AndroidDeviceManager> device_manager_; scoped_refptr<AndroidDeviceManager> device_manager_;
RemoteDevices devices_;
typedef std::vector<DeviceListListener*> DeviceListListeners; typedef std::vector<DeviceListListener*> DeviceListListeners;
DeviceListListeners device_list_listeners_; DeviceListListeners device_list_listeners_;
...@@ -294,7 +238,6 @@ class DevToolsAndroidBridge ...@@ -294,7 +238,6 @@ class DevToolsAndroidBridge
typedef std::vector<DeviceCountListener*> DeviceCountListeners; typedef std::vector<DeviceCountListener*> DeviceCountListeners;
DeviceCountListeners device_count_listeners_; DeviceCountListeners device_count_listeners_;
AndroidDeviceManager::DeviceProviders device_providers_;
PrefChangeRegistrar pref_change_registrar_; PrefChangeRegistrar pref_change_registrar_;
DISALLOW_COPY_AND_ASSIGN(DevToolsAndroidBridge); DISALLOW_COPY_AND_ASSIGN(DevToolsAndroidBridge);
}; };
......
...@@ -13,29 +13,31 @@ namespace { ...@@ -13,29 +13,31 @@ namespace {
const char kDeviceModel[] = "Local Chrome"; const char kDeviceModel[] = "Local Chrome";
const char kBrowserName[] = "Chrome"; const char kBrowserName[] = "Chrome";
const char kLocalhost[] = "127.0.0.1"; const char kLocalhost[] = "127.0.0.1";
const char kSerial[] = "local";
class SelfAsDevice : public AndroidDeviceManager::Device { static void RunSocketCallback(
public: const AndroidDeviceManager::SocketCallback& callback,
explicit SelfAsDevice(int port); net::StreamSocket* socket,
int result) {
virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) OVERRIDE; callback.Run(result, socket);
}
virtual void OpenSocket(const std::string& socket_name, } // namespace
const SocketCallback& callback) OVERRIDE;
private:
virtual ~SelfAsDevice() {}
int port_; SelfAsDeviceProvider::SelfAsDeviceProvider(int port) : port_(port) {
}; }
SelfAsDevice::SelfAsDevice(int port) void SelfAsDeviceProvider::QueryDevices(const SerialsCallback& callback) {
: Device("local", true), std::vector<std::string> result;
port_(port) result.push_back(kSerial);
{} callback.Run(result);
}
void SelfAsDevice::QueryDeviceInfo(const DeviceInfoCallback& callback) { void SelfAsDeviceProvider::QueryDeviceInfo(const std::string& serial,
const DeviceInfoCallback& callback) {
AndroidDeviceManager::DeviceInfo device_info; AndroidDeviceManager::DeviceInfo device_info;
device_info.model = kDeviceModel; device_info.model = kDeviceModel;
device_info.connected = true;
AndroidDeviceManager::BrowserInfo browser_info; AndroidDeviceManager::BrowserInfo browser_info;
browser_info.socket_name = base::IntToString(port_); browser_info.socket_name = base::IntToString(port_);
...@@ -48,16 +50,9 @@ void SelfAsDevice::QueryDeviceInfo(const DeviceInfoCallback& callback) { ...@@ -48,16 +50,9 @@ void SelfAsDevice::QueryDeviceInfo(const DeviceInfoCallback& callback) {
FROM_HERE, base::Bind(callback, device_info)); FROM_HERE, base::Bind(callback, device_info));
} }
static void RunSocketCallback( void SelfAsDeviceProvider::OpenSocket(const std::string& serial,
const AndroidDeviceManager::SocketCallback& callback, const std::string& socket_name,
net::StreamSocket* socket, const SocketCallback& callback) {
int result) {
callback.Run(result, socket);
}
void SelfAsDevice::OpenSocket(const std::string& socket_name,
const SocketCallback& callback) {
DCHECK(CalledOnValidThread());
// Use plain socket for remote debugging and port forwarding on Desktop // Use plain socket for remote debugging and port forwarding on Desktop
// (debugging purposes). // (debugging purposes).
net::IPAddressNumber ip_number; net::IPAddressNumber ip_number;
...@@ -70,15 +65,3 @@ void SelfAsDevice::OpenSocket(const std::string& socket_name, ...@@ -70,15 +65,3 @@ void SelfAsDevice::OpenSocket(const std::string& socket_name,
address_list, NULL, net::NetLog::Source()); address_list, NULL, net::NetLog::Source());
socket->Connect(base::Bind(&RunSocketCallback, callback, socket)); socket->Connect(base::Bind(&RunSocketCallback, callback, socket));
} }
} // namespace
SelfAsDeviceProvider::SelfAsDeviceProvider(int port)
: port_(port) {
}
void SelfAsDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) {
AndroidDeviceManager::Devices result;
result.push_back(new SelfAsDevice(port_));
callback.Run(result);
}
...@@ -12,7 +12,14 @@ class SelfAsDeviceProvider : public AndroidDeviceManager::DeviceProvider { ...@@ -12,7 +12,14 @@ class SelfAsDeviceProvider : public AndroidDeviceManager::DeviceProvider {
public: public:
explicit SelfAsDeviceProvider(int port); explicit SelfAsDeviceProvider(int port);
virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE; virtual void QueryDevices(const SerialsCallback& callback) OVERRIDE;
virtual void QueryDeviceInfo(const std::string& serial,
const DeviceInfoCallback& callback) OVERRIDE;
virtual void OpenSocket(const std::string& serial,
const std::string& socket_name,
const SocketCallback& callback) OVERRIDE;
private: private:
virtual ~SelfAsDeviceProvider(){} virtual ~SelfAsDeviceProvider(){}
......
...@@ -18,123 +18,59 @@ const char kLocalAbstractCommand[] = "localabstract:%s"; ...@@ -18,123 +18,59 @@ const char kLocalAbstractCommand[] = "localabstract:%s";
const int kBufferSize = 16 * 1024; const int kBufferSize = 16 * 1024;
class UsbDeviceImpl : public AndroidDeviceManager::Device { void OnOpenSocket(const UsbDeviceProvider::SocketCallback& callback,
public:
explicit UsbDeviceImpl(AndroidUsbDevice* device);
virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) OVERRIDE;
virtual void OpenSocket(const std::string& name,
const SocketCallback& callback) OVERRIDE;
private:
void OnOpenSocket(const SocketCallback& callback,
net::StreamSocket* socket,
int result);
void RunCommand(const std::string& command,
const CommandCallback& callback);
void OpenedForCommand(const CommandCallback& callback,
net::StreamSocket* socket,
int result);
void OnRead(net::StreamSocket* socket,
scoped_refptr<net::IOBuffer> buffer,
const std::string& data,
const CommandCallback& callback,
int result);
virtual ~UsbDeviceImpl() {}
scoped_refptr<AndroidUsbDevice> device_;
};
UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device)
: Device(device->serial(), device->is_connected()),
device_(device) {
device_->InitOnCallerThread();
}
void UsbDeviceImpl::QueryDeviceInfo(const DeviceInfoCallback& callback) {
AdbDeviceInfoQuery::Start(
base::Bind(&UsbDeviceImpl::RunCommand, this), callback);
}
void UsbDeviceImpl::OpenSocket(const std::string& name,
const SocketCallback& callback) {
DCHECK(CalledOnValidThread());
std::string socket_name =
base::StringPrintf(kLocalAbstractCommand, name.c_str());
net::StreamSocket* socket = device_->CreateSocket(socket_name);
if (!socket) {
callback.Run(net::ERR_CONNECTION_FAILED, NULL);
return;
}
int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this,
callback, socket));
if (result != net::ERR_IO_PENDING)
callback.Run(result, NULL);
}
void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback,
net::StreamSocket* socket, net::StreamSocket* socket,
int result) { int result) {
callback.Run(result, result == net::OK ? socket : NULL); callback.Run(result, result == net::OK ? socket : NULL);
} }
void UsbDeviceImpl::RunCommand(const std::string& command, void OnRead(net::StreamSocket* socket,
const CommandCallback& callback) { scoped_refptr<net::IOBuffer> buffer,
DCHECK(CalledOnValidThread()); const std::string& data,
net::StreamSocket* socket = device_->CreateSocket(command); const UsbDeviceProvider::CommandCallback& callback,
if (!socket) { int result) {
callback.Run(net::ERR_CONNECTION_FAILED, std::string()); if (result <= 0) {
callback.Run(result, result == 0 ? data : std::string());
delete socket;
return; return;
} }
int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand,
this, callback, socket)); std::string new_data = data + std::string(buffer->data(), result);
result =
socket->Read(buffer,
kBufferSize,
base::Bind(&OnRead, socket, buffer, new_data, callback));
if (result != net::ERR_IO_PENDING) if (result != net::ERR_IO_PENDING)
callback.Run(result, std::string()); OnRead(socket, buffer, new_data, callback, result);
} }
void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback, void OpenedForCommand(const UsbDeviceProvider::CommandCallback& callback,
net::StreamSocket* socket, net::StreamSocket* socket,
int result) { int result) {
if (result != net::OK) { if (result != net::OK) {
callback.Run(result, std::string()); callback.Run(result, std::string());
return; return;
} }
scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize); scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
result = socket->Read(buffer, kBufferSize, result = socket->Read(
base::Bind(&UsbDeviceImpl::OnRead, this, buffer,
socket, buffer, std::string(), callback)); kBufferSize,
base::Bind(&OnRead, socket, buffer, std::string(), callback));
if (result != net::ERR_IO_PENDING) if (result != net::ERR_IO_PENDING)
OnRead(socket, buffer, std::string(), callback, result); OnRead(socket, buffer, std::string(), callback, result);
} }
void UsbDeviceImpl::OnRead(net::StreamSocket* socket, void RunCommand(scoped_refptr<AndroidUsbDevice> device,
scoped_refptr<net::IOBuffer> buffer, const std::string& command,
const std::string& data, const UsbDeviceProvider::CommandCallback& callback) {
const CommandCallback& callback, net::StreamSocket* socket = device->CreateSocket(command);
int result) { if (!socket) {
if (result <= 0) { callback.Run(net::ERR_CONNECTION_FAILED, std::string());
callback.Run(result, result == 0 ? data : std::string());
delete socket;
return; return;
} }
int result = socket->Connect(base::Bind(&OpenedForCommand, callback, socket));
std::string new_data = data + std::string(buffer->data(), result);
result = socket->Read(buffer, kBufferSize,
base::Bind(&UsbDeviceImpl::OnRead, this,
socket, buffer, new_data, callback));
if (result != net::ERR_IO_PENDING) if (result != net::ERR_IO_PENDING)
OnRead(socket, buffer, new_data, callback, result); callback.Run(result, std::string());
}
static void EnumeratedDevices(
const UsbDeviceProvider::QueryDevicesCallback& callback,
const AndroidUsbDevices& devices) {
AndroidDeviceManager::Devices result;
for (AndroidUsbDevices::const_iterator it = devices.begin();
it != devices.end(); ++it)
result.push_back(new UsbDeviceImpl(*it));
callback.Run(result);
} }
} // namespace } // namespace
...@@ -149,10 +85,60 @@ UsbDeviceProvider::UsbDeviceProvider(Profile* profile){ ...@@ -149,10 +85,60 @@ UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
rsa_key_.reset(AndroidRSAPrivateKey(profile)); rsa_key_.reset(AndroidRSAPrivateKey(profile));
} }
void UsbDeviceProvider::QueryDevices(const SerialsCallback& callback) {
AndroidUsbDevice::Enumerate(
rsa_key_.get(),
base::Bind(&UsbDeviceProvider::EnumeratedDevices, this, callback));
}
void UsbDeviceProvider::QueryDeviceInfo(const std::string& serial,
const DeviceInfoCallback& callback) {
UsbDeviceMap::iterator it = device_map_.find(serial);
if (it == device_map_.end() || !it->second->is_connected()) {
AndroidDeviceManager::DeviceInfo offline_info;
callback.Run(offline_info);
return;
}
AdbDeviceInfoQuery::Start(base::Bind(&RunCommand, it->second), callback);
}
void UsbDeviceProvider::OpenSocket(const std::string& serial,
const std::string& name,
const SocketCallback& callback) {
UsbDeviceMap::iterator it = device_map_.find(serial);
if (it == device_map_.end()) {
callback.Run(net::ERR_CONNECTION_FAILED, NULL);
return;
}
std::string socket_name =
base::StringPrintf(kLocalAbstractCommand, name.c_str());
net::StreamSocket* socket = it->second->CreateSocket(socket_name);
if (!socket) {
callback.Run(net::ERR_CONNECTION_FAILED, NULL);
return;
}
int result = socket->Connect(base::Bind(&OnOpenSocket, callback, socket));
if (result != net::ERR_IO_PENDING)
callback.Run(result, NULL);
}
void UsbDeviceProvider::ReleaseDevice(const std::string& serial) {
device_map_.erase(serial);
}
UsbDeviceProvider::~UsbDeviceProvider() { UsbDeviceProvider::~UsbDeviceProvider() {
} }
void UsbDeviceProvider::QueryDevices(const QueryDevicesCallback& callback) { void UsbDeviceProvider::EnumeratedDevices(const SerialsCallback& callback,
AndroidUsbDevice::Enumerate( const AndroidUsbDevices& devices) {
rsa_key_.get(), base::Bind(&EnumeratedDevices, callback)); std::vector<std::string> result;
device_map_.clear();
for (AndroidUsbDevices::const_iterator it = devices.begin();
it != devices.end(); ++it) {
result.push_back((*it)->serial());
device_map_[(*it)->serial()] = *it;
(*it)->InitOnCallerThread();
}
callback.Run(result);
} }
...@@ -11,20 +11,36 @@ namespace crypto { ...@@ -11,20 +11,36 @@ namespace crypto {
class RSAPrivateKey; class RSAPrivateKey;
} }
class AndroidUsbDevice;
class UsbDeviceProvider : public AndroidDeviceManager::DeviceProvider { class UsbDeviceProvider : public AndroidDeviceManager::DeviceProvider {
public: public:
typedef DeviceProvider::QueryDevicesCallback QueryDevicesCallback;
static void CountDevices(const base::Callback<void(int)>& callback); static void CountDevices(const base::Callback<void(int)>& callback);
explicit UsbDeviceProvider(Profile* profile); explicit UsbDeviceProvider(Profile* profile);
virtual void QueryDevices(const QueryDevicesCallback& callback) OVERRIDE; virtual void QueryDevices(const SerialsCallback& callback) OVERRIDE;
virtual void QueryDeviceInfo(const std::string& serial,
const DeviceInfoCallback& callback) OVERRIDE;
virtual void OpenSocket(const std::string& serial,
const std::string& socket_name,
const SocketCallback& callback) OVERRIDE;
virtual void ReleaseDevice(const std::string& serial) OVERRIDE;
private: private:
virtual ~UsbDeviceProvider(); virtual ~UsbDeviceProvider();
void EnumeratedDevices(
const SerialsCallback& callback,
const std::vector<scoped_refptr<AndroidUsbDevice> >& devices);
typedef std::map<std::string, scoped_refptr<AndroidUsbDevice> > UsbDeviceMap;
scoped_ptr<crypto::RSAPrivateKey> rsa_key_; scoped_ptr<crypto::RSAPrivateKey> rsa_key_;
UsbDeviceMap device_map_;
}; };
#endif // CHROME_BROWSER_DEVTOOLS_DEVICE_USB_USB_DEVICE_PROVIDER_H_ #endif // CHROME_BROWSER_DEVTOOLS_DEVICE_USB_USB_DEVICE_PROVIDER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment