| Index: chrome/browser/devtools/device/devtools_android_bridge.cc | 
| diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc | 
| index deaf9d6b5b2832664a786b4c245cf23ada6dd411..465d5449d6f8b96a3ef059e3975a5a353e3437ec 100644 | 
| --- a/chrome/browser/devtools/device/devtools_android_bridge.cc | 
| +++ b/chrome/browser/devtools/device/devtools_android_bridge.cc | 
| @@ -5,6 +5,7 @@ | 
| #include "chrome/browser/devtools/device/devtools_android_bridge.h" | 
|  | 
| #include <map> | 
| +#include <set> | 
| #include <vector> | 
|  | 
| #include "base/base64.h" | 
| @@ -296,7 +297,8 @@ KeyedService* DevToolsAndroidBridge::Factory::BuildServiceInstanceFor( | 
|  | 
| class DevToolsAndroidBridge::AgentHostDelegate | 
| : public content::DevToolsExternalAgentProxyDelegate, | 
| -      public AndroidDeviceManager::AndroidWebSocket::Delegate { | 
| +      public AndroidDeviceManager::AndroidWebSocket::Delegate, | 
| +      public DevToolsAndroidBridge::DeviceListListener { | 
| public: | 
| static scoped_refptr<content::DevToolsAgentHost> GetOrCreateAgentHost( | 
| DevToolsAndroidBridge* bridge, | 
| @@ -314,10 +316,16 @@ class DevToolsAndroidBridge::AgentHostDelegate | 
| void Attach(content::DevToolsExternalAgentProxy* proxy) override; | 
| void Detach() override; | 
| void SendMessageToBackend(const std::string& message) override; | 
| +  void OpenWorkerInspector(content::BrowserContext* context, | 
| +                           const std::string& id) override; | 
| void OnSocketOpened() override; | 
| void OnFrameRead(const std::string& message) override; | 
| void OnSocketClosed() override; | 
|  | 
| +  // DevToolsAndroidBridge::Listener overrides. | 
| +  void DeviceListChanged( | 
| +      const DevToolsAndroidBridge::RemoteDevices& devices) override; | 
| + | 
| std::string id_; | 
| base::WeakPtr<DevToolsAndroidBridge> bridge_; | 
| BrowserId browser_id_; | 
| @@ -328,6 +336,10 @@ class DevToolsAndroidBridge::AgentHostDelegate | 
| scoped_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_; | 
| content::DevToolsAgentHost* agent_host_; | 
| content::DevToolsExternalAgentProxy* proxy_; | 
| +  content::BrowserContext* context_; | 
| +  std::set<std::string> pending_workers_; | 
| +  base::WeakPtrFactory<DevToolsAndroidBridge::AgentHostDelegate> weak_factory_; | 
| + | 
| DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); | 
| }; | 
|  | 
| @@ -340,8 +352,10 @@ DevToolsAndroidBridge::AgentHostDelegate::GetOrCreateAgentHost( | 
| const std::string& debug_url) { | 
| DCHECK_CURRENTLY_ON(BrowserThread::UI); | 
| AgentHostDelegates::iterator it = bridge->host_delegates_.find(id); | 
| -  if (it != bridge->host_delegates_.end()) | 
| +  if (it != bridge->host_delegates_.end()) { | 
| +    it->second->debug_url_ = debug_url; | 
| return it->second->agent_host_; | 
| +  } | 
|  | 
| AgentHostDelegate* delegate = | 
| new AgentHostDelegate(bridge, id, browser_id, debug_url); | 
| @@ -362,13 +376,19 @@ DevToolsAndroidBridge::AgentHostDelegate::AgentHostDelegate( | 
| debug_url_(debug_url), | 
| socket_opened_(false), | 
| agent_host_(NULL), | 
| -      proxy_(NULL) { | 
| +      proxy_(NULL), | 
| +      context_(NULL), | 
| +      weak_factory_(this) { | 
| bridge_->host_delegates_[id] = this; | 
| } | 
|  | 
| DevToolsAndroidBridge::AgentHostDelegate::~AgentHostDelegate() { | 
| -  if (bridge_) | 
| +  if (bridge_) { | 
| +    if (pending_workers_.size()) { | 
| +      bridge_->RemoveDeviceListListener(this); | 
| +    } | 
| bridge_->host_delegates_.erase(id_); | 
| +  } | 
| } | 
|  | 
| void DevToolsAndroidBridge::AgentHostDelegate::Attach( | 
| @@ -383,7 +403,6 @@ void DevToolsAndroidBridge::AgentHostDelegate::Attach( | 
| device_ = bridge_->FindDevice(browser_id_.first); | 
| if (!device_.get()) | 
| return; | 
| - | 
| web_socket_.reset( | 
| device_->CreateWebSocket(browser_id_.second, debug_url_, this)); | 
| } | 
| @@ -401,6 +420,71 @@ void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend( | 
| pending_messages_.push_back(message); | 
| } | 
|  | 
| +void DevToolsAndroidBridge::AgentHostDelegate::OpenWorkerInspector( | 
| +    content::BrowserContext* context, | 
| +    const std::string& id) { | 
| +  if (!bridge_) | 
| +    return; | 
| +  const std::string full_id = | 
| +      base::StringPrintf("%s:%s:%s", browser_id_.first.c_str(), | 
| +                         browser_id_.second.c_str(), id.c_str()); | 
| +  if (pending_workers_.size()) { | 
| +    pending_workers_.insert(full_id); | 
| +  } else { | 
| +    pending_workers_.insert(full_id); | 
| +    context_ = context; | 
| +    bridge_->AddDeviceListListener(this); | 
| +  } | 
| +} | 
| + | 
| +static std::string GetStringProperty(const base::DictionaryValue& value, | 
| +                                     const std::string& name) { | 
| +  std::string result; | 
| +  value.GetString(name, &result); | 
| +  return result; | 
| +} | 
| + | 
| +static std::string BuildUniqueTargetId( | 
| +    const DevToolsAndroidBridge::BrowserId& browser_id, | 
| +    const base::DictionaryValue& value) { | 
| +  return base::StringPrintf("%s:%s:%s", browser_id.first.c_str(), | 
| +                            browser_id.second.c_str(), | 
| +                            GetStringProperty(value, "id").c_str()); | 
| +} | 
| + | 
| +static std::string GetDebugURL(const base::DictionaryValue& value) { | 
| +  std::string debug_url = GetStringProperty(value, "webSocketDebuggerUrl"); | 
| + | 
| +  if (debug_url.find("ws://") == 0) | 
| +    debug_url = debug_url.substr(5); | 
| +  else | 
| +    debug_url = std::string(); | 
| +  return debug_url; | 
| +} | 
| + | 
| +void DevToolsAndroidBridge::AgentHostDelegate::DeviceListChanged( | 
| +    const DevToolsAndroidBridge::RemoteDevices& devices) { | 
| +  if (!bridge_) { | 
| +    pending_workers_.clear(); | 
| +    return; | 
| +  } | 
| +  for (const auto& device : devices) { | 
| +    for (const auto& browser : device->browsers()) { | 
| +      for (const auto& page : browser->pages()) { | 
| +        scoped_ptr<DevToolsTargetImpl> target(bridge_->CreatePageTarget(page)); | 
| +        if (pending_workers_.count(target->GetId())) { | 
| +          if (GetDebugURL(*page->dict_).length()) { | 
| +            target->Inspect(Profile::FromBrowserContext(context_)); | 
| +          } | 
| +        } | 
| +      } | 
| +    } | 
| +  } | 
| +  pending_workers_.clear(); | 
| +  if (bridge_) | 
| +    bridge_->RemoveDeviceListListener(this); | 
| +} | 
| + | 
| void DevToolsAndroidBridge::AgentHostDelegate::OnSocketOpened() { | 
| socket_opened_ = true; | 
| for (std::vector<std::string>::iterator it = pending_messages_.begin(); | 
| @@ -449,20 +533,6 @@ class DevToolsAndroidBridge::RemotePageTarget : public DevToolsTargetImpl { | 
| DISALLOW_COPY_AND_ASSIGN(RemotePageTarget); | 
| }; | 
|  | 
| -static std::string GetStringProperty(const base::DictionaryValue& value, | 
| -                                     const std::string& name) { | 
| -  std::string result; | 
| -  value.GetString(name, &result); | 
| -  return result; | 
| -} | 
| - | 
| -static std::string BuildUniqueTargetId( | 
| -    const DevToolsAndroidBridge::BrowserId& browser_id, | 
| -    const base::DictionaryValue& value) { | 
| -  return base::StringPrintf("%s:%s:%s", browser_id.first.c_str(), | 
| -      browser_id.second.c_str(), GetStringProperty(value, "id").c_str()); | 
| -} | 
| - | 
| static std::string GetFrontendURL(const base::DictionaryValue& value) { | 
| std::string frontend_url = GetStringProperty(value, "devtoolsFrontendUrl"); | 
| size_t ws_param = frontend_url.find("?ws"); | 
| @@ -473,15 +543,6 @@ static std::string GetFrontendURL(const base::DictionaryValue& value) { | 
| return frontend_url; | 
| } | 
|  | 
| -static std::string GetDebugURL(const base::DictionaryValue& value) { | 
| -  std::string debug_url = GetStringProperty(value, "webSocketDebuggerUrl"); | 
| - | 
| -  if (debug_url.find("ws://") == 0) | 
| -    debug_url = debug_url.substr(5); | 
| -  else | 
| -    debug_url = std::string(); | 
| -  return debug_url; | 
| -} | 
|  | 
| DevToolsAndroidBridge::RemotePageTarget::RemotePageTarget( | 
| DevToolsAndroidBridge* bridge, | 
|  |