Index: chrome/browser/devtools/devtools_adb_bridge.cc |
diff --git a/chrome/browser/devtools/devtools_adb_bridge.cc b/chrome/browser/devtools/devtools_adb_bridge.cc |
index bece183cd1200404402eb749336f1a818c6fda64..2f4219debd64f88eaff6eea44075525159ce3f31 100644 |
--- a/chrome/browser/devtools/devtools_adb_bridge.cc |
+++ b/chrome/browser/devtools/devtools_adb_bridge.cc |
@@ -19,14 +19,12 @@ |
#include "base/strings/string_number_conversions.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/adb/android_rsa.h" |
#include "chrome/browser/devtools/adb_client_socket.h" |
#include "chrome/browser/devtools/adb_web_socket.h" |
#include "chrome/browser/devtools/devtools_protocol.h" |
-#include "chrome/browser/devtools/devtools_target_impl.h" |
#include "chrome/browser/devtools/devtools_window.h" |
#include "chrome/browser/profiles/profile.h" |
#include "components/browser_context_keyed_service/browser_context_dependency_manager.h" |
@@ -36,7 +34,6 @@ |
#include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
#include "content/public/browser/devtools_manager.h" |
#include "crypto/rsa_private_key.h" |
-#include "net/base/escape.h" |
#include "net/base/net_errors.h" |
using content::BrowserThread; |
@@ -55,7 +52,6 @@ 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"; |
const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n"; |
const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n"; |
-const char kNewPageRequestWithURL[] = "GET /json/new?%s HTTP/1.1\r\n\r\n"; |
const char kActivatePageRequest[] = |
"GET /json/activate/%s HTTP/1.1\r\n\r\n"; |
const int kAdbPollingIntervalMs = 1000; |
@@ -64,11 +60,8 @@ const char kUrlParam[] = "url"; |
const char kPageReloadCommand[] = "Page.reload"; |
const char kPageNavigateCommand[] = "Page.navigate"; |
-const char kChromeProductName[] = "Chrome"; |
-const int kMinVersionNewWithURL = 32; |
-const int kNewPageNavigateDelayMs = 500; |
- |
#if defined(DEBUG_DEVTOOLS) |
+const char kChrome[] = "Chrome"; |
const char kLocalChrome[] = "Local Chrome"; |
#endif // defined(DEBUG_DEVTOOLS) |
@@ -187,7 +180,7 @@ void AdbPagesCommand::ProcessSerials() { |
scoped_refptr<DevToolsAdbBridge::RemoteBrowser> remote_browser = |
new DevToolsAdbBridge::RemoteBrowser( |
adb_thread_, device, std::string()); |
- remote_browser->set_product(kChromeProductName); |
+ remote_browser->set_product(kChrome); |
remote_devices_->back()->AddBrowser(remote_browser); |
browsers_.push_back(remote_browser); |
device->HttpQuery( |
@@ -319,8 +312,20 @@ void AdbPagesCommand::ReceivedPages(int result, |
scoped_ptr<base::Value> value(base::JSONReader::Read(response)); |
base::ListValue* list_value; |
- if (value && value->GetAsList(&list_value)) { |
- browser->SetPageDescriptors(*list_value); |
+ if (!value || !value->GetAsList(&list_value)) { |
+ ProcessSockets(); |
+ return; |
+ } |
+ |
+ base::Value* item; |
+ |
+ for (size_t i = 0; i < list_value->GetSize(); ++i) { |
+ list_value->Get(i, &item); |
+ base::DictionaryValue* dict; |
+ if (!item || !item->GetAsDictionary(&dict)) |
+ continue; |
+ browser->AddPage(new DevToolsAdbBridge::RemotePage( |
+ adb_thread_, browser->device(), browser->socket(), *dict)); |
} |
ProcessSockets(); |
} |
@@ -544,24 +549,6 @@ DevToolsAdbBridge::Factory::BuildServiceInstanceFor( |
class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, |
public AdbWebSocket::Delegate { |
public: |
- static void Create(const std::string& id, |
- scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser, |
- const std::string& debug_url, |
- const std::string& frontend_url, |
- Profile* profile) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- AgentHostDelegates::iterator it = |
- g_host_delegates.Get().find(id); |
- if (it != g_host_delegates.Get().end()) { |
- it->second->OpenFrontend(); |
- } else if (!frontend_url.empty()) { |
- new AgentHostDelegate( |
- id, browser->device(), browser->socket(), debug_url, |
- frontend_url, browser->adb_thread()->message_loop(), profile); |
- } |
- } |
- |
- private: |
AgentHostDelegate( |
const std::string& id, |
scoped_refptr<AndroidDevice> device, |
@@ -571,6 +558,7 @@ class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, |
base::MessageLoop* adb_message_loop, |
Profile* profile) |
: id_(id), |
+ serial_(device->serial()), |
frontend_url_(frontend_url), |
adb_message_loop_(adb_message_loop), |
profile_(profile) { |
@@ -586,6 +574,7 @@ class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, |
profile_, frontend_url_, proxy_->GetAgentHost().get()); |
} |
+ private: |
virtual ~AgentHostDelegate() { |
g_host_delegates.Get().erase(id_); |
} |
@@ -620,6 +609,7 @@ class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, |
} |
const std::string id_; |
+ const std::string serial_; |
const std::string frontend_url_; |
base::MessageLoop* adb_message_loop_; |
Profile* profile_; |
@@ -629,48 +619,22 @@ class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, |
DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); |
}; |
-//// RemotePageTarget ---------------------------------------------- |
- |
-class RemotePageTarget : public DevToolsTargetImpl { |
- public: |
- RemotePageTarget(scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser, |
- const base::DictionaryValue& value); |
- virtual ~RemotePageTarget(); |
- |
- // content::DevToolsTarget overrides: |
- virtual bool IsAttached() const OVERRIDE; |
- virtual bool Activate() const OVERRIDE; |
- virtual bool Close() const OVERRIDE; |
- |
- // DevToolsTargetImpl overrides: |
- virtual void Inspect(Profile* profile) const OVERRIDE; |
- virtual void Reload() const OVERRIDE; |
- void Navigate(const std::string& url) const; |
+// DevToolsAdbBridge::RemotePage ---------------------------------------------- |
- private: |
- scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser_; |
- std::string debug_url_; |
- std::string frontend_url_; |
- std::string agent_id_; |
- DISALLOW_COPY_AND_ASSIGN(RemotePageTarget); |
-}; |
- |
-RemotePageTarget::RemotePageTarget( |
- scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser, |
+DevToolsAdbBridge::RemotePage::RemotePage( |
+ scoped_refptr<RefCountedAdbThread> adb_thread, |
+ scoped_refptr<AndroidDevice> device, |
+ const std::string& socket, |
const base::DictionaryValue& value) |
- : browser_(browser) { |
- type_ = "adb_page"; |
+ : adb_thread_(adb_thread), |
+ device_(device), |
+ socket_(socket) { |
value.GetString("id", &id_); |
- std::string url; |
- value.GetString("url", &url); |
- url_ = GURL(url); |
+ value.GetString("url", &url_); |
value.GetString("title", &title_); |
- title_ = UTF16ToUTF8(net::UnescapeForHTML(UTF8ToUTF16(title_))); |
value.GetString("description", &description_); |
- std::string favicon_url; |
- value.GetString("faviconUrl", &favicon_url); |
- favicon_url_ = GURL(favicon_url); |
+ value.GetString("faviconUrl", &favicon_url_); |
value.GetString("webSocketDebuggerUrl", &debug_url_); |
value.GetString("devtoolsFrontendUrl", &frontend_url_); |
@@ -694,154 +658,108 @@ RemotePageTarget::RemotePageTarget( |
frontend_url_ = "https:" + frontend_url_.substr(5); |
agent_id_ = base::StringPrintf("%s:%s:%s", |
- browser_->device()->serial().c_str(), |
- browser_->socket().c_str(), |
- id_.c_str()); |
+ device_->serial().c_str(), socket_.c_str(), id_.c_str()); |
} |
-RemotePageTarget::~RemotePageTarget() { |
+bool DevToolsAdbBridge::RemotePage::HasDevToolsWindow() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ return g_host_delegates.Get().find(agent_id_) != g_host_delegates.Get().end(); |
} |
-bool RemotePageTarget::IsAttached() const { |
- return debug_url_.empty(); |
+void DevToolsAdbBridge::RemotePage::Inspect(Profile* profile) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ RequestActivate( |
+ base::Bind(&RemotePage::InspectOnHandlerThread, this, profile)); |
} |
-void RemotePageTarget::Inspect(Profile* profile) const { |
- std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str()); |
- base::Closure inspect_callback = base::Bind(&AgentHostDelegate::Create, |
- id_, browser_, debug_url_, frontend_url_, profile); |
- browser_->SendJsonRequest(request, inspect_callback); |
-} |
+static void Noop(int, const std::string&) {} |
-bool RemotePageTarget::Activate() const { |
- std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str()); |
- browser_->SendJsonRequest(request, base::Closure()); |
- return true; |
+void DevToolsAdbBridge::RemotePage::Activate() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ RequestActivate(base::Bind(&Noop)); |
} |
-bool RemotePageTarget::Close() const { |
- if (IsAttached()) |
- return false; |
+void DevToolsAdbBridge::RemotePage::Close() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (attached()) |
+ return; |
std::string request = base::StringPrintf(kClosePageRequest, id_.c_str()); |
- browser_->SendJsonRequest(request, base::Closure()); |
- return true; |
+ adb_thread_->message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&AndroidDevice::HttpQuery, |
+ device_, socket_, request, base::Bind(&Noop))); |
} |
-void RemotePageTarget::Reload() const { |
- browser_->SendProtocolCommand(debug_url_, kPageReloadCommand, NULL); |
+void DevToolsAdbBridge::RemotePage::Reload() { |
+ SendProtocolCommand(kPageReloadCommand, NULL); |
} |
-void RemotePageTarget::Navigate(const std::string& url) const { |
- base::DictionaryValue params; |
- params.SetString(kUrlParam, url); |
- browser_->SendProtocolCommand(debug_url_, kPageNavigateCommand, ¶ms); |
+void DevToolsAdbBridge::RemotePage::SendProtocolCommand( |
+ const std::string& method, |
+ base::DictionaryValue* params) { |
+ if (attached()) |
+ return; |
+ DevToolsProtocol::Command command(1, method, params); |
+ new AdbProtocolCommand( |
+ adb_thread_, device_, socket_, debug_url_, command.Serialize()); |
} |
-// DevToolsAdbBridge::RemoteBrowser ------------------------------------------- |
- |
-DevToolsAdbBridge::RemoteBrowser::RemoteBrowser( |
- scoped_refptr<RefCountedAdbThread> adb_thread, |
- scoped_refptr<AndroidDevice> device, |
- const std::string& socket) |
- : adb_thread_(adb_thread), |
- device_(device), |
- socket_(socket) { |
+DevToolsAdbBridge::RemotePage::~RemotePage() { |
} |
-bool DevToolsAdbBridge::RemoteBrowser::IsChrome() const { |
- return product_.find(kChromeProductName) == 0; |
+void DevToolsAdbBridge::RemotePage::RequestActivate( |
+ const AndroidDevice::CommandCallback& callback) { |
+ std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str()); |
+ adb_thread_->message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&AndroidDevice::HttpQuery, |
+ device_, socket_, request, callback)); |
} |
-DevToolsAdbBridge::RemoteBrowser::ParsedVersion |
-DevToolsAdbBridge::RemoteBrowser::GetParsedVersion() const { |
- ParsedVersion result; |
- std::vector<std::string> parts; |
- Tokenize(version_, ".", &parts); |
- for (size_t i = 0; i != parts.size(); ++i) { |
- int value = 0; |
- base::StringToInt(parts[i], &value); |
- result.push_back(value); |
- } |
- return result; |
+void DevToolsAdbBridge::RemotePage::InspectOnHandlerThread( |
+ Profile* profile, int result, const std::string& response) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&RemotePage::InspectOnUIThread, this, profile)); |
} |
-std::vector<DevToolsTargetImpl*> |
-DevToolsAdbBridge::RemoteBrowser::CreatePageTargets() { |
- std::vector<DevToolsTargetImpl*> result; |
- for (size_t i = 0; i < page_descriptors_->GetSize(); ++i) { |
- base::Value* item; |
- page_descriptors_->Get(i, &item); |
- if (!item) |
- continue; |
- base::DictionaryValue* dict; |
- if (!item->GetAsDictionary(&dict)) |
- continue; |
- result.push_back(new RemotePageTarget(this, *dict)); |
+void DevToolsAdbBridge::RemotePage::InspectOnUIThread(Profile* profile) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ AgentHostDelegates::iterator it = |
+ g_host_delegates.Get().find(agent_id_); |
+ if (it != g_host_delegates.Get().end()) { |
+ it->second->OpenFrontend(); |
+ } else if (!attached()) { |
+ new AgentHostDelegate( |
+ agent_id_, device_, socket_, debug_url_, |
+ frontend_url_, adb_thread_->message_loop(), profile); |
} |
- return result; |
} |
-void DevToolsAdbBridge::RemoteBrowser::SetPageDescriptors( |
- const base::ListValue& list) { |
- page_descriptors_.reset(list.DeepCopy()); |
-} |
- |
-static void RespondOnUIThread(base::Closure callback, int, const std::string&) { |
- if (!callback.is_null()) |
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback); |
-} |
-void DevToolsAdbBridge::RemoteBrowser::SendJsonRequest( |
- const std::string& request, base::Closure callback) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- adb_thread_->message_loop()->PostTask(FROM_HERE, |
- base::Bind(&AndroidDevice::HttpQuery, device_, socket_, request, |
- base::Bind(&RespondOnUIThread, callback))); |
-} |
+// DevToolsAdbBridge::RemoteBrowser ------------------------------------------- |
-void DevToolsAdbBridge::RemoteBrowser::SendProtocolCommand( |
- const std::string& debug_url, |
- const std::string& method, |
- base::DictionaryValue* params) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- if (debug_url.empty()) |
- return; |
- DevToolsProtocol::Command command(1, method, params); |
- new AdbProtocolCommand( |
- adb_thread_, device_, socket_, debug_url, command.Serialize()); |
+DevToolsAdbBridge::RemoteBrowser::RemoteBrowser( |
+ scoped_refptr<RefCountedAdbThread> adb_thread, |
+ scoped_refptr<AndroidDevice> device, |
+ const std::string& socket) |
+ : adb_thread_(adb_thread), |
+ device_(device), |
+ socket_(socket) { |
} |
-static void NoOp(int, const std::string&) {} |
- |
void DevToolsAdbBridge::RemoteBrowser::Open(const std::string& url) { |
- ParsedVersion parsed_version = GetParsedVersion(); |
- if (IsChrome() && |
- !parsed_version.empty() && |
- parsed_version[0] >= kMinVersionNewWithURL) { |
- std::string query = net::EscapeQueryParamValue(url, false /* use_plus */); |
- std::string request = |
- base::StringPrintf(kNewPageRequestWithURL, query.c_str()); |
- adb_thread_->message_loop()->PostTask(FROM_HERE, |
- base::Bind(&AndroidDevice::HttpQuery, |
- device_, socket_, request, base::Bind(&NoOp))); |
- } else { |
- adb_thread_->message_loop()->PostTask(FROM_HERE, |
- base::Bind(&AndroidDevice::HttpQuery, |
- device_, socket_, kNewPageRequest, |
- base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url))); |
- } |
+ adb_thread_->message_loop()->PostTask(FROM_HERE, |
+ base::Bind(&AndroidDevice::HttpQuery, |
+ device_, socket_, kNewPageRequest, |
+ base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url))); |
} |
void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnHandlerThread( |
const std::string& url, int result, const std::string& response) { |
if (result < 0) |
return; |
- // Navigating too soon after the page creation breaks navigation history |
- // (crbug.com/311014). This can be avoided by adding a moderate delay. |
- BrowserThread::PostDelayedTask( |
+ BrowserThread::PostTask( |
BrowserThread::UI, FROM_HERE, |
- base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, response, url), |
- base::TimeDelta::FromMilliseconds(kNewPageNavigateDelayMs)); |
+ base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, response, url)); |
} |
void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread( |
@@ -849,8 +767,11 @@ void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread( |
scoped_ptr<base::Value> value(base::JSONReader::Read(response)); |
base::DictionaryValue* dict; |
if (value && value->GetAsDictionary(&dict)) { |
- RemotePageTarget new_page(this, *dict); |
- new_page.Navigate(url); |
+ scoped_refptr<RemotePage> new_page = |
+ new RemotePage(adb_thread_, device_, socket_, *dict); |
+ base::DictionaryValue params; |
+ params.SetString(kUrlParam, url); |
+ new_page->SendProtocolCommand(kPageNavigateCommand, ¶ms); |
} |
} |
@@ -908,11 +829,6 @@ void DevToolsAdbBridge::RemoveListener(Listener* listener) { |
listeners_.erase(it); |
} |
-bool DevToolsAdbBridge::HasDevToolsWindow(const std::string& agent_id) { |
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
- return g_host_delegates.Get().find(agent_id) != g_host_delegates.Get().end(); |
-} |
- |
DevToolsAdbBridge::~DevToolsAdbBridge() { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
DCHECK(listeners_.empty()); |