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

Side by Side Diff: chrome/browser/devtools/device/devtools_android_bridge.cc

Issue 2431483003: [DevTools] Split device discovery off DevToolsAnrdoidBridge. (Closed)
Patch Set: the bug with invalid weak pointer Created 4 years, 2 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
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/device/devtools_android_bridge.h" 5 #include "chrome/browser/devtools/device/devtools_android_bridge.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <algorithm> 8 #include <algorithm>
9 #include <map> 9 #include <map>
10 #include <set> 10 #include <set>
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 53
54 #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY) 54 #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
55 #include "chrome/browser/devtools/device/cast_device_provider.h" 55 #include "chrome/browser/devtools/device/cast_device_provider.h"
56 #endif 56 #endif
57 57
58 using content::BrowserThread; 58 using content::BrowserThread;
59 using content::DevToolsAgentHost; 59 using content::DevToolsAgentHost;
60 60
61 namespace { 61 namespace {
62 62
63 const char kPageListRequest[] = "/json";
64 const char kVersionRequest[] = "/json/version";
65 const char kClosePageRequest[] = "/json/close/%s";
66 const char kNewPageRequestWithURL[] = "/json/new?%s"; 63 const char kNewPageRequestWithURL[] = "/json/new?%s";
67 const char kActivatePageRequest[] = "/json/activate/%s";
68 const char kBrowserTargetSocket[] = "/devtools/browser";
69 const int kAdbPollingIntervalMs = 1000;
70
71 const char kPageReloadCommand[] = "Page.reload";
72
73 const char kWebViewSocketPrefix[] = "webview_devtools_remote";
74
75 const char kChromeDiscoveryURL[] = "localhost:9222"; 64 const char kChromeDiscoveryURL[] = "localhost:9222";
76 const char kNodeDiscoveryURL[] = "localhost:9229"; 65 const char kNodeDiscoveryURL[] = "localhost:9229";
77 66
78 bool BrowserIdFromString(const std::string& browser_id_str, 67 bool BrowserIdFromString(const std::string& browser_id_str,
79 std::string* serial, 68 std::string* serial,
80 std::string* browser_id) { 69 std::string* browser_id) {
81 size_t colon_pos = browser_id_str.find(':'); 70 size_t colon_pos = browser_id_str.find(':');
82 if (colon_pos == std::string::npos) 71 if (colon_pos == std::string::npos)
83 return false; 72 return false;
84 *serial = browser_id_str.substr(0, colon_pos); 73 *serial = browser_id_str.substr(0, colon_pos);
85 *browser_id = browser_id_str.substr(colon_pos + 1); 74 *browser_id = browser_id_str.substr(colon_pos + 1);
86 return true; 75 return true;
87 } 76 }
88 77
89 static void NoOp(int, const std::string&) {} 78 static void NoOp(int, const std::string&) {}
90 79
91 } // namespace 80 } // namespace
92 81
93 // DiscoveryRequest -----------------------------------------------------
94
95 class DevToolsAndroidBridge::DiscoveryRequest
96 : public base::RefCountedThreadSafe<DiscoveryRequest,
97 BrowserThread::DeleteOnUIThread> {
98 public:
99 DiscoveryRequest(AndroidDeviceManager* device_manager,
100 const DeviceListCallback& callback);
101 private:
102 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
103 friend class base::DeleteHelper<DiscoveryRequest>;
104 virtual ~DiscoveryRequest();
105
106 void ReceivedDevices(const AndroidDeviceManager::Devices& devices);
107 void ReceivedDeviceInfo(scoped_refptr<AndroidDeviceManager::Device> device,
108 const AndroidDeviceManager::DeviceInfo& device_info);
109 void ReceivedVersion(scoped_refptr<RemoteBrowser>,
110 int result,
111 const std::string& response);
112 void ReceivedPages(scoped_refptr<AndroidDeviceManager::Device> device,
113 scoped_refptr<RemoteBrowser>,
114 int result,
115 const std::string& response);
116
117 DeviceListCallback callback_;
118 CompleteDevices complete_devices_;
119 };
120
121 DevToolsAndroidBridge::DiscoveryRequest::DiscoveryRequest(
122 AndroidDeviceManager* device_manager,
123 const DeviceListCallback& callback)
124 : callback_(callback) {
125 DCHECK_CURRENTLY_ON(BrowserThread::UI);
126 device_manager->QueryDevices(
127 base::Bind(&DiscoveryRequest::ReceivedDevices, this));
128 }
129
130 DevToolsAndroidBridge::DiscoveryRequest::~DiscoveryRequest() {
131 DCHECK_CURRENTLY_ON(BrowserThread::UI);
132 callback_.Run(complete_devices_);
133 }
134
135 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedDevices(
136 const AndroidDeviceManager::Devices& devices) {
137 DCHECK_CURRENTLY_ON(BrowserThread::UI);
138 for (const auto& device : devices) {
139 device->QueryDeviceInfo(
140 base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this, device));
141 }
142 }
143
144 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedDeviceInfo(
145 scoped_refptr<AndroidDeviceManager::Device> device,
146 const AndroidDeviceManager::DeviceInfo& device_info) {
147 DCHECK_CURRENTLY_ON(BrowserThread::UI);
148 scoped_refptr<RemoteDevice> remote_device =
149 new RemoteDevice(device->serial(), device_info);
150 complete_devices_.push_back(std::make_pair(device, remote_device));
151 for (RemoteBrowsers::iterator it = remote_device->browsers().begin();
152 it != remote_device->browsers().end(); ++it) {
153 device->SendJsonRequest(
154 (*it)->socket(),
155 kVersionRequest,
156 base::Bind(&DiscoveryRequest::ReceivedVersion, this, *it));
157 device->SendJsonRequest(
158 (*it)->socket(),
159 kPageListRequest,
160 base::Bind(&DiscoveryRequest::ReceivedPages, this, device, *it));
161 }
162 }
163
164 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedVersion(
165 scoped_refptr<RemoteBrowser> browser,
166 int result,
167 const std::string& response) {
168 DCHECK_CURRENTLY_ON(BrowserThread::UI);
169 if (result < 0)
170 return;
171 // Parse version, append to package name if available,
172 std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
173 base::DictionaryValue* dict;
174 if (value && value->GetAsDictionary(&dict)) {
175 std::string browser_name;
176 if (dict->GetString("Browser", &browser_name)) {
177 std::vector<std::string> parts = base::SplitString(
178 browser_name, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
179 if (parts.size() == 2)
180 browser->version_ = parts[1];
181 else
182 browser->version_ = browser_name;
183 }
184 std::string package;
185 if (dict->GetString("Android-Package", &package)) {
186 browser->display_name_ =
187 AndroidDeviceManager::GetBrowserName(browser->socket(), package);
188 }
189 }
190 }
191
192 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedPages(
193 scoped_refptr<AndroidDeviceManager::Device> device,
194 scoped_refptr<RemoteBrowser> browser,
195 int result,
196 const std::string& response) {
197 DCHECK_CURRENTLY_ON(BrowserThread::UI);
198 if (result < 0)
199 return;
200 std::unique_ptr<base::Value> value = base::JSONReader::Read(response);
201 base::ListValue* list_value;
202 if (value && value->GetAsList(&list_value)) {
203 for (const auto& page_value : *list_value) {
204 base::DictionaryValue* dict;
205 if (page_value->GetAsDictionary(&dict))
206 browser->pages_.push_back(
207 new RemotePage(device, browser->browser_id_, *dict));
208 }
209 }
210 }
211
212 // ProtocolCommand ------------------------------------------------------------
213
214 namespace {
215
216 class ProtocolCommand
217 : public AndroidDeviceManager::AndroidWebSocket::Delegate {
218 public:
219 ProtocolCommand(
220 scoped_refptr<AndroidDeviceManager::Device> device,
221 const std::string& socket,
222 const std::string& target_path,
223 const std::string& command,
224 const base::Closure callback);
225
226 private:
227 void OnSocketOpened() override;
228 void OnFrameRead(const std::string& message) override;
229 void OnSocketClosed() override;
230 ~ProtocolCommand() override;
231
232 const std::string command_;
233 const base::Closure callback_;
234 std::unique_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_;
235
236 DISALLOW_COPY_AND_ASSIGN(ProtocolCommand);
237 };
238
239 ProtocolCommand::ProtocolCommand(
240 scoped_refptr<AndroidDeviceManager::Device> device,
241 const std::string& socket,
242 const std::string& target_path,
243 const std::string& command,
244 const base::Closure callback)
245 : command_(command),
246 callback_(callback),
247 web_socket_(device->CreateWebSocket(socket, target_path, this)) {
248 }
249
250 void ProtocolCommand::OnSocketOpened() {
251 web_socket_->SendFrame(command_);
252 }
253
254 void ProtocolCommand::OnFrameRead(const std::string& message) {
255 delete this;
256 }
257
258 void ProtocolCommand::OnSocketClosed() {
259 delete this;
260 }
261
262 ProtocolCommand::~ProtocolCommand() {
263 if (!callback_.is_null())
264 callback_.Run();
265 }
266
267 } // namespace
268
269 // static 82 // static
270 DevToolsAndroidBridge::Factory* DevToolsAndroidBridge::Factory::GetInstance() { 83 DevToolsAndroidBridge::Factory* DevToolsAndroidBridge::Factory::GetInstance() {
271 return base::Singleton<DevToolsAndroidBridge::Factory>::get(); 84 return base::Singleton<DevToolsAndroidBridge::Factory>::get();
272 } 85 }
273 86
274 // static 87 // static
275 DevToolsAndroidBridge* DevToolsAndroidBridge::Factory::GetForProfile( 88 DevToolsAndroidBridge* DevToolsAndroidBridge::Factory::GetForProfile(
276 Profile* profile) { 89 Profile* profile) {
277 return static_cast<DevToolsAndroidBridge*>(GetInstance()-> 90 return static_cast<DevToolsAndroidBridge*>(GetInstance()->
278 GetServiceForBrowserContext(profile->GetOriginalProfile(), true)); 91 GetServiceForBrowserContext(profile->GetOriginalProfile(), true));
279 } 92 }
280 93
281 DevToolsAndroidBridge::Factory::Factory() 94 DevToolsAndroidBridge::Factory::Factory()
282 : BrowserContextKeyedServiceFactory( 95 : BrowserContextKeyedServiceFactory(
283 "DevToolsAndroidBridge", 96 "DevToolsAndroidBridge",
284 BrowserContextDependencyManager::GetInstance()) { 97 BrowserContextDependencyManager::GetInstance()) {
285 } 98 }
286 99
287 DevToolsAndroidBridge::Factory::~Factory() {} 100 DevToolsAndroidBridge::Factory::~Factory() {}
288 101
289 KeyedService* DevToolsAndroidBridge::Factory::BuildServiceInstanceFor( 102 KeyedService* DevToolsAndroidBridge::Factory::BuildServiceInstanceFor(
290 content::BrowserContext* context) const { 103 content::BrowserContext* context) const {
291 Profile* profile = Profile::FromBrowserContext(context); 104 Profile* profile = Profile::FromBrowserContext(context);
292 105
293 return new DevToolsAndroidBridge(profile); 106 return new DevToolsAndroidBridge(profile);
294 } 107 }
295 108
296 // AgentHostDelegate ----------------------------------------------------------
297
298 class DevToolsAndroidBridge::AgentHostDelegate
299 : public content::DevToolsExternalAgentProxyDelegate,
300 public AndroidDeviceManager::AndroidWebSocket::Delegate {
301 public:
302 static scoped_refptr<content::DevToolsAgentHost> GetOrCreateAgentHost(
303 scoped_refptr<AndroidDeviceManager::Device> device,
304 const std::string& browser_id,
305 const std::string& local_id,
306 const std::string& target_path,
307 const std::string& type,
308 base::DictionaryValue* value);
309 ~AgentHostDelegate() override;
310
311 private:
312 AgentHostDelegate(
313 scoped_refptr<AndroidDeviceManager::Device> device,
314 const std::string& browser_id,
315 const std::string& local_id,
316 const std::string& target_path,
317 const std::string& type,
318 base::DictionaryValue* value);
319 // DevToolsExternalAgentProxyDelegate overrides.
320 void Attach(content::DevToolsExternalAgentProxy* proxy) override;
321 void Detach() override;
322 std::string GetType() override;
323 std::string GetTitle() override;
324 std::string GetDescription() override;
325 GURL GetURL() override;
326 GURL GetFaviconURL() override;
327 std::string GetFrontendURL() override;
328 bool Activate() override;
329 void Reload() override;
330 bool Close() override;
331 void SendMessageToBackend(const std::string& message) override;
332
333 void OnSocketOpened() override;
334 void OnFrameRead(const std::string& message) override;
335 void OnSocketClosed() override;
336
337 void SendProtocolCommand(const std::string& target_path,
338 const std::string& method,
339 std::unique_ptr<base::DictionaryValue> params,
340 const base::Closure callback);
341
342 scoped_refptr<AndroidDeviceManager::Device> device_;
343 std::string browser_id_;
344 std::string local_id_;
345 std::string target_path_;
346 std::string remote_type_;
347 std::string remote_id_;
348 std::string frontend_url_;
349 std::string title_;
350 std::string description_;
351 GURL url_;
352 GURL favicon_url_;
353 bool socket_opened_;
354 std::vector<std::string> pending_messages_;
355 std::unique_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_;
356 content::DevToolsAgentHost* agent_host_;
357 content::DevToolsExternalAgentProxy* proxy_;
358 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
359 };
360
361 static std::string GetStringProperty(base::DictionaryValue* value,
362 const std::string& name) {
363 std::string result;
364 value->GetString(name, &result);
365 return result;
366 }
367
368 static std::string BuildUniqueTargetId(
369 const std::string& serial,
370 const std::string& browser_id,
371 base::DictionaryValue* value) {
372 return base::StringPrintf("%s:%s:%s", serial.c_str(),
373 browser_id.c_str(), GetStringProperty(value, "id").c_str());
374 }
375
376 static std::string GetFrontendURLFromValue(base::DictionaryValue* value) {
377 std::string frontend_url = GetStringProperty(value, "devtoolsFrontendUrl");
378 size_t ws_param = frontend_url.find("?ws");
379 if (ws_param != std::string::npos)
380 frontend_url = frontend_url.substr(0, ws_param);
381 if (base::StartsWith(frontend_url, "http:", base::CompareCase::SENSITIVE))
382 frontend_url = "https:" + frontend_url.substr(5);
383 return frontend_url;
384 }
385
386 static std::string GetTargetPath(base::DictionaryValue* value) {
387 std::string target_path = GetStringProperty(value, "webSocketDebuggerUrl");
388
389 if (base::StartsWith(target_path, "ws://", base::CompareCase::SENSITIVE)) {
390 size_t pos = target_path.find("/", 5);
391 if (pos == std::string::npos)
392 pos = 5;
393 target_path = target_path.substr(pos);
394 } else {
395 target_path = std::string();
396 }
397 return target_path;
398 }
399
400 // static
401 scoped_refptr<content::DevToolsAgentHost>
402 DevToolsAndroidBridge::AgentHostDelegate::GetOrCreateAgentHost(
403 scoped_refptr<AndroidDeviceManager::Device> device,
404 const std::string& browser_id,
405 const std::string& local_id,
406 const std::string& target_path,
407 const std::string& type,
408 base::DictionaryValue* value) {
409 DCHECK_CURRENTLY_ON(BrowserThread::UI);
410 scoped_refptr<DevToolsAgentHost> result =
411 DevToolsAgentHost::GetForId(local_id);
412 if (result)
413 return result;
414
415 AgentHostDelegate* delegate = new AgentHostDelegate(
416 device, browser_id, local_id, target_path, type, value);
417 result = content::DevToolsAgentHost::Forward(
418 local_id, base::WrapUnique(delegate));
419 delegate->agent_host_ = result.get();
420 return result;
421 }
422
423 DevToolsAndroidBridge::AgentHostDelegate::AgentHostDelegate(
424 scoped_refptr<AndroidDeviceManager::Device> device,
425 const std::string& browser_id,
426 const std::string& local_id,
427 const std::string& target_path,
428 const std::string& type,
429 base::DictionaryValue* value)
430 : device_(device),
431 browser_id_(browser_id),
432 local_id_(local_id),
433 target_path_(target_path),
434 remote_type_(type),
435 remote_id_(value ? GetStringProperty(value, "id") : ""),
436 frontend_url_(value ? GetFrontendURLFromValue(value) : ""),
437 title_(value ? base::UTF16ToUTF8(net::UnescapeForHTML(base::UTF8ToUTF16(
438 GetStringProperty(value, "title")))) : ""),
439 description_(value ? GetStringProperty(value, "description") : ""),
440 url_(GURL(value ? GetStringProperty(value, "url") : "")),
441 favicon_url_(GURL(value ? GetStringProperty(value, "faviconUrl") : "")),
442 socket_opened_(false),
443 agent_host_(nullptr),
444 proxy_(nullptr) {
445 }
446
447 DevToolsAndroidBridge::AgentHostDelegate::~AgentHostDelegate() {
448 }
449
450 void DevToolsAndroidBridge::AgentHostDelegate::Attach(
451 content::DevToolsExternalAgentProxy* proxy) {
452 proxy_ = proxy;
453 content::RecordAction(
454 base::StartsWith(browser_id_, kWebViewSocketPrefix,
455 base::CompareCase::SENSITIVE)
456 ? base::UserMetricsAction("DevTools_InspectAndroidWebView")
457 : base::UserMetricsAction("DevTools_InspectAndroidPage"));
458 web_socket_.reset(
459 device_->CreateWebSocket(browser_id_, target_path_, this));
460 }
461
462 void DevToolsAndroidBridge::AgentHostDelegate::Detach() {
463 web_socket_.reset();
464 proxy_ = nullptr;
465 }
466
467 std::string DevToolsAndroidBridge::AgentHostDelegate::GetType() {
468 return remote_type_;
469 }
470
471 std::string DevToolsAndroidBridge::AgentHostDelegate::GetTitle() {
472 return title_;
473 }
474
475 std::string DevToolsAndroidBridge::AgentHostDelegate::GetDescription() {
476 return description_;
477 }
478
479 GURL DevToolsAndroidBridge::AgentHostDelegate::GetURL() {
480 return url_;
481 }
482
483 GURL DevToolsAndroidBridge::AgentHostDelegate::GetFaviconURL() {
484 return favicon_url_;
485 }
486
487 std::string DevToolsAndroidBridge::AgentHostDelegate::GetFrontendURL() {
488 return frontend_url_;
489 }
490
491 bool DevToolsAndroidBridge::AgentHostDelegate::Activate() {
492 std::string request = base::StringPrintf(kActivatePageRequest,
493 remote_id_.c_str());
494 device_->SendJsonRequest(browser_id_, request, base::Bind(&NoOp));
495 return true;
496 }
497
498 void DevToolsAndroidBridge::AgentHostDelegate::Reload() {
499 SendProtocolCommand(target_path_, kPageReloadCommand, nullptr,
500 base::Closure());
501 }
502
503 bool DevToolsAndroidBridge::AgentHostDelegate::Close() {
504 std::string request = base::StringPrintf(kClosePageRequest,
505 remote_id_.c_str());
506 device_->SendJsonRequest(browser_id_, request, base::Bind(&NoOp));
507 return true;
508 }
509
510 void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend(
511 const std::string& message) {
512 // We could have detached due to physical connection being closed.
513 if (!proxy_)
514 return;
515 if (socket_opened_)
516 web_socket_->SendFrame(message);
517 else
518 pending_messages_.push_back(message);
519 }
520
521 void DevToolsAndroidBridge::AgentHostDelegate::OnSocketOpened() {
522 socket_opened_ = true;
523 for (std::vector<std::string>::iterator it = pending_messages_.begin();
524 it != pending_messages_.end(); ++it) {
525 SendMessageToBackend(*it);
526 }
527 pending_messages_.clear();
528 }
529
530 void DevToolsAndroidBridge::AgentHostDelegate::OnFrameRead(
531 const std::string& message) {
532 if (proxy_)
533 proxy_->DispatchOnClientHost(message);
534 }
535
536 void DevToolsAndroidBridge::AgentHostDelegate::OnSocketClosed() {
537 if (proxy_) {
538 std::string message = "{ \"method\": \"Inspector.detached\", "
539 "\"params\": { \"reason\": \"Connection lost.\"} }";
540 proxy_->DispatchOnClientHost(message);
541 Detach();
542 }
543 }
544
545 void DevToolsAndroidBridge::AgentHostDelegate::SendProtocolCommand(
546 const std::string& target_path,
547 const std::string& method,
548 std::unique_ptr<base::DictionaryValue> params,
549 const base::Closure callback) {
550 DCHECK_CURRENTLY_ON(BrowserThread::UI);
551 if (target_path.empty())
552 return;
553 new ProtocolCommand(
554 device_, browser_id_, target_path,
555 DevToolsProtocol::SerializeCommand(1, method, std::move(params)),
556 callback);
557 }
558
559 // DevToolsAndroidBridge::RemotePage ------------------------------------------
560
561 DevToolsAndroidBridge::RemotePage::RemotePage(
562 scoped_refptr<AndroidDeviceManager::Device> device,
563 const std::string& browser_id,
564 const base::DictionaryValue& dict)
565 : device_(device),
566 browser_id_(browser_id),
567 dict_(dict.DeepCopy()) {
568 }
569
570 DevToolsAndroidBridge::RemotePage::~RemotePage() {
571 }
572
573 scoped_refptr<content::DevToolsAgentHost>
574 DevToolsAndroidBridge::RemotePage::CreateTarget() {
575 std::string local_id = BuildUniqueTargetId(device_->serial(),
576 browser_id_,
577 dict_.get());
578 std::string target_path = GetTargetPath(dict_.get());
579 std::string type = GetStringProperty(dict_.get(), "type");
580
581 return AgentHostDelegate::GetOrCreateAgentHost(
582 device_, browser_id_, local_id, target_path, type, dict_.get());
583 }
584
585 // DevToolsAndroidBridge::RemoteBrowser ---------------------------------------
586
587 DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser(
588 const std::string& serial,
589 const AndroidDeviceManager::BrowserInfo& browser_info)
590 : serial_(serial),
591 browser_id_(browser_info.socket_name),
592 display_name_(browser_info.display_name),
593 user_(browser_info.user),
594 type_(browser_info.type) {
595 }
596
597 bool DevToolsAndroidBridge::RemoteBrowser::IsChrome() {
598 return type_ == AndroidDeviceManager::BrowserInfo::kTypeChrome;
599 }
600
601 std::string DevToolsAndroidBridge::RemoteBrowser::GetId() {
602 return serial() + ":" + socket();
603 }
604
605 DevToolsAndroidBridge::RemoteBrowser::ParsedVersion
606 DevToolsAndroidBridge::RemoteBrowser::GetParsedVersion() {
607 ParsedVersion result;
608 for (const base::StringPiece& part :
609 base::SplitStringPiece(
610 version_, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY)) {
611 int value = 0;
612 base::StringToInt(part, &value);
613 result.push_back(value);
614 }
615 return result;
616 }
617
618 scoped_refptr<content::DevToolsAgentHost> 109 scoped_refptr<content::DevToolsAgentHost>
619 DevToolsAndroidBridge::GetBrowserAgentHost( 110 DevToolsAndroidBridge::GetBrowserAgentHost(
620 scoped_refptr<RemoteBrowser> browser) { 111 scoped_refptr<RemoteBrowser> browser) {
621 DeviceMap::iterator it = device_map_.find(browser->serial()); 112 DeviceMap::iterator it = device_map_.find(browser->serial());
622 if (it == device_map_.end()) 113 if (it == device_map_.end())
623 return nullptr; 114 return nullptr;
624 115
625 return AgentHostDelegate::GetOrCreateAgentHost( 116 return DevToolsDeviceDiscovery::CreateBrowserAgentHost(it->second, browser);
626 it->second,
627 browser->browser_id_,
628 "adb:" + browser->serial() + ":" + browser->socket(),
629 kBrowserTargetSocket, DevToolsAgentHost::kTypeBrowser, nullptr);
630 } 117 }
631 118
632 void DevToolsAndroidBridge::SendJsonRequest( 119 void DevToolsAndroidBridge::SendJsonRequest(
633 const std::string& browser_id_str, 120 const std::string& browser_id_str,
634 const std::string& url, 121 const std::string& url,
635 const JsonRequestCallback& callback) { 122 const JsonRequestCallback& callback) {
636 std::string serial; 123 std::string serial;
637 std::string browser_id; 124 std::string browser_id;
638 if (!BrowserIdFromString(browser_id_str, &serial, &browser_id)) { 125 if (!BrowserIdFromString(browser_id_str, &serial, &browser_id)) {
639 callback.Run(net::ERR_FAILED, std::string()); 126 callback.Run(net::ERR_FAILED, std::string());
(...skipping 18 matching lines...) Expand all
658 } 145 }
659 std::string url = gurl.spec(); 146 std::string url = gurl.spec();
660 RemoteBrowser::ParsedVersion parsed_version = browser->GetParsedVersion(); 147 RemoteBrowser::ParsedVersion parsed_version = browser->GetParsedVersion();
661 148
662 std::string query = net::EscapeQueryParamValue(url, false /* use_plus */); 149 std::string query = net::EscapeQueryParamValue(url, false /* use_plus */);
663 std::string request = 150 std::string request =
664 base::StringPrintf(kNewPageRequestWithURL, query.c_str()); 151 base::StringPrintf(kNewPageRequestWithURL, query.c_str());
665 SendJsonRequest(browser->GetId(), request, base::Bind(&NoOp)); 152 SendJsonRequest(browser->GetId(), request, base::Bind(&NoOp));
666 } 153 }
667 154
668 DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() {
669 }
670
671 // DevToolsAndroidBridge::RemoteDevice ----------------------------------------
672
673 DevToolsAndroidBridge::RemoteDevice::RemoteDevice(
674 const std::string& serial,
675 const AndroidDeviceManager::DeviceInfo& device_info)
676 : serial_(serial),
677 model_(device_info.model),
678 connected_(device_info.connected),
679 screen_size_(device_info.screen_size) {
680 for (std::vector<AndroidDeviceManager::BrowserInfo>::const_iterator it =
681 device_info.browser_info.begin();
682 it != device_info.browser_info.end();
683 ++it) {
684 browsers_.push_back(new RemoteBrowser(serial, *it));
685 }
686 }
687
688 DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() {
689 }
690
691 // DevToolsAndroidBridge ------------------------------------------------------
692
693 // static
694 void DevToolsAndroidBridge::QueryCompleteDevices(
695 AndroidDeviceManager* device_manager,
696 const DeviceListCallback& callback) {
697 new DiscoveryRequest(device_manager, callback);
698 }
699
700 DevToolsAndroidBridge::DevToolsAndroidBridge( 155 DevToolsAndroidBridge::DevToolsAndroidBridge(
701 Profile* profile) 156 Profile* profile)
702 : profile_(profile), 157 : profile_(profile),
703 device_manager_(AndroidDeviceManager::Create()), 158 device_manager_(AndroidDeviceManager::Create()),
704 task_scheduler_(base::Bind(&DevToolsAndroidBridge::ScheduleTaskDefault)),
705 port_forwarding_controller_(new PortForwardingController(profile)), 159 port_forwarding_controller_(new PortForwardingController(profile)),
706 weak_factory_(this) { 160 weak_factory_(this) {
707 DCHECK_CURRENTLY_ON(BrowserThread::UI); 161 DCHECK_CURRENTLY_ON(BrowserThread::UI);
708 pref_change_registrar_.Init(profile_->GetPrefs()); 162 pref_change_registrar_.Init(profile_->GetPrefs());
709 pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled, 163 pref_change_registrar_.Add(prefs::kDevToolsDiscoverUsbDevicesEnabled,
710 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders, 164 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
711 base::Unretained(this))); 165 base::Unretained(this)));
712 pref_change_registrar_.Add(prefs::kDevToolsTCPDiscoveryConfig, 166 pref_change_registrar_.Add(prefs::kDevToolsTCPDiscoveryConfig,
713 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders, 167 base::Bind(&DevToolsAndroidBridge::CreateDeviceProviders,
714 base::Unretained(this))); 168 base::Unretained(this)));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 236 }
783 237
784 DevToolsAndroidBridge::~DevToolsAndroidBridge() { 238 DevToolsAndroidBridge::~DevToolsAndroidBridge() {
785 DCHECK_CURRENTLY_ON(BrowserThread::UI); 239 DCHECK_CURRENTLY_ON(BrowserThread::UI);
786 DCHECK(device_list_listeners_.empty()); 240 DCHECK(device_list_listeners_.empty());
787 DCHECK(device_count_listeners_.empty()); 241 DCHECK(device_count_listeners_.empty());
788 DCHECK(port_forwarding_listeners_.empty()); 242 DCHECK(port_forwarding_listeners_.empty());
789 } 243 }
790 244
791 void DevToolsAndroidBridge::StartDeviceListPolling() { 245 void DevToolsAndroidBridge::StartDeviceListPolling() {
792 device_list_callback_.Reset( 246 device_discovery_.reset(new DevToolsDeviceDiscovery(device_manager_.get(),
793 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, AsWeakPtr())); 247 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList,
794 RequestDeviceList(device_list_callback_.callback()); 248 base::Unretained(this))));
249 if (!task_scheduler_.is_null())
250 device_discovery_->SetScheduler(task_scheduler_);
795 } 251 }
796 252
797 void DevToolsAndroidBridge::StopDeviceListPolling() { 253 void DevToolsAndroidBridge::StopDeviceListPolling() {
798 device_list_callback_.Cancel(); 254 device_discovery_.reset();
799 device_map_.clear(); 255 device_map_.clear();
800 port_forwarding_controller_->CloseAllConnections(); 256 port_forwarding_controller_->CloseAllConnections();
801 } 257 }
802 258
803 bool DevToolsAndroidBridge::NeedsDeviceListPolling() { 259 bool DevToolsAndroidBridge::NeedsDeviceListPolling() {
804 return !device_list_listeners_.empty() || !port_forwarding_listeners_.empty(); 260 return !device_list_listeners_.empty() || !port_forwarding_listeners_.empty();
805 } 261 }
806 262
807 void DevToolsAndroidBridge::RequestDeviceList(
808 const DeviceListCallback& callback) {
809 DCHECK_CURRENTLY_ON(BrowserThread::UI);
810
811 if (!NeedsDeviceListPolling() ||
812 !callback.Equals(device_list_callback_.callback()))
813 return;
814
815 new DiscoveryRequest(device_manager_.get(), callback);
816 }
817
818 void DevToolsAndroidBridge::ReceivedDeviceList( 263 void DevToolsAndroidBridge::ReceivedDeviceList(
819 const CompleteDevices& complete_devices) { 264 const CompleteDevices& complete_devices) {
820 DCHECK_CURRENTLY_ON(BrowserThread::UI); 265 DCHECK_CURRENTLY_ON(BrowserThread::UI);
821 266
822 device_map_.clear(); 267 device_map_.clear();
823 RemoteDevices remote_devices; 268 RemoteDevices remote_devices;
824 for (const auto& pair : complete_devices) { 269 for (const auto& pair : complete_devices) {
825 device_map_[pair.first->serial()] = pair.first; 270 device_map_[pair.first->serial()] = pair.first;
826 remote_devices.push_back(pair.second); 271 remote_devices.push_back(pair.second);
827 } 272 }
828 273
829 DeviceListListeners copy(device_list_listeners_); 274 DeviceListListeners copy(device_list_listeners_);
830 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it) 275 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it)
831 (*it)->DeviceListChanged(remote_devices); 276 (*it)->DeviceListChanged(remote_devices);
832 277
833 ForwardingStatus status = 278 ForwardingStatus status =
834 port_forwarding_controller_->DeviceListChanged(complete_devices); 279 port_forwarding_controller_->DeviceListChanged(complete_devices);
835 PortForwardingListeners forwarding_listeners(port_forwarding_listeners_); 280 PortForwardingListeners forwarding_listeners(port_forwarding_listeners_);
836 for (PortForwardingListeners::iterator it = forwarding_listeners.begin(); 281 for (PortForwardingListeners::iterator it = forwarding_listeners.begin();
837 it != forwarding_listeners.end(); ++it) { 282 it != forwarding_listeners.end(); ++it) {
838 (*it)->PortStatusChanged(status); 283 (*it)->PortStatusChanged(status);
839 } 284 }
840
841 if (!NeedsDeviceListPolling())
842 return;
843
844 task_scheduler_.Run(
845 base::Bind(&DevToolsAndroidBridge::RequestDeviceList,
846 AsWeakPtr(), device_list_callback_.callback()));
847 } 285 }
848 286
849 void DevToolsAndroidBridge::StartDeviceCountPolling() { 287 void DevToolsAndroidBridge::StartDeviceCountPolling() {
850 device_count_callback_.Reset( 288 device_count_callback_.Reset(
851 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, AsWeakPtr())); 289 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, AsWeakPtr()));
852 RequestDeviceCount(device_count_callback_.callback()); 290 RequestDeviceCount(device_count_callback_.callback());
853 } 291 }
854 292
855 void DevToolsAndroidBridge::StopDeviceCountPolling() { 293 void DevToolsAndroidBridge::StopDeviceCountPolling() {
856 device_count_callback_.Cancel(); 294 device_count_callback_.Cancel();
(...skipping 18 matching lines...) Expand all
875 (*it)->DeviceCountChanged(count); 313 (*it)->DeviceCountChanged(count);
876 314
877 if (device_count_listeners_.empty()) 315 if (device_count_listeners_.empty())
878 return; 316 return;
879 317
880 task_scheduler_.Run( 318 task_scheduler_.Run(
881 base::Bind(&DevToolsAndroidBridge::RequestDeviceCount, 319 base::Bind(&DevToolsAndroidBridge::RequestDeviceCount,
882 AsWeakPtr(), device_count_callback_.callback())); 320 AsWeakPtr(), device_count_callback_.callback()));
883 } 321 }
884 322
885 // static
886 void DevToolsAndroidBridge::ScheduleTaskDefault(const base::Closure& task) {
887 BrowserThread::PostDelayedTask(
888 BrowserThread::UI,
889 FROM_HERE,
890 task,
891 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs));
892 }
893
894 static std::set<net::HostPortPair> ParseTargetDiscoveryPreferenceValue( 323 static std::set<net::HostPortPair> ParseTargetDiscoveryPreferenceValue(
895 const base::ListValue* preferenceValue) { 324 const base::ListValue* preferenceValue) {
896 std::set<net::HostPortPair> targets; 325 std::set<net::HostPortPair> targets;
897 if (!preferenceValue || preferenceValue->empty()) 326 if (!preferenceValue || preferenceValue->empty())
898 return targets; 327 return targets;
899 std::string address; 328 std::string address;
900 for (size_t i = 0; i < preferenceValue->GetSize(); i++) { 329 for (size_t i = 0; i < preferenceValue->GetSize(); i++) {
901 if (!preferenceValue->GetString(i, &address)) 330 if (!preferenceValue->GetString(i, &address))
902 continue; 331 continue;
903 net::HostPortPair target = net::HostPortPair::FromString(address); 332 net::HostPortPair target = net::HostPortPair::FromString(address);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 StopDeviceListPolling(); 398 StopDeviceListPolling();
970 StartDeviceListPolling(); 399 StartDeviceListPolling();
971 } 400 }
972 } 401 }
973 402
974 void DevToolsAndroidBridge::set_tcp_provider_callback_for_test( 403 void DevToolsAndroidBridge::set_tcp_provider_callback_for_test(
975 TCPProviderCallback callback) { 404 TCPProviderCallback callback) {
976 tcp_provider_callback_ = callback; 405 tcp_provider_callback_ = callback;
977 CreateDeviceProviders(); 406 CreateDeviceProviders();
978 } 407 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/device/devtools_android_bridge.h ('k') | chrome/browser/devtools/device/devtools_device_discovery.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698