Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1123)

Unified Diff: chrome/browser/devtools/device/android_device_manager.cc

Issue 287643002: DevTools: Partially redesigned DevToolsAndroidBridge and AndroidDeviceManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved Device::OpenSocket callback to HandlerThread Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/devtools/device/android_device_manager.cc
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc
index 6184fe560fee2fc06495a6f00918d12742ff49ab..9020d60939f78161101129cbddffc789638760d7 100644
--- a/chrome/browser/devtools/device/android_device_manager.cc
+++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -11,10 +11,16 @@
#include "net/base/net_errors.h"
#include "net/socket/stream_socket.h"
+using content::BrowserThread;
+
namespace {
+const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread";
+
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 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"
"\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 {
public:
typedef AndroidDeviceManager::CommandCallback CommandCallback;
@@ -53,11 +84,9 @@ class HttpRequest {
private:
HttpRequest(net::StreamSocket* socket,
- const std::string& request,
- const CommandCallback& callback)
- : socket_(socket),
- command_callback_(callback),
- body_pos_(0) {
+ const std::string& request,
+ const CommandCallback& callback)
+ : socket_(socket), command_callback_(callback), body_pos_(0) {
SendRequest(request);
}
@@ -174,33 +203,117 @@ class HttpRequest {
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
AndroidDeviceManager::BrowserInfo::BrowserInfo()
: type(kTypeOther) {
}
-AndroidDeviceManager::DeviceInfo::DeviceInfo() {
+AndroidDeviceManager::DeviceInfo::DeviceInfo()
+ : model(kModelOffline), connected(false) {
}
AndroidDeviceManager::DeviceInfo::~DeviceInfo() {
}
-AndroidDeviceManager::Device::Device(const std::string& serial,
- bool is_connected)
- : serial_(serial),
- is_connected_(is_connected) {
+AndroidDeviceManager::DeviceDescriptor::DeviceDescriptor() {
}
-void AndroidDeviceManager::Device::HttpQuery(const std::string& socket_name,
- 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::DeviceDescriptor::~DeviceDescriptor() {
}
-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() {
@@ -209,131 +322,181 @@ AndroidDeviceManager::DeviceProvider::DeviceProvider() {
AndroidDeviceManager::DeviceProvider::~DeviceProvider() {
}
-// static
-scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() {
- return new AndroidDeviceManager();
+void AndroidDeviceManager::Device::QueryDeviceInfo(
+ const DeviceInfoCallback& callback) {
+ device_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&DeviceProvider::QueryDeviceInfo,
+ provider_,
+ serial_,
+ base::Bind(&PostDeviceInfoCallback,
+ base::MessageLoopProxy::current(),
+ callback)));
}
-void AndroidDeviceManager::QueryDevices(
- const DeviceProviders& providers,
- const QueryDevicesCallback& callback) {
- DCHECK(CalledOnValidThread());
- stopped_ = false;
- Devices empty;
- QueryNextProvider(callback, providers, empty, empty);
+void AndroidDeviceManager::Device::OpenSocket(const std::string& socket_name,
+ const SocketCallback& callback) {
+ device_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&DeviceProvider::OpenSocket,
+ provider_,
+ serial_,
+ socket_name,
+ callback));
}
-void AndroidDeviceManager::Stop() {
- DCHECK(CalledOnValidThread());
- stopped_ = true;
- devices_.clear();
+void AndroidDeviceManager::Device::SendJsonRequest(
+ const std::string& socket_name,
+ const std::string& request,
+ 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) {
- DCHECK(CalledOnValidThread());
- Device* device = FindDevice(serial);
- return device && device->is_connected();
+void AndroidDeviceManager::Device::HttpUpgrade(const std::string& socket_name,
+ const std::string& url,
+ const SocketCallback& callback) {
+ 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,
- const DeviceInfoCallback& callback) {
- DCHECK(CalledOnValidThread());
- Device* device = FindDevice(serial);
- if (device)
- device->QueryDeviceInfo(callback);
- else
- callback.Run(DeviceInfo());
+AndroidDeviceManager::Device::Device(
+ scoped_refptr<base::MessageLoopProxy> device_message_loop,
+ scoped_refptr<DeviceProvider> provider,
+ const std::string& serial)
+ : device_message_loop_(device_message_loop),
+ provider_(provider),
+ serial_(serial),
+ weak_factory_(this) {
}
-void AndroidDeviceManager::OpenSocket(
- const std::string& serial,
- const std::string& socket_name,
- const SocketCallback& callback) {
- DCHECK(CalledOnValidThread());
- Device* device = FindDevice(serial);
- if (device)
- device->OpenSocket(socket_name, callback);
- else
- callback.Run(net::ERR_CONNECTION_FAILED, NULL);
+AndroidDeviceManager::Device::~Device() {
+ provider_->AddRef();
+ DeviceProvider* raw_ptr = provider_.get();
+ provider_ = NULL;
+ device_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&ReleaseDeviceAndProvider,
+ base::Unretained(raw_ptr),
+ serial_));
}
-void AndroidDeviceManager::HttpQuery(
- const std::string& serial,
- const std::string& socket_name,
- const std::string& request,
- const CommandCallback& callback) {
- DCHECK(CalledOnValidThread());
- Device* device = FindDevice(serial);
- if (device)
- device->HttpQuery(socket_name, request, callback);
- else
- callback.Run(net::ERR_CONNECTION_FAILED, std::string());
+AndroidDeviceManager::HandlerThread*
+AndroidDeviceManager::HandlerThread::instance_ = NULL;
+
+// static
+scoped_refptr<AndroidDeviceManager::HandlerThread>
+AndroidDeviceManager::HandlerThread::GetInstance() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ if (!instance_)
+ new HandlerThread();
+ return instance_;
}
-void AndroidDeviceManager::HttpUpgrade(
- const std::string& serial,
- const std::string& socket_name,
- const std::string& url,
- const SocketCallback& callback) {
- DCHECK(CalledOnValidThread());
- Device* device = FindDevice(serial);
- if (device) {
- device->OpenSocket(
- socket_name,
- base::Bind(&HttpRequest::SocketRequest,
- base::StringPrintf(kWebSocketUpgradeRequest, url.c_str()),
- callback));
- } else {
- callback.Run(net::ERR_CONNECTION_FAILED, NULL);
+AndroidDeviceManager::HandlerThread::HandlerThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ 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;
}
}
-AndroidDeviceManager::AndroidDeviceManager()
- : stopped_(false) {
+scoped_refptr<base::MessageLoopProxy>
+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(
- const QueryDevicesCallback& callback,
- const DeviceProviders& providers,
- const Devices& total_devices,
- const Devices& new_devices) {
- DCHECK(CalledOnValidThread());
-
- if (stopped_)
+AndroidDeviceManager::HandlerThread::~HandlerThread() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ instance_ = NULL;
+ if (!thread_)
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);
- more_devices.insert(
- more_devices.end(), new_devices.begin(), new_devices.end());
-
- if (providers.empty()) {
- std::vector<std::string> serials;
- devices_.clear();
- for (Devices::const_iterator it = more_devices.begin();
- it != more_devices.end(); ++it) {
- devices_[(*it)->serial()] = *it;
- serials.push_back((*it)->serial());
- }
- callback.Run(serials);
- return;
+// static
+scoped_refptr<AndroidDeviceManager> AndroidDeviceManager::Create() {
+ return new AndroidDeviceManager();
+}
+
+void AndroidDeviceManager::SetDeviceProviders(
+ const DeviceProviders& providers) {
+ for (DeviceProviders::iterator it = providers_.begin();
+ it != providers_.end(); ++it) {
+ (*it)->AddRef();
+ DeviceProvider* raw_ptr = it->get();
+ *it = NULL;
+ handler_thread_->message_loop()->ReleaseSoon(FROM_HERE, raw_ptr);
}
+ 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();
- DeviceProviders less_providers = providers;
- less_providers.pop_back();
- current_provider->QueryDevices(
- base::Bind(&AndroidDeviceManager::QueryNextProvider,
- this, callback, less_providers, more_devices));
+AndroidDeviceManager::~AndroidDeviceManager() {
+ SetDeviceProviders(DeviceProviders());
}
-AndroidDeviceManager::Device*
-AndroidDeviceManager::FindDevice(const std::string& serial) {
- DCHECK(CalledOnValidThread());
- DeviceMap::const_iterator it = devices_.find(serial);
- if (it == devices_.end())
- return NULL;
- return (*it).second.get();
+void AndroidDeviceManager::UpdateDevices(
+ const DevicesCallback& callback,
+ DeviceDescriptors* descriptors_raw) {
+ scoped_ptr<DeviceDescriptors> descriptors(descriptors_raw);
+ Devices response;
+ DeviceWeakMap new_devices;
+ 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);
}
« no previous file with comments | « chrome/browser/devtools/device/android_device_manager.h ('k') | chrome/browser/devtools/device/android_web_socket.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698