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

Side by Side Diff: chrome/browser/devtools/devtools_adb_bridge.cc

Issue 46523002: Fix Telemetry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/devtools/devtools_adb_bridge.h" 5 #include "chrome/browser/devtools/devtools_adb_bridge.h"
6 6
7 #include <map> 7 #include <map>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 13 #include "base/compiler_specific.h"
14 #include "base/json/json_reader.h" 14 #include "base/json/json_reader.h"
15 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/memory/singleton.h" 17 #include "base/memory/singleton.h"
18 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
19 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/threading/thread.h" 22 #include "base/threading/thread.h"
24 #include "base/values.h" 23 #include "base/values.h"
25 #include "chrome/browser/devtools/adb/android_rsa.h" 24 #include "chrome/browser/devtools/adb/android_rsa.h"
26 #include "chrome/browser/devtools/adb_client_socket.h" 25 #include "chrome/browser/devtools/adb_client_socket.h"
27 #include "chrome/browser/devtools/adb_web_socket.h" 26 #include "chrome/browser/devtools/adb_web_socket.h"
28 #include "chrome/browser/devtools/devtools_protocol.h" 27 #include "chrome/browser/devtools/devtools_protocol.h"
29 #include "chrome/browser/devtools/devtools_target_impl.h"
30 #include "chrome/browser/devtools/devtools_window.h" 28 #include "chrome/browser/devtools/devtools_window.h"
31 #include "chrome/browser/profiles/profile.h" 29 #include "chrome/browser/profiles/profile.h"
32 #include "components/browser_context_keyed_service/browser_context_dependency_ma nager.h" 30 #include "components/browser_context_keyed_service/browser_context_dependency_ma nager.h"
33 #include "content/public/browser/devtools_agent_host.h" 31 #include "content/public/browser/devtools_agent_host.h"
34 #include "content/public/browser/devtools_client_host.h" 32 #include "content/public/browser/devtools_client_host.h"
35 #include "content/public/browser/devtools_external_agent_proxy.h" 33 #include "content/public/browser/devtools_external_agent_proxy.h"
36 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" 34 #include "content/public/browser/devtools_external_agent_proxy_delegate.h"
37 #include "content/public/browser/devtools_manager.h" 35 #include "content/public/browser/devtools_manager.h"
38 #include "crypto/rsa_private_key.h" 36 #include "crypto/rsa_private_key.h"
39 #include "net/base/escape.h"
40 #include "net/base/net_errors.h" 37 #include "net/base/net_errors.h"
41 38
42 using content::BrowserThread; 39 using content::BrowserThread;
43 40
44 namespace { 41 namespace {
45 42
46 const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; 43 const char kDeviceModelCommand[] = "shell:getprop ro.product.model";
47 const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; 44 const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix";
48 const char kListProcessesCommand[] = "shell:ps"; 45 const char kListProcessesCommand[] = "shell:ps";
49 const char kDumpsysCommand[] = "shell:dumpsys window policy"; 46 const char kDumpsysCommand[] = "shell:dumpsys window policy";
50 const char kDumpsysScreenSizePrefix[] = "mStable="; 47 const char kDumpsysScreenSizePrefix[] = "mStable=";
51 48
52 const char kUnknownModel[] = "Offline"; 49 const char kUnknownModel[] = "Offline";
53 50
54 const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; 51 const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n";
55 const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; 52 const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n";
56 const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n"; 53 const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n";
57 const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n"; 54 const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n";
58 const char kNewPageRequestWithURL[] = "GET /json/new?%s HTTP/1.1\r\n\r\n";
59 const char kActivatePageRequest[] = 55 const char kActivatePageRequest[] =
60 "GET /json/activate/%s HTTP/1.1\r\n\r\n"; 56 "GET /json/activate/%s HTTP/1.1\r\n\r\n";
61 const int kAdbPollingIntervalMs = 1000; 57 const int kAdbPollingIntervalMs = 1000;
62 58
63 const char kUrlParam[] = "url"; 59 const char kUrlParam[] = "url";
64 const char kPageReloadCommand[] = "Page.reload"; 60 const char kPageReloadCommand[] = "Page.reload";
65 const char kPageNavigateCommand[] = "Page.navigate"; 61 const char kPageNavigateCommand[] = "Page.navigate";
66 62
67 const char kChromeProductName[] = "Chrome";
68 const int kMinVersionNewWithURL = 32;
69 const int kNewPageNavigateDelayMs = 500;
70
71 #if defined(DEBUG_DEVTOOLS) 63 #if defined(DEBUG_DEVTOOLS)
64 const char kChrome[] = "Chrome";
72 const char kLocalChrome[] = "Local Chrome"; 65 const char kLocalChrome[] = "Local Chrome";
73 #endif // defined(DEBUG_DEVTOOLS) 66 #endif // defined(DEBUG_DEVTOOLS)
74 67
75 typedef DevToolsAdbBridge::Callback Callback; 68 typedef DevToolsAdbBridge::Callback Callback;
76 typedef std::vector<scoped_refptr<AndroidDevice> > 69 typedef std::vector<scoped_refptr<AndroidDevice> >
77 AndroidDevices; 70 AndroidDevices;
78 typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback; 71 typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback;
79 72
80 // AdbPagesCommand ------------------------------------------------------------ 73 // AdbPagesCommand ------------------------------------------------------------
81 74
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 // For desktop remote debugging. 173 // For desktop remote debugging.
181 if (devices_.back()->serial().empty()) { 174 if (devices_.back()->serial().empty()) {
182 scoped_refptr<AndroidDevice> device = 175 scoped_refptr<AndroidDevice> device =
183 devices_.back(); 176 devices_.back();
184 device->set_model(kLocalChrome); 177 device->set_model(kLocalChrome);
185 remote_devices_->push_back( 178 remote_devices_->push_back(
186 new DevToolsAdbBridge::RemoteDevice(device)); 179 new DevToolsAdbBridge::RemoteDevice(device));
187 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> remote_browser = 180 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> remote_browser =
188 new DevToolsAdbBridge::RemoteBrowser( 181 new DevToolsAdbBridge::RemoteBrowser(
189 adb_thread_, device, std::string()); 182 adb_thread_, device, std::string());
190 remote_browser->set_product(kChromeProductName); 183 remote_browser->set_product(kChrome);
191 remote_devices_->back()->AddBrowser(remote_browser); 184 remote_devices_->back()->AddBrowser(remote_browser);
192 browsers_.push_back(remote_browser); 185 browsers_.push_back(remote_browser);
193 device->HttpQuery( 186 device->HttpQuery(
194 std::string(), kVersionRequest, 187 std::string(), kVersionRequest,
195 base::Bind(&AdbPagesCommand::ReceivedVersion, this)); 188 base::Bind(&AdbPagesCommand::ReceivedVersion, this));
196 return; 189 return;
197 } 190 }
198 #endif // defined(DEBUG_DEVTOOLS) 191 #endif // defined(DEBUG_DEVTOOLS)
199 192
200 scoped_refptr<AndroidDevice> device = devices_.back(); 193 scoped_refptr<AndroidDevice> device = devices_.back();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); 305 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
313 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser = browsers_.back(); 306 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser = browsers_.back();
314 browsers_.pop_back(); 307 browsers_.pop_back();
315 if (result < 0) { 308 if (result < 0) {
316 ProcessSockets(); 309 ProcessSockets();
317 return; 310 return;
318 } 311 }
319 312
320 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); 313 scoped_ptr<base::Value> value(base::JSONReader::Read(response));
321 base::ListValue* list_value; 314 base::ListValue* list_value;
322 if (value && value->GetAsList(&list_value)) { 315 if (!value || !value->GetAsList(&list_value)) {
323 browser->SetPageDescriptors(*list_value); 316 ProcessSockets();
317 return;
318 }
319
320 base::Value* item;
321
322 for (size_t i = 0; i < list_value->GetSize(); ++i) {
323 list_value->Get(i, &item);
324 base::DictionaryValue* dict;
325 if (!item || !item->GetAsDictionary(&dict))
326 continue;
327 browser->AddPage(new DevToolsAdbBridge::RemotePage(
328 adb_thread_, browser->device(), browser->socket(), *dict));
324 } 329 }
325 ProcessSockets(); 330 ProcessSockets();
326 } 331 }
327 332
328 void AdbPagesCommand::Respond() { 333 void AdbPagesCommand::Respond() {
329 callback_.Run(remote_devices_.release()); 334 callback_.Run(remote_devices_.release());
330 } 335 }
331 336
332 void AdbPagesCommand::ParseSocketsList(const std::string& response) { 337 void AdbPagesCommand::ParseSocketsList(const std::string& response) {
333 // On Android, '/proc/net/unix' looks like this: 338 // On Android, '/proc/net/unix' looks like this:
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 content::BrowserContext* context) const { 542 content::BrowserContext* context) const {
538 return new DevToolsAdbBridge::Wrapper(); 543 return new DevToolsAdbBridge::Wrapper();
539 } 544 }
540 545
541 546
542 // AgentHostDelegate ---------------------------------------------------------- 547 // AgentHostDelegate ----------------------------------------------------------
543 548
544 class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, 549 class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate,
545 public AdbWebSocket::Delegate { 550 public AdbWebSocket::Delegate {
546 public: 551 public:
547 static void Create(const std::string& id,
548 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser,
549 const std::string& debug_url,
550 const std::string& frontend_url,
551 Profile* profile) {
552 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
553 AgentHostDelegates::iterator it =
554 g_host_delegates.Get().find(id);
555 if (it != g_host_delegates.Get().end()) {
556 it->second->OpenFrontend();
557 } else if (!frontend_url.empty()) {
558 new AgentHostDelegate(
559 id, browser->device(), browser->socket(), debug_url,
560 frontend_url, browser->adb_thread()->message_loop(), profile);
561 }
562 }
563
564 private:
565 AgentHostDelegate( 552 AgentHostDelegate(
566 const std::string& id, 553 const std::string& id,
567 scoped_refptr<AndroidDevice> device, 554 scoped_refptr<AndroidDevice> device,
568 const std::string& socket_name, 555 const std::string& socket_name,
569 const std::string& debug_url, 556 const std::string& debug_url,
570 const std::string& frontend_url, 557 const std::string& frontend_url,
571 base::MessageLoop* adb_message_loop, 558 base::MessageLoop* adb_message_loop,
572 Profile* profile) 559 Profile* profile)
573 : id_(id), 560 : id_(id),
561 serial_(device->serial()),
574 frontend_url_(frontend_url), 562 frontend_url_(frontend_url),
575 adb_message_loop_(adb_message_loop), 563 adb_message_loop_(adb_message_loop),
576 profile_(profile) { 564 profile_(profile) {
577 web_socket_ = new AdbWebSocket( 565 web_socket_ = new AdbWebSocket(
578 device, socket_name, debug_url, adb_message_loop, this); 566 device, socket_name, debug_url, adb_message_loop, this);
579 g_host_delegates.Get()[id] = this; 567 g_host_delegates.Get()[id] = this;
580 } 568 }
581 569
582 void OpenFrontend() { 570 void OpenFrontend() {
583 if (!proxy_) 571 if (!proxy_)
584 return; 572 return;
585 DevToolsWindow::OpenExternalFrontend( 573 DevToolsWindow::OpenExternalFrontend(
586 profile_, frontend_url_, proxy_->GetAgentHost().get()); 574 profile_, frontend_url_, proxy_->GetAgentHost().get());
587 } 575 }
588 576
577 private:
589 virtual ~AgentHostDelegate() { 578 virtual ~AgentHostDelegate() {
590 g_host_delegates.Get().erase(id_); 579 g_host_delegates.Get().erase(id_);
591 } 580 }
592 581
593 virtual void Attach() OVERRIDE {} 582 virtual void Attach() OVERRIDE {}
594 583
595 virtual void Detach() OVERRIDE { 584 virtual void Detach() OVERRIDE {
596 web_socket_->Disconnect(); 585 web_socket_->Disconnect();
597 } 586 }
598 587
(...skipping 14 matching lines...) Expand all
613 if (proxy_ && closed_by_device) 602 if (proxy_ && closed_by_device)
614 proxy_->ConnectionClosed(); 603 proxy_->ConnectionClosed();
615 delete this; 604 delete this;
616 } 605 }
617 606
618 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE { 607 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE {
619 return false; 608 return false;
620 } 609 }
621 610
622 const std::string id_; 611 const std::string id_;
612 const std::string serial_;
623 const std::string frontend_url_; 613 const std::string frontend_url_;
624 base::MessageLoop* adb_message_loop_; 614 base::MessageLoop* adb_message_loop_;
625 Profile* profile_; 615 Profile* profile_;
626 616
627 scoped_ptr<content::DevToolsExternalAgentProxy> proxy_; 617 scoped_ptr<content::DevToolsExternalAgentProxy> proxy_;
628 scoped_refptr<AdbWebSocket> web_socket_; 618 scoped_refptr<AdbWebSocket> web_socket_;
629 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); 619 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
630 }; 620 };
631 621
632 //// RemotePageTarget ----------------------------------------------
633 622
634 class RemotePageTarget : public DevToolsTargetImpl { 623 // DevToolsAdbBridge::RemotePage ----------------------------------------------
635 public:
636 RemotePageTarget(scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser,
637 const base::DictionaryValue& value);
638 virtual ~RemotePageTarget();
639 624
640 // content::DevToolsTarget overrides: 625 DevToolsAdbBridge::RemotePage::RemotePage(
641 virtual bool IsAttached() const OVERRIDE; 626 scoped_refptr<RefCountedAdbThread> adb_thread,
642 virtual bool Activate() const OVERRIDE; 627 scoped_refptr<AndroidDevice> device,
643 virtual bool Close() const OVERRIDE; 628 const std::string& socket,
644
645 // DevToolsTargetImpl overrides:
646 virtual void Inspect(Profile* profile) const OVERRIDE;
647 virtual void Reload() const OVERRIDE;
648
649 void Navigate(const std::string& url) const;
650
651 private:
652 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser_;
653 std::string debug_url_;
654 std::string frontend_url_;
655 std::string agent_id_;
656 DISALLOW_COPY_AND_ASSIGN(RemotePageTarget);
657 };
658
659 RemotePageTarget::RemotePageTarget(
660 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser,
661 const base::DictionaryValue& value) 629 const base::DictionaryValue& value)
662 : browser_(browser) { 630 : adb_thread_(adb_thread),
663 type_ = "adb_page"; 631 device_(device),
632 socket_(socket) {
664 value.GetString("id", &id_); 633 value.GetString("id", &id_);
665 std::string url; 634 value.GetString("url", &url_);
666 value.GetString("url", &url);
667 url_ = GURL(url);
668 value.GetString("title", &title_); 635 value.GetString("title", &title_);
669 title_ = UTF16ToUTF8(net::UnescapeForHTML(UTF8ToUTF16(title_)));
670 value.GetString("description", &description_); 636 value.GetString("description", &description_);
671 std::string favicon_url; 637 value.GetString("faviconUrl", &favicon_url_);
672 value.GetString("faviconUrl", &favicon_url);
673 favicon_url_ = GURL(favicon_url);
674 value.GetString("webSocketDebuggerUrl", &debug_url_); 638 value.GetString("webSocketDebuggerUrl", &debug_url_);
675 value.GetString("devtoolsFrontendUrl", &frontend_url_); 639 value.GetString("devtoolsFrontendUrl", &frontend_url_);
676 640
677 if (id_.empty() && !debug_url_.empty()) { 641 if (id_.empty() && !debug_url_.empty()) {
678 // Target id is not available until Chrome 26. Use page id at the end of 642 // Target id is not available until Chrome 26. Use page id at the end of
679 // debug_url_ instead. For attached targets the id will remain empty. 643 // debug_url_ instead. For attached targets the id will remain empty.
680 std::vector<std::string> parts; 644 std::vector<std::string> parts;
681 Tokenize(debug_url_, "/", &parts); 645 Tokenize(debug_url_, "/", &parts);
682 id_ = parts[parts.size()-1]; 646 id_ = parts[parts.size()-1];
683 } 647 }
684 648
685 if (debug_url_.find("ws://") == 0) 649 if (debug_url_.find("ws://") == 0)
686 debug_url_ = debug_url_.substr(5); 650 debug_url_ = debug_url_.substr(5);
687 else 651 else
688 debug_url_ = ""; 652 debug_url_ = "";
689 653
690 size_t ws_param = frontend_url_.find("?ws"); 654 size_t ws_param = frontend_url_.find("?ws");
691 if (ws_param != std::string::npos) 655 if (ws_param != std::string::npos)
692 frontend_url_ = frontend_url_.substr(0, ws_param); 656 frontend_url_ = frontend_url_.substr(0, ws_param);
693 if (frontend_url_.find("http:") == 0) 657 if (frontend_url_.find("http:") == 0)
694 frontend_url_ = "https:" + frontend_url_.substr(5); 658 frontend_url_ = "https:" + frontend_url_.substr(5);
695 659
696 agent_id_ = base::StringPrintf("%s:%s:%s", 660 agent_id_ = base::StringPrintf("%s:%s:%s",
697 browser_->device()->serial().c_str(), 661 device_->serial().c_str(), socket_.c_str(), id_.c_str());
698 browser_->socket().c_str(),
699 id_.c_str());
700 } 662 }
701 663
702 RemotePageTarget::~RemotePageTarget() { 664 bool DevToolsAdbBridge::RemotePage::HasDevToolsWindow() {
665 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
666 return g_host_delegates.Get().find(agent_id_) != g_host_delegates.Get().end();
703 } 667 }
704 668
705 bool RemotePageTarget::IsAttached() const { 669 void DevToolsAdbBridge::RemotePage::Inspect(Profile* profile) {
706 return debug_url_.empty(); 670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
671 RequestActivate(
672 base::Bind(&RemotePage::InspectOnHandlerThread, this, profile));
707 } 673 }
708 674
709 void RemotePageTarget::Inspect(Profile* profile) const { 675 static void Noop(int, const std::string&) {}
710 std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str()); 676
711 base::Closure inspect_callback = base::Bind(&AgentHostDelegate::Create, 677 void DevToolsAdbBridge::RemotePage::Activate() {
712 id_, browser_, debug_url_, frontend_url_, profile); 678 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
713 browser_->SendJsonRequest(request, inspect_callback); 679 RequestActivate(base::Bind(&Noop));
714 } 680 }
715 681
716 bool RemotePageTarget::Activate() const { 682 void DevToolsAdbBridge::RemotePage::Close() {
717 std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str()); 683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
718 browser_->SendJsonRequest(request, base::Closure()); 684 if (attached())
719 return true; 685 return;
686 std::string request = base::StringPrintf(kClosePageRequest, id_.c_str());
687 adb_thread_->message_loop()->PostTask(FROM_HERE,
688 base::Bind(&AndroidDevice::HttpQuery,
689 device_, socket_, request, base::Bind(&Noop)));
720 } 690 }
721 691
722 bool RemotePageTarget::Close() const { 692 void DevToolsAdbBridge::RemotePage::Reload() {
723 if (IsAttached()) 693 SendProtocolCommand(kPageReloadCommand, NULL);
724 return false;
725 std::string request = base::StringPrintf(kClosePageRequest, id_.c_str());
726 browser_->SendJsonRequest(request, base::Closure());
727 return true;
728 } 694 }
729 695
730 void RemotePageTarget::Reload() const { 696 void DevToolsAdbBridge::RemotePage::SendProtocolCommand(
731 browser_->SendProtocolCommand(debug_url_, kPageReloadCommand, NULL); 697 const std::string& method,
698 base::DictionaryValue* params) {
699 if (attached())
700 return;
701 DevToolsProtocol::Command command(1, method, params);
702 new AdbProtocolCommand(
703 adb_thread_, device_, socket_, debug_url_, command.Serialize());
732 } 704 }
733 705
734 void RemotePageTarget::Navigate(const std::string& url) const { 706 DevToolsAdbBridge::RemotePage::~RemotePage() {
735 base::DictionaryValue params;
736 params.SetString(kUrlParam, url);
737 browser_->SendProtocolCommand(debug_url_, kPageNavigateCommand, &params);
738 } 707 }
739 708
709 void DevToolsAdbBridge::RemotePage::RequestActivate(
710 const AndroidDevice::CommandCallback& callback) {
711 std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str());
712 adb_thread_->message_loop()->PostTask(FROM_HERE,
713 base::Bind(&AndroidDevice::HttpQuery,
714 device_, socket_, request, callback));
715 }
716
717 void DevToolsAdbBridge::RemotePage::InspectOnHandlerThread(
718 Profile* profile, int result, const std::string& response) {
719 BrowserThread::PostTask(
720 BrowserThread::UI, FROM_HERE,
721 base::Bind(&RemotePage::InspectOnUIThread, this, profile));
722 }
723
724 void DevToolsAdbBridge::RemotePage::InspectOnUIThread(Profile* profile) {
725 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
726 AgentHostDelegates::iterator it =
727 g_host_delegates.Get().find(agent_id_);
728 if (it != g_host_delegates.Get().end()) {
729 it->second->OpenFrontend();
730 } else if (!attached()) {
731 new AgentHostDelegate(
732 agent_id_, device_, socket_, debug_url_,
733 frontend_url_, adb_thread_->message_loop(), profile);
734 }
735 }
736
737
740 // DevToolsAdbBridge::RemoteBrowser ------------------------------------------- 738 // DevToolsAdbBridge::RemoteBrowser -------------------------------------------
741 739
742 DevToolsAdbBridge::RemoteBrowser::RemoteBrowser( 740 DevToolsAdbBridge::RemoteBrowser::RemoteBrowser(
743 scoped_refptr<RefCountedAdbThread> adb_thread, 741 scoped_refptr<RefCountedAdbThread> adb_thread,
744 scoped_refptr<AndroidDevice> device, 742 scoped_refptr<AndroidDevice> device,
745 const std::string& socket) 743 const std::string& socket)
746 : adb_thread_(adb_thread), 744 : adb_thread_(adb_thread),
747 device_(device), 745 device_(device),
748 socket_(socket) { 746 socket_(socket) {
749 } 747 }
750 748
751 bool DevToolsAdbBridge::RemoteBrowser::IsChrome() const { 749 void DevToolsAdbBridge::RemoteBrowser::Open(const std::string& url) {
752 return product_.find(kChromeProductName) == 0;
753 }
754
755 DevToolsAdbBridge::RemoteBrowser::ParsedVersion
756 DevToolsAdbBridge::RemoteBrowser::GetParsedVersion() const {
757 ParsedVersion result;
758 std::vector<std::string> parts;
759 Tokenize(version_, ".", &parts);
760 for (size_t i = 0; i != parts.size(); ++i) {
761 int value = 0;
762 base::StringToInt(parts[i], &value);
763 result.push_back(value);
764 }
765 return result;
766 }
767
768 std::vector<DevToolsTargetImpl*>
769 DevToolsAdbBridge::RemoteBrowser::CreatePageTargets() {
770 std::vector<DevToolsTargetImpl*> result;
771 for (size_t i = 0; i < page_descriptors_->GetSize(); ++i) {
772 base::Value* item;
773 page_descriptors_->Get(i, &item);
774 if (!item)
775 continue;
776 base::DictionaryValue* dict;
777 if (!item->GetAsDictionary(&dict))
778 continue;
779 result.push_back(new RemotePageTarget(this, *dict));
780 }
781 return result;
782 }
783
784 void DevToolsAdbBridge::RemoteBrowser::SetPageDescriptors(
785 const base::ListValue& list) {
786 page_descriptors_.reset(list.DeepCopy());
787 }
788
789 static void RespondOnUIThread(base::Closure callback, int, const std::string&) {
790 if (!callback.is_null())
791 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, callback);
792 }
793
794 void DevToolsAdbBridge::RemoteBrowser::SendJsonRequest(
795 const std::string& request, base::Closure callback) {
796 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
797 adb_thread_->message_loop()->PostTask(FROM_HERE, 750 adb_thread_->message_loop()->PostTask(FROM_HERE,
798 base::Bind(&AndroidDevice::HttpQuery, device_, socket_, request, 751 base::Bind(&AndroidDevice::HttpQuery,
799 base::Bind(&RespondOnUIThread, callback))); 752 device_, socket_, kNewPageRequest,
800 } 753 base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url)));
801
802 void DevToolsAdbBridge::RemoteBrowser::SendProtocolCommand(
803 const std::string& debug_url,
804 const std::string& method,
805 base::DictionaryValue* params) {
806 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
807 if (debug_url.empty())
808 return;
809 DevToolsProtocol::Command command(1, method, params);
810 new AdbProtocolCommand(
811 adb_thread_, device_, socket_, debug_url, command.Serialize());
812 }
813
814 static void NoOp(int, const std::string&) {}
815
816 void DevToolsAdbBridge::RemoteBrowser::Open(const std::string& url) {
817 ParsedVersion parsed_version = GetParsedVersion();
818 if (IsChrome() &&
819 !parsed_version.empty() &&
820 parsed_version[0] >= kMinVersionNewWithURL) {
821 std::string query = net::EscapeQueryParamValue(url, false /* use_plus */);
822 std::string request =
823 base::StringPrintf(kNewPageRequestWithURL, query.c_str());
824 adb_thread_->message_loop()->PostTask(FROM_HERE,
825 base::Bind(&AndroidDevice::HttpQuery,
826 device_, socket_, request, base::Bind(&NoOp)));
827 } else {
828 adb_thread_->message_loop()->PostTask(FROM_HERE,
829 base::Bind(&AndroidDevice::HttpQuery,
830 device_, socket_, kNewPageRequest,
831 base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url)));
832 }
833 } 754 }
834 755
835 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnHandlerThread( 756 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnHandlerThread(
836 const std::string& url, int result, const std::string& response) { 757 const std::string& url, int result, const std::string& response) {
837 if (result < 0) 758 if (result < 0)
838 return; 759 return;
839 // Navigating too soon after the page creation breaks navigation history 760 BrowserThread::PostTask(
840 // (crbug.com/311014). This can be avoided by adding a moderate delay.
841 BrowserThread::PostDelayedTask(
842 BrowserThread::UI, FROM_HERE, 761 BrowserThread::UI, FROM_HERE,
843 base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, response, url), 762 base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, response, url));
844 base::TimeDelta::FromMilliseconds(kNewPageNavigateDelayMs));
845 } 763 }
846 764
847 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread( 765 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread(
848 const std::string& response, const std::string& url) { 766 const std::string& response, const std::string& url) {
849 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); 767 scoped_ptr<base::Value> value(base::JSONReader::Read(response));
850 base::DictionaryValue* dict; 768 base::DictionaryValue* dict;
851 if (value && value->GetAsDictionary(&dict)) { 769 if (value && value->GetAsDictionary(&dict)) {
852 RemotePageTarget new_page(this, *dict); 770 scoped_refptr<RemotePage> new_page =
853 new_page.Navigate(url); 771 new RemotePage(adb_thread_, device_, socket_, *dict);
772 base::DictionaryValue params;
773 params.SetString(kUrlParam, url);
774 new_page->SendProtocolCommand(kPageNavigateCommand, &params);
854 } 775 }
855 } 776 }
856 777
857 DevToolsAdbBridge::RemoteBrowser::~RemoteBrowser() { 778 DevToolsAdbBridge::RemoteBrowser::~RemoteBrowser() {
858 } 779 }
859 780
860 781
861 // DevToolsAdbBridge::RemoteDevice -------------------------------------------- 782 // DevToolsAdbBridge::RemoteDevice --------------------------------------------
862 783
863 DevToolsAdbBridge::RemoteDevice::RemoteDevice( 784 DevToolsAdbBridge::RemoteDevice::RemoteDevice(
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 } 822 }
902 823
903 void DevToolsAdbBridge::RemoveListener(Listener* listener) { 824 void DevToolsAdbBridge::RemoveListener(Listener* listener) {
904 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 825 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
905 Listeners::iterator it = 826 Listeners::iterator it =
906 std::find(listeners_.begin(), listeners_.end(), listener); 827 std::find(listeners_.begin(), listeners_.end(), listener);
907 DCHECK(it != listeners_.end()); 828 DCHECK(it != listeners_.end());
908 listeners_.erase(it); 829 listeners_.erase(it);
909 } 830 }
910 831
911 bool DevToolsAdbBridge::HasDevToolsWindow(const std::string& agent_id) {
912 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
913 return g_host_delegates.Get().find(agent_id) != g_host_delegates.Get().end();
914 }
915
916 DevToolsAdbBridge::~DevToolsAdbBridge() { 832 DevToolsAdbBridge::~DevToolsAdbBridge() {
917 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 833 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
918 DCHECK(listeners_.empty()); 834 DCHECK(listeners_.empty());
919 } 835 }
920 836
921 void DevToolsAdbBridge::RequestRemoteDevices() { 837 void DevToolsAdbBridge::RequestRemoteDevices() {
922 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 838 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
923 if (!has_message_loop_) 839 if (!has_message_loop_)
924 return; 840 return;
925 841
(...skipping 13 matching lines...) Expand all
939 855
940 if (listeners_.empty()) 856 if (listeners_.empty())
941 return; 857 return;
942 858
943 BrowserThread::PostDelayedTask( 859 BrowserThread::PostDelayedTask(
944 BrowserThread::UI, 860 BrowserThread::UI,
945 FROM_HERE, 861 FROM_HERE,
946 base::Bind(&DevToolsAdbBridge::RequestRemoteDevices, this), 862 base::Bind(&DevToolsAdbBridge::RequestRemoteDevices, this),
947 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); 863 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs));
948 } 864 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/devtools_adb_bridge.h ('k') | chrome/browser/devtools/devtools_sanity_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698