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

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

Issue 596253003: DevTools: RemoteDevice and RemoteBrowser are now value types (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@pfc3
Patch Set: Rebased. Addressed comments Created 6 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 <map> 7 #include <map>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
(...skipping 19 matching lines...) Expand all
30 #include "chrome/browser/devtools/devtools_target_impl.h" 30 #include "chrome/browser/devtools/devtools_target_impl.h"
31 #include "chrome/browser/devtools/devtools_window.h" 31 #include "chrome/browser/devtools/devtools_window.h"
32 #include "chrome/browser/profiles/profile.h" 32 #include "chrome/browser/profiles/profile.h"
33 #include "chrome/common/pref_names.h" 33 #include "chrome/common/pref_names.h"
34 #include "components/keyed_service/content/browser_context_dependency_manager.h" 34 #include "components/keyed_service/content/browser_context_dependency_manager.h"
35 #include "content/public/browser/devtools_agent_host.h" 35 #include "content/public/browser/devtools_agent_host.h"
36 #include "content/public/browser/devtools_external_agent_proxy.h" 36 #include "content/public/browser/devtools_external_agent_proxy.h"
37 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" 37 #include "content/public/browser/devtools_external_agent_proxy_delegate.h"
38 #include "content/public/browser/user_metrics.h" 38 #include "content/public/browser/user_metrics.h"
39 #include "net/base/escape.h" 39 #include "net/base/escape.h"
40 #include "net/base/net_errors.h"
40 41
41 using content::BrowserThread; 42 using content::BrowserThread;
42 43
43 namespace { 44 namespace {
44 45
45 const char kPageListRequest[] = "/json"; 46 const char kPageListRequest[] = "/json";
46 const char kVersionRequest[] = "/json/version"; 47 const char kVersionRequest[] = "/json/version";
47 const char kClosePageRequest[] = "/json/close/%s"; 48 const char kClosePageRequest[] = "/json/close/%s";
48 const char kNewPageRequest[] = "/json/new"; 49 const char kNewPageRequest[] = "/json/new";
49 const char kNewPageRequestWithURL[] = "/json/new?%s"; 50 const char kNewPageRequestWithURL[] = "/json/new?%s";
50 const char kActivatePageRequest[] = "/json/activate/%s"; 51 const char kActivatePageRequest[] = "/json/activate/%s";
51 const char kBrowserTargetSocket[] = "/devtools/browser"; 52 const char kBrowserTargetSocket[] = "/devtools/browser";
52 const int kAdbPollingIntervalMs = 1000; 53 const int kAdbPollingIntervalMs = 1000;
53 54
54 const char kUrlParam[] = "url"; 55 const char kUrlParam[] = "url";
55 const char kPageReloadCommand[] = "Page.reload"; 56 const char kPageReloadCommand[] = "Page.reload";
56 const char kPageNavigateCommand[] = "Page.navigate"; 57 const char kPageNavigateCommand[] = "Page.navigate";
57 58
58 const int kMinVersionNewWithURL = 32; 59 const int kMinVersionNewWithURL = 32;
59 const int kNewPageNavigateDelayMs = 500; 60 const int kNewPageNavigateDelayMs = 500;
60 61
62 } // namespace
63
61 // DiscoveryRequest ----------------------------------------------------- 64 // DiscoveryRequest -----------------------------------------------------
62 65
63 class DiscoveryRequest : public base::RefCountedThreadSafe< 66 class DevToolsAndroidBridge::DiscoveryRequest
64 DiscoveryRequest, 67 : public base::RefCountedThreadSafe<DiscoveryRequest,
65 BrowserThread::DeleteOnUIThread> { 68 BrowserThread::DeleteOnUIThread> {
66 public: 69 public:
67 typedef AndroidDeviceManager::Device Device;
68 typedef AndroidDeviceManager::Devices Devices;
69 typedef AndroidDeviceManager::DeviceInfo DeviceInfo;
70 typedef DevToolsAndroidBridge::RemoteDevice RemoteDevice;
71 typedef DevToolsAndroidBridge::RemoteDevices RemoteDevices;
72 typedef DevToolsAndroidBridge::RemoteBrowser RemoteBrowser;
73 typedef DevToolsAndroidBridge::RemoteBrowsers RemoteBrowsers;
74 typedef base::Callback<void(const RemoteDevices&)> DiscoveryCallback;
75
76 DiscoveryRequest(AndroidDeviceManager* device_manager, 70 DiscoveryRequest(AndroidDeviceManager* device_manager,
77 const DiscoveryCallback& callback); 71 const DeviceListCallback& callback);
78 private: 72 private:
79 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; 73 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
80 friend class base::DeleteHelper<DiscoveryRequest>; 74 friend class base::DeleteHelper<DiscoveryRequest>;
81 virtual ~DiscoveryRequest(); 75 virtual ~DiscoveryRequest();
82 76
83 void ReceivedDevices(const Devices& devices); 77 void ReceivedDevices(const AndroidDeviceManager::Devices& devices);
84 void ReceivedDeviceInfo(scoped_refptr<Device> device, 78 void ReceivedDeviceInfo(scoped_refptr<AndroidDeviceManager::Device> device,
85 const DeviceInfo& device_info); 79 const AndroidDeviceManager::DeviceInfo& device_info);
86 void ReceivedVersion(scoped_refptr<RemoteBrowser>, 80 void ReceivedVersion(scoped_refptr<RemoteBrowser>,
87 int result, 81 int result,
88 const std::string& response); 82 const std::string& response);
89 void ReceivedPages(scoped_refptr<RemoteBrowser>, 83 void ReceivedPages(scoped_refptr<RemoteBrowser>,
90 int result, 84 int result,
91 const std::string& response); 85 const std::string& response);
92 86
93 DiscoveryCallback callback_; 87 DeviceListCallback callback_;
94 RemoteDevices remote_devices_; 88 CompleteDevices complete_devices_;
95 }; 89 };
96 90
97 DiscoveryRequest::DiscoveryRequest( 91 DevToolsAndroidBridge::DiscoveryRequest::DiscoveryRequest(
98 AndroidDeviceManager* device_manager, 92 AndroidDeviceManager* device_manager,
99 const DiscoveryCallback& callback) 93 const DeviceListCallback& callback)
100 : callback_(callback) { 94 : callback_(callback) {
101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
102 device_manager->QueryDevices( 96 device_manager->QueryDevices(
103 base::Bind(&DiscoveryRequest::ReceivedDevices, this)); 97 base::Bind(&DiscoveryRequest::ReceivedDevices, this));
104 } 98 }
105 99
106 DiscoveryRequest::~DiscoveryRequest() { 100 DevToolsAndroidBridge::DiscoveryRequest::~DiscoveryRequest() {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 101 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108 callback_.Run(remote_devices_); 102 callback_.Run(complete_devices_);
109 } 103 }
110 104
111 void DiscoveryRequest::ReceivedDevices(const Devices& devices) { 105 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedDevices(
106 const AndroidDeviceManager::Devices& devices) {
112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
113 for (Devices::const_iterator it = devices.begin(); 108 for (AndroidDeviceManager::Devices::const_iterator it = devices.begin();
dgozman 2014/10/02 12:19:34 for (const auto& device : devices)
vkuzkokov 2014/10/02 13:07:46 Done.
114 it != devices.end(); ++it) { 109 it != devices.end(); ++it) {
115 (*it)->QueryDeviceInfo( 110 (*it)->QueryDeviceInfo(
116 base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this, *it)); 111 base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this, *it));
117 } 112 }
118 } 113 }
119 114
120 void DiscoveryRequest::ReceivedDeviceInfo(scoped_refptr<Device> device, 115 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedDeviceInfo(
121 const DeviceInfo& device_info) { 116 scoped_refptr<AndroidDeviceManager::Device> device,
117 const AndroidDeviceManager::DeviceInfo& device_info) {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 118 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
123 scoped_refptr<RemoteDevice> remote_device = 119 scoped_refptr<RemoteDevice> remote_device =
124 new RemoteDevice(device, device_info); 120 new RemoteDevice(device->serial(), device_info);
125 remote_devices_.push_back(remote_device); 121 complete_devices_.push_back(std::make_pair(device, remote_device));
126 for (RemoteBrowsers::iterator it = remote_device->browsers().begin(); 122 for (RemoteBrowsers::iterator it = remote_device->browsers().begin();
127 it != remote_device->browsers().end(); ++it) { 123 it != remote_device->browsers().end(); ++it) {
128 (*it)->SendJsonRequest( 124 device->SendJsonRequest(
125 (*it)->socket(),
129 kVersionRequest, 126 kVersionRequest,
130 base::Bind(&DiscoveryRequest::ReceivedVersion, this, *it)); 127 base::Bind(&DiscoveryRequest::ReceivedVersion, this, *it));
131 (*it)->SendJsonRequest( 128 device->SendJsonRequest(
129 (*it)->socket(),
132 kPageListRequest, 130 kPageListRequest,
133 base::Bind(&DiscoveryRequest::ReceivedPages, this, *it)); 131 base::Bind(&DiscoveryRequest::ReceivedPages, this, *it));
134 } 132 }
135 } 133 }
136 134
137 void DiscoveryRequest::ReceivedVersion(scoped_refptr<RemoteBrowser> browser, 135 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedVersion(
138 int result, 136 scoped_refptr<RemoteBrowser> browser,
139 const std::string& response) { 137 int result,
138 const std::string& response) {
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 139 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
141 if (result < 0) 140 if (result < 0)
142 return; 141 return;
143 // Parse version, append to package name if available, 142 // Parse version, append to package name if available,
144 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); 143 scoped_ptr<base::Value> value(base::JSONReader::Read(response));
145 base::DictionaryValue* dict; 144 base::DictionaryValue* dict;
146 if (value && value->GetAsDictionary(&dict)) { 145 if (value && value->GetAsDictionary(&dict)) {
147 std::string browser_name; 146 std::string browser_name;
148 if (dict->GetString("Browser", &browser_name)) { 147 if (dict->GetString("Browser", &browser_name)) {
149 std::vector<std::string> parts; 148 std::vector<std::string> parts;
150 Tokenize(browser_name, "/", &parts); 149 Tokenize(browser_name, "/", &parts);
151 if (parts.size() == 2) 150 if (parts.size() == 2)
152 browser->set_version(parts[1]); 151 browser->version_ = parts[1];
153 else 152 else
154 browser->set_version(browser_name); 153 browser->version_ = browser_name;
155 } 154 }
156 std::string package; 155 std::string package;
157 if (dict->GetString("Android-Package", &package)) { 156 if (dict->GetString("Android-Package", &package)) {
158 browser->set_display_name( 157 browser->display_name_ =
159 AdbDeviceInfoQuery::GetDisplayName(browser->socket(), package)); 158 AdbDeviceInfoQuery::GetDisplayName(browser->socket(), package);
160 } 159 }
161 } 160 }
162 } 161 }
163 162
164 void DiscoveryRequest::ReceivedPages(scoped_refptr<RemoteBrowser> browser, 163 void DevToolsAndroidBridge::DiscoveryRequest::ReceivedPages(
165 int result, 164 scoped_refptr<RemoteBrowser> browser,
166 const std::string& response) { 165 int result,
166 const std::string& response) {
167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 167 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168 if (result < 0) 168 if (result < 0)
169 return; 169 return;
170 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); 170 scoped_ptr<base::Value> value(base::JSONReader::Read(response));
171 base::ListValue* list_value; 171 base::ListValue* list_value;
172 if (value && value->GetAsList(&list_value)) 172 if (value && value->GetAsList(&list_value))
173 browser->SetPageDescriptors(*list_value); 173 browser->page_descriptors_.reset(list_value->DeepCopy());
174 } 174 }
175 175
176 // ProtocolCommand ------------------------------------------------------------ 176 // ProtocolCommand ------------------------------------------------------------
177 177
178 namespace {
179
178 class ProtocolCommand 180 class ProtocolCommand
179 : public DevToolsAndroidBridge::AndroidWebSocket::Delegate { 181 : public AndroidDeviceManager::AndroidWebSocket::Delegate {
180 public: 182 public:
181 ProtocolCommand( 183 ProtocolCommand(
182 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 184 scoped_refptr<AndroidDeviceManager::Device> device,
185 const std::string& socket,
183 const std::string& debug_url, 186 const std::string& debug_url,
184 const std::string& command, 187 const std::string& command,
185 const base::Closure callback); 188 const base::Closure callback);
186 189
187 private: 190 private:
188 virtual void OnSocketOpened() OVERRIDE; 191 virtual void OnSocketOpened() OVERRIDE;
189 virtual void OnFrameRead(const std::string& message) OVERRIDE; 192 virtual void OnFrameRead(const std::string& message) OVERRIDE;
190 virtual void OnSocketClosed() OVERRIDE; 193 virtual void OnSocketClosed() OVERRIDE;
191 virtual ~ProtocolCommand(); 194 virtual ~ProtocolCommand();
192 195
193 const std::string command_; 196 const std::string command_;
194 const base::Closure callback_; 197 const base::Closure callback_;
195 scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_; 198 scoped_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_;
196 199
197 DISALLOW_COPY_AND_ASSIGN(ProtocolCommand); 200 DISALLOW_COPY_AND_ASSIGN(ProtocolCommand);
198 }; 201 };
199 202
200 ProtocolCommand::ProtocolCommand( 203 ProtocolCommand::ProtocolCommand(
201 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 204 scoped_refptr<AndroidDeviceManager::Device> device,
205 const std::string& socket,
202 const std::string& debug_url, 206 const std::string& debug_url,
203 const std::string& command, 207 const std::string& command,
204 const base::Closure callback) 208 const base::Closure callback)
205 : command_(command), 209 : command_(command),
206 callback_(callback), 210 callback_(callback),
207 web_socket_(browser->CreateWebSocket(debug_url, this)) { 211 web_socket_(device->CreateWebSocket(socket, debug_url, this)) {
208 } 212 }
209 213
210 void ProtocolCommand::OnSocketOpened() { 214 void ProtocolCommand::OnSocketOpened() {
211 web_socket_->SendFrame(command_); 215 web_socket_->SendFrame(command_);
212 } 216 }
213 217
214 void ProtocolCommand::OnFrameRead(const std::string& message) { 218 void ProtocolCommand::OnFrameRead(const std::string& message) {
215 delete this; 219 delete this;
216 } 220 }
217 221
218 void ProtocolCommand::OnSocketClosed() { 222 void ProtocolCommand::OnSocketClosed() {
219 delete this; 223 delete this;
220 } 224 }
221 225
222 ProtocolCommand::~ProtocolCommand() { 226 ProtocolCommand::~ProtocolCommand() {
223 if (!callback_.is_null()) 227 if (!callback_.is_null())
224 callback_.Run(); 228 callback_.Run();
225 } 229 }
226 230
227 } // namespace 231 } // namespace
228 232
229 class AgentHostDelegate;
230
231 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates;
232
233 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates =
234 LAZY_INSTANCE_INITIALIZER;
235
236 DevToolsAndroidBridge::Wrapper::Wrapper(content::BrowserContext* context) { 233 DevToolsAndroidBridge::Wrapper::Wrapper(content::BrowserContext* context) {
237 bridge_ = new DevToolsAndroidBridge(Profile::FromBrowserContext(context)); 234 bridge_ = new DevToolsAndroidBridge(Profile::FromBrowserContext(context));
238 } 235 }
239 236
240 DevToolsAndroidBridge::Wrapper::~Wrapper() { 237 DevToolsAndroidBridge::Wrapper::~Wrapper() {
241 } 238 }
242 239
243 DevToolsAndroidBridge* DevToolsAndroidBridge::Wrapper::Get() { 240 DevToolsAndroidBridge* DevToolsAndroidBridge::Wrapper::Get() {
244 return bridge_.get(); 241 return bridge_.get();
245 } 242 }
(...skipping 17 matching lines...) Expand all
263 "DevToolsAndroidBridge", 260 "DevToolsAndroidBridge",
264 BrowserContextDependencyManager::GetInstance()) {} 261 BrowserContextDependencyManager::GetInstance()) {}
265 262
266 DevToolsAndroidBridge::Factory::~Factory() {} 263 DevToolsAndroidBridge::Factory::~Factory() {}
267 264
268 KeyedService* DevToolsAndroidBridge::Factory::BuildServiceInstanceFor( 265 KeyedService* DevToolsAndroidBridge::Factory::BuildServiceInstanceFor(
269 content::BrowserContext* context) const { 266 content::BrowserContext* context) const {
270 return new DevToolsAndroidBridge::Wrapper(context); 267 return new DevToolsAndroidBridge::Wrapper(context);
271 } 268 }
272 269
273
274 // AgentHostDelegate ---------------------------------------------------------- 270 // AgentHostDelegate ----------------------------------------------------------
275 271
276 class AgentHostDelegate 272 class DevToolsAndroidBridge::AgentHostDelegate
277 : public content::DevToolsExternalAgentProxyDelegate, 273 : public content::DevToolsExternalAgentProxyDelegate,
278 public DevToolsAndroidBridge::AndroidWebSocket::Delegate { 274 public AndroidDeviceManager::AndroidWebSocket::Delegate {
279 public: 275 public:
280 static scoped_refptr<content::DevToolsAgentHost> GetOrCreateAgentHost( 276 static scoped_refptr<content::DevToolsAgentHost> GetOrCreateAgentHost(
277 scoped_refptr<DevToolsAndroidBridge> bridge,
281 const std::string& id, 278 const std::string& id,
282 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 279 scoped_refptr<RemoteBrowser> browser,
283 const std::string& debug_url); 280 const std::string& debug_url);
284 281
285 private: 282 private:
286 AgentHostDelegate( 283 AgentHostDelegate(
284 scoped_refptr<DevToolsAndroidBridge> bridge,
287 const std::string& id, 285 const std::string& id,
288 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 286 scoped_refptr<RemoteBrowser> browser,
289 const std::string& debug_url); 287 const std::string& debug_url);
290 virtual ~AgentHostDelegate(); 288 virtual ~AgentHostDelegate();
291 virtual void Attach(content::DevToolsExternalAgentProxy* proxy) OVERRIDE; 289 virtual void Attach(content::DevToolsExternalAgentProxy* proxy) OVERRIDE;
292 virtual void Detach() OVERRIDE; 290 virtual void Detach() OVERRIDE;
293 virtual void SendMessageToBackend( 291 virtual void SendMessageToBackend(
294 const std::string& message) OVERRIDE; 292 const std::string& message) OVERRIDE;
295 virtual void OnSocketOpened() OVERRIDE; 293 virtual void OnSocketOpened() OVERRIDE;
296 virtual void OnFrameRead(const std::string& message) OVERRIDE; 294 virtual void OnFrameRead(const std::string& message) OVERRIDE;
297 virtual void OnSocketClosed() OVERRIDE; 295 virtual void OnSocketClosed() OVERRIDE;
298 296
299 const std::string id_; 297 std::string id_;
dgozman 2014/10/02 12:19:33 Why removed const?
vkuzkokov 2014/10/02 13:07:46 for consistency.
300 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_; 298 scoped_refptr<DevToolsAndroidBridge> bridge_;
301 const std::string debug_url_; 299 scoped_refptr<RemoteBrowser> browser_;
300 std::string debug_url_;
dgozman 2014/10/02 12:19:33 ditto
302 bool socket_opened_; 301 bool socket_opened_;
303 bool is_web_view_; 302 bool is_web_view_;
304 std::vector<std::string> pending_messages_; 303 std::vector<std::string> pending_messages_;
305 scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_; 304 scoped_ptr<AndroidDeviceManager::AndroidWebSocket> web_socket_;
306 content::DevToolsAgentHost* agent_host_; 305 content::DevToolsAgentHost* agent_host_;
307 content::DevToolsExternalAgentProxy* proxy_; 306 content::DevToolsExternalAgentProxy* proxy_;
308 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); 307 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
309 }; 308 };
310 309
311 // static 310 // static
312 scoped_refptr<content::DevToolsAgentHost> 311 scoped_refptr<content::DevToolsAgentHost>
313 AgentHostDelegate::GetOrCreateAgentHost( 312 DevToolsAndroidBridge::AgentHostDelegate::GetOrCreateAgentHost(
313 scoped_refptr<DevToolsAndroidBridge> bridge,
314 const std::string& id, 314 const std::string& id,
315 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 315 scoped_refptr<RemoteBrowser> browser,
316 const std::string& debug_url) { 316 const std::string& debug_url) {
317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 317 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
318 AgentHostDelegates::iterator it = g_host_delegates.Get().find(id); 318 AgentHostDelegates::iterator it = bridge->host_delegates_.find(id);
319 if (it != g_host_delegates.Get().end()) 319 if (it != bridge->host_delegates_.end())
320 return it->second->agent_host_; 320 return it->second->agent_host_;
321 321
322 AgentHostDelegate* delegate = new AgentHostDelegate(id, browser, debug_url); 322 AgentHostDelegate* delegate =
323 new AgentHostDelegate(bridge, id, browser, debug_url);
323 scoped_refptr<content::DevToolsAgentHost> result = 324 scoped_refptr<content::DevToolsAgentHost> result =
324 content::DevToolsAgentHost::Create(delegate); 325 content::DevToolsAgentHost::Create(delegate);
325 delegate->agent_host_ = result.get(); 326 delegate->agent_host_ = result.get();
326 return result; 327 return result;
327 } 328 }
328 329
329 AgentHostDelegate::AgentHostDelegate( 330 DevToolsAndroidBridge::AgentHostDelegate::AgentHostDelegate(
331 scoped_refptr<DevToolsAndroidBridge> bridge,
330 const std::string& id, 332 const std::string& id,
331 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 333 scoped_refptr<RemoteBrowser> browser,
332 const std::string& debug_url) 334 const std::string& debug_url)
333 : id_(id), 335 : id_(id),
336 bridge_(bridge),
334 browser_(browser), 337 browser_(browser),
335 debug_url_(debug_url), 338 debug_url_(debug_url),
336 socket_opened_(false), 339 socket_opened_(false),
337 is_web_view_(browser->IsWebView()), 340 is_web_view_(browser->IsWebView()),
338 agent_host_(NULL), 341 agent_host_(NULL),
339 proxy_(NULL) { 342 proxy_(NULL) {
340 g_host_delegates.Get()[id] = this; 343 bridge_->host_delegates_[id] = this;
341 } 344 }
342 345
343 AgentHostDelegate::~AgentHostDelegate() { 346 DevToolsAndroidBridge::AgentHostDelegate::~AgentHostDelegate() {
344 g_host_delegates.Get().erase(id_); 347 bridge_->host_delegates_.erase(id_);
345 } 348 }
346 349
347 void AgentHostDelegate::Attach(content::DevToolsExternalAgentProxy* proxy) { 350 void DevToolsAndroidBridge::AgentHostDelegate::Attach(
351 content::DevToolsExternalAgentProxy* proxy) {
348 proxy_ = proxy; 352 proxy_ = proxy;
349 content::RecordAction(base::UserMetricsAction(is_web_view_ ? 353 content::RecordAction(base::UserMetricsAction(is_web_view_ ?
350 "DevTools_InspectAndroidWebView" : "DevTools_InspectAndroidPage")); 354 "DevTools_InspectAndroidWebView" : "DevTools_InspectAndroidPage"));
351 web_socket_.reset(browser_->CreateWebSocket(debug_url_, this)); 355 web_socket_.reset(
356 bridge_->CreateWebSocket(browser_, debug_url_, this));
352 } 357 }
353 358
354 void AgentHostDelegate::Detach() { 359 void DevToolsAndroidBridge::AgentHostDelegate::Detach() {
355 web_socket_.reset(); 360 web_socket_.reset();
356 } 361 }
357 362
358 void AgentHostDelegate::SendMessageToBackend(const std::string& message) { 363 void DevToolsAndroidBridge::AgentHostDelegate::SendMessageToBackend(
364 const std::string& message) {
359 if (socket_opened_) 365 if (socket_opened_)
360 web_socket_->SendFrame(message); 366 web_socket_->SendFrame(message);
361 else 367 else
362 pending_messages_.push_back(message); 368 pending_messages_.push_back(message);
363 } 369 }
364 370
365 void AgentHostDelegate::OnSocketOpened() { 371 void DevToolsAndroidBridge::AgentHostDelegate::OnSocketOpened() {
366 socket_opened_ = true; 372 socket_opened_ = true;
367 for (std::vector<std::string>::iterator it = pending_messages_.begin(); 373 for (std::vector<std::string>::iterator it = pending_messages_.begin();
368 it != pending_messages_.end(); ++it) { 374 it != pending_messages_.end(); ++it) {
369 SendMessageToBackend(*it); 375 SendMessageToBackend(*it);
370 } 376 }
371 pending_messages_.clear(); 377 pending_messages_.clear();
372 } 378 }
373 379
374 void AgentHostDelegate::OnFrameRead(const std::string& message) { 380 void DevToolsAndroidBridge::AgentHostDelegate::OnFrameRead(
381 const std::string& message) {
375 if (proxy_) 382 if (proxy_)
376 proxy_->DispatchOnClientHost(message); 383 proxy_->DispatchOnClientHost(message);
377 } 384 }
378 385
379 void AgentHostDelegate::OnSocketClosed() { 386 void DevToolsAndroidBridge::AgentHostDelegate::OnSocketClosed() {
380 if (proxy_) 387 if (proxy_)
381 proxy_->ConnectionClosed(); 388 proxy_->ConnectionClosed();
382 } 389 }
383 390
384 //// RemotePageTarget ---------------------------------------------- 391 //// RemotePageTarget ----------------------------------------------
385 392
386 class RemotePageTarget : public DevToolsTargetImpl, 393 class DevToolsAndroidBridge::RemotePageTarget
387 public DevToolsAndroidBridge::RemotePage { 394 : public DevToolsTargetImpl,
395 public DevToolsAndroidBridge::RemotePage {
388 public: 396 public:
389 RemotePageTarget(scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 397 RemotePageTarget(scoped_refptr<DevToolsAndroidBridge> bridge,
398 scoped_refptr<RemoteBrowser> browser,
390 const base::DictionaryValue& value); 399 const base::DictionaryValue& value);
391 virtual ~RemotePageTarget(); 400 virtual ~RemotePageTarget();
392 401
393 // DevToolsAndroidBridge::RemotePage implementation. 402 // DevToolsAndroidBridge::RemotePage implementation.
394 virtual DevToolsTargetImpl* GetTarget() OVERRIDE; 403 virtual DevToolsTargetImpl* GetTarget() OVERRIDE;
395 virtual std::string GetFrontendURL() OVERRIDE; 404 virtual std::string GetFrontendURL() OVERRIDE;
396 405
397 // DevToolsTargetImpl overrides. 406 // DevToolsTargetImpl overrides.
398 virtual std::string GetId() const OVERRIDE; 407 virtual std::string GetId() const OVERRIDE;
399 virtual bool IsAttached() const OVERRIDE; 408 virtual bool IsAttached() const OVERRIDE;
400 virtual bool Activate() const OVERRIDE; 409 virtual bool Activate() const OVERRIDE;
401 virtual bool Close() const OVERRIDE; 410 virtual bool Close() const OVERRIDE;
402 virtual void Inspect(Profile* profile) const OVERRIDE; 411 virtual void Inspect(Profile* profile) const OVERRIDE;
403 virtual void Reload() const OVERRIDE; 412 virtual void Reload() const OVERRIDE;
404 413
405 void Navigate(const std::string& url, base::Closure callback) const; 414 void Navigate(const std::string& url, base::Closure callback) const;
406 415
407 private: 416 private:
408 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_; 417 scoped_refptr<DevToolsAndroidBridge> bridge_;
418 scoped_refptr<RemoteBrowser> browser_;
409 std::string debug_url_; 419 std::string debug_url_;
410 std::string frontend_url_; 420 std::string frontend_url_;
411 std::string remote_id_; 421 std::string remote_id_;
412 std::string remote_type_; 422 std::string remote_type_;
413 std::string local_id_; 423 std::string local_id_;
414 DISALLOW_COPY_AND_ASSIGN(RemotePageTarget); 424 DISALLOW_COPY_AND_ASSIGN(RemotePageTarget);
415 }; 425 };
416 426
417 static std::string GetStringProperty(const base::DictionaryValue& value, 427 static std::string GetStringProperty(const base::DictionaryValue& value,
418 const std::string& name) { 428 const std::string& name) {
419 std::string result; 429 std::string result;
420 value.GetString(name, &result); 430 value.GetString(name, &result);
421 return result; 431 return result;
422 } 432 }
423 433
424 static std::string BuildUniqueTargetId( 434 static std::string BuildUniqueTargetId(
425 DevToolsAndroidBridge::RemoteBrowser* browser, 435 DevToolsAndroidBridge::RemoteBrowser* browser,
426 const base::DictionaryValue& value) { 436 const base::DictionaryValue& value) {
427 return base::StringPrintf("%s:%s:%s", browser->serial().c_str(), 437 return base::StringPrintf("%s:%s:%s", browser->serial().c_str(),
428 browser->socket().c_str(), GetStringProperty(value, "id").c_str()); 438 browser->socket().c_str(), GetStringProperty(value, "id").c_str());
429 } 439 }
430 440
431 static std::string GetDebugURL(const base::DictionaryValue& value) { 441 static std::string GetDebugURL(const base::DictionaryValue& value) {
432 std::string debug_url = GetStringProperty(value, "webSocketDebuggerUrl"); 442 std::string debug_url = GetStringProperty(value, "webSocketDebuggerUrl");
433 443
434 if (debug_url.find("ws://") == 0) 444 if (debug_url.find("ws://") == 0)
435 debug_url = debug_url.substr(5); 445 debug_url = debug_url.substr(5);
436 else 446 else
437 debug_url = ""; 447 debug_url = std::string();
438 return debug_url; 448 return debug_url;
439 } 449 }
440 450
441 RemotePageTarget::RemotePageTarget( 451 DevToolsAndroidBridge::RemotePageTarget::RemotePageTarget(
442 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, 452 scoped_refptr<DevToolsAndroidBridge> bridge,
453 scoped_refptr<RemoteBrowser> browser,
443 const base::DictionaryValue& value) 454 const base::DictionaryValue& value)
444 : DevToolsTargetImpl(AgentHostDelegate::GetOrCreateAgentHost( 455 : DevToolsTargetImpl(AgentHostDelegate::GetOrCreateAgentHost(
456 bridge,
445 BuildUniqueTargetId(browser.get(), value), 457 BuildUniqueTargetId(browser.get(), value),
446 browser, GetDebugURL(value))), 458 browser,
459 GetDebugURL(value))),
460 bridge_(bridge),
447 browser_(browser), 461 browser_(browser),
448 debug_url_(GetDebugURL(value)), 462 debug_url_(GetDebugURL(value)),
449 remote_id_(GetStringProperty(value, "id")), 463 remote_id_(GetStringProperty(value, "id")),
450 remote_type_(GetStringProperty(value, "type")), 464 remote_type_(GetStringProperty(value, "type")),
451 local_id_(BuildUniqueTargetId(browser.get(), value)) { 465 local_id_(BuildUniqueTargetId(browser.get(), value)) {
452 set_type("adb_page"); 466 set_type("adb_page");
453 set_url(GURL(GetStringProperty(value, "url"))); 467 set_url(GURL(GetStringProperty(value, "url")));
454 set_title(base::UTF16ToUTF8(net::UnescapeForHTML(base::UTF8ToUTF16( 468 set_title(base::UTF16ToUTF8(net::UnescapeForHTML(base::UTF8ToUTF16(
455 GetStringProperty(value, "title"))))); 469 GetStringProperty(value, "title")))));
456 set_description(GetStringProperty(value, "description")); 470 set_description(GetStringProperty(value, "description"));
457 set_favicon_url(GURL(GetStringProperty(value, "faviconUrl"))); 471 set_favicon_url(GURL(GetStringProperty(value, "faviconUrl")));
458 debug_url_ = GetDebugURL(value); 472 debug_url_ = GetDebugURL(value);
459 frontend_url_ = GetStringProperty(value, "devtoolsFrontendUrl"); 473 frontend_url_ = GetStringProperty(value, "devtoolsFrontendUrl");
460 474
461 size_t ws_param = frontend_url_.find("?ws"); 475 size_t ws_param = frontend_url_.find("?ws");
462 if (ws_param != std::string::npos) 476 if (ws_param != std::string::npos)
463 frontend_url_ = frontend_url_.substr(0, ws_param); 477 frontend_url_ = frontend_url_.substr(0, ws_param);
464 if (frontend_url_.find("http:") == 0) 478 if (frontend_url_.find("http:") == 0)
465 frontend_url_ = "https:" + frontend_url_.substr(5); 479 frontend_url_ = "https:" + frontend_url_.substr(5);
466 } 480 }
467 481
468 RemotePageTarget::~RemotePageTarget() { 482 DevToolsAndroidBridge::RemotePageTarget::~RemotePageTarget() {
469 } 483 }
470 484
471 DevToolsTargetImpl* RemotePageTarget::GetTarget() { 485 DevToolsTargetImpl* DevToolsAndroidBridge::RemotePageTarget::GetTarget() {
472 return this; 486 return this;
473 } 487 }
474 488
475 std::string RemotePageTarget::GetFrontendURL() { 489 std::string DevToolsAndroidBridge::RemotePageTarget::GetFrontendURL() {
476 return frontend_url_; 490 return frontend_url_;
477 } 491 }
478 492
479 std::string RemotePageTarget::GetId() const { 493 std::string DevToolsAndroidBridge::RemotePageTarget::GetId() const {
480 return local_id_; 494 return local_id_;
481 } 495 }
482 496
483 bool RemotePageTarget::IsAttached() const { 497 bool DevToolsAndroidBridge::RemotePageTarget::IsAttached() const {
484 return debug_url_.empty(); 498 return debug_url_.empty();
485 } 499 }
486 500
487 static void NoOp(int, const std::string&) {} 501 static void NoOp(int, const std::string&) {}
488 502
489 void RemotePageTarget::Inspect(Profile* profile) const { 503 void DevToolsAndroidBridge::RemotePageTarget::Inspect(Profile* profile) const {
490 Activate(); 504 Activate();
491 bool isWorker = remote_type_ == kTargetTypeWorker || 505 bool isWorker = remote_type_ == kTargetTypeWorker ||
492 remote_type_ == kTargetTypeServiceWorker; 506 remote_type_ == kTargetTypeServiceWorker;
493 DevToolsWindow::OpenExternalFrontend(profile, frontend_url_, GetAgentHost(), 507 DevToolsWindow::OpenExternalFrontend(profile, frontend_url_, GetAgentHost(),
494 isWorker); 508 isWorker);
495 } 509 }
496 510
497 bool RemotePageTarget::Activate() const { 511 bool DevToolsAndroidBridge::RemotePageTarget::Activate() const {
498 std::string request = base::StringPrintf(kActivatePageRequest, 512 std::string request = base::StringPrintf(kActivatePageRequest,
499 remote_id_.c_str()); 513 remote_id_.c_str());
500 browser_->SendJsonRequest(request, base::Bind(&NoOp)); 514 bridge_->SendJsonRequest(browser_, request, base::Bind(&NoOp));
501 return true; 515 return true;
502 } 516 }
503 517
504 bool RemotePageTarget::Close() const { 518 bool DevToolsAndroidBridge::RemotePageTarget::Close() const {
505 std::string request = base::StringPrintf(kClosePageRequest, 519 std::string request = base::StringPrintf(kClosePageRequest,
506 remote_id_.c_str()); 520 remote_id_.c_str());
507 browser_->SendJsonRequest(request, base::Bind(&NoOp)); 521 bridge_->SendJsonRequest(browser_, request, base::Bind(&NoOp));
508 return true; 522 return true;
509 } 523 }
510 524
511 void RemotePageTarget::Reload() const { 525 void DevToolsAndroidBridge::RemotePageTarget::Reload() const {
512 browser_->SendProtocolCommand(debug_url_, kPageReloadCommand, NULL, 526 bridge_->SendProtocolCommand(browser_, debug_url_, kPageReloadCommand,
513 base::Closure()); 527 NULL, base::Closure());
514 } 528 }
515 529
516 void RemotePageTarget::Navigate(const std::string& url, 530 void DevToolsAndroidBridge::RemotePageTarget::Navigate(
517 base::Closure callback) const { 531 const std::string& url,
532 base::Closure callback) const {
518 base::DictionaryValue params; 533 base::DictionaryValue params;
519 params.SetString(kUrlParam, url); 534 params.SetString(kUrlParam, url);
520 browser_->SendProtocolCommand(debug_url_, kPageNavigateCommand, &params, 535 bridge_->SendProtocolCommand(browser_, debug_url_, kPageNavigateCommand,
521 callback); 536 &params, callback);
522 } 537 }
523 538
524 // DevToolsAndroidBridge::RemoteBrowser --------------------------------------- 539 // DevToolsAndroidBridge::RemoteBrowser ---------------------------------------
525 540
526 DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser( 541 DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser(
527 scoped_refptr<Device> device, 542 const std::string& serial,
528 const AndroidDeviceManager::BrowserInfo& browser_info) 543 const AndroidDeviceManager::BrowserInfo& browser_info)
529 : device_(device), 544 : serial_(serial),
530 socket_(browser_info.socket_name), 545 socket_(browser_info.socket_name),
531 display_name_(browser_info.display_name), 546 display_name_(browser_info.display_name),
532 type_(browser_info.type), 547 type_(browser_info.type),
533 page_descriptors_(new base::ListValue()) { 548 page_descriptors_(new base::ListValue()) {
534 } 549 }
535 550
536 bool DevToolsAndroidBridge::RemoteBrowser::IsChrome() const { 551 bool DevToolsAndroidBridge::RemoteBrowser::IsChrome() {
537 return type_ == AndroidDeviceManager::BrowserInfo::kTypeChrome; 552 return type_ == AndroidDeviceManager::BrowserInfo::kTypeChrome;
538 } 553 }
539 554
540 bool DevToolsAndroidBridge::RemoteBrowser::IsWebView() const { 555 bool DevToolsAndroidBridge::RemoteBrowser::IsWebView() {
541 return type_ == AndroidDeviceManager::BrowserInfo::kTypeWebView; 556 return type_ == AndroidDeviceManager::BrowserInfo::kTypeWebView;
542 } 557 }
543 558
544 DevToolsAndroidBridge::RemoteBrowser::ParsedVersion 559 DevToolsAndroidBridge::RemoteBrowser::ParsedVersion
545 DevToolsAndroidBridge::RemoteBrowser::GetParsedVersion() const { 560 DevToolsAndroidBridge::RemoteBrowser::GetParsedVersion() {
546 ParsedVersion result; 561 ParsedVersion result;
547 std::vector<std::string> parts; 562 std::vector<std::string> parts;
548 Tokenize(version_, ".", &parts); 563 Tokenize(version_, ".", &parts);
549 for (size_t i = 0; i != parts.size(); ++i) { 564 for (size_t i = 0; i != parts.size(); ++i) {
550 int value = 0; 565 int value = 0;
551 base::StringToInt(parts[i], &value); 566 base::StringToInt(parts[i], &value);
552 result.push_back(value); 567 result.push_back(value);
553 } 568 }
554 return result; 569 return result;
555 } 570 }
556 571
557 std::vector<DevToolsAndroidBridge::RemotePage*> 572 std::vector<DevToolsAndroidBridge::RemotePage*>
558 DevToolsAndroidBridge::RemoteBrowser::CreatePages() { 573 DevToolsAndroidBridge::CreatePages(scoped_refptr<RemoteBrowser> browser) {
559 std::vector<DevToolsAndroidBridge::RemotePage*> result; 574 std::vector<RemotePage*> result;
560 for (size_t i = 0; i < page_descriptors_->GetSize(); ++i) { 575 for (base::ListValue::const_iterator it = browser->page_descriptors().begin();
dgozman 2014/10/02 12:19:34 for (const auto& list : browser->page_descriptors(
vkuzkokov 2014/10/02 13:07:46 Done.
561 base::Value* item; 576 it != browser->page_descriptors().end(); ++it) {
562 page_descriptors_->Get(i, &item);
563 if (!item)
564 continue;
565 base::DictionaryValue* dict; 577 base::DictionaryValue* dict;
566 if (!item->GetAsDictionary(&dict)) 578 if (*it && (*it)->GetAsDictionary(&dict))
567 continue; 579 result.push_back(new RemotePageTarget(this, browser, *dict));
568 result.push_back(new RemotePageTarget(this, *dict));
569 } 580 }
570 return result; 581 return result;
571 } 582 }
572 583
573 void DevToolsAndroidBridge::RemoteBrowser::SetPageDescriptors( 584 const base::ListValue&
574 const base::ListValue& list) { 585 DevToolsAndroidBridge::RemoteBrowser::page_descriptors() {
575 page_descriptors_.reset(list.DeepCopy()); 586 return *page_descriptors_;
576 } 587 }
577 588
578 static void RespondOnUIThread( 589 void DevToolsAndroidBridge::SendJsonRequest(
579 const DevToolsAndroidBridge::JsonRequestCallback& callback, 590 scoped_refptr<RemoteBrowser> browser,
580 int result, 591 const std::string& request,
581 const std::string& response) { 592 const JsonRequestCallback& callback) {
582 if (callback.is_null()) 593 DeviceMap::iterator it = device_map_.find(browser->serial());
594 if (it == device_map_.end()) {
595 callback.Run(net::ERR_FAILED, std::string());
583 return; 596 return;
584 BrowserThread::PostTask( 597 }
585 BrowserThread::UI, FROM_HERE, base::Bind(callback, result, response)); 598 it->second->SendJsonRequest(browser->socket(), request, callback);
586 } 599 }
587 600
588 void DevToolsAndroidBridge::RemoteBrowser::SendJsonRequest( 601 void DevToolsAndroidBridge::SendProtocolCommand(
589 const std::string& request, const JsonRequestCallback& callback) { 602 scoped_refptr<RemoteBrowser> browser,
590 device_->SendJsonRequest(socket_, request, callback);
591 }
592
593 void DevToolsAndroidBridge::RemoteBrowser::SendProtocolCommand(
594 const std::string& debug_url, 603 const std::string& debug_url,
595 const std::string& method, 604 const std::string& method,
596 base::DictionaryValue* params, 605 base::DictionaryValue* params,
597 const base::Closure callback) { 606 const base::Closure callback) {
598 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 607 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
599 if (debug_url.empty()) 608 if (debug_url.empty())
600 return; 609 return;
610 DeviceMap::iterator it = device_map_.find(browser->serial());
611 if (it == device_map_.end()) {
612 callback.Run();
613 return;
614 }
601 DevToolsProtocol::Command command(1, method, params); 615 DevToolsProtocol::Command command(1, method, params);
602 new ProtocolCommand(this, debug_url, command.Serialize(), callback); 616 new ProtocolCommand(it->second, browser->socket(), debug_url,
603 } 617 command.Serialize(), callback);
604
605 void DevToolsAndroidBridge::RemoteBrowser::Open(
606 const std::string& url,
607 const DevToolsAndroidBridge::RemotePageCallback& callback) {
608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
609 InnerOpen(url, base::Bind(&RemoteBrowser::RespondToOpenOnUIThread,
610 this, callback));
611 } 618 }
612 619
613 scoped_refptr<content::DevToolsAgentHost> 620 scoped_refptr<content::DevToolsAgentHost>
614 DevToolsAndroidBridge::RemoteBrowser::GetAgentHost() { 621 DevToolsAndroidBridge::GetBrowserAgentHost(
622 scoped_refptr<RemoteBrowser> browser) {
615 return AgentHostDelegate::GetOrCreateAgentHost( 623 return AgentHostDelegate::GetOrCreateAgentHost(
616 "adb:" + device_->serial() + ":" + socket_, this, kBrowserTargetSocket); 624 this,
625 "adb:" + browser->serial() + ":" + browser->socket(),
626 browser,
627 kBrowserTargetSocket);
617 } 628 }
618 629
619 DevToolsAndroidBridge::AndroidWebSocket* 630 AndroidDeviceManager::AndroidWebSocket*
620 DevToolsAndroidBridge::RemoteBrowser::CreateWebSocket( 631 DevToolsAndroidBridge::CreateWebSocket(
632 scoped_refptr<RemoteBrowser> browser,
621 const std::string& url, 633 const std::string& url,
622 DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate) { 634 AndroidDeviceManager::AndroidWebSocket::Delegate* delegate) {
623 return device_->CreateWebSocket(socket_, url, delegate); 635 DeviceMap::iterator it = device_map_.find(browser->serial());
636 if (it == device_map_.end())
637 return NULL;
638
639 return it->second->CreateWebSocket(browser->socket(), url, delegate);
624 } 640 }
625 641
626 void DevToolsAndroidBridge::RemoteBrowser::RespondToOpenOnUIThread( 642 void DevToolsAndroidBridge::RespondToOpenOnUIThread(
627 const DevToolsAndroidBridge::RemotePageCallback& callback, 643 scoped_refptr<RemoteBrowser> browser,
644 const RemotePageCallback& callback,
628 int result, 645 int result,
629 const std::string& response) { 646 const std::string& response) {
630 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 647 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
631 if (result < 0) { 648 if (result < 0) {
632 callback.Run(NULL); 649 callback.Run(NULL);
633 return; 650 return;
634 } 651 }
635 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); 652 scoped_ptr<base::Value> value(base::JSONReader::Read(response));
636 base::DictionaryValue* dict; 653 base::DictionaryValue* dict;
637 if (value && value->GetAsDictionary(&dict)) { 654 if (value && value->GetAsDictionary(&dict)) {
638 RemotePageTarget* new_page = new RemotePageTarget(this, *dict); 655 RemotePageTarget* new_page = new RemotePageTarget(this, browser, *dict);
639 callback.Run(new_page); 656 callback.Run(new_page);
640 } 657 }
641 } 658 }
642 659
643 void DevToolsAndroidBridge::RemoteBrowser::InnerOpen( 660 void DevToolsAndroidBridge::Open(
661 scoped_refptr<RemoteBrowser> browser,
644 const std::string& input_url, 662 const std::string& input_url,
645 const JsonRequestCallback& callback) { 663 const DevToolsAndroidBridge::RemotePageCallback& callback) {
646 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 664 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
647 GURL gurl(input_url); 665 GURL gurl(input_url);
648 if (!gurl.is_valid()) { 666 if (!gurl.is_valid()) {
649 gurl = GURL("http://" + input_url); 667 gurl = GURL("http://" + input_url);
650 if (!gurl.is_valid()) 668 if (!gurl.is_valid())
651 return; 669 return;
652 } 670 }
653 std::string url = gurl.spec(); 671 std::string url = gurl.spec();
672 RemoteBrowser::ParsedVersion parsed_version = browser->GetParsedVersion();
654 673
655 ParsedVersion parsed_version = GetParsedVersion(); 674 if (browser->IsChrome() &&
656 if (IsChrome() &&
657 !parsed_version.empty() && 675 !parsed_version.empty() &&
658 parsed_version[0] >= kMinVersionNewWithURL) { 676 parsed_version[0] >= kMinVersionNewWithURL) {
659 std::string query = net::EscapeQueryParamValue(url, false /* use_plus */); 677 std::string query = net::EscapeQueryParamValue(url, false /* use_plus */);
660 std::string request = 678 std::string request =
661 base::StringPrintf(kNewPageRequestWithURL, query.c_str()); 679 base::StringPrintf(kNewPageRequestWithURL, query.c_str());
662 SendJsonRequest(request, callback); 680 SendJsonRequest(browser, request,
681 base::Bind(&DevToolsAndroidBridge::RespondToOpenOnUIThread,
682 this, browser, callback));
663 } else { 683 } else {
664 SendJsonRequest(kNewPageRequest, 684 SendJsonRequest(browser, kNewPageRequest,
665 base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, 685 base::Bind(&DevToolsAndroidBridge::PageCreatedOnUIThread,
666 callback, url)); 686 this, browser, callback, url));
667 } 687 }
668 } 688 }
669 689
670 void DevToolsAndroidBridge::RemoteBrowser::PageCreatedOnUIThread( 690 void DevToolsAndroidBridge::PageCreatedOnUIThread(
671 const JsonRequestCallback& callback, 691 scoped_refptr<RemoteBrowser> browser,
672 const std::string& url, int result, const std::string& response) { 692 const RemotePageCallback& callback,
693 const std::string& url,
694 int result,
695 const std::string& response) {
673 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 696 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
674 697
675 if (result < 0) 698 if (result < 0)
676 return; 699 return;
677 // Navigating too soon after the page creation breaks navigation history 700 // Navigating too soon after the page creation breaks navigation history
678 // (crbug.com/311014). This can be avoided by adding a moderate delay. 701 // (crbug.com/311014). This can be avoided by adding a moderate delay.
679 BrowserThread::PostDelayedTask( 702 BrowserThread::PostDelayedTask(
680 BrowserThread::UI, FROM_HERE, 703 BrowserThread::UI, FROM_HERE,
681 base::Bind(&RemoteBrowser::NavigatePageOnUIThread, 704 base::Bind(&DevToolsAndroidBridge::NavigatePageOnUIThread,
682 this, callback, result, response, url), 705 this, browser, callback, result, response, url),
683 base::TimeDelta::FromMilliseconds(kNewPageNavigateDelayMs)); 706 base::TimeDelta::FromMilliseconds(kNewPageNavigateDelayMs));
684 } 707 }
685 708
686 void DevToolsAndroidBridge::RemoteBrowser::NavigatePageOnUIThread( 709 void DevToolsAndroidBridge::NavigatePageOnUIThread(
687 const JsonRequestCallback& callback, 710 scoped_refptr<RemoteBrowser> browser,
688 int result, const std::string& response, const std::string& url) { 711 const RemotePageCallback& callback,
712 int result,
713 const std::string& response,
714 const std::string& url) {
689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
690 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); 716 scoped_ptr<base::Value> value(base::JSONReader::Read(response));
691 base::DictionaryValue* dict; 717 base::DictionaryValue* dict;
692 718
693 if (value && value->GetAsDictionary(&dict)) { 719 if (value && value->GetAsDictionary(&dict)) {
694 RemotePageTarget new_page(this, *dict); 720 RemotePageTarget new_page(this, browser, *dict);
695 new_page.Navigate(url, 721 new_page.Navigate(url,
696 base::Bind(&RespondOnUIThread, callback, result, response)); 722 base::Bind(&DevToolsAndroidBridge::RespondToOpenOnUIThread,
723 this, browser, callback, result, response));
697 } 724 }
698 } 725 }
699 726
700 DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() { 727 DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() {
701 } 728 }
702 729
703 // DevToolsAndroidBridge::RemoteDevice ---------------------------------------- 730 // DevToolsAndroidBridge::RemoteDevice ----------------------------------------
704 731
705 DevToolsAndroidBridge::RemoteDevice::RemoteDevice( 732 DevToolsAndroidBridge::RemoteDevice::RemoteDevice(
706 scoped_refptr<AndroidDeviceManager::Device> device, 733 const std::string& serial,
707 const AndroidDeviceManager::DeviceInfo& device_info) 734 const AndroidDeviceManager::DeviceInfo& device_info)
708 : device_(device), 735 : serial_(serial),
709 model_(device_info.model), 736 model_(device_info.model),
710 connected_(device_info.connected), 737 connected_(device_info.connected),
711 screen_size_(device_info.screen_size) { 738 screen_size_(device_info.screen_size) {
712 for (std::vector<AndroidDeviceManager::BrowserInfo>::const_iterator it = 739 for (std::vector<AndroidDeviceManager::BrowserInfo>::const_iterator it =
713 device_info.browser_info.begin(); 740 device_info.browser_info.begin();
714 it != device_info.browser_info.end(); 741 it != device_info.browser_info.end();
715 ++it) { 742 ++it) {
716 browsers_.push_back(new DevToolsAndroidBridge::RemoteBrowser(device, *it)); 743 browsers_.push_back(new RemoteBrowser(serial, *it));
717 } 744 }
718 } 745 }
719 746
720 void DevToolsAndroidBridge::RemoteDevice::OpenSocket(
721 const std::string& socket_name,
722 const AndroidDeviceManager::SocketCallback& callback) {
723 device_->OpenSocket(socket_name, callback);
724 }
725
726 DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() { 747 DevToolsAndroidBridge::RemoteDevice::~RemoteDevice() {
727 } 748 }
728 749
729 // DevToolsAndroidBridge ------------------------------------------------------ 750 // DevToolsAndroidBridge ------------------------------------------------------
730 751
731 DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile) 752 DevToolsAndroidBridge::DevToolsAndroidBridge(Profile* profile)
732 : profile_(profile), 753 : profile_(profile),
733 device_manager_(AndroidDeviceManager::Create()), 754 device_manager_(AndroidDeviceManager::Create()),
734 task_scheduler_(base::Bind(&DevToolsAndroidBridge::ScheduleTaskDefault)), 755 task_scheduler_(base::Bind(&DevToolsAndroidBridge::ScheduleTaskDefault)),
735 port_forwarding_controller_(new PortForwardingController(profile)) { 756 port_forwarding_controller_(new PortForwardingController(profile)) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 PortForwardingListeners::iterator it = std::find( 813 PortForwardingListeners::iterator it = std::find(
793 port_forwarding_listeners_.begin(), 814 port_forwarding_listeners_.begin(),
794 port_forwarding_listeners_.end(), 815 port_forwarding_listeners_.end(),
795 listener); 816 listener);
796 DCHECK(it != port_forwarding_listeners_.end()); 817 DCHECK(it != port_forwarding_listeners_.end());
797 port_forwarding_listeners_.erase(it); 818 port_forwarding_listeners_.erase(it);
798 if (!NeedsDeviceListPolling()) 819 if (!NeedsDeviceListPolling())
799 StopDeviceListPolling(); 820 StopDeviceListPolling();
800 } 821 }
801 822
802 // static
803 bool DevToolsAndroidBridge::HasDevToolsWindow(const std::string& agent_id) { 823 bool DevToolsAndroidBridge::HasDevToolsWindow(const std::string& agent_id) {
804 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 824 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
805 return g_host_delegates.Get().find(agent_id) != g_host_delegates.Get().end(); 825 return host_delegates_.find(agent_id) != host_delegates_.end();
806 } 826 }
807 827
808 DevToolsAndroidBridge::~DevToolsAndroidBridge() { 828 DevToolsAndroidBridge::~DevToolsAndroidBridge() {
809 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 829 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
810 DCHECK(device_list_listeners_.empty()); 830 DCHECK(device_list_listeners_.empty());
811 DCHECK(device_count_listeners_.empty()); 831 DCHECK(device_count_listeners_.empty());
812 DCHECK(port_forwarding_listeners_.empty()); 832 DCHECK(port_forwarding_listeners_.empty());
813 } 833 }
814 834
815 void DevToolsAndroidBridge::StartDeviceListPolling() { 835 void DevToolsAndroidBridge::StartDeviceListPolling() {
816 device_list_callback_.Reset( 836 device_list_callback_.Reset(
817 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this)); 837 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceList, this));
818 RequestDeviceList(device_list_callback_.callback()); 838 RequestDeviceList(device_list_callback_.callback());
819 } 839 }
820 840
821 void DevToolsAndroidBridge::StopDeviceListPolling() { 841 void DevToolsAndroidBridge::StopDeviceListPolling() {
822 device_list_callback_.Cancel(); 842 device_list_callback_.Cancel();
823 devices_.clear(); 843 device_map_.clear();
824 } 844 }
825 845
826 bool DevToolsAndroidBridge::NeedsDeviceListPolling() { 846 bool DevToolsAndroidBridge::NeedsDeviceListPolling() {
827 return !device_list_listeners_.empty() || !port_forwarding_listeners_.empty(); 847 return !device_list_listeners_.empty() || !port_forwarding_listeners_.empty();
828 } 848 }
829 849
830 void DevToolsAndroidBridge::RequestDeviceList( 850 void DevToolsAndroidBridge::RequestDeviceList(
831 const base::Callback<void(const RemoteDevices&)>& callback) { 851 const DeviceListCallback& callback) {
832 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 852 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
833 853
834 if (!NeedsDeviceListPolling() || 854 if (!NeedsDeviceListPolling() ||
835 !callback.Equals(device_list_callback_.callback())) 855 !callback.Equals(device_list_callback_.callback()))
836 return; 856 return;
837 857
838 new DiscoveryRequest(device_manager_.get(), callback); 858 new DiscoveryRequest(device_manager_.get(), callback);
839 } 859 }
840 860
841 void DevToolsAndroidBridge::ReceivedDeviceList(const RemoteDevices& devices) { 861 void DevToolsAndroidBridge::ReceivedDeviceList(
862 const CompleteDevices& complete_devices) {
842 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 863 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
843 864
865 device_map_.clear();
866 RemoteDevices remote_devices;
867 for (CompleteDevices::const_iterator it = complete_devices.begin();
dgozman 2014/10/02 12:19:34 for (const auto& pair : complete_devices)
vkuzkokov 2014/10/02 13:07:46 Done.
868 it != complete_devices.end(); ++it) {
869 device_map_[it->first->serial()] = it->first;
870 remote_devices.push_back(it->second);
871 }
872
844 DeviceListListeners copy(device_list_listeners_); 873 DeviceListListeners copy(device_list_listeners_);
845 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it) 874 for (DeviceListListeners::iterator it = copy.begin(); it != copy.end(); ++it)
846 (*it)->DeviceListChanged(devices); 875 (*it)->DeviceListChanged(remote_devices);
847 876
848 ForwardingStatus status = 877 ForwardingStatus status =
849 port_forwarding_controller_->DeviceListChanged(devices); 878 port_forwarding_controller_->DeviceListChanged(complete_devices);
850 PortForwardingListeners forwarding_listeners(port_forwarding_listeners_); 879 PortForwardingListeners forwarding_listeners(port_forwarding_listeners_);
851 for (PortForwardingListeners::iterator it = forwarding_listeners.begin(); 880 for (PortForwardingListeners::iterator it = forwarding_listeners.begin();
852 it != forwarding_listeners.end(); ++it) { 881 it != forwarding_listeners.end(); ++it) {
853 (*it)->PortStatusChanged(status); 882 (*it)->PortStatusChanged(status);
854 } 883 }
855 884
856 if (!NeedsDeviceListPolling()) 885 if (!NeedsDeviceListPolling())
857 return; 886 return;
858 887
859 devices_ = devices;
860
861 task_scheduler_.Run( 888 task_scheduler_.Run(
862 base::Bind(&DevToolsAndroidBridge::RequestDeviceList, 889 base::Bind(&DevToolsAndroidBridge::RequestDeviceList,
863 this, device_list_callback_.callback())); 890 this, device_list_callback_.callback()));
864 } 891 }
865 892
866 void DevToolsAndroidBridge::StartDeviceCountPolling() { 893 void DevToolsAndroidBridge::StartDeviceCountPolling() {
867 device_count_callback_.Reset( 894 device_count_callback_.Reset(
868 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, this)); 895 base::Bind(&DevToolsAndroidBridge::ReceivedDeviceCount, this));
869 RequestDeviceCount(device_count_callback_.callback()); 896 RequestDeviceCount(device_count_callback_.callback());
870 } 897 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 bool enabled; 954 bool enabled;
928 if (pref_value->GetAsBoolean(&enabled) && enabled) { 955 if (pref_value->GetAsBoolean(&enabled) && enabled) {
929 device_providers.push_back(new UsbDeviceProvider(profile_)); 956 device_providers.push_back(new UsbDeviceProvider(profile_));
930 } 957 }
931 device_manager_->SetDeviceProviders(device_providers); 958 device_manager_->SetDeviceProviders(device_providers);
932 if (NeedsDeviceListPolling()) { 959 if (NeedsDeviceListPolling()) {
933 StopDeviceListPolling(); 960 StopDeviceListPolling();
934 StartDeviceListPolling(); 961 StartDeviceListPolling();
935 } 962 }
936 } 963 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698