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

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

Issue 22277007: chrome://inspect: Add "open", "close" and "reload" actions to Devices tab (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View 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/json/json_writer.h"
15 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
16 #include "base/logging.h" 17 #include "base/logging.h"
17 #include "base/memory/singleton.h" 18 #include "base/memory/singleton.h"
18 #include "base/message_loop/message_loop.h" 19 #include "base/message_loop/message_loop.h"
19 #include "base/strings/string_number_conversions.h" 20 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
22 #include "base/threading/thread.h" 23 #include "base/threading/thread.h"
23 #include "base/values.h" 24 #include "base/values.h"
24 #include "chrome/browser/devtools/adb/android_rsa.h" 25 #include "chrome/browser/devtools/adb/android_rsa.h"
(...skipping 19 matching lines...) Expand all
44 static const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; 45 static const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread";
45 static const char kHostDevicesCommand[] = "host:devices"; 46 static const char kHostDevicesCommand[] = "host:devices";
46 static const char kHostTransportCommand[] = "host:transport:%s|%s"; 47 static const char kHostTransportCommand[] = "host:transport:%s|%s";
47 static const char kLocalAbstractCommand[] = "localabstract:%s"; 48 static const char kLocalAbstractCommand[] = "localabstract:%s";
48 static const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; 49 static const char kDeviceModelCommand[] = "shell:getprop ro.product.model";
49 static const char kUnknownModel[] = "Unknown"; 50 static const char kUnknownModel[] = "Unknown";
50 static const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; 51 static const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix";
51 52
52 static const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; 53 static const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n";
53 static const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; 54 static const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n";
55 static const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n";
56 static const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n";
54 const int kAdbPort = 5037; 57 const int kAdbPort = 5037;
55 const int kBufferSize = 16 * 1024; 58 const int kBufferSize = 16 * 1024;
56 const int kAdbPollingIntervalMs = 1000; 59 const int kAdbPollingIntervalMs = 1000;
57 60
58 typedef DevToolsAdbBridge::Callback Callback; 61 typedef DevToolsAdbBridge::Callback Callback;
59 typedef std::vector<scoped_refptr<DevToolsAdbBridge::AndroidDevice> > 62 typedef std::vector<scoped_refptr<DevToolsAdbBridge::AndroidDevice> >
60 AndroidDevices; 63 AndroidDevices;
61 typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback; 64 typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback;
62 65
63 class AdbDeviceImpl : public DevToolsAdbBridge::AndroidDevice { 66 class AdbDeviceImpl : public DevToolsAdbBridge::AndroidDevice {
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 } 380 }
378 381
379 scoped_refptr<DevToolsAdbBridge> bridge_; 382 scoped_refptr<DevToolsAdbBridge> bridge_;
380 Callback callback_; 383 Callback callback_;
381 AndroidDevices devices_; 384 AndroidDevices devices_;
382 std::vector<std::string> sockets_; 385 std::vector<std::string> sockets_;
383 std::map<std::string, std::string> socket_to_package_; 386 std::map<std::string, std::string> socket_to_package_;
384 scoped_ptr<DevToolsAdbBridge::RemoteDevices> remote_devices_; 387 scoped_ptr<DevToolsAdbBridge::RemoteDevices> remote_devices_;
385 }; 388 };
386 389
390 class AdbRemotePageCommand : public base::RefCountedThreadSafe<
pfeldman 2013/08/06 13:33:34 Wat?
Vladislav Kaznacheev 2013/08/07 09:35:12 Replaced with a bind On 2013/08/06 13:33:34, pfeld
391 AdbRemotePageCommand,
392 content::BrowserThread::DeleteOnUIThread> {
393 public:
394 AdbRemotePageCommand(scoped_refptr<DevToolsAdbBridge::AndroidDevice> device,
395 const std::string& socket,
396 const std::string& command,
397 const CommandCallback& callback)
398 : device_(device),
399 socket_(socket),
400 command_(command),
401 callback_(callback) {
402 }
403
404 void Run() {
405 device_->HttpQuery(socket_, command_, callback_);
406 }
407
408 private:
409 friend struct content::BrowserThread::DeleteOnThread<
410 content::BrowserThread::UI>;
411 friend class base::DeleteHelper<AdbRemotePageCommand>;
412
413 virtual ~AdbRemotePageCommand() {}
414
415 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device_;
416 const std::string socket_;
417 const std::string command_;
418 CommandCallback callback_;
419 };
420
421 class DebuggerCommand : public AdbWebSocket::Delegate {
pfeldman 2013/08/06 13:33:34 Lets split this into declaration and definition wi
Vladislav Kaznacheev 2013/08/07 09:35:12 Done.
422 public:
423 DebuggerCommand(
424 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device,
425 const std::string& socket_name,
426 const std::string& debug_url,
427 base::MessageLoop* adb_message_loop,
428 const std::string& command)
429 : command_(command) {
430 web_socket_ = new AdbWebSocket(
431 device, socket_name, debug_url, adb_message_loop, this);
432 }
433
434 private:
435 virtual ~DebuggerCommand() {}
436
437 virtual void OnSocketOpened() OVERRIDE {
438 web_socket_->SendFrame(command_);
439 web_socket_->Disconnect();
440 }
441
442 virtual void OnFrameRead(const std::string& message) OVERRIDE {}
443
444 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE {
445 delete this;
pfeldman 2013/08/06 13:33:34 This object leaks when message loop closes.
Vladislav Kaznacheev 2013/08/07 09:35:12 Retaining DevToolsAdbBridge instance now to make s
446 }
447
448 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE {
449 return false;
450 }
451
452 const std::string command_;
453 scoped_refptr<AdbWebSocket> web_socket_;
454
455 DISALLOW_COPY_AND_ASSIGN(DebuggerCommand);
456 };
457
387 } // namespace 458 } // namespace
388 459
389 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; 460 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote";
390 461
391 class AgentHostDelegate; 462 class AgentHostDelegate;
392 463
393 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates; 464 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates;
394 465
395 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates = 466 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates =
396 LAZY_INSTANCE_INITIALIZER; 467 LAZY_INSTANCE_INITIALIZER;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 g_host_delegates.Get()[id] = this; 572 g_host_delegates.Get()[id] = this;
502 } 573 }
503 574
504 void OpenFrontend() { 575 void OpenFrontend() {
505 if (!proxy_) 576 if (!proxy_)
506 return; 577 return;
507 DevToolsWindow::OpenExternalFrontend( 578 DevToolsWindow::OpenExternalFrontend(
508 profile_, frontend_url_, proxy_->GetAgentHost().get()); 579 profile_, frontend_url_, proxy_->GetAgentHost().get());
509 } 580 }
510 581
582 void SendCommand(const std::string& command) {
583 SendMessageToBackend(command);
584 }
585
511 private: 586 private:
512 virtual ~AgentHostDelegate() { 587 virtual ~AgentHostDelegate() {
513 g_host_delegates.Get().erase(id_); 588 g_host_delegates.Get().erase(id_);
514 } 589 }
515 590
516 virtual void Attach() OVERRIDE {} 591 virtual void Attach() OVERRIDE {}
517 592
518 virtual void Detach() OVERRIDE { 593 virtual void Detach() OVERRIDE {
519 web_socket_->Disconnect(); 594 web_socket_->Disconnect();
520 } 595 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 else 653 else
579 debug_url_ = ""; 654 debug_url_ = "";
580 655
581 size_t ws_param = frontend_url_.find("?ws"); 656 size_t ws_param = frontend_url_.find("?ws");
582 if (ws_param != std::string::npos) 657 if (ws_param != std::string::npos)
583 frontend_url_ = frontend_url_.substr(0, ws_param); 658 frontend_url_ = frontend_url_.substr(0, ws_param);
584 if (frontend_url_.find("http:") == 0) 659 if (frontend_url_.find("http:") == 0)
585 frontend_url_ = "https:" + frontend_url_.substr(5); 660 frontend_url_ = "https:" + frontend_url_.substr(5);
586 661
587 global_id_ = base::StringPrintf( 662 global_id_ = base::StringPrintf(
588 "%s:%s:%s", device->serial().c_str(), socket_.c_str(), id_.c_str()); 663 "page:%s:%s:%s", device->serial().c_str(), socket_.c_str(), id_.c_str());
589 } 664 }
590 665
591 void DevToolsAdbBridge::RemotePage::Inspect(Profile* profile) { 666 void DevToolsAdbBridge::RemotePage::Inspect(Profile* profile) {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
593 AgentHostDelegates::iterator it = 668 AgentHostDelegates::iterator it =
594 g_host_delegates.Get().find(global_id()); 669 g_host_delegates.Get().find(global_id());
595 if (it != g_host_delegates.Get().end()) 670 if (it != g_host_delegates.Get().end())
596 it->second->OpenFrontend(); 671 it->second->OpenFrontend();
597 else if (!debug_url_.empty()) 672 else if (!debug_url_.empty())
598 new AgentHostDelegate( 673 new AgentHostDelegate(
599 global_id_, device_, socket_, debug_url_, 674 global_id_, device_, socket_, debug_url_,
600 frontend_url_, bridge_->GetAdbMessageLoop(), profile); 675 frontend_url_, bridge_->GetAdbMessageLoop(), profile);
601 } 676 }
602 677
678 static void Noop(int, const std::string&) {}
679
680 void DevToolsAdbBridge::RemotePage::Close() {
681 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
682 std::string request = base::StringPrintf(kClosePageRequest, id_.c_str());
683 scoped_refptr<AdbRemotePageCommand> close =
684 new AdbRemotePageCommand(device_, socket_, request, base::Bind(&Noop));
685 bridge_->GetAdbMessageLoop()->PostTask(FROM_HERE,
686 base::Bind(&AdbRemotePageCommand::Run, close));
687 }
688
689 void DevToolsAdbBridge::RemotePage::Reload() {
690 SendDebuggerCommand("Page.reload", NULL);
691 }
692
693 static const char kIdAttribute[] = "id";
694 static const char kMethodAttribute[] = "method";
695 static const char kParamsAttribute[] = "params";
696
697 void DevToolsAdbBridge::RemotePage::SendDebuggerCommand(
698 const std::string& method,
699 const base::DictionaryValue* params) {
700 base::DictionaryValue command;
701 command.SetInteger(kIdAttribute, -1);
702 command.SetString(kMethodAttribute, method);
703 if (params)
704 command.Set(kParamsAttribute, params->DeepCopy());
705 std::string json_command;
706 base::JSONWriter::Write(&command, &json_command);
707
708 AgentHostDelegates::iterator it =
709 g_host_delegates.Get().find(global_id());
710 if (it != g_host_delegates.Get().end())
pfeldman 2013/08/06 13:33:34 Please don't
Vladislav Kaznacheev 2013/08/07 09:35:12 Doing no longer.
711 it->second->SendCommand(json_command);
712 else if (!debug_url_.empty())
713 new DebuggerCommand(device_, socket_, debug_url_,
714 bridge_->GetAdbMessageLoop(), json_command);
715 }
716
603 DevToolsAdbBridge::RemotePage::~RemotePage() { 717 DevToolsAdbBridge::RemotePage::~RemotePage() {
604 } 718 }
605 719
606 DevToolsAdbBridge::RemoteBrowser::RemoteBrowser( 720 DevToolsAdbBridge::RemoteBrowser::RemoteBrowser(
607 scoped_refptr<DevToolsAdbBridge> bridge, 721 scoped_refptr<DevToolsAdbBridge> bridge,
608 scoped_refptr<AndroidDevice> device, 722 scoped_refptr<AndroidDevice> device,
609 const std::string& socket, 723 const std::string& socket,
610 const std::string& name) 724 const std::string& name)
611 : bridge_(bridge), 725 : bridge_(bridge),
612 device_(device), 726 device_(device),
613 socket_(socket), 727 socket_(socket),
614 name_(name) { 728 name_(name) {
729 global_id_ = base::StringPrintf(
730 "browser:%s:%s", device_->serial().c_str(), socket_.c_str());
731 }
732
733 void DevToolsAdbBridge::RemoteBrowser::Open(const std::string& url) {
734 scoped_refptr<AdbRemotePageCommand> command =
735 new AdbRemotePageCommand(
pfeldman 2013/08/06 13:33:34 JsonCommand ProtocolCommand
Vladislav Kaznacheev 2013/08/07 09:35:12 Done.
736 device_, socket_, kNewPageRequest,
737 base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url));
738 bridge_->GetAdbMessageLoop()->PostTask(FROM_HERE,
739 base::Bind(&AdbRemotePageCommand::Run, command));
740 }
741
742 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnHandlerThread(
743 const std::string& url, int result, const std::string& response) {
744 if (result < 0)
745 return;
746 std::string body = response.substr(result);
pfeldman 2013/08/06 13:33:34 This is insane! Lets factor it out first plz. I kn
Vladislav Kaznacheev 2013/08/07 09:35:12 see https://chromiumcodereview.appspot.com/2242900
747 BrowserThread::PostTask(
748 BrowserThread::UI, FROM_HERE,
749 base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, body, url));
750 }
751
752 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread(
753 const std::string& response, const std::string& url) {
754 scoped_ptr<base::Value> value(base::JSONReader::Read(response));
755 base::DictionaryValue* dict;
756 if (value && value->GetAsDictionary(&dict)) {
757 scoped_refptr<RemotePage> new_page =
758 new RemotePage(bridge_, device_, socket_, *dict);
759 base::DictionaryValue params;
760 params.SetString("url", url);
761 new_page->SendDebuggerCommand("Page.navigate", &params);
762 }
615 } 763 }
616 764
617 DevToolsAdbBridge::RemoteBrowser::~RemoteBrowser() { 765 DevToolsAdbBridge::RemoteBrowser::~RemoteBrowser() {
618 } 766 }
619 767
620 DevToolsAdbBridge::RemoteDevice::RemoteDevice( 768 DevToolsAdbBridge::RemoteDevice::RemoteDevice(
621 scoped_refptr<DevToolsAdbBridge> bridge, 769 scoped_refptr<DevToolsAdbBridge> bridge,
622 scoped_refptr<AndroidDevice> device) 770 scoped_refptr<AndroidDevice> device)
623 : bridge_(bridge), 771 : bridge_(bridge),
624 device_(device) { 772 device_(device) {
773 global_id_ = base::StringPrintf("device:%s", device_->serial().c_str());
625 } 774 }
626 775
627 DevToolsAdbBridge::RemoteDevice::~RemoteDevice() { 776 DevToolsAdbBridge::RemoteDevice::~RemoteDevice() {
628 } 777 }
629 778
630 779
631 DevToolsAdbBridge::RefCountedAdbThread* 780 DevToolsAdbBridge::RefCountedAdbThread*
632 DevToolsAdbBridge::RefCountedAdbThread::instance_ = NULL; 781 DevToolsAdbBridge::RefCountedAdbThread::instance_ = NULL;
633 782
634 // static 783 // static
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 932
784 if (listeners_.empty()) 933 if (listeners_.empty())
785 return; 934 return;
786 935
787 BrowserThread::PostDelayedTask( 936 BrowserThread::PostDelayedTask(
788 BrowserThread::UI, 937 BrowserThread::UI,
789 FROM_HERE, 938 FROM_HERE,
790 base::Bind(&DevToolsAdbBridge::RequestRemoteDevices, this), 939 base::Bind(&DevToolsAdbBridge::RequestRemoteDevices, this),
791 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); 940 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs));
792 } 941 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/devtools_adb_bridge.h ('k') | chrome/browser/resources/inspect/inspect.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698