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

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

Issue 1060053002: [WIP] Support opening an inspector window for ServiceWorker running on Android (chromium) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 <map> 7 #include <map>
8 #include <set>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/base64.h" 11 #include "base/base64.h"
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/command_line.h" 13 #include "base/command_line.h"
13 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
14 #include "base/json/json_reader.h" 15 #include "base/json/json_reader.h"
15 #include "base/lazy_instance.h" 16 #include "base/lazy_instance.h"
16 #include "base/memory/singleton.h" 17 #include "base/memory/singleton.h"
17 #include "base/message_loop/message_loop.h" 18 #include "base/message_loop/message_loop.h"
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 } 290 }
290 291
291 return new DevToolsAndroidBridge( 292 return new DevToolsAndroidBridge(
292 profile, signin_manager, token_service); 293 profile, signin_manager, token_service);
293 } 294 }
294 295
295 // AgentHostDelegate ---------------------------------------------------------- 296 // AgentHostDelegate ----------------------------------------------------------
296 297
297 class DevToolsAndroidBridge::AgentHostDelegate 298 class DevToolsAndroidBridge::AgentHostDelegate
298 : public content::DevToolsExternalAgentProxyDelegate, 299 : public content::DevToolsExternalAgentProxyDelegate,
299 public AndroidDeviceManager::AndroidWebSocket::Delegate { 300 public AndroidDeviceManager::AndroidWebSocket::Delegate,
301 public DevToolsAndroidBridge::DeviceListListener {
300 public: 302 public:
301 static scoped_refptr<content::DevToolsAgentHost> GetOrCreateAgentHost( 303 static scoped_refptr<content::DevToolsAgentHost> GetOrCreateAgentHost(
302 DevToolsAndroidBridge* bridge, 304 DevToolsAndroidBridge* bridge,
303 const std::string& id, 305 const std::string& id,
304 const BrowserId& browser_id, 306 const BrowserId& browser_id,
305 const std::string& debug_url); 307 const std::string& debug_url);
306 308
307 private: 309 private:
308 AgentHostDelegate( 310 AgentHostDelegate(
309 DevToolsAndroidBridge* bridge, 311 DevToolsAndroidBridge* bridge,
310 const std::string& id, 312 const std::string& id,
311 const BrowserId& browser_id, 313 const BrowserId& browser_id,
312 const std::string& debug_url); 314 const std::string& debug_url);
313 ~AgentHostDelegate() override; 315 ~AgentHostDelegate() override;
314 void Attach(content::DevToolsExternalAgentProxy* proxy) override; 316 void Attach(content::DevToolsExternalAgentProxy* proxy) override;
315 void Detach() override; 317 void Detach() override;
316 void SendMessageToBackend(const std::string& message) override; 318 void SendMessageToBackend(const std::string& message) override;
319 void OpenWorkerInspector(content::BrowserContext* context,
320 const std::string& id) override;
317 void OnSocketOpened() override; 321 void OnSocketOpened() override;
318 void OnFrameRead(const std::string& message) override; 322 void OnFrameRead(const std::string& message) override;
319 void OnSocketClosed() override; 323 void OnSocketClosed() override;
320 324
325 // DevToolsAndroidBridge::Listener overrides.
326 void DeviceListChanged(
327 const DevToolsAndroidBridge::RemoteDevices& devices) override;
328
321 std::string id_; 329 std::string id_;
322 base::WeakPtr<DevToolsAndroidBridge> bridge_; 330 base::WeakPtr<DevToolsAndroidBridge> bridge_;
323 BrowserId browser_id_; 331 BrowserId browser_id_;
324 std::string debug_url_; 332 std::string debug_url_;
325 bool socket_opened_; 333 bool socket_opened_;
326 std::vector<std::string> pending_messages_; 334 std::vector<std::string> pending_messages_;
327 scoped_refptr<AndroidDeviceManager::Device> device_; 335 scoped_refptr<AndroidDeviceManager::Device> device_;
328 scoped_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_; 336 scoped_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_;
329 content::DevToolsAgentHost* agent_host_; 337 content::DevToolsAgentHost* agent_host_;
330 content::DevToolsExternalAgentProxy* proxy_; 338 content::DevToolsExternalAgentProxy* proxy_;
339 content::BrowserContext* context_;
340 std::set<std::string> pending_workers_;
341 base::WeakPtrFactory<DevToolsAndroidBridge::AgentHostDelegate> weak_factory_;
342
331 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); 343 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
332 }; 344 };
333 345
334 // static 346 // static
335 scoped_refptr<content::DevToolsAgentHost> 347 scoped_refptr<content::DevToolsAgentHost>
336 DevToolsAndroidBridge::AgentHostDelegate::GetOrCreateAgentHost( 348 DevToolsAndroidBridge::AgentHostDelegate::GetOrCreateAgentHost(
337 DevToolsAndroidBridge* bridge, 349 DevToolsAndroidBridge* bridge,
338 const std::string& id, 350 const std::string& id,
339 const BrowserId& browser_id, 351 const BrowserId& browser_id,
340 const std::string& debug_url) { 352 const std::string& debug_url) {
341 DCHECK_CURRENTLY_ON(BrowserThread::UI); 353 DCHECK_CURRENTLY_ON(BrowserThread::UI);
342 AgentHostDelegates::iterator it = bridge->host_delegates_.find(id); 354 AgentHostDelegates::iterator it = bridge->host_delegates_.find(id);
343 if (it != bridge->host_delegates_.end()) 355 if (it != bridge->host_delegates_.end()) {
356 it->second->debug_url_ = debug_url;
344 return it->second->agent_host_; 357 return it->second->agent_host_;
358 }
345 359
346 AgentHostDelegate* delegate = 360 AgentHostDelegate* delegate =
347 new AgentHostDelegate(bridge, id, browser_id, debug_url); 361 new AgentHostDelegate(bridge, id, browser_id, debug_url);
348 scoped_refptr<content::DevToolsAgentHost> result = 362 scoped_refptr<content::DevToolsAgentHost> result =
349 content::DevToolsAgentHost::Create(delegate); 363 content::DevToolsAgentHost::Create(delegate);
350 delegate->agent_host_ = result.get(); 364 delegate->agent_host_ = result.get();
351 return result; 365 return result;
352 } 366 }
353 367
354 DevToolsAndroidBridge::AgentHostDelegate::AgentHostDelegate( 368 DevToolsAndroidBridge::AgentHostDelegate::AgentHostDelegate(
355 DevToolsAndroidBridge* bridge, 369 DevToolsAndroidBridge* bridge,
356 const std::string& id, 370 const std::string& id,
357 const BrowserId& browser_id, 371 const BrowserId& browser_id,
358 const std::string& debug_url) 372 const std::string& debug_url)
359 : id_(id), 373 : id_(id),
360 bridge_(bridge->AsWeakPtr()), 374 bridge_(bridge->AsWeakPtr()),
361 browser_id_(browser_id), 375 browser_id_(browser_id),
362 debug_url_(debug_url), 376 debug_url_(debug_url),
363 socket_opened_(false), 377 socket_opened_(false),
364 agent_host_(NULL), 378 agent_host_(NULL),
365 proxy_(NULL) { 379 proxy_(NULL),
380 context_(NULL),
381 weak_factory_(this) {
366 bridge_->host_delegates_[id] = this; 382 bridge_->host_delegates_[id] = this;
367 } 383 }
368 384
369 DevToolsAndroidBridge::AgentHostDelegate::~AgentHostDelegate() { 385 DevToolsAndroidBridge::AgentHostDelegate::~AgentHostDelegate() {
370 if (bridge_) 386 if (bridge_) {
387 if (pending_workers_.size()) {
388 bridge_->RemoveDeviceListListener(this);
389 }
371 bridge_->host_delegates_.erase(id_); 390 bridge_->host_delegates_.erase(id_);
391 }
372 } 392 }
373 393
374 void DevToolsAndroidBridge::AgentHostDelegate::Attach( 394 void DevToolsAndroidBridge::AgentHostDelegate::Attach(
375 content::DevToolsExternalAgentProxy* proxy) { 395 content::DevToolsExternalAgentProxy* proxy) {
376 proxy_ = proxy; 396 proxy_ = proxy;
377 content::RecordAction(browser_id_.second.find(kWebViewSocketPrefix) == 0 ? 397 content::RecordAction(browser_id_.second.find(kWebViewSocketPrefix) == 0 ?
378 base::UserMetricsAction("DevTools_InspectAndroidWebView") : 398 base::UserMetricsAction("DevTools_InspectAndroidWebView") :
379 base::UserMetricsAction("DevTools_InspectAndroidPage")); 399 base::UserMetricsAction("DevTools_InspectAndroidPage"));
380 400
381 // Retain the device so it's not released until AgentHost is detached. 401 // Retain the device so it's not released until AgentHost is detached.
382 if (bridge_) 402 if (bridge_)
383 device_ = bridge_->FindDevice(browser_id_.first); 403 device_ = bridge_->FindDevice(browser_id_.first);
384 if (!device_.get()) 404 if (!device_.get())
385 return; 405 return;
386
387 web_socket_.reset( 406 web_socket_.reset(
388 device_->CreateWebSocket(browser_id_.second, debug_url_, this)); 407 device_->CreateWebSocket(browser_id_.second, debug_url_, this));
389 } 408 }
390 409
391 void DevToolsAndroidBridge::AgentHostDelegate::Detach() { 410 void DevToolsAndroidBridge::AgentHostDelegate::Detach() {
392 web_socket_.reset(); 411 web_socket_.reset();
393 device_ = nullptr; 412 device_ = nullptr;
394 } 413 }
395 414
396 void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend( 415 void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend(
397 const std::string& message) { 416 const std::string& message) {
398 if (socket_opened_) 417 if (socket_opened_)
399 web_socket_->SendFrame(message); 418 web_socket_->SendFrame(message);
400 else 419 else
401 pending_messages_.push_back(message); 420 pending_messages_.push_back(message);
402 } 421 }
403 422
423 void DevToolsAndroidBridge::AgentHostDelegate::OpenWorkerInspector(
424 content::BrowserContext* context,
425 const std::string& id) {
426 if (!bridge_)
427 return;
428 const std::string full_id =
429 base::StringPrintf("%s:%s:%s", browser_id_.first.c_str(),
430 browser_id_.second.c_str(), id.c_str());
431 if (pending_workers_.size()) {
432 pending_workers_.insert(full_id);
433 } else {
434 pending_workers_.insert(full_id);
435 context_ = context;
436 bridge_->AddDeviceListListener(this);
437 }
438 }
439
440 static std::string GetStringProperty(const base::DictionaryValue& value,
441 const std::string& name) {
442 std::string result;
443 value.GetString(name, &result);
444 return result;
445 }
446
447 static std::string BuildUniqueTargetId(
448 const DevToolsAndroidBridge::BrowserId& browser_id,
449 const base::DictionaryValue& value) {
450 return base::StringPrintf("%s:%s:%s", browser_id.first.c_str(),
451 browser_id.second.c_str(),
452 GetStringProperty(value, "id").c_str());
453 }
454
455 static std::string GetDebugURL(const base::DictionaryValue& value) {
456 std::string debug_url = GetStringProperty(value, "webSocketDebuggerUrl");
457
458 if (debug_url.find("ws://") == 0)
459 debug_url = debug_url.substr(5);
460 else
461 debug_url = std::string();
462 return debug_url;
463 }
464
465 void DevToolsAndroidBridge::AgentHostDelegate::DeviceListChanged(
466 const DevToolsAndroidBridge::RemoteDevices& devices) {
467 if (!bridge_) {
468 pending_workers_.clear();
469 return;
470 }
471 for (const auto& device : devices) {
472 for (const auto& browser : device->browsers()) {
473 for (const auto& page : browser->pages()) {
474 scoped_ptr<DevToolsTargetImpl> target(bridge_->CreatePageTarget(page));
475 if (pending_workers_.count(target->GetId())) {
476 if (GetDebugURL(*page->dict_).length()) {
477 target->Inspect(Profile::FromBrowserContext(context_));
478 }
479 }
480 }
481 }
482 }
483 pending_workers_.clear();
484 if (bridge_)
485 bridge_->RemoveDeviceListListener(this);
486 }
487
404 void DevToolsAndroidBridge::AgentHostDelegate::OnSocketOpened() { 488 void DevToolsAndroidBridge::AgentHostDelegate::OnSocketOpened() {
405 socket_opened_ = true; 489 socket_opened_ = true;
406 for (std::vector<std::string>::iterator it = pending_messages_.begin(); 490 for (std::vector<std::string>::iterator it = pending_messages_.begin();
407 it != pending_messages_.end(); ++it) { 491 it != pending_messages_.end(); ++it) {
408 SendMessageToBackend(*it); 492 SendMessageToBackend(*it);
409 } 493 }
410 pending_messages_.clear(); 494 pending_messages_.clear();
411 } 495 }
412 496
413 void DevToolsAndroidBridge::AgentHostDelegate::OnFrameRead( 497 void DevToolsAndroidBridge::AgentHostDelegate::OnFrameRead(
(...skipping 28 matching lines...) Expand all
442 base::WeakPtr<DevToolsAndroidBridge> bridge_; 526 base::WeakPtr<DevToolsAndroidBridge> bridge_;
443 BrowserId browser_id_; 527 BrowserId browser_id_;
444 std::string debug_url_; 528 std::string debug_url_;
445 std::string frontend_url_; 529 std::string frontend_url_;
446 std::string remote_id_; 530 std::string remote_id_;
447 std::string remote_type_; 531 std::string remote_type_;
448 std::string local_id_; 532 std::string local_id_;
449 DISALLOW_COPY_AND_ASSIGN(RemotePageTarget); 533 DISALLOW_COPY_AND_ASSIGN(RemotePageTarget);
450 }; 534 };
451 535
452 static std::string GetStringProperty(const base::DictionaryValue& value,
453 const std::string& name) {
454 std::string result;
455 value.GetString(name, &result);
456 return result;
457 }
458
459 static std::string BuildUniqueTargetId(
460 const DevToolsAndroidBridge::BrowserId& browser_id,
461 const base::DictionaryValue& value) {
462 return base::StringPrintf("%s:%s:%s", browser_id.first.c_str(),
463 browser_id.second.c_str(), GetStringProperty(value, "id").c_str());
464 }
465
466 static std::string GetFrontendURL(const base::DictionaryValue& value) { 536 static std::string GetFrontendURL(const base::DictionaryValue& value) {
467 std::string frontend_url = GetStringProperty(value, "devtoolsFrontendUrl"); 537 std::string frontend_url = GetStringProperty(value, "devtoolsFrontendUrl");
468 size_t ws_param = frontend_url.find("?ws"); 538 size_t ws_param = frontend_url.find("?ws");
469 if (ws_param != std::string::npos) 539 if (ws_param != std::string::npos)
470 frontend_url = frontend_url.substr(0, ws_param); 540 frontend_url = frontend_url.substr(0, ws_param);
471 if (frontend_url.find("http:") == 0) 541 if (frontend_url.find("http:") == 0)
472 frontend_url = "https:" + frontend_url.substr(5); 542 frontend_url = "https:" + frontend_url.substr(5);
473 return frontend_url; 543 return frontend_url;
474 } 544 }
475 545
476 static std::string GetDebugURL(const base::DictionaryValue& value) {
477 std::string debug_url = GetStringProperty(value, "webSocketDebuggerUrl");
478
479 if (debug_url.find("ws://") == 0)
480 debug_url = debug_url.substr(5);
481 else
482 debug_url = std::string();
483 return debug_url;
484 }
485 546
486 DevToolsAndroidBridge::RemotePageTarget::RemotePageTarget( 547 DevToolsAndroidBridge::RemotePageTarget::RemotePageTarget(
487 DevToolsAndroidBridge* bridge, 548 DevToolsAndroidBridge* bridge,
488 const BrowserId& browser_id, 549 const BrowserId& browser_id,
489 const base::DictionaryValue& value) 550 const base::DictionaryValue& value)
490 : DevToolsTargetImpl(AgentHostDelegate::GetOrCreateAgentHost( 551 : DevToolsTargetImpl(AgentHostDelegate::GetOrCreateAgentHost(
491 bridge, 552 bridge,
492 BuildUniqueTargetId(browser_id, value), 553 BuildUniqueTargetId(browser_id, value),
493 browser_id, 554 browser_id,
494 GetDebugURL(value))), 555 GetDebugURL(value))),
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 device_providers.push_back( 988 device_providers.push_back(
928 new WebRTCDeviceProvider(profile_, signin_manager_, token_service_)); 989 new WebRTCDeviceProvider(profile_, signin_manager_, token_service_));
929 } 990 }
930 991
931 device_manager_->SetDeviceProviders(device_providers); 992 device_manager_->SetDeviceProviders(device_providers);
932 if (NeedsDeviceListPolling()) { 993 if (NeedsDeviceListPolling()) {
933 StopDeviceListPolling(); 994 StopDeviceListPolling();
934 StartDeviceListPolling(); 995 StartDeviceListPolling();
935 } 996 }
936 } 997 }
OLDNEW
« no previous file with comments | « chrome/browser/devtools/device/android_web_socket.cc ('k') | chrome/browser/devtools/devtools_embedder_message_dispatcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698