| Index: chrome/browser/devtools/device/devtools_device_discovery.cc
|
| diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_device_discovery.cc
|
| similarity index 50%
|
| copy from chrome/browser/devtools/device/devtools_android_bridge.cc
|
| copy to chrome/browser/devtools/device/devtools_device_discovery.cc
|
| index 229ef1967011c10b582aaa54efcdc03246e020c8..9436d34b6e1e6232d9caf0c96d817af49c50d127 100644
|
| --- a/chrome/browser/devtools/device/devtools_android_bridge.cc
|
| +++ b/chrome/browser/devtools/device/devtools_device_discovery.cc
|
| @@ -2,217 +2,56 @@
|
| // 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/devtools_android_bridge.h"
|
| +#include "chrome/browser/devtools/device/devtools_device_discovery.h"
|
|
|
| -#include <stddef.h>
|
| -#include <algorithm>
|
| -#include <map>
|
| -#include <set>
|
| -#include <utility>
|
| -#include <vector>
|
| -
|
| -#include "base/base64.h"
|
| #include "base/bind.h"
|
| -#include "base/command_line.h"
|
| -#include "base/compiler_specific.h"
|
| #include "base/json/json_reader.h"
|
| -#include "base/lazy_instance.h"
|
| -#include "base/macros.h"
|
| #include "base/memory/ptr_util.h"
|
| -#include "base/memory/singleton.h"
|
| -#include "base/message_loop/message_loop.h"
|
| #include "base/strings/string_number_conversions.h"
|
| #include "base/strings/string_split.h"
|
| #include "base/strings/string_util.h"
|
| #include "base/strings/stringprintf.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| -#include "base/threading/thread.h"
|
| #include "base/values.h"
|
| -#include "chrome/browser/devtools/device/adb/adb_device_provider.h"
|
| -#include "chrome/browser/devtools/device/port_forwarding_controller.h"
|
| -#include "chrome/browser/devtools/device/tcp_device_provider.h"
|
| -#include "chrome/browser/devtools/device/usb/usb_device_provider.h"
|
| #include "chrome/browser/devtools/devtools_protocol.h"
|
| #include "chrome/browser/devtools/devtools_window.h"
|
| -#include "chrome/browser/devtools/remote_debugging_server.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/common/chrome_switches.h"
|
| -#include "chrome/common/features.h"
|
| -#include "chrome/common/pref_names.h"
|
| -#include "components/keyed_service/content/browser_context_dependency_manager.h"
|
| -#include "components/prefs/pref_service.h"
|
| -#include "components/signin/core/browser/profile_oauth2_token_service.h"
|
| -#include "components/signin/core/browser/signin_manager.h"
|
| #include "content/public/browser/devtools_agent_host.h"
|
| #include "content/public/browser/devtools_external_agent_proxy.h"
|
| #include "content/public/browser/devtools_external_agent_proxy_delegate.h"
|
| #include "content/public/browser/user_metrics.h"
|
| #include "net/base/escape.h"
|
| -#include "net/base/host_port_pair.h"
|
| -#include "net/base/net_errors.h"
|
| -
|
| -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
|
| -#include "chrome/browser/devtools/device/cast_device_provider.h"
|
| -#endif
|
|
|
| using content::BrowserThread;
|
| using content::DevToolsAgentHost;
|
| +using RemoteBrowser = DevToolsDeviceDiscovery::RemoteBrowser;
|
| +using RemoteDevice = DevToolsDeviceDiscovery::RemoteDevice;
|
| +using RemotePage = DevToolsDeviceDiscovery::RemotePage;
|
|
|
| namespace {
|
|
|
| const char kPageListRequest[] = "/json";
|
| const char kVersionRequest[] = "/json/version";
|
| const char kClosePageRequest[] = "/json/close/%s";
|
| -const char kNewPageRequestWithURL[] = "/json/new?%s";
|
| const char kActivatePageRequest[] = "/json/activate/%s";
|
| const char kBrowserTargetSocket[] = "/devtools/browser";
|
| -const int kAdbPollingIntervalMs = 1000;
|
| +const int kPollingIntervalMs = 1000;
|
|
|
| const char kPageReloadCommand[] = "Page.reload";
|
|
|
| const char kWebViewSocketPrefix[] = "webview_devtools_remote";
|
|
|
| -const char kChromeDiscoveryURL[] = "localhost:9222";
|
| -const char kNodeDiscoveryURL[] = "localhost:9229";
|
| -
|
| -bool BrowserIdFromString(const std::string& browser_id_str,
|
| - std::string* serial,
|
| - std::string* browser_id) {
|
| - size_t colon_pos = browser_id_str.find(':');
|
| - if (colon_pos == std::string::npos)
|
| - return false;
|
| - *serial = browser_id_str.substr(0, colon_pos);
|
| - *browser_id = browser_id_str.substr(colon_pos + 1);
|
| - return true;
|
| -}
|
| -
|
| static void NoOp(int, const std::string&) {}
|
|
|
| -} // namespace
|
| -
|
| -// DiscoveryRequest -----------------------------------------------------
|
| -
|
| -class DevToolsAndroidBridge::DiscoveryRequest
|
| - : public base::RefCountedThreadSafe<DiscoveryRequest,
|
| - BrowserThread::DeleteOnUIThread> {
|
| - public:
|
| - DiscoveryRequest(AndroidDeviceManager* device_manager,
|
| - const DeviceListCallback& callback);
|
| - private:
|
| - friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
|
| - friend class base::DeleteHelper<DiscoveryRequest>;
|
| - virtual ~DiscoveryRequest();
|
| -
|
| - void ReceivedDevices(const AndroidDeviceManager::Devices& devices);
|
| - void ReceivedDeviceInfo(scoped_refptr<AndroidDeviceManager::Device> device,
|
| - const AndroidDeviceManager::DeviceInfo& device_info);
|
| - void ReceivedVersion(scoped_refptr<RemoteBrowser>,
|
| - int result,
|
| - const std::string& response);
|
| - void ReceivedPages(scoped_refptr<AndroidDeviceManager::Device> device,
|
| - scoped_refptr<RemoteBrowser>,
|
| - int result,
|
| - const std::string& response);
|
| -
|
| - DeviceListCallback callback_;
|
| - CompleteDevices complete_devices_;
|
| -};
|
| -
|
| -DevToolsAndroidBridge::DiscoveryRequest::DiscoveryRequest(
|
| - AndroidDeviceManager* device_manager,
|
| - const DeviceListCallback& callback)
|
| - : callback_(callback) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - device_manager->QueryDevices(
|
| - base::Bind(&DiscoveryRequest::ReceivedDevices, this));
|
| -}
|
| -
|
| -DevToolsAndroidBridge::DiscoveryRequest::~DiscoveryRequest() {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - callback_.Run(complete_devices_);
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::DiscoveryRequest::ReceivedDevices(
|
| - const AndroidDeviceManager::Devices& devices) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - for (const auto& device : devices) {
|
| - device->QueryDeviceInfo(
|
| - base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this, device));
|
| - }
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::DiscoveryRequest::ReceivedDeviceInfo(
|
| - scoped_refptr<AndroidDeviceManager::Device> device,
|
| - const AndroidDeviceManager::DeviceInfo& device_info) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - scoped_refptr<RemoteDevice> remote_device =
|
| - new RemoteDevice(device->serial(), device_info);
|
| - complete_devices_.push_back(std::make_pair(device, remote_device));
|
| - for (RemoteBrowsers::iterator it = remote_device->browsers().begin();
|
| - it != remote_device->browsers().end(); ++it) {
|
| - device->SendJsonRequest(
|
| - (*it)->socket(),
|
| - kVersionRequest,
|
| - base::Bind(&DiscoveryRequest::ReceivedVersion, this, *it));
|
| - device->SendJsonRequest(
|
| - (*it)->socket(),
|
| - kPageListRequest,
|
| - base::Bind(&DiscoveryRequest::ReceivedPages, this, device, *it));
|
| - }
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::DiscoveryRequest::ReceivedVersion(
|
| - scoped_refptr<RemoteBrowser> browser,
|
| - int result,
|
| - const std::string& response) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - if (result < 0)
|
| - return;
|
| - // Parse version, append to package name if available,
|
| - std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
|
| - base::DictionaryValue* dict;
|
| - if (value && value->GetAsDictionary(&dict)) {
|
| - std::string browser_name;
|
| - if (dict->GetString("Browser", &browser_name)) {
|
| - std::vector<std::string> parts = base::SplitString(
|
| - browser_name, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
| - if (parts.size() == 2)
|
| - browser->version_ = parts[1];
|
| - else
|
| - browser->version_ = browser_name;
|
| - }
|
| - std::string package;
|
| - if (dict->GetString("Android-Package", &package)) {
|
| - browser->display_name_ =
|
| - AndroidDeviceManager::GetBrowserName(browser->socket(), package);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::DiscoveryRequest::ReceivedPages(
|
| - scoped_refptr<AndroidDeviceManager::Device> device,
|
| - scoped_refptr<RemoteBrowser> browser,
|
| - int result,
|
| - const std::string& response) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - if (result < 0)
|
| - return;
|
| - std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
|
| - base::ListValue* list_value;
|
| - if (value && value->GetAsList(&list_value)) {
|
| - for (const auto& page_value : *list_value) {
|
| - base::DictionaryValue* dict;
|
| - if (page_value->GetAsDictionary(&dict))
|
| - browser->pages_.push_back(
|
| - new RemotePage(device, browser->browser_id_, *dict));
|
| - }
|
| - }
|
| +static void ScheduleTaskDefault(const base::Closure& task) {
|
| + BrowserThread::PostDelayedTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + task,
|
| + base::TimeDelta::FromMilliseconds(kPollingIntervalMs));
|
| }
|
|
|
| // ProtocolCommand ------------------------------------------------------------
|
|
|
| -namespace {
|
| -
|
| class ProtocolCommand
|
| : public AndroidDeviceManager::AndroidWebSocket::Delegate {
|
| public:
|
| @@ -264,38 +103,9 @@ ProtocolCommand::~ProtocolCommand() {
|
| callback_.Run();
|
| }
|
|
|
| -} // namespace
|
| -
|
| -// static
|
| -DevToolsAndroidBridge::Factory* DevToolsAndroidBridge::Factory::GetInstance() {
|
| - return base::Singleton<DevToolsAndroidBridge::Factory>::get();
|
| -}
|
| -
|
| -// static
|
| -DevToolsAndroidBridge* DevToolsAndroidBridge::Factory::GetForProfile(
|
| - Profile* profile) {
|
| - return static_cast<DevToolsAndroidBridge*>(GetInstance()->
|
| - GetServiceForBrowserContext(profile->GetOriginalProfile(), true));
|
| -}
|
| -
|
| -DevToolsAndroidBridge::Factory::Factory()
|
| - : BrowserContextKeyedServiceFactory(
|
| - "DevToolsAndroidBridge",
|
| - BrowserContextDependencyManager::GetInstance()) {
|
| -}
|
| -
|
| -DevToolsAndroidBridge::Factory::~Factory() {}
|
| -
|
| -KeyedService* DevToolsAndroidBridge::Factory::BuildServiceInstanceFor(
|
| - content::BrowserContext* context) const {
|
| - Profile* profile = Profile::FromBrowserContext(context);
|
| -
|
| - return new DevToolsAndroidBridge(profile);
|
| -}
|
| -
|
| // AgentHostDelegate ----------------------------------------------------------
|
|
|
| -class DevToolsAndroidBridge::AgentHostDelegate
|
| +class AgentHostDelegate
|
| : public content::DevToolsExternalAgentProxyDelegate,
|
| public AndroidDeviceManager::AndroidWebSocket::Delegate {
|
| public:
|
| @@ -399,7 +209,7 @@ static std::string GetTargetPath(base::DictionaryValue* value) {
|
|
|
| // static
|
| scoped_refptr<content::DevToolsAgentHost>
|
| -DevToolsAndroidBridge::AgentHostDelegate::GetOrCreateAgentHost(
|
| +AgentHostDelegate::GetOrCreateAgentHost(
|
| scoped_refptr<AndroidDeviceManager::Device> device,
|
| const std::string& browser_id,
|
| const std::string& local_id,
|
| @@ -420,7 +230,7 @@ DevToolsAndroidBridge::AgentHostDelegate::GetOrCreateAgentHost(
|
| return result;
|
| }
|
|
|
| -DevToolsAndroidBridge::AgentHostDelegate::AgentHostDelegate(
|
| +AgentHostDelegate::AgentHostDelegate(
|
| scoped_refptr<AndroidDeviceManager::Device> device,
|
| const std::string& browser_id,
|
| const std::string& local_id,
|
| @@ -444,11 +254,10 @@ DevToolsAndroidBridge::AgentHostDelegate::AgentHostDelegate(
|
| proxy_(nullptr) {
|
| }
|
|
|
| -DevToolsAndroidBridge::AgentHostDelegate::~AgentHostDelegate() {
|
| +AgentHostDelegate::~AgentHostDelegate() {
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::Attach(
|
| - content::DevToolsExternalAgentProxy* proxy) {
|
| +void AgentHostDelegate::Attach(content::DevToolsExternalAgentProxy* proxy) {
|
| proxy_ = proxy;
|
| content::RecordAction(
|
| base::StartsWith(browser_id_, kWebViewSocketPrefix,
|
| @@ -459,56 +268,55 @@ void DevToolsAndroidBridge::AgentHostDelegate::Attach(
|
| device_->CreateWebSocket(browser_id_, target_path_, this));
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::Detach() {
|
| +void AgentHostDelegate::Detach() {
|
| web_socket_.reset();
|
| proxy_ = nullptr;
|
| }
|
|
|
| -std::string DevToolsAndroidBridge::AgentHostDelegate::GetType() {
|
| +std::string AgentHostDelegate::GetType() {
|
| return remote_type_;
|
| }
|
|
|
| -std::string DevToolsAndroidBridge::AgentHostDelegate::GetTitle() {
|
| +std::string AgentHostDelegate::GetTitle() {
|
| return title_;
|
| }
|
|
|
| -std::string DevToolsAndroidBridge::AgentHostDelegate::GetDescription() {
|
| +std::string AgentHostDelegate::GetDescription() {
|
| return description_;
|
| }
|
|
|
| -GURL DevToolsAndroidBridge::AgentHostDelegate::GetURL() {
|
| +GURL AgentHostDelegate::GetURL() {
|
| return url_;
|
| }
|
|
|
| -GURL DevToolsAndroidBridge::AgentHostDelegate::GetFaviconURL() {
|
| +GURL AgentHostDelegate::GetFaviconURL() {
|
| return favicon_url_;
|
| }
|
|
|
| -std::string DevToolsAndroidBridge::AgentHostDelegate::GetFrontendURL() {
|
| +std::string AgentHostDelegate::GetFrontendURL() {
|
| return frontend_url_;
|
| }
|
|
|
| -bool DevToolsAndroidBridge::AgentHostDelegate::Activate() {
|
| +bool AgentHostDelegate::Activate() {
|
| std::string request = base::StringPrintf(kActivatePageRequest,
|
| remote_id_.c_str());
|
| device_->SendJsonRequest(browser_id_, request, base::Bind(&NoOp));
|
| return true;
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::Reload() {
|
| +void AgentHostDelegate::Reload() {
|
| SendProtocolCommand(target_path_, kPageReloadCommand, nullptr,
|
| base::Closure());
|
| }
|
|
|
| -bool DevToolsAndroidBridge::AgentHostDelegate::Close() {
|
| +bool AgentHostDelegate::Close() {
|
| std::string request = base::StringPrintf(kClosePageRequest,
|
| remote_id_.c_str());
|
| device_->SendJsonRequest(browser_id_, request, base::Bind(&NoOp));
|
| return true;
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend(
|
| - const std::string& message) {
|
| +void AgentHostDelegate::SendMessageToBackend(const std::string& message) {
|
| // We could have detached due to physical connection being closed.
|
| if (!proxy_)
|
| return;
|
| @@ -518,7 +326,7 @@ void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend(
|
| pending_messages_.push_back(message);
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::OnSocketOpened() {
|
| +void AgentHostDelegate::OnSocketOpened() {
|
| socket_opened_ = true;
|
| for (std::vector<std::string>::iterator it = pending_messages_.begin();
|
| it != pending_messages_.end(); ++it) {
|
| @@ -527,13 +335,12 @@ void DevToolsAndroidBridge::AgentHostDelegate::OnSocketOpened() {
|
| pending_messages_.clear();
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::OnFrameRead(
|
| - const std::string& message) {
|
| +void AgentHostDelegate::OnFrameRead(const std::string& message) {
|
| if (proxy_)
|
| proxy_->DispatchOnClientHost(message);
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::OnSocketClosed() {
|
| +void AgentHostDelegate::OnSocketClosed() {
|
| if (proxy_) {
|
| std::string message = "{ \"method\": \"Inspector.detached\", "
|
| "\"params\": { \"reason\": \"Connection lost.\"} }";
|
| @@ -542,7 +349,7 @@ void DevToolsAndroidBridge::AgentHostDelegate::OnSocketClosed() {
|
| }
|
| }
|
|
|
| -void DevToolsAndroidBridge::AgentHostDelegate::SendProtocolCommand(
|
| +void AgentHostDelegate::SendProtocolCommand(
|
| const std::string& target_path,
|
| const std::string& method,
|
| std::unique_ptr<base::DictionaryValue> params,
|
| @@ -556,9 +363,130 @@ void DevToolsAndroidBridge::AgentHostDelegate::SendProtocolCommand(
|
| callback);
|
| }
|
|
|
| -// DevToolsAndroidBridge::RemotePage ------------------------------------------
|
| +} // namespace
|
| +
|
| +// DevToolsDeviceDiscovery::DiscoveryRequest ----------------------------------
|
| +
|
| +class DevToolsDeviceDiscovery::DiscoveryRequest
|
| + : public base::RefCountedThreadSafe<DiscoveryRequest,
|
| + BrowserThread::DeleteOnUIThread> {
|
| + public:
|
| + DiscoveryRequest(AndroidDeviceManager* device_manager,
|
| + const DevToolsDeviceDiscovery::DeviceListCallback& callback);
|
| + private:
|
| + friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
|
| + friend class base::DeleteHelper<DiscoveryRequest>;
|
| + virtual ~DiscoveryRequest();
|
| +
|
| + void ReceivedDevices(const AndroidDeviceManager::Devices& devices);
|
| + void ReceivedDeviceInfo(scoped_refptr<AndroidDeviceManager::Device> device,
|
| + const AndroidDeviceManager::DeviceInfo& device_info);
|
| + void ReceivedVersion(scoped_refptr<RemoteBrowser>,
|
| + int result,
|
| + const std::string& response);
|
| + void ReceivedPages(scoped_refptr<AndroidDeviceManager::Device> device,
|
| + scoped_refptr<RemoteBrowser>,
|
| + int result,
|
| + const std::string& response);
|
| +
|
| + DevToolsDeviceDiscovery::DeviceListCallback callback_;
|
| + DevToolsDeviceDiscovery::CompleteDevices complete_devices_;
|
| +};
|
| +
|
| +DevToolsDeviceDiscovery::DiscoveryRequest::DiscoveryRequest(
|
| + AndroidDeviceManager* device_manager,
|
| + const DevToolsDeviceDiscovery::DeviceListCallback& callback)
|
| + : callback_(callback) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + device_manager->QueryDevices(
|
| + base::Bind(&DiscoveryRequest::ReceivedDevices, this));
|
| +}
|
|
|
| -DevToolsAndroidBridge::RemotePage::RemotePage(
|
| +DevToolsDeviceDiscovery::DiscoveryRequest::~DiscoveryRequest() {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + callback_.Run(complete_devices_);
|
| +}
|
| +
|
| +void DevToolsDeviceDiscovery::DiscoveryRequest::ReceivedDevices(
|
| + const AndroidDeviceManager::Devices& devices) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + for (const auto& device : devices) {
|
| + device->QueryDeviceInfo(
|
| + base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this, device));
|
| + }
|
| +}
|
| +
|
| +void DevToolsDeviceDiscovery::DiscoveryRequest::ReceivedDeviceInfo(
|
| + scoped_refptr<AndroidDeviceManager::Device> device,
|
| + const AndroidDeviceManager::DeviceInfo& device_info) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + scoped_refptr<RemoteDevice> remote_device =
|
| + new RemoteDevice(device->serial(), device_info);
|
| + complete_devices_.push_back(std::make_pair(device, remote_device));
|
| + for (RemoteBrowsers::iterator it = remote_device->browsers().begin();
|
| + it != remote_device->browsers().end(); ++it) {
|
| + device->SendJsonRequest(
|
| + (*it)->socket(),
|
| + kVersionRequest,
|
| + base::Bind(&DiscoveryRequest::ReceivedVersion, this, *it));
|
| + device->SendJsonRequest(
|
| + (*it)->socket(),
|
| + kPageListRequest,
|
| + base::Bind(&DiscoveryRequest::ReceivedPages, this, device, *it));
|
| + }
|
| +}
|
| +
|
| +void DevToolsDeviceDiscovery::DiscoveryRequest::ReceivedVersion(
|
| + scoped_refptr<RemoteBrowser> browser,
|
| + int result,
|
| + const std::string& response) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + if (result < 0)
|
| + return;
|
| + // Parse version, append to package name if available,
|
| + std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
|
| + base::DictionaryValue* dict;
|
| + if (value && value->GetAsDictionary(&dict)) {
|
| + std::string browser_name;
|
| + if (dict->GetString("Browser", &browser_name)) {
|
| + std::vector<std::string> parts = base::SplitString(
|
| + browser_name, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
| + if (parts.size() == 2)
|
| + browser->version_ = parts[1];
|
| + else
|
| + browser->version_ = browser_name;
|
| + }
|
| + std::string package;
|
| + if (dict->GetString("Android-Package", &package)) {
|
| + browser->display_name_ =
|
| + AndroidDeviceManager::GetBrowserName(browser->socket(), package);
|
| + }
|
| + }
|
| +}
|
| +
|
| +void DevToolsDeviceDiscovery::DiscoveryRequest::ReceivedPages(
|
| + scoped_refptr<AndroidDeviceManager::Device> device,
|
| + scoped_refptr<RemoteBrowser> browser,
|
| + int result,
|
| + const std::string& response) {
|
| + DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + if (result < 0)
|
| + return;
|
| + std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
|
| + base::ListValue* list_value;
|
| + if (value && value->GetAsList(&list_value)) {
|
| + for (const auto& page_value : *list_value) {
|
| + base::DictionaryValue* dict;
|
| + if (page_value->GetAsDictionary(&dict))
|
| + browser->pages_.push_back(
|
| + new RemotePage(device, browser->browser_id_, *dict));
|
| + }
|
| + }
|
| +}
|
| +
|
| +// DevToolsDeviceDiscovery::RemotePage ----------------------------------------
|
| +
|
| +DevToolsDeviceDiscovery::RemotePage::RemotePage(
|
| scoped_refptr<AndroidDeviceManager::Device> device,
|
| const std::string& browser_id,
|
| const base::DictionaryValue& dict)
|
| @@ -567,11 +495,11 @@ DevToolsAndroidBridge::RemotePage::RemotePage(
|
| dict_(dict.DeepCopy()) {
|
| }
|
|
|
| -DevToolsAndroidBridge::RemotePage::~RemotePage() {
|
| +DevToolsDeviceDiscovery::RemotePage::~RemotePage() {
|
| }
|
|
|
| scoped_refptr<content::DevToolsAgentHost>
|
| -DevToolsAndroidBridge::RemotePage::CreateTarget() {
|
| +DevToolsDeviceDiscovery::RemotePage::CreateTarget() {
|
| std::string local_id = BuildUniqueTargetId(device_->serial(),
|
| browser_id_,
|
| dict_.get());
|
| @@ -582,9 +510,9 @@ DevToolsAndroidBridge::RemotePage::CreateTarget() {
|
| device_, browser_id_, local_id, target_path, type, dict_.get());
|
| }
|
|
|
| -// DevToolsAndroidBridge::RemoteBrowser ---------------------------------------
|
| +// DevToolsDeviceDiscovery::RemoteBrowser -------------------------------------
|
|
|
| -DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser(
|
| +DevToolsDeviceDiscovery::RemoteBrowser::RemoteBrowser(
|
| const std::string& serial,
|
| const AndroidDeviceManager::BrowserInfo& browser_info)
|
| : serial_(serial),
|
| @@ -594,16 +522,16 @@ DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser(
|
| type_(browser_info.type) {
|
| }
|
|
|
| -bool DevToolsAndroidBridge::RemoteBrowser::IsChrome() {
|
| +bool DevToolsDeviceDiscovery::RemoteBrowser::IsChrome() {
|
| return type_ == AndroidDeviceManager::BrowserInfo::kTypeChrome;
|
| }
|
|
|
| -std::string DevToolsAndroidBridge::RemoteBrowser::GetId() {
|
| +std::string DevToolsDeviceDiscovery::RemoteBrowser::GetId() {
|
| return serial() + ":" + socket();
|
| }
|
|
|
| -DevToolsAndroidBridge::RemoteBrowser::ParsedVersion
|
| -DevToolsAndroidBridge::RemoteBrowser::GetParsedVersion() {
|
| +DevToolsDeviceDiscovery::RemoteBrowser::ParsedVersion
|
| +DevToolsDeviceDiscovery::RemoteBrowser::GetParsedVersion() {
|
| ParsedVersion result;
|
| for (const base::StringPiece& part :
|
| base::SplitStringPiece(
|
| @@ -615,62 +543,12 @@ DevToolsAndroidBridge::RemoteBrowser::GetParsedVersion() {
|
| return result;
|
| }
|
|
|
| -scoped_refptr<content::DevToolsAgentHost>
|
| -DevToolsAndroidBridge::GetBrowserAgentHost(
|
| - scoped_refptr<RemoteBrowser> browser) {
|
| - DeviceMap::iterator it = device_map_.find(browser->serial());
|
| - if (it == device_map_.end())
|
| - return nullptr;
|
| -
|
| - return AgentHostDelegate::GetOrCreateAgentHost(
|
| - it->second,
|
| - browser->browser_id_,
|
| - "adb:" + browser->serial() + ":" + browser->socket(),
|
| - kBrowserTargetSocket, DevToolsAgentHost::kTypeBrowser, nullptr);
|
| +DevToolsDeviceDiscovery::RemoteBrowser::~RemoteBrowser() {
|
| }
|
|
|
| -void DevToolsAndroidBridge::SendJsonRequest(
|
| - const std::string& browser_id_str,
|
| - const std::string& url,
|
| - const JsonRequestCallback& callback) {
|
| - std::string serial;
|
| - std::string browser_id;
|
| - if (!BrowserIdFromString(browser_id_str, &serial, &browser_id)) {
|
| - callback.Run(net::ERR_FAILED, std::string());
|
| - return;
|
| - }
|
| - DeviceMap::iterator it = device_map_.find(serial);
|
| - if (it == device_map_.end()) {
|
| - callback.Run(net::ERR_FAILED, std::string());
|
| - return;
|
| - }
|
| - it->second->SendJsonRequest(browser_id, url, callback);
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::OpenRemotePage(scoped_refptr<RemoteBrowser> browser,
|
| - const std::string& input_url) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - GURL gurl(input_url);
|
| - if (!gurl.is_valid()) {
|
| - gurl = GURL("http://" + input_url);
|
| - if (!gurl.is_valid())
|
| - return;
|
| - }
|
| - std::string url = gurl.spec();
|
| - RemoteBrowser::ParsedVersion parsed_version = browser->GetParsedVersion();
|
| +// DevToolsDeviceDiscovery::RemoteDevice --------------------------------------
|
|
|
| - std::string query = net::EscapeQueryParamValue(url, false /* use_plus */);
|
| - std::string request =
|
| - base::StringPrintf(kNewPageRequestWithURL, query.c_str());
|
| - SendJsonRequest(browser->GetId(), request, base::Bind(&NoOp));
|
| -}
|
| -
|
| -DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() {
|
| -}
|
| -
|
| -// DevToolsAndroidBridge::RemoteDevice ----------------------------------------
|
| -
|
| -DevToolsAndroidBridge::RemoteDevice::RemoteDevice(
|
| +DevToolsDeviceDiscovery::RemoteDevice::RemoteDevice(
|
| const std::string& serial,
|
| const AndroidDeviceManager::DeviceInfo& device_info)
|
| : serial_(serial),
|
| @@ -685,294 +563,90 @@ DevToolsAndroidBridge::RemoteDevice::RemoteDevice(
|
| }
|
| }
|
|
|
| -DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() {
|
| +DevToolsDeviceDiscovery::RemoteDevice::~RemoteDevice() {
|
| }
|
|
|
| -// DevToolsAndroidBridge ------------------------------------------------------
|
| +// DevToolsDeviceDiscovery ----------------------------------------------------
|
|
|
| -// static
|
| -void DevToolsAndroidBridge::QueryCompleteDevices(
|
| +DevToolsDeviceDiscovery::DevToolsDeviceDiscovery(
|
| AndroidDeviceManager* device_manager,
|
| - const DeviceListCallback& callback) {
|
| - new DiscoveryRequest(device_manager, callback);
|
| -}
|
| -
|
| -DevToolsAndroidBridge::DevToolsAndroidBridge(
|
| - Profile* profile)
|
| - : profile_(profile),
|
| - device_manager_(AndroidDeviceManager::Create()),
|
| - task_scheduler_(base::Bind(&DevToolsAndroidBridge::ScheduleTaskDefault)),
|
| - port_forwarding_controller_(new PortForwardingController(profile)),
|
| + const DeviceListCallback& callback)
|
| + : device_manager_(device_manager),
|
| + callback_(callback),
|
| + task_scheduler_(base::Bind(&ScheduleTaskDefault)),
|
| weak_factory_(this) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - pref_change_registrar_.Init(profile_->GetPrefs());
|
| - pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled,
|
| - base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
|
| - base::Unretained(this)));
|
| - pref_change_registrar_.Add(prefs::kDevToolsTCPDiscoveryConfig,
|
| - base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
|
| - base::Unretained(this)));
|
| - pref_change_registrar_.Add(prefs::kDevToolsDiscoverTCPTargetsEnabled,
|
| - base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
|
| - base::Unretained(this)));
|
| - base::ListValue* target_discovery = new base::ListValue();
|
| - target_discovery->AppendString(kChromeDiscoveryURL);
|
| - target_discovery->AppendString(kNodeDiscoveryURL);
|
| - profile->GetPrefs()->SetDefaultPrefValue(
|
| - prefs::kDevToolsTCPDiscoveryConfig, target_discovery);
|
| - CreateDeviceProviders();
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::AddDeviceListListener(
|
| - DeviceListListener* listener) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - bool polling_was_off = !NeedsDeviceListPolling();
|
| - device_list_listeners_.push_back(listener);
|
| - if (polling_was_off)
|
| - StartDeviceListPolling();
|
| + RequestDeviceList();
|
| }
|
|
|
| -void DevToolsAndroidBridge::RemoveDeviceListListener(
|
| - DeviceListListener* listener) {
|
| +DevToolsDeviceDiscovery::~DevToolsDeviceDiscovery() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - DeviceListListeners::iterator it = std::find(
|
| - device_list_listeners_.begin(), device_list_listeners_.end(), listener);
|
| - DCHECK(it != device_list_listeners_.end());
|
| - device_list_listeners_.erase(it);
|
| - if (!NeedsDeviceListPolling())
|
| - StopDeviceListPolling();
|
| }
|
|
|
| -void DevToolsAndroidBridge::AddDeviceCountListener(
|
| - DeviceCountListener* listener) {
|
| - device_count_listeners_.push_back(listener);
|
| - if (device_count_listeners_.size() == 1)
|
| - StartDeviceCountPolling();
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::RemoveDeviceCountListener(
|
| - DeviceCountListener* listener) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - DeviceCountListeners::iterator it = std::find(
|
| - device_count_listeners_.begin(), device_count_listeners_.end(), listener);
|
| - DCHECK(it != device_count_listeners_.end());
|
| - device_count_listeners_.erase(it);
|
| - if (device_count_listeners_.empty())
|
| - StopDeviceCountPolling();
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::AddPortForwardingListener(
|
| - PortForwardingListener* listener) {
|
| - bool polling_was_off = !NeedsDeviceListPolling();
|
| - port_forwarding_listeners_.push_back(listener);
|
| - if (polling_was_off)
|
| - StartDeviceListPolling();
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::RemovePortForwardingListener(
|
| - PortForwardingListener* listener) {
|
| - PortForwardingListeners::iterator it = std::find(
|
| - port_forwarding_listeners_.begin(),
|
| - port_forwarding_listeners_.end(),
|
| - listener);
|
| - DCHECK(it != port_forwarding_listeners_.end());
|
| - port_forwarding_listeners_.erase(it);
|
| - if (!NeedsDeviceListPolling())
|
| - StopDeviceListPolling();
|
| -}
|
| -
|
| -DevToolsAndroidBridge::~DevToolsAndroidBridge() {
|
| +void DevToolsDeviceDiscovery::SetScheduler(
|
| + base::Callback<void(const base::Closure&)> scheduler) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - DCHECK(device_list_listeners_.empty());
|
| - DCHECK(device_count_listeners_.empty());
|
| - DCHECK(port_forwarding_listeners_.empty());
|
| + task_scheduler_ = scheduler;
|
| }
|
|
|
| -void DevToolsAndroidBridge::StartDeviceListPolling() {
|
| - device_list_callback_.Reset(
|
| - base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, AsWeakPtr()));
|
| - RequestDeviceList(device_list_callback_.callback());
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::StopDeviceListPolling() {
|
| - device_list_callback_.Cancel();
|
| - device_map_.clear();
|
| - port_forwarding_controller_->CloseAllConnections();
|
| -}
|
| -
|
| -bool DevToolsAndroidBridge::NeedsDeviceListPolling() {
|
| - return !device_list_listeners_.empty() || !port_forwarding_listeners_.empty();
|
| +// static
|
| +scoped_refptr<content::DevToolsAgentHost>
|
| +DevToolsDeviceDiscovery::CreateBrowserAgentHost(
|
| + scoped_refptr<AndroidDeviceManager::Device> device,
|
| + scoped_refptr<RemoteBrowser> browser) {
|
| + return AgentHostDelegate::GetOrCreateAgentHost(
|
| + device,
|
| + browser->browser_id_,
|
| + "adb:" + browser->serial() + ":" + browser->socket(),
|
| + kBrowserTargetSocket, DevToolsAgentHost::kTypeBrowser, nullptr);
|
| }
|
|
|
| -void DevToolsAndroidBridge::RequestDeviceList(
|
| - const DeviceListCallback& callback) {
|
| +void DevToolsDeviceDiscovery::RequestDeviceList() {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| -
|
| - if (!NeedsDeviceListPolling() ||
|
| - !callback.Equals(device_list_callback_.callback()))
|
| - return;
|
| -
|
| - new DiscoveryRequest(device_manager_.get(), callback);
|
| + new DiscoveryRequest(
|
| + device_manager_,
|
| + base::Bind(&DevToolsDeviceDiscovery::ReceivedDeviceList,
|
| + weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| -void DevToolsAndroidBridge::ReceivedDeviceList(
|
| +void DevToolsDeviceDiscovery::ReceivedDeviceList(
|
| const CompleteDevices& complete_devices) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| -
|
| - device_map_.clear();
|
| - RemoteDevices remote_devices;
|
| - for (const auto& pair : complete_devices) {
|
| - device_map_[pair.first->serial()] = pair.first;
|
| - remote_devices.push_back(pair.second);
|
| - }
|
| -
|
| - DeviceListListeners copy(device_list_listeners_);
|
| - for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it)
|
| - (*it)->DeviceListChanged(remote_devices);
|
| -
|
| - ForwardingStatus status =
|
| - port_forwarding_controller_->DeviceListChanged(complete_devices);
|
| - PortForwardingListeners forwarding_listeners(port_forwarding_listeners_);
|
| - for (PortForwardingListeners::iterator it = forwarding_listeners.begin();
|
| - it != forwarding_listeners.end(); ++it) {
|
| - (*it)->PortStatusChanged(status);
|
| - }
|
| -
|
| - if (!NeedsDeviceListPolling())
|
| - return;
|
| -
|
| - task_scheduler_.Run(
|
| - base::Bind(&DevToolsAndroidBridge::RequestDeviceList,
|
| - AsWeakPtr(), device_list_callback_.callback()));
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::StartDeviceCountPolling() {
|
| - device_count_callback_.Reset(
|
| - base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, AsWeakPtr()));
|
| - RequestDeviceCount(device_count_callback_.callback());
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::StopDeviceCountPolling() {
|
| - device_count_callback_.Cancel();
|
| + task_scheduler_.Run(base::Bind(&DevToolsDeviceDiscovery::RequestDeviceList,
|
| + weak_factory_.GetWeakPtr()));
|
| + // |callback_| should be run last as it may destroy |this|.
|
| + callback_.Run(complete_devices);
|
| }
|
|
|
| -void DevToolsAndroidBridge::RequestDeviceCount(
|
| - const base::Callback<void(int)>& callback) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| -
|
| - if (device_count_listeners_.empty() ||
|
| - !callback.Equals(device_count_callback_.callback()))
|
| - return;
|
| +namespace {
|
|
|
| - UsbDeviceProvider::CountDevices(callback);
|
| -}
|
| +class OnceWrapper {
|
| + public:
|
| + OnceWrapper(AndroidDeviceManager* device_manager,
|
| + const DevToolsDeviceDiscovery::DeviceListCallback& callback)
|
| + : callback_(callback) {
|
| + discovery_.reset(new DevToolsDeviceDiscovery(device_manager,
|
| + base::Bind(&OnceWrapper::Callback, base::Unretained(this))));
|
| + discovery_->SetScheduler(base::Bind(&OnceWrapper::NoOp));
|
| + }
|
|
|
| -void DevToolsAndroidBridge::ReceivedDeviceCount(int count) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| + private:
|
| + static void NoOp(const base::Closure&) {}
|
|
|
| - DeviceCountListeners copy(device_count_listeners_);
|
| - for (DeviceCountListeners::iterator it = copy.begin(); it != copy.end(); ++it)
|
| - (*it)->DeviceCountChanged(count);
|
| + void Callback(const DevToolsDeviceDiscovery::CompleteDevices& devices) {
|
| + callback_.Run(devices);
|
| + delete this;
|
| + }
|
|
|
| - if (device_count_listeners_.empty())
|
| - return;
|
| + std::unique_ptr<DevToolsDeviceDiscovery> discovery_;
|
| + const DevToolsDeviceDiscovery::DeviceListCallback callback_;
|
| +};
|
|
|
| - task_scheduler_.Run(
|
| - base::Bind(&DevToolsAndroidBridge::RequestDeviceCount,
|
| - AsWeakPtr(), device_count_callback_.callback()));
|
| -}
|
| +} // namespace
|
|
|
| // static
|
| -void DevToolsAndroidBridge::ScheduleTaskDefault(const base::Closure& task) {
|
| - BrowserThread::PostDelayedTask(
|
| - BrowserThread::UI,
|
| - FROM_HERE,
|
| - task,
|
| - base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs));
|
| -}
|
| -
|
| -static std::set<net::HostPortPair> ParseTargetDiscoveryPreferenceValue(
|
| - const base::ListValue* preferenceValue) {
|
| - std::set<net::HostPortPair> targets;
|
| - if (!preferenceValue || preferenceValue->empty())
|
| - return targets;
|
| - std::string address;
|
| - for (size_t i = 0; i < preferenceValue->GetSize(); i++) {
|
| - if (!preferenceValue->GetString(i, &address))
|
| - continue;
|
| - net::HostPortPair target = net::HostPortPair::FromString(address);
|
| - if (target.IsEmpty()) {
|
| - LOG(WARNING) << "Invalid target: " << address;
|
| - continue;
|
| - }
|
| - targets.insert(target);
|
| - }
|
| - return targets;
|
| -}
|
| -
|
| -static scoped_refptr<TCPDeviceProvider> CreateTCPDeviceProvider(
|
| - const base::ListValue* targetDiscoveryConfig) {
|
| - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
|
| - std::set<net::HostPortPair> targets =
|
| - ParseTargetDiscoveryPreferenceValue(targetDiscoveryConfig);
|
| - if (targets.empty() &&
|
| - !command_line->HasSwitch(switches::kRemoteDebuggingTargets))
|
| - return nullptr;
|
| - std::string value =
|
| - command_line->GetSwitchValueASCII(switches::kRemoteDebuggingTargets);
|
| - std::vector<std::string> addresses = base::SplitString(
|
| - value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
| - for (const std::string& address : addresses) {
|
| - net::HostPortPair target = net::HostPortPair::FromString(address);
|
| - if (target.IsEmpty()) {
|
| - LOG(WARNING) << "Invalid target: " << address;
|
| - continue;
|
| - }
|
| - targets.insert(target);
|
| - }
|
| - if (targets.empty())
|
| - return nullptr;
|
| - return new TCPDeviceProvider(targets);
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::CreateDeviceProviders() {
|
| - AndroidDeviceManager::DeviceProviders device_providers;
|
| - PrefService* service = profile_->GetPrefs();
|
| - const base::ListValue* targets =
|
| - service->GetBoolean(prefs::kDevToolsDiscoverTCPTargetsEnabled)
|
| - ? service->GetList(prefs::kDevToolsTCPDiscoveryConfig)
|
| - : nullptr;
|
| - scoped_refptr<TCPDeviceProvider> provider = CreateTCPDeviceProvider(targets);
|
| - if (tcp_provider_callback_)
|
| - tcp_provider_callback_.Run(provider);
|
| -
|
| - if (provider)
|
| - device_providers.push_back(provider);
|
| -
|
| -#if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
|
| - device_providers.push_back(new CastDeviceProvider());
|
| -#endif
|
| -
|
| - device_providers.push_back(new AdbDeviceProvider());
|
| -
|
| - const PrefService::Preference* pref =
|
| - service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled);
|
| - const base::Value* pref_value = pref->GetValue();
|
| -
|
| - bool enabled;
|
| - if (pref_value->GetAsBoolean(&enabled) && enabled) {
|
| - device_providers.push_back(new UsbDeviceProvider(profile_));
|
| - }
|
| -
|
| - device_manager_->SetDeviceProviders(device_providers);
|
| - if (NeedsDeviceListPolling()) {
|
| - StopDeviceListPolling();
|
| - StartDeviceListPolling();
|
| - }
|
| -}
|
| -
|
| -void DevToolsAndroidBridge::set_tcp_provider_callback_for_test(
|
| - TCPProviderCallback callback) {
|
| - tcp_provider_callback_ = callback;
|
| - CreateDeviceProviders();
|
| +void DevToolsDeviceDiscovery::DiscoverOnce(
|
| + AndroidDeviceManager* device_manager,
|
| + const DeviceListCallback& callback) {
|
| + new OnceWrapper(device_manager, callback);
|
| }
|
|
|