diff options
author | kaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-16 18:57:45 +0000 |
---|---|---|
committer | kaznacheev@chromium.org <kaznacheev@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-16 18:57:45 +0000 |
commit | 4c8db8452104b1627206432314291ec092b52a18 (patch) | |
tree | cfdd7752bc9378ca86cb4e62ee202b12372a5f71 /chrome | |
parent | b6c5b43d10f854a8aa28fda976cb611eb010f605 (diff) | |
download | chromium_src-4c8db8452104b1627206432314291ec092b52a18.zip chromium_src-4c8db8452104b1627206432314291ec092b52a18.tar.gz chromium_src-4c8db8452104b1627206432314291ec092b52a18.tar.bz2 |
DevTools: Extract ADB specific requests from DevToolsAndroidBridge into a separate class.
BUG=None
Review URL: https://codereview.chromium.org/274573002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@271071 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
10 files changed, 625 insertions, 483 deletions
diff --git a/chrome/browser/devtools/device/adb/adb_device_info_query.cc b/chrome/browser/devtools/device/adb/adb_device_info_query.cc new file mode 100644 index 0000000..d5cd764 --- /dev/null +++ b/chrome/browser/devtools/device/adb/adb_device_info_query.cc @@ -0,0 +1,412 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/devtools/device/adb/adb_device_info_query.h" + +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" + +namespace { + + +const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; +const char kInstalledChromePackagesCommand[] = "shell:pm list packages"; +const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; +const char kListProcessesCommand[] = "shell:ps"; +const char kDumpsysCommand[] = "shell:dumpsys window policy"; +const char kDumpsysScreenSizePrefix[] = "mStable="; + +const char kDevToolsSocketSuffix[] = "_devtools_remote"; + +const char kChromeDefaultName[] = "Chrome"; +const char kChromeDefaultSocket[] = "chrome_devtools_remote"; + +const char kWebViewSocketPrefix[] = "webview_devtools_remote"; +const char kWebViewNameTemplate[] = "WebView in %s"; + +struct BrowserDescriptor { + const char* package; + const char* socket; + const char* display_name; +}; + +const BrowserDescriptor kBrowserDescriptors[] = { + { + "com.android.chrome", + kChromeDefaultSocket, + kChromeDefaultName + }, + { + "com.chrome.beta", + kChromeDefaultSocket, + "Chrome Beta" + }, + { + "com.google.android.apps.chrome_dev", + kChromeDefaultSocket, + "Chrome Dev" + }, + { + "com.chrome.canary", + kChromeDefaultSocket, + "Chrome Canary" + }, + { + "com.google.android.apps.chrome", + kChromeDefaultSocket, + "Chromium" + }, + { + "org.chromium.content_shell_apk", + "content_shell_devtools_remote", + "Content Shell" + }, + { + "org.chromium.chrome.shell", + "chrome_shell_devtools_remote", + "Chrome Shell" + }, + { + "org.chromium.android_webview.shell", + "webview_devtools_remote", + "WebView Test Shell" + } +}; + +const BrowserDescriptor* FindBrowserDescriptor(const std::string& package) { + int count = sizeof(kBrowserDescriptors) / sizeof(kBrowserDescriptors[0]); + for (int i = 0; i < count; i++) + if (kBrowserDescriptors[i].package == package) + return &kBrowserDescriptors[i]; + return NULL; +} + +typedef std::map<std::string, const BrowserDescriptor*> DescriptorMap; + +static DescriptorMap FindInstalledBrowserPackages(const std::string& response) { + // Parse 'pm list packages' output which on Android looks like this: + // + // package:com.android.chrome + // package:com.chrome.beta + // package:com.example.app + // + DescriptorMap package_to_descriptor; + const std::string package_prefix = "package:"; + std::vector<std::string> entries; + Tokenize(response, "'\r\n", &entries); + for (size_t i = 0; i < entries.size(); ++i) { + if (entries[i].find(package_prefix) != 0) + continue; + std::string package = entries[i].substr(package_prefix.size()); + const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); + if (!descriptor) + continue; + package_to_descriptor[descriptor->package] = descriptor; + } + return package_to_descriptor; +} + +typedef std::map<std::string, std::string> StringMap; + +static void MapProcessesToPackages(const std::string& response, + StringMap& pid_to_package, + StringMap& package_to_pid) { + // Parse 'ps' output which on Android looks like this: + // + // USER PID PPID VSIZE RSS WCHAN PC ? NAME + // + std::vector<std::string> entries; + Tokenize(response, "\n", &entries); + for (size_t i = 1; i < entries.size(); ++i) { + std::vector<std::string> fields; + Tokenize(entries[i], " \r", &fields); + if (fields.size() < 9) + continue; + std::string pid = fields[1]; + std::string package = fields[8]; + pid_to_package[pid] = package; + package_to_pid[package] = pid; + } +} + +static StringMap MapSocketsToProcesses(const std::string& response, + const std::string& channel_pattern) { + // Parse 'cat /proc/net/unix' output which on Android looks like this: + // + // Num RefCount Protocol Flags Type St Inode Path + // 00000000: 00000002 00000000 00010000 0001 01 331813 /dev/socket/zygote + // 00000000: 00000002 00000000 00010000 0001 01 358606 @xxx_devtools_remote + // 00000000: 00000002 00000000 00010000 0001 01 347300 @yyy_devtools_remote + // + // We need to find records with paths starting from '@' (abstract socket) + // and containing the channel pattern ("_devtools_remote"). + StringMap socket_to_pid; + std::vector<std::string> entries; + Tokenize(response, "\n", &entries); + for (size_t i = 1; i < entries.size(); ++i) { + std::vector<std::string> fields; + Tokenize(entries[i], " \r", &fields); + if (fields.size() < 8) + continue; + if (fields[3] != "00010000" || fields[5] != "01") + continue; + std::string path_field = fields[7]; + if (path_field.size() < 1 || path_field[0] != '@') + continue; + size_t socket_name_pos = path_field.find(channel_pattern); + if (socket_name_pos == std::string::npos) + continue; + + std::string socket = path_field.substr(1); + + std::string pid; + size_t socket_name_end = socket_name_pos + channel_pattern.size(); + if (socket_name_end < path_field.size() && + path_field[socket_name_end] == '_') { + pid = path_field.substr(socket_name_end + 1); + } + socket_to_pid[socket] = pid; + } + return socket_to_pid; +} + +} // namespace + +// static +AndroidDeviceManager::BrowserInfo::Type +AdbDeviceInfoQuery::GetBrowserType(const std::string& socket) { + if (socket.find(kChromeDefaultSocket) == 0) + return AndroidDeviceManager::BrowserInfo::kTypeChrome; + + if (socket.find(kWebViewSocketPrefix) == 0) + return AndroidDeviceManager::BrowserInfo::kTypeWebView; + + return AndroidDeviceManager::BrowserInfo::kTypeOther; +} + +// static +std::string AdbDeviceInfoQuery::GetDisplayName(const std::string& socket, + const std::string& package) { + if (package.empty()) { + // Derive a fallback display name from the socket name. + std::string name = socket.substr(0, socket.find(kDevToolsSocketSuffix)); + name[0] = base::ToUpperASCII(name[0]); + return name; + } + + const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); + if (descriptor) + return descriptor->display_name; + + if (GetBrowserType(socket) == + AndroidDeviceManager::BrowserInfo::kTypeWebView) + return base::StringPrintf(kWebViewNameTemplate, package.c_str()); + + return package; +} + +// static +void AdbDeviceInfoQuery::Start(const RunCommandCallback& command_callback, + const DeviceInfoCallback& callback) { + new AdbDeviceInfoQuery(command_callback, callback); +} + +AdbDeviceInfoQuery::AdbDeviceInfoQuery( + const RunCommandCallback& command_callback, + const DeviceInfoCallback& callback) + : command_callback_(command_callback), + callback_(callback) { + DCHECK(CalledOnValidThread()); + command_callback_.Run( + kDeviceModelCommand, + base::Bind(&AdbDeviceInfoQuery::ReceivedModel, base::Unretained(this))); +} + +AdbDeviceInfoQuery::~AdbDeviceInfoQuery() { +} + +void AdbDeviceInfoQuery::ReceivedModel(int result, + const std::string& response) { + DCHECK(CalledOnValidThread()); + if (result < 0) { + Respond(); + return; + } + device_info_.model = response; + command_callback_.Run( + kDumpsysCommand, + base::Bind(&AdbDeviceInfoQuery::ReceivedDumpsys, base::Unretained(this))); +} + +void AdbDeviceInfoQuery::ReceivedDumpsys(int result, + const std::string& response) { + DCHECK(CalledOnValidThread()); + if (result >= 0) + ParseDumpsysResponse(response); + + command_callback_.Run( + kInstalledChromePackagesCommand, + base::Bind(&AdbDeviceInfoQuery::ReceivedPackages, + base::Unretained(this))); +} + +void AdbDeviceInfoQuery::ParseDumpsysResponse(const std::string& response) { + std::vector<std::string> lines; + Tokenize(response, "\r", &lines); + for (size_t i = 0; i < lines.size(); ++i) { + std::string line = lines[i]; + size_t pos = line.find(kDumpsysScreenSizePrefix); + if (pos != std::string::npos) { + ParseScreenSize( + line.substr(pos + std::string(kDumpsysScreenSizePrefix).size())); + break; + } + } +} + +void AdbDeviceInfoQuery::ParseScreenSize(const std::string& str) { + std::vector<std::string> pairs; + Tokenize(str, "-", &pairs); + if (pairs.size() != 2) + return; + + int width; + int height; + std::vector<std::string> numbers; + Tokenize(pairs[1].substr(1, pairs[1].size() - 2), ",", &numbers); + if (numbers.size() != 2 || + !base::StringToInt(numbers[0], &width) || + !base::StringToInt(numbers[1], &height)) + return; + + device_info_.screen_size = gfx::Size(width, height); +} + + +void AdbDeviceInfoQuery::ReceivedPackages( + int result, + const std::string& packages_response) { + DCHECK(CalledOnValidThread()); + if (result < 0) { + Respond(); + return; + } + command_callback_.Run( + kListProcessesCommand, + base::Bind(&AdbDeviceInfoQuery::ReceivedProcesses, + base::Unretained(this), packages_response)); +} + +void AdbDeviceInfoQuery::ReceivedProcesses( + const std::string& packages_response, + int result, + const std::string& processes_response) { + DCHECK(CalledOnValidThread()); + if (result < 0) { + Respond(); + return; + } + command_callback_.Run( + kOpenedUnixSocketsCommand, + base::Bind(&AdbDeviceInfoQuery::ReceivedSockets, + base::Unretained(this), + packages_response, + processes_response)); +} + +void AdbDeviceInfoQuery::ReceivedSockets( + const std::string& packages_response, + const std::string& processes_response, + int result, + const std::string& sockets_response) { + DCHECK(CalledOnValidThread()); + if (result >= 0) + ParseBrowserInfo(packages_response, processes_response, sockets_response); + Respond(); +} + +void AdbDeviceInfoQuery::ParseBrowserInfo( + const std::string& packages_response, + const std::string& processes_response, + const std::string& sockets_response) { + DCHECK(CalledOnValidThread()); + DescriptorMap package_to_descriptor = + FindInstalledBrowserPackages(packages_response); + StringMap pid_to_package; + StringMap package_to_pid; + MapProcessesToPackages(processes_response, pid_to_package, package_to_pid); + + StringMap socket_to_pid = MapSocketsToProcesses(sockets_response, + kDevToolsSocketSuffix); + + std::set<std::string> packages_for_running_browsers; + + typedef std::map<std::string, int> BrowserMap; + BrowserMap socket_to_unnamed_browser_index; + + for (StringMap::iterator it = socket_to_pid.begin(); + it != socket_to_pid.end(); ++it) { + std::string socket = it->first; + std::string pid = it->second; + + std::string package; + StringMap::iterator pit = pid_to_package.find(pid); + if (pit != pid_to_package.end()) { + package = pit->second; + packages_for_running_browsers.insert(package); + } else { + socket_to_unnamed_browser_index[socket] = + device_info_.browser_info.size(); + } + + AndroidDeviceManager::BrowserInfo browser_info; + browser_info.socket_name = socket; + browser_info.type = GetBrowserType(socket); + browser_info.display_name = GetDisplayName(socket, package); + device_info_.browser_info.push_back(browser_info); + } + + // Find installed packages not mapped to browsers. + typedef std::multimap<std::string, const BrowserDescriptor*> + DescriptorMultimap; + DescriptorMultimap socket_to_descriptor; + for (DescriptorMap::iterator it = package_to_descriptor.begin(); + it != package_to_descriptor.end(); ++it) { + std::string package = it->first; + const BrowserDescriptor* descriptor = it->second; + + if (packages_for_running_browsers.count(package)) + continue; // This package is already mapped to a browser. + + if (package_to_pid.find(package) != package_to_pid.end()) { + // This package is running but not mapped to a browser. + socket_to_descriptor.insert( + DescriptorMultimap::value_type(descriptor->socket, descriptor)); + continue; + } + } + + // Try naming remaining unnamed browsers. + for (DescriptorMultimap::iterator it = socket_to_descriptor.begin(); + it != socket_to_descriptor.end(); ++it) { + std::string socket = it->first; + const BrowserDescriptor* descriptor = it->second; + + if (socket_to_descriptor.count(socket) != 1) + continue; // No definitive match. + + BrowserMap::iterator bit = socket_to_unnamed_browser_index.find(socket); + if (bit != socket_to_unnamed_browser_index.end()) { + device_info_.browser_info[bit->second].display_name = + descriptor->display_name; + } + } +} + +void AdbDeviceInfoQuery::Respond() { + DCHECK(CalledOnValidThread()); + callback_.Run(device_info_); + delete this; +} diff --git a/chrome/browser/devtools/device/adb/adb_device_info_query.h b/chrome/browser/devtools/device/adb/adb_device_info_query.h new file mode 100644 index 0000000..8818595 --- /dev/null +++ b/chrome/browser/devtools/device/adb/adb_device_info_query.h @@ -0,0 +1,66 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_DEVTOOLS_DEVICE_ADB_ADB_DEVICE_INFO_QUERY_H_ +#define CHROME_BROWSER_DEVTOOLS_DEVICE_ADB_ADB_DEVICE_INFO_QUERY_H_ + +#include "base/threading/non_thread_safe.h" +#include "chrome/browser/devtools/device/android_device_manager.h" + +class AdbDeviceInfoQuery : public base::NonThreadSafe { + public: + static AndroidDeviceManager::BrowserInfo::Type GetBrowserType( + const std::string& socket); + + static std::string GetDisplayName(const std::string& socket, + const std::string& package); + + typedef AndroidDeviceManager::CommandCallback CommandCallback; + typedef AndroidDeviceManager::DeviceInfoCallback DeviceInfoCallback; + + typedef base::Callback< + void(const std::string&, const CommandCallback&)> RunCommandCallback; + + static void Start(const RunCommandCallback& command_callback, + const DeviceInfoCallback& callback); + + private: + AdbDeviceInfoQuery(const RunCommandCallback& command_callback, + const DeviceInfoCallback& callback); + + virtual ~AdbDeviceInfoQuery(); + + void ReceivedModel(int result, const std::string& response); + + void ReceivedDumpsys(int result, const std::string& response); + + void ParseDumpsysResponse(const std::string& response); + + void ParseScreenSize(const std::string& str); + + void ReceivedPackages(int result, const std::string& response); + + void ReceivedProcesses(const std::string& packages_response, + int result, + const std::string& processes_response); + + void ReceivedSockets(const std::string& packages_response, + const std::string& processes_response, + int result, + const std::string& sockets_response); + + void ParseBrowserInfo(const std::string& packages_response, + const std::string& processes_response, + const std::string& sockets_response); + + void Respond(); + + RunCommandCallback command_callback_; + DeviceInfoCallback callback_; + AndroidDeviceManager::DeviceInfo device_info_; + + DISALLOW_COPY_AND_ASSIGN(AdbDeviceInfoQuery); +}; + +#endif // CHROME_BROWSER_DEVTOOLS_DEVICE_ADB_ADB_DEVICE_INFO_QUERY_H_ diff --git a/chrome/browser/devtools/device/adb/adb_device_provider.cc b/chrome/browser/devtools/device/adb/adb_device_provider.cc index 904bea6..14bddf7 100644 --- a/chrome/browser/devtools/device/adb/adb_device_provider.cc +++ b/chrome/browser/devtools/device/adb/adb_device_provider.cc @@ -7,6 +7,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "chrome/browser/devtools/device/adb/adb_client_socket.h" +#include "chrome/browser/devtools/device/adb/adb_device_info_query.h" namespace { @@ -19,26 +20,24 @@ const int kAdbPort = 5037; class AdbDeviceImpl : public AndroidDeviceManager::Device { public: AdbDeviceImpl(const std::string& serial, bool is_connected); - - virtual void RunCommand(const std::string& command, - const CommandCallback& callback) OVERRIDE; + virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) OVERRIDE; 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::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); +void AdbDeviceImpl::QueryDeviceInfo(const DeviceInfoCallback& callback) { + AdbDeviceInfoQuery::Start( + base::Bind(&AdbDeviceImpl::RunCommand, this), callback); } void AdbDeviceImpl::OpenSocket(const std::string& name, @@ -49,6 +48,14 @@ void AdbDeviceImpl::OpenSocket(const std::string& name, 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); +} + // static void ReceivedAdbDevices( const AdbDeviceProvider::QueryDevicesCallback& callback, diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc index d4b31c9..5dd2627 100644 --- a/chrome/browser/devtools/device/android_device_manager.cc +++ b/chrome/browser/devtools/device/android_device_manager.cc @@ -11,8 +11,6 @@ #include "net/base/net_errors.h" #include "net/socket/stream_socket.h" -using content::BrowserThread; - namespace { const int kBufferSize = 16 * 1024; @@ -176,6 +174,16 @@ class HttpRequest { } // namespace +AndroidDeviceManager::BrowserInfo::BrowserInfo() + : type(kTypeOther) { +} + +AndroidDeviceManager::DeviceInfo::DeviceInfo() { +} + +AndroidDeviceManager::DeviceInfo::~DeviceInfo() { +} + AndroidDeviceManager::Device::Device(const std::string& serial, bool is_connected) : serial_(serial), @@ -217,16 +225,14 @@ bool AndroidDeviceManager::IsConnected(const std::string& serial) { return device && device->is_connected(); } -void AndroidDeviceManager::RunCommand( - const std::string& serial, - const std::string& command, - const CommandCallback& callback) { +void AndroidDeviceManager::QueryDeviceInfo(const std::string& serial, + const DeviceInfoCallback& callback) { DCHECK(CalledOnValidThread()); Device* device = FindDevice(serial); if (device) - device->RunCommand(command, callback); + device->QueryDeviceInfo(callback); else - callback.Run(net::ERR_CONNECTION_FAILED, std::string()); + callback.Run(DeviceInfo()); } void AndroidDeviceManager::OpenSocket( diff --git a/chrome/browser/devtools/device/android_device_manager.h b/chrome/browser/devtools/device/android_device_manager.h index 0e473c9..a1b3029 100644 --- a/chrome/browser/devtools/device/android_device_manager.h +++ b/chrome/browser/devtools/device/android_device_manager.h @@ -11,6 +11,7 @@ #include "base/threading/non_thread_safe.h" #include "chrome/browser/profiles/profile.h" #include "content/public/browser/browser_thread.h" +#include "ui/gfx/size.h" namespace net { class StreamSocket; @@ -23,6 +24,31 @@ class AndroidDeviceManager typedef base::Callback<void(int, const std::string&)> CommandCallback; typedef base::Callback<void(int result, net::StreamSocket*)> SocketCallback; + struct BrowserInfo { + BrowserInfo(); + + enum Type { + kTypeChrome, + kTypeWebView, + kTypeOther + }; + + std::string socket_name; + std::string display_name; + Type type; + }; + + struct DeviceInfo { + DeviceInfo(); + ~DeviceInfo(); + + std::string model; + gfx::Size screen_size; + std::vector<BrowserInfo> browser_info; + }; + + typedef base::Callback<void(const DeviceInfo&)> DeviceInfoCallback; + class Device : public base::RefCounted<Device>, public base::NonThreadSafe { protected: @@ -30,11 +56,12 @@ class AndroidDeviceManager typedef AndroidDeviceManager::CommandCallback CommandCallback; typedef AndroidDeviceManager::SocketCallback SocketCallback; + typedef AndroidDeviceManager::DeviceInfoCallback DeviceInfoCallback; Device(const std::string& serial, bool is_connected); - virtual void RunCommand(const std::string& command, - const CommandCallback& callback) = 0; + virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) = 0; + virtual void OpenSocket(const std::string& socket_name, const SocketCallback& callback) = 0; @@ -87,9 +114,8 @@ class AndroidDeviceManager bool IsConnected(const std::string& serial); - void RunCommand(const std::string& serial, - const std::string& command, - const CommandCallback& callback); + void QueryDeviceInfo(const std::string& serial, + const DeviceInfoCallback& callback); void OpenSocket(const std::string& serial, const std::string& socket_name, diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc index 5534b54..a42f061 100644 --- a/chrome/browser/devtools/device/devtools_android_bridge.cc +++ b/chrome/browser/devtools/device/devtools_android_bridge.cc @@ -21,6 +21,7 @@ #include "base/threading/thread.h" #include "base/values.h" #include "chrome/browser/devtools/browser_list_tabcontents_provider.h" +#include "chrome/browser/devtools/device/adb/adb_device_info_query.h" #include "chrome/browser/devtools/device/adb/adb_device_provider.h" #include "chrome/browser/devtools/device/self_device_provider.h" #include "chrome/browser/devtools/device/usb/usb_device_provider.h" @@ -40,14 +41,7 @@ using content::BrowserThread; namespace { -const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; -const char kInstalledChromePackagesCommand[] = "shell:pm list packages"; -const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; -const char kListProcessesCommand[] = "shell:ps"; -const char kDumpsysCommand[] = "shell:dumpsys window policy"; -const char kDumpsysScreenSizePrefix[] = "mStable="; - -const char kUnknownModel[] = "Offline"; +const char kModelOffline[] = "Offline"; const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; @@ -63,168 +57,9 @@ const char kUrlParam[] = "url"; const char kPageReloadCommand[] = "Page.reload"; const char kPageNavigateCommand[] = "Page.navigate"; -// The format used for constructing DevTools server socket names. -const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; - -const char kChromeDefaultName[] = "Chrome"; -const char kChromeDefaultSocket[] = "chrome_devtools_remote"; const int kMinVersionNewWithURL = 32; const int kNewPageNavigateDelayMs = 500; -const char kWebViewSocketPrefix[] = "webview_devtools_remote"; -const char kWebViewNameTemplate[] = "WebView in %s"; - -struct BrowserDescriptor { - const char* package; - const char* socket; - const char* display_name; -}; - -const BrowserDescriptor kBrowserDescriptors[] = { - { - "com.android.chrome", - kChromeDefaultSocket, - kChromeDefaultName - }, - { - "com.chrome.beta", - kChromeDefaultSocket, - "Chrome Beta" - }, - { - "com.google.android.apps.chrome_dev", - kChromeDefaultSocket, - "Chrome Dev" - }, - { - "com.chrome.canary", - kChromeDefaultSocket, - "Chrome Canary" - }, - { - "com.google.android.apps.chrome", - kChromeDefaultSocket, - "Chromium" - }, - { - "org.chromium.content_shell_apk", - "content_shell_devtools_remote", - "Content Shell" - }, - { - "org.chromium.chrome.shell", - "chrome_shell_devtools_remote", - "Chrome Shell" - }, - { - "org.chromium.android_webview.shell", - "webview_devtools_remote", - "WebView Test Shell" - } -}; - -const BrowserDescriptor* FindBrowserDescriptor(const std::string& package) { - int count = sizeof(kBrowserDescriptors) / sizeof(kBrowserDescriptors[0]); - for (int i = 0; i < count; i++) - if (kBrowserDescriptors[i].package == package) - return &kBrowserDescriptors[i]; - return NULL; -} - -typedef std::map<std::string, const BrowserDescriptor*> DescriptorMap; - -static DescriptorMap FindInstalledBrowserPackages( - const std::string& response) { - // Parse 'pm list packages' output which on Android looks like this: - // - // package:com.android.chrome - // package:com.chrome.beta - // package:com.example.app - // - DescriptorMap package_to_descriptor; - const std::string package_prefix = "package:"; - std::vector<std::string> entries; - Tokenize(response, "'\r\n", &entries); - for (size_t i = 0; i < entries.size(); ++i) { - if (entries[i].find(package_prefix) != 0) - continue; - std::string package = entries[i].substr(package_prefix.size()); - const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); - if (!descriptor) - continue; - package_to_descriptor[descriptor->package] = descriptor; - } - return package_to_descriptor; -} - -typedef std::map<std::string, std::string> StringMap; - -static void MapProcessesToPackages(const std::string& response, - StringMap& pid_to_package, - StringMap& package_to_pid) { - // Parse 'ps' output which on Android looks like this: - // - // USER PID PPID VSIZE RSS WCHAN PC ? NAME - // - std::vector<std::string> entries; - Tokenize(response, "\n", &entries); - for (size_t i = 1; i < entries.size(); ++i) { - std::vector<std::string> fields; - Tokenize(entries[i], " \r", &fields); - if (fields.size() < 9) - continue; - std::string pid = fields[1]; - std::string package = fields[8]; - pid_to_package[pid] = package; - package_to_pid[package] = pid; - } -} - -typedef std::map<std::string, - scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> > - BrowserMap; - -static StringMap MapSocketsToProcesses(const std::string& response, - const std::string& channel_pattern) { - // Parse 'cat /proc/net/unix' output which on Android looks like this: - // - // Num RefCount Protocol Flags Type St Inode Path - // 00000000: 00000002 00000000 00010000 0001 01 331813 /dev/socket/zygote - // 00000000: 00000002 00000000 00010000 0001 01 358606 @xxx_devtools_remote - // 00000000: 00000002 00000000 00010000 0001 01 347300 @yyy_devtools_remote - // - // We need to find records with paths starting from '@' (abstract socket) - // and containing the channel pattern ("_devtools_remote"). - StringMap socket_to_pid; - std::vector<std::string> entries; - Tokenize(response, "\n", &entries); - for (size_t i = 1; i < entries.size(); ++i) { - std::vector<std::string> fields; - Tokenize(entries[i], " \r", &fields); - if (fields.size() < 8) - continue; - if (fields[3] != "00010000" || fields[5] != "01") - continue; - std::string path_field = fields[7]; - if (path_field.size() < 1 || path_field[0] != '@') - continue; - size_t socket_name_pos = path_field.find(channel_pattern); - if (socket_name_pos == std::string::npos) - continue; - - std::string socket = path_field.substr(1); - - std::string pid; - size_t socket_name_end = socket_name_pos + channel_pattern.size(); - if (socket_name_end < path_field.size() && - path_field[socket_name_end] == '_') { - pid = path_field.substr(socket_name_end + 1); - } - socket_to_pid[socket] = pid; - } - return socket_to_pid; -} - // DiscoveryRequest ----------------------------------------------------- class DiscoveryRequest : public base::RefCountedThreadSafe< @@ -248,18 +83,7 @@ class DiscoveryRequest : public base::RefCountedThreadSafe< void ReceivedSerials(const std::vector<std::string>& serials); void ProcessSerials(); - void ReceivedModel(int result, const std::string& response); - void ReceivedDumpsys(int result, const std::string& response); - void ReceivedPackages(int result, const std::string& response); - void ReceivedProcesses( - const std::string& packages_response, - int result, - const std::string& processes_response); - void ReceivedSockets( - const std::string& packages_response, - const std::string& processes_response, - int result, - const std::string& sockets_response); + void ReceivedDeviceInfo(const AndroidDeviceManager::DeviceInfo& device_info); void ProcessSockets(); void ReceivedVersion(int result, const std::string& response); void ReceivedPages(int result, const std::string& response); @@ -275,13 +99,6 @@ class DiscoveryRequest : public base::RefCountedThreadSafe< void Respond(); - void CreateBrowsers(const std::string& packages_response, - const std::string& processes_response, - const std::string& sockets_response); - - void ParseDumpsysResponse(const std::string& response); - void ParseScreenSize(const std::string& str); - scoped_refptr<DevToolsAndroidBridge> android_bridge_; AndroidDeviceManager* device_manager_; base::MessageLoop* device_message_loop_; @@ -332,79 +149,22 @@ void DiscoveryRequest::ProcessSerials() { } if (device_manager_->IsConnected(current_serial())) { - device_manager_->RunCommand(current_serial(), kDeviceModelCommand, - base::Bind(&DiscoveryRequest::ReceivedModel, this)); + device_manager_->QueryDeviceInfo(current_serial(), + 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(), kUnknownModel, false)); + android_bridge_, current_serial(), offline_info, false)); NextDevice(); } } -void DiscoveryRequest::ReceivedModel(int result, const std::string& response) { - DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); - if (result < 0) { - NextDevice(); - return; - } +void DiscoveryRequest::ReceivedDeviceInfo( + const AndroidDeviceManager::DeviceInfo& device_info) { remote_devices_->push_back(new DevToolsAndroidBridge::RemoteDevice( - android_bridge_, current_serial(), response, true)); - device_manager_->RunCommand(current_serial(), kDumpsysCommand, - base::Bind(&DiscoveryRequest::ReceivedDumpsys, this)); -} - -void DiscoveryRequest::ReceivedDumpsys(int result, - const std::string& response) { - DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); - if (result >= 0) - ParseDumpsysResponse(response); - - device_manager_->RunCommand( - current_serial(), - kInstalledChromePackagesCommand, - base::Bind(&DiscoveryRequest::ReceivedPackages, this)); -} - -void DiscoveryRequest::ReceivedPackages(int result, - const std::string& packages_response) { - DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); - if (result < 0) { - NextDevice(); - return; - } - device_manager_->RunCommand( - current_serial(), - kListProcessesCommand, - base::Bind( - &DiscoveryRequest::ReceivedProcesses, this, packages_response)); -} - -void DiscoveryRequest::ReceivedProcesses( - const std::string& packages_response, - int result, - const std::string& processes_response) { - DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); - if (result < 0) { - NextDevice(); - return; - } - device_manager_->RunCommand( - current_serial(), - kOpenedUnixSocketsCommand, - base::Bind(&DiscoveryRequest::ReceivedSockets, - this, - packages_response, - processes_response)); -} - -void DiscoveryRequest::ReceivedSockets( - const std::string& packages_response, - const std::string& processes_response, - int result, - const std::string& sockets_response) { - DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); - if (result >= 0) - CreateBrowsers(packages_response, processes_response, sockets_response); + android_bridge_, current_serial(), device_info, true)); + browsers_ = remote_devices_->back()->browsers(); ProcessSockets(); } @@ -445,9 +205,9 @@ void DiscoveryRequest::ReceivedVersion(int result, } std::string package; if (dict->GetString("Android-Package", &package)) { - const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); - if (descriptor) - current_browser()->set_display_name(descriptor->display_name); + current_browser()->set_display_name( + AdbDeviceInfoQuery::GetDisplayName(current_browser()->socket(), + package)); } } @@ -484,133 +244,6 @@ void DiscoveryRequest::Respond() { callback_.Run(remote_devices_.release()); } -void DiscoveryRequest::CreateBrowsers( - const std::string& packages_response, - const std::string& processes_response, - const std::string& sockets_response) { - DescriptorMap package_to_descriptor = - FindInstalledBrowserPackages(packages_response); - - StringMap pid_to_package; - StringMap package_to_pid; - MapProcessesToPackages(processes_response, pid_to_package, package_to_pid); - - const std::string channel_pattern = - base::StringPrintf(kDevToolsChannelNameFormat, ""); - - StringMap socket_to_pid = MapSocketsToProcesses(sockets_response, - channel_pattern); - - scoped_refptr<DevToolsAndroidBridge::RemoteDevice> remote_device = - remote_devices_->back(); - - // Create RemoteBrowser instances. - BrowserMap package_to_running_browser; - BrowserMap socket_to_unnamed_browser; - for (StringMap::iterator it = socket_to_pid.begin(); - it != socket_to_pid.end(); ++it) { - std::string socket = it->first; - std::string pid = it->second; - - scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser = - new DevToolsAndroidBridge::RemoteBrowser( - android_bridge_, current_serial(), socket); - - StringMap::iterator pit = pid_to_package.find(pid); - if (pit != pid_to_package.end()) { - std::string package = pit->second; - package_to_running_browser[package] = browser; - const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); - if (descriptor) { - browser->set_display_name(descriptor->display_name); - } else if (socket.find(kWebViewSocketPrefix) == 0) { - browser->set_display_name( - base::StringPrintf(kWebViewNameTemplate, package.c_str())); - } else { - browser->set_display_name(package); - } - } else { - // Set fallback display name. - std::string name = socket.substr(0, socket.find(channel_pattern)); - name[0] = base::ToUpperASCII(name[0]); - browser->set_display_name(name); - - socket_to_unnamed_browser[socket] = browser; - } - remote_device->AddBrowser(browser); - } - - browsers_ = remote_device->browsers(); - - // Find installed packages not mapped to browsers. - typedef std::multimap<std::string, const BrowserDescriptor*> - DescriptorMultimap; - DescriptorMultimap socket_to_descriptor; - for (DescriptorMap::iterator it = package_to_descriptor.begin(); - it != package_to_descriptor.end(); ++it) { - std::string package = it->first; - const BrowserDescriptor* descriptor = it->second; - - if (package_to_running_browser.find(package) != - package_to_running_browser.end()) - continue; // This package is already mapped to a browser. - - if (package_to_pid.find(package) != package_to_pid.end()) { - // This package is running but not mapped to a browser. - socket_to_descriptor.insert( - DescriptorMultimap::value_type(descriptor->socket, descriptor)); - continue; - } - } - - // Try naming remaining unnamed browsers. - for (DescriptorMultimap::iterator it = socket_to_descriptor.begin(); - it != socket_to_descriptor.end(); ++it) { - std::string socket = it->first; - const BrowserDescriptor* descriptor = it->second; - - if (socket_to_descriptor.count(socket) != 1) - continue; // No definitive match. - - BrowserMap::iterator bit = socket_to_unnamed_browser.find(socket); - if (bit != socket_to_unnamed_browser.end()) - bit->second->set_display_name(descriptor->display_name); - } -} - -void DiscoveryRequest::ParseDumpsysResponse(const std::string& response) { - std::vector<std::string> lines; - Tokenize(response, "\r", &lines); - for (size_t i = 0; i < lines.size(); ++i) { - std::string line = lines[i]; - size_t pos = line.find(kDumpsysScreenSizePrefix); - if (pos != std::string::npos) { - ParseScreenSize( - line.substr(pos + std::string(kDumpsysScreenSizePrefix).size())); - break; - } - } -} - -void DiscoveryRequest::ParseScreenSize(const std::string& str) { - std::vector<std::string> pairs; - Tokenize(str, "-", &pairs); - if (pairs.size() != 2) - return; - - int width; - int height; - std::vector<std::string> numbers; - Tokenize(pairs[1].substr(1, pairs[1].size() - 2), ",", &numbers); - if (numbers.size() != 2 || - !base::StringToInt(numbers[0], &width) || - !base::StringToInt(numbers[1], &height)) - return; - - remote_devices_->back()->set_screen_size(gfx::Size(width, height)); -} - - // ProtocolCommand ------------------------------------------------------------ class ProtocolCommand @@ -763,7 +396,7 @@ AgentHostDelegate::AgentHostDelegate( : id_(id), socket_opened_(false), detached_(false), - is_web_view_(browser->socket().find(kWebViewSocketPrefix) == 0), + is_web_view_(browser->IsWebView()), web_socket_(browser->CreateWebSocket(debug_url, this)), proxy_(content::DevToolsExternalAgentProxy::Create(this)) { g_host_delegates.Get()[id] = this; @@ -952,15 +585,21 @@ void RemotePageTarget::Navigate(const std::string& url, DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser( scoped_refptr<DevToolsAndroidBridge> android_bridge, const std::string& serial, - const std::string& socket) + const AndroidDeviceManager::BrowserInfo& browser_info) : android_bridge_(android_bridge), serial_(serial), - socket_(socket), + socket_(browser_info.socket_name), + display_name_(browser_info.display_name), + type_(browser_info.type), page_descriptors_(new base::ListValue()) { } bool DevToolsAndroidBridge::RemoteBrowser::IsChrome() const { - return socket_.find(kChromeDefaultSocket) == 0; + return type_ == AndroidDeviceManager::BrowserInfo::kTypeChrome; +} + +bool DevToolsAndroidBridge::RemoteBrowser::IsWebView() const { + return type_ == AndroidDeviceManager::BrowserInfo::kTypeWebView; } DevToolsAndroidBridge::RemoteBrowser::ParsedVersion @@ -1126,17 +765,20 @@ DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() { DevToolsAndroidBridge::RemoteDevice::RemoteDevice( scoped_refptr<DevToolsAndroidBridge> android_bridge, const std::string& serial, - const std::string& model, + const AndroidDeviceManager::DeviceInfo& device_info, bool connected) : android_bridge_(android_bridge), serial_(serial), - model_(model), - connected_(connected) { -} - -void DevToolsAndroidBridge::RemoteDevice::AddBrowser( - scoped_refptr<RemoteBrowser> browser) { - browsers_.push_back(browser); + model_(device_info.model), + connected_(connected), + screen_size_(device_info.screen_size) { + for (std::vector<AndroidDeviceManager::BrowserInfo>::const_iterator it = + device_info.browser_info.begin(); + it != device_info.browser_info.end(); + ++it) { + browsers_.push_back(new DevToolsAndroidBridge::RemoteBrowser( + android_bridge_, serial_, *it)); + } } void DevToolsAndroidBridge::RemoteDevice::OpenSocket( diff --git a/chrome/browser/devtools/device/devtools_android_bridge.h b/chrome/browser/devtools/device/devtools_android_bridge.h index af97252..6a0f781 100644 --- a/chrome/browser/devtools/device/devtools_android_bridge.h +++ b/chrome/browser/devtools/device/devtools_android_bridge.h @@ -113,7 +113,7 @@ class DevToolsAndroidBridge RemoteBrowser( scoped_refptr<DevToolsAndroidBridge> android_bridge, const std::string& serial, - const std::string& socket); + const AndroidDeviceManager::BrowserInfo& browser_info); std::string serial() { return serial_; } std::string socket() { return socket_; } @@ -125,6 +125,7 @@ class DevToolsAndroidBridge void set_version(const std::string& version) { version_ = version; } bool IsChrome() const; + bool IsWebView() const; typedef std::vector<int> ParsedVersion; ParsedVersion GetParsedVersion() const; @@ -174,6 +175,7 @@ class DevToolsAndroidBridge const std::string serial_; const std::string socket_; std::string display_name_; + const AndroidDeviceManager::BrowserInfo::Type type_; std::string version_; scoped_ptr<base::ListValue> page_descriptors_; @@ -186,17 +188,14 @@ class DevToolsAndroidBridge public: RemoteDevice(scoped_refptr<DevToolsAndroidBridge> android_bridge, const std::string& serial, - const std::string& model, + const AndroidDeviceManager::DeviceInfo& device_info, bool connected); std::string serial() { return serial_; } std::string model() { return model_; } bool is_connected() { return connected_; } - void AddBrowser(scoped_refptr<RemoteBrowser> browser); - RemoteBrowsers& browsers() { return browsers_; } gfx::Size screen_size() { return screen_size_; } - void set_screen_size(const gfx::Size& size) { screen_size_ = size; } void OpenSocket(const std::string& socket_name, const AndroidDeviceManager::SocketCallback& callback); diff --git a/chrome/browser/devtools/device/self_device_provider.cc b/chrome/browser/devtools/device/self_device_provider.cc index fb782fc..24fa6ca 100644 --- a/chrome/browser/devtools/device/self_device_provider.cc +++ b/chrome/browser/devtools/device/self_device_provider.cc @@ -10,32 +10,19 @@ namespace { -const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; -const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; -const char kOpenedUnixSocketsResponse[] = - "Num RefCount Protocol Flags Type St Inode Path\n" - "00000000: 00000002 00000000 00010000 0001 01 20894 @%s\n"; -const char kRemoteDebuggingSocket[] = "chrome_devtools_remote"; - const char kDeviceModel[] = "Local Chrome"; +const char kBrowserName[] = "Chrome"; const char kLocalhost[] = "127.0.0.1"; class SelfAsDevice : public AndroidDeviceManager::Device { public: explicit SelfAsDevice(int port); - virtual void RunCommand(const std::string& command, - const CommandCallback& callback) OVERRIDE; + virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) OVERRIDE; + virtual void OpenSocket(const std::string& socket_name, const SocketCallback& callback) OVERRIDE; private: - void RunCommandCallback(const CommandCallback& callback, - const std::string& response, - int result); - - void RunSocketCallback(const SocketCallback& callback, - net::StreamSocket* socket, - int result); virtual ~SelfAsDevice() {} int port_; @@ -46,32 +33,26 @@ SelfAsDevice::SelfAsDevice(int port) port_(port) {} -void SelfAsDevice::RunCommandCallback(const CommandCallback& callback, - const std::string& response, - int result) { - callback.Run(result, response); -} +void SelfAsDevice::QueryDeviceInfo(const DeviceInfoCallback& callback) { + AndroidDeviceManager::DeviceInfo device_info; + device_info.model = kDeviceModel; -void SelfAsDevice::RunSocketCallback(const SocketCallback& callback, - net::StreamSocket* socket, - int result) { - callback.Run(result, socket); + AndroidDeviceManager::BrowserInfo browser_info; + browser_info.socket_name = base::IntToString(port_); + browser_info.display_name = kBrowserName; + browser_info.type = AndroidDeviceManager::BrowserInfo::kTypeChrome; + + device_info.browser_info.push_back(browser_info); + + base::MessageLoop::current()->PostTask( + FROM_HERE, base::Bind(callback, device_info)); } -void SelfAsDevice::RunCommand(const std::string& command, - const CommandCallback& callback) { - DCHECK(CalledOnValidThread()); - std::string response; - if (command == kDeviceModelCommand) { - response = kDeviceModel; - } else if (command == kOpenedUnixSocketsCommand) { - response = base::StringPrintf(kOpenedUnixSocketsResponse, - kRemoteDebuggingSocket); - } - - base::MessageLoop::current()->PostTask(FROM_HERE, - base::Bind(&SelfAsDevice::RunCommandCallback, this, callback, - response, 0)); +static void RunSocketCallback( + const AndroidDeviceManager::SocketCallback& callback, + net::StreamSocket* socket, + int result) { + callback.Run(result, socket); } void SelfAsDevice::OpenSocket(const std::string& socket_name, @@ -81,19 +62,13 @@ void SelfAsDevice::OpenSocket(const std::string& socket_name, // (debugging purposes). net::IPAddressNumber ip_number; net::ParseIPLiteralToNumber(kLocalhost, &ip_number); - - int port = 0; - if (socket_name == kRemoteDebuggingSocket) - port = port_; - else - base::StringToInt(socket_name, &port); - + int port; + base::StringToInt(socket_name, &port); net::AddressList address_list = net::AddressList::CreateFromIPAddress(ip_number, port); net::TCPClientSocket* socket = new net::TCPClientSocket( address_list, NULL, net::NetLog::Source()); - socket->Connect(base::Bind(&SelfAsDevice::RunSocketCallback, this, callback, - socket)); + socket->Connect(base::Bind(&RunSocketCallback, callback, socket)); } } // namespace diff --git a/chrome/browser/devtools/device/usb/usb_device_provider.cc b/chrome/browser/devtools/device/usb/usb_device_provider.cc index a4a51e9..566f121 100644 --- a/chrome/browser/devtools/device/usb/usb_device_provider.cc +++ b/chrome/browser/devtools/device/usb/usb_device_provider.cc @@ -5,6 +5,7 @@ #include "chrome/browser/devtools/device/usb/usb_device_provider.h" #include "base/strings/stringprintf.h" +#include "chrome/browser/devtools/device/adb/adb_device_info_query.h" #include "chrome/browser/devtools/device/usb/android_rsa.h" #include "chrome/browser/devtools/device/usb/android_usb_device.h" #include "crypto/rsa_private_key.h" @@ -21,8 +22,7 @@ class UsbDeviceImpl : public AndroidDeviceManager::Device { public: explicit UsbDeviceImpl(AndroidUsbDevice* device); - virtual void RunCommand(const std::string& command, - const CommandCallback& callback) OVERRIDE; + virtual void QueryDeviceInfo(const DeviceInfoCallback& callback) OVERRIDE; virtual void OpenSocket(const std::string& name, const SocketCallback& callback) OVERRIDE; @@ -30,6 +30,8 @@ class UsbDeviceImpl : public AndroidDeviceManager::Device { 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); @@ -50,18 +52,9 @@ UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device) device_->InitOnCallerThread(); } -void UsbDeviceImpl::RunCommand(const std::string& command, - const CommandCallback& callback) { - DCHECK(CalledOnValidThread()); - net::StreamSocket* socket = device_->CreateSocket(command); - if (!socket) { - callback.Run(net::ERR_CONNECTION_FAILED, std::string()); - return; - } - int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand, - this, callback, socket)); - if (result != net::ERR_IO_PENDING) - callback.Run(result, std::string()); +void UsbDeviceImpl::QueryDeviceInfo(const DeviceInfoCallback& callback) { + AdbDeviceInfoQuery::Start( + base::Bind(&UsbDeviceImpl::RunCommand, this), callback); } void UsbDeviceImpl::OpenSocket(const std::string& name, @@ -86,6 +79,20 @@ void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback, callback.Run(result, result == net::OK ? socket : NULL); } +void UsbDeviceImpl::RunCommand(const std::string& command, + const CommandCallback& callback) { + DCHECK(CalledOnValidThread()); + net::StreamSocket* socket = device_->CreateSocket(command); + if (!socket) { + callback.Run(net::ERR_CONNECTION_FAILED, std::string()); + return; + } + int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand, + this, callback, socket)); + if (result != net::ERR_IO_PENDING) + callback.Run(result, std::string()); +} + void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback, net::StreamSocket* socket, int result) { diff --git a/chrome/chrome_debugger.gypi b/chrome/chrome_debugger.gypi index 930adb9..76942a3 100644 --- a/chrome/chrome_debugger.gypi +++ b/chrome/chrome_debugger.gypi @@ -30,6 +30,8 @@ 'sources': [ 'browser/devtools/device/adb/adb_client_socket.cc', 'browser/devtools/device/adb/adb_client_socket.h', + 'browser/devtools/device/adb/adb_device_info_query.cc', + 'browser/devtools/device/adb/adb_device_info_query.h', 'browser/devtools/device/adb/adb_device_provider.cc', 'browser/devtools/device/adb/adb_device_provider.h', 'browser/devtools/device/android_device_manager.cc', |