OLD | NEW |
---|---|
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" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/prefs/pref_service.h" | 16 #include "base/prefs/pref_service.h" |
17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
19 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
20 #include "base/strings/utf_string_conversions.h" | 20 #include "base/strings/utf_string_conversions.h" |
21 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
22 #include "base/values.h" | 22 #include "base/values.h" |
23 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h" | 23 #include "chrome/browser/devtools/browser_list_tabcontents_provider.h" |
24 #include "chrome/browser/devtools/device/adb/adb_device_info_query.h" | |
24 #include "chrome/browser/devtools/device/adb/adb_device_provider.h" | 25 #include "chrome/browser/devtools/device/adb/adb_device_provider.h" |
25 #include "chrome/browser/devtools/device/self_device_provider.h" | 26 #include "chrome/browser/devtools/device/self_device_provider.h" |
26 #include "chrome/browser/devtools/device/usb/usb_device_provider.h" | 27 #include "chrome/browser/devtools/device/usb/usb_device_provider.h" |
27 #include "chrome/browser/devtools/devtools_protocol.h" | 28 #include "chrome/browser/devtools/devtools_protocol.h" |
28 #include "chrome/browser/devtools/devtools_target_impl.h" | 29 #include "chrome/browser/devtools/devtools_target_impl.h" |
29 #include "chrome/browser/devtools/devtools_window.h" | 30 #include "chrome/browser/devtools/devtools_window.h" |
30 #include "chrome/browser/profiles/profile.h" | 31 #include "chrome/browser/profiles/profile.h" |
31 #include "chrome/common/pref_names.h" | 32 #include "chrome/common/pref_names.h" |
32 #include "components/keyed_service/content/browser_context_dependency_manager.h" | 33 #include "components/keyed_service/content/browser_context_dependency_manager.h" |
33 #include "content/public/browser/devtools_agent_host.h" | 34 #include "content/public/browser/devtools_agent_host.h" |
34 #include "content/public/browser/devtools_external_agent_proxy.h" | 35 #include "content/public/browser/devtools_external_agent_proxy.h" |
35 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" | 36 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
36 #include "content/public/browser/user_metrics.h" | 37 #include "content/public/browser/user_metrics.h" |
37 #include "net/base/escape.h" | 38 #include "net/base/escape.h" |
38 | 39 |
39 using content::BrowserThread; | 40 using content::BrowserThread; |
40 | 41 |
41 namespace { | 42 namespace { |
42 | 43 |
43 const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; | 44 const char kModelOffline[] = "Offline"; |
44 const char kInstalledChromePackagesCommand[] = "shell:pm list packages"; | |
45 const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; | |
46 const char kListProcessesCommand[] = "shell:ps"; | |
47 const char kDumpsysCommand[] = "shell:dumpsys window policy"; | |
48 const char kDumpsysScreenSizePrefix[] = "mStable="; | |
49 | |
50 const char kUnknownModel[] = "Offline"; | |
51 | 45 |
52 const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; | 46 const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; |
53 const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; | 47 const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; |
54 const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n"; | 48 const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n"; |
55 const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n"; | 49 const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n"; |
56 const char kNewPageRequestWithURL[] = "GET /json/new?%s HTTP/1.1\r\n\r\n"; | 50 const char kNewPageRequestWithURL[] = "GET /json/new?%s HTTP/1.1\r\n\r\n"; |
57 const char kActivatePageRequest[] = | 51 const char kActivatePageRequest[] = |
58 "GET /json/activate/%s HTTP/1.1\r\n\r\n"; | 52 "GET /json/activate/%s HTTP/1.1\r\n\r\n"; |
59 const int kAdbPollingIntervalMs = 1000; | 53 const int kAdbPollingIntervalMs = 1000; |
60 | 54 |
61 const char kUrlParam[] = "url"; | 55 const char kUrlParam[] = "url"; |
62 const char kPageReloadCommand[] = "Page.reload"; | 56 const char kPageReloadCommand[] = "Page.reload"; |
63 const char kPageNavigateCommand[] = "Page.navigate"; | 57 const char kPageNavigateCommand[] = "Page.navigate"; |
64 | 58 |
65 // The format used for constructing DevTools server socket names. | |
66 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; | |
67 | |
68 const char kChromeDefaultName[] = "Chrome"; | |
69 const char kChromeDefaultSocket[] = "chrome_devtools_remote"; | |
70 const int kMinVersionNewWithURL = 32; | 59 const int kMinVersionNewWithURL = 32; |
71 const int kNewPageNavigateDelayMs = 500; | 60 const int kNewPageNavigateDelayMs = 500; |
72 | 61 |
73 const char kWebViewSocketPrefix[] = "webview_devtools_remote"; | |
74 const char kWebViewNameTemplate[] = "WebView in %s"; | |
75 | |
76 struct BrowserDescriptor { | |
77 const char* package; | |
78 const char* socket; | |
79 const char* display_name; | |
80 }; | |
81 | |
82 const BrowserDescriptor kBrowserDescriptors[] = { | |
83 { | |
84 "com.android.chrome", | |
85 kChromeDefaultSocket, | |
86 kChromeDefaultName | |
87 }, | |
88 { | |
89 "com.chrome.beta", | |
90 kChromeDefaultSocket, | |
91 "Chrome Beta" | |
92 }, | |
93 { | |
94 "com.google.android.apps.chrome_dev", | |
95 kChromeDefaultSocket, | |
96 "Chrome Dev" | |
97 }, | |
98 { | |
99 "com.chrome.canary", | |
100 kChromeDefaultSocket, | |
101 "Chrome Canary" | |
102 }, | |
103 { | |
104 "com.google.android.apps.chrome", | |
105 kChromeDefaultSocket, | |
106 "Chromium" | |
107 }, | |
108 { | |
109 "org.chromium.content_shell_apk", | |
110 "content_shell_devtools_remote", | |
111 "Content Shell" | |
112 }, | |
113 { | |
114 "org.chromium.chrome.shell", | |
115 "chrome_shell_devtools_remote", | |
116 "Chrome Shell" | |
117 }, | |
118 { | |
119 "org.chromium.android_webview.shell", | |
120 "webview_devtools_remote", | |
121 "WebView Test Shell" | |
122 } | |
123 }; | |
124 | |
125 const BrowserDescriptor* FindBrowserDescriptor(const std::string& package) { | |
126 int count = sizeof(kBrowserDescriptors) / sizeof(kBrowserDescriptors[0]); | |
127 for (int i = 0; i < count; i++) | |
128 if (kBrowserDescriptors[i].package == package) | |
129 return &kBrowserDescriptors[i]; | |
130 return NULL; | |
131 } | |
132 | |
133 typedef std::map<std::string, const BrowserDescriptor*> DescriptorMap; | |
134 | |
135 static DescriptorMap FindInstalledBrowserPackages( | |
136 const std::string& response) { | |
137 // Parse 'pm list packages' output which on Android looks like this: | |
138 // | |
139 // package:com.android.chrome | |
140 // package:com.chrome.beta | |
141 // package:com.example.app | |
142 // | |
143 DescriptorMap package_to_descriptor; | |
144 const std::string package_prefix = "package:"; | |
145 std::vector<std::string> entries; | |
146 Tokenize(response, "'\r\n", &entries); | |
147 for (size_t i = 0; i < entries.size(); ++i) { | |
148 if (entries[i].find(package_prefix) != 0) | |
149 continue; | |
150 std::string package = entries[i].substr(package_prefix.size()); | |
151 const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); | |
152 if (!descriptor) | |
153 continue; | |
154 package_to_descriptor[descriptor->package] = descriptor; | |
155 } | |
156 return package_to_descriptor; | |
157 } | |
158 | |
159 typedef std::map<std::string, std::string> StringMap; | |
160 | |
161 static void MapProcessesToPackages(const std::string& response, | |
162 StringMap& pid_to_package, | |
163 StringMap& package_to_pid) { | |
164 // Parse 'ps' output which on Android looks like this: | |
165 // | |
166 // USER PID PPID VSIZE RSS WCHAN PC ? NAME | |
167 // | |
168 std::vector<std::string> entries; | |
169 Tokenize(response, "\n", &entries); | |
170 for (size_t i = 1; i < entries.size(); ++i) { | |
171 std::vector<std::string> fields; | |
172 Tokenize(entries[i], " \r", &fields); | |
173 if (fields.size() < 9) | |
174 continue; | |
175 std::string pid = fields[1]; | |
176 std::string package = fields[8]; | |
177 pid_to_package[pid] = package; | |
178 package_to_pid[package] = pid; | |
179 } | |
180 } | |
181 | |
182 typedef std::map<std::string, | |
183 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> > | |
184 BrowserMap; | |
185 | |
186 static StringMap MapSocketsToProcesses(const std::string& response, | |
187 const std::string& channel_pattern) { | |
188 // Parse 'cat /proc/net/unix' output which on Android looks like this: | |
189 // | |
190 // Num RefCount Protocol Flags Type St Inode Path | |
191 // 00000000: 00000002 00000000 00010000 0001 01 331813 /dev/socket/zygote | |
192 // 00000000: 00000002 00000000 00010000 0001 01 358606 @xxx_devtools_remote | |
193 // 00000000: 00000002 00000000 00010000 0001 01 347300 @yyy_devtools_remote | |
194 // | |
195 // We need to find records with paths starting from '@' (abstract socket) | |
196 // and containing the channel pattern ("_devtools_remote"). | |
197 StringMap socket_to_pid; | |
198 std::vector<std::string> entries; | |
199 Tokenize(response, "\n", &entries); | |
200 for (size_t i = 1; i < entries.size(); ++i) { | |
201 std::vector<std::string> fields; | |
202 Tokenize(entries[i], " \r", &fields); | |
203 if (fields.size() < 8) | |
204 continue; | |
205 if (fields[3] != "00010000" || fields[5] != "01") | |
206 continue; | |
207 std::string path_field = fields[7]; | |
208 if (path_field.size() < 1 || path_field[0] != '@') | |
209 continue; | |
210 size_t socket_name_pos = path_field.find(channel_pattern); | |
211 if (socket_name_pos == std::string::npos) | |
212 continue; | |
213 | |
214 std::string socket = path_field.substr(1); | |
215 | |
216 std::string pid; | |
217 size_t socket_name_end = socket_name_pos + channel_pattern.size(); | |
218 if (socket_name_end < path_field.size() && | |
219 path_field[socket_name_end] == '_') { | |
220 pid = path_field.substr(socket_name_end + 1); | |
221 } | |
222 socket_to_pid[socket] = pid; | |
223 } | |
224 return socket_to_pid; | |
225 } | |
226 | |
227 // DiscoveryRequest ----------------------------------------------------- | 62 // DiscoveryRequest ----------------------------------------------------- |
228 | 63 |
229 class DiscoveryRequest : public base::RefCountedThreadSafe< | 64 class DiscoveryRequest : public base::RefCountedThreadSafe< |
230 DiscoveryRequest, | 65 DiscoveryRequest, |
231 BrowserThread::DeleteOnUIThread> { | 66 BrowserThread::DeleteOnUIThread> { |
232 public: | 67 public: |
233 typedef base::Callback<void(DevToolsAndroidBridge::RemoteDevices*)> Callback; | 68 typedef base::Callback<void(DevToolsAndroidBridge::RemoteDevices*)> Callback; |
234 | 69 |
235 DiscoveryRequest( | 70 DiscoveryRequest( |
236 scoped_refptr<DevToolsAndroidBridge> android_bridge, | 71 scoped_refptr<DevToolsAndroidBridge> android_bridge, |
237 AndroidDeviceManager* device_manager, | 72 AndroidDeviceManager* device_manager, |
238 base::MessageLoop* device_message_loop, | 73 base::MessageLoop* device_message_loop, |
239 const AndroidDeviceManager::DeviceProviders& device_providers, | 74 const AndroidDeviceManager::DeviceProviders& device_providers, |
240 const Callback& callback); | 75 const Callback& callback); |
241 | 76 |
242 private: | 77 private: |
243 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; | 78 friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; |
244 friend class base::DeleteHelper<DiscoveryRequest>; | 79 friend class base::DeleteHelper<DiscoveryRequest>; |
245 | 80 |
246 virtual ~DiscoveryRequest(); | 81 virtual ~DiscoveryRequest(); |
247 | 82 |
248 void ReceivedSerials(const std::vector<std::string>& serials); | 83 void ReceivedSerials(const std::vector<std::string>& serials); |
249 void ProcessSerials(); | 84 void ProcessSerials(); |
250 void ReceivedModel(int result, const std::string& response); | 85 void ReceivedDeviceInfo(const AndroidDeviceManager::DeviceInfo& device_info); |
251 void ReceivedDumpsys(int result, const std::string& response); | |
252 void ReceivedPackages(int result, const std::string& response); | |
253 void ReceivedProcesses( | |
254 const std::string& packages_response, | |
255 int result, | |
256 const std::string& processes_response); | |
257 void ReceivedSockets( | |
258 const std::string& packages_response, | |
259 const std::string& processes_response, | |
260 int result, | |
261 const std::string& sockets_response); | |
262 void ProcessSockets(); | 86 void ProcessSockets(); |
263 void ReceivedVersion(int result, const std::string& response); | 87 void ReceivedVersion(int result, const std::string& response); |
264 void ReceivedPages(int result, const std::string& response); | 88 void ReceivedPages(int result, const std::string& response); |
265 | 89 |
266 std::string current_serial() const { return serials_.back(); } | 90 std::string current_serial() const { return serials_.back(); } |
267 | 91 |
268 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> current_browser() const { | 92 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> current_browser() const { |
269 return browsers_.back(); | 93 return browsers_.back(); |
270 } | 94 } |
271 | 95 |
272 void NextBrowser(); | 96 void NextBrowser(); |
273 void NextDevice(); | 97 void NextDevice(); |
274 | 98 |
275 void Respond(); | 99 void Respond(); |
276 | 100 |
277 void CreateBrowsers(const std::string& packages_response, | |
278 const std::string& processes_response, | |
279 const std::string& sockets_response); | |
280 | |
281 void ParseDumpsysResponse(const std::string& response); | |
282 void ParseScreenSize(const std::string& str); | |
283 | |
284 scoped_refptr<DevToolsAndroidBridge> android_bridge_; | 101 scoped_refptr<DevToolsAndroidBridge> android_bridge_; |
285 AndroidDeviceManager* device_manager_; | 102 AndroidDeviceManager* device_manager_; |
286 base::MessageLoop* device_message_loop_; | 103 base::MessageLoop* device_message_loop_; |
287 Callback callback_; | 104 Callback callback_; |
288 std::vector<std::string> serials_; | 105 std::vector<std::string> serials_; |
289 DevToolsAndroidBridge::RemoteBrowsers browsers_; | 106 DevToolsAndroidBridge::RemoteBrowsers browsers_; |
290 scoped_ptr<DevToolsAndroidBridge::RemoteDevices> remote_devices_; | 107 scoped_ptr<DevToolsAndroidBridge::RemoteDevices> remote_devices_; |
291 }; | 108 }; |
292 | 109 |
293 DiscoveryRequest::DiscoveryRequest( | 110 DiscoveryRequest::DiscoveryRequest( |
(...skipping 30 matching lines...) Expand all Loading... | |
324 void DiscoveryRequest::ProcessSerials() { | 141 void DiscoveryRequest::ProcessSerials() { |
325 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); | 142 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); |
326 if (serials_.size() == 0) { | 143 if (serials_.size() == 0) { |
327 BrowserThread::PostTask( | 144 BrowserThread::PostTask( |
328 BrowserThread::UI, FROM_HERE, | 145 BrowserThread::UI, FROM_HERE, |
329 base::Bind(&DiscoveryRequest::Respond, this)); | 146 base::Bind(&DiscoveryRequest::Respond, this)); |
330 return; | 147 return; |
331 } | 148 } |
332 | 149 |
333 if (device_manager_->IsConnected(current_serial())) { | 150 if (device_manager_->IsConnected(current_serial())) { |
334 device_manager_->RunCommand(current_serial(), kDeviceModelCommand, | 151 device_manager_->QueryDeviceInfo(current_serial(), |
335 base::Bind(&DiscoveryRequest::ReceivedModel, this)); | 152 base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this)); |
336 } else { | 153 } else { |
154 AndroidDeviceManager::DeviceInfo offline_info; | |
155 offline_info.model = kModelOffline; | |
337 remote_devices_->push_back(new DevToolsAndroidBridge::RemoteDevice( | 156 remote_devices_->push_back(new DevToolsAndroidBridge::RemoteDevice( |
338 android_bridge_, current_serial(), kUnknownModel, false)); | 157 android_bridge_, current_serial(), offline_info, false)); |
339 NextDevice(); | 158 NextDevice(); |
340 } | 159 } |
341 } | 160 } |
342 | 161 |
343 void DiscoveryRequest::ReceivedModel(int result, const std::string& response) { | 162 void DiscoveryRequest::ReceivedDeviceInfo( |
344 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); | 163 const AndroidDeviceManager::DeviceInfo& device_info) { |
345 if (result < 0) { | |
346 NextDevice(); | |
347 return; | |
348 } | |
349 remote_devices_->push_back(new DevToolsAndroidBridge::RemoteDevice( | 164 remote_devices_->push_back(new DevToolsAndroidBridge::RemoteDevice( |
350 android_bridge_, current_serial(), response, true)); | 165 android_bridge_, current_serial(), device_info, true)); |
351 device_manager_->RunCommand(current_serial(), kDumpsysCommand, | 166 browsers_ = remote_devices_->back()->browsers(); |
352 base::Bind(&DiscoveryRequest::ReceivedDumpsys, this)); | |
353 } | |
354 | |
355 void DiscoveryRequest::ReceivedDumpsys(int result, | |
356 const std::string& response) { | |
357 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); | |
358 if (result >= 0) | |
359 ParseDumpsysResponse(response); | |
360 | |
361 device_manager_->RunCommand( | |
362 current_serial(), | |
363 kInstalledChromePackagesCommand, | |
364 base::Bind(&DiscoveryRequest::ReceivedPackages, this)); | |
365 } | |
366 | |
367 void DiscoveryRequest::ReceivedPackages(int result, | |
368 const std::string& packages_response) { | |
369 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); | |
370 if (result < 0) { | |
371 NextDevice(); | |
372 return; | |
373 } | |
374 device_manager_->RunCommand( | |
375 current_serial(), | |
376 kListProcessesCommand, | |
377 base::Bind( | |
378 &DiscoveryRequest::ReceivedProcesses, this, packages_response)); | |
379 } | |
380 | |
381 void DiscoveryRequest::ReceivedProcesses( | |
382 const std::string& packages_response, | |
383 int result, | |
384 const std::string& processes_response) { | |
385 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); | |
386 if (result < 0) { | |
387 NextDevice(); | |
388 return; | |
389 } | |
390 device_manager_->RunCommand( | |
391 current_serial(), | |
392 kOpenedUnixSocketsCommand, | |
393 base::Bind(&DiscoveryRequest::ReceivedSockets, | |
394 this, | |
395 packages_response, | |
396 processes_response)); | |
397 } | |
398 | |
399 void DiscoveryRequest::ReceivedSockets( | |
400 const std::string& packages_response, | |
401 const std::string& processes_response, | |
402 int result, | |
403 const std::string& sockets_response) { | |
404 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); | |
405 if (result >= 0) | |
406 CreateBrowsers(packages_response, processes_response, sockets_response); | |
407 ProcessSockets(); | 167 ProcessSockets(); |
408 } | 168 } |
409 | 169 |
410 void DiscoveryRequest::ProcessSockets() { | 170 void DiscoveryRequest::ProcessSockets() { |
411 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); | 171 DCHECK_EQ(device_message_loop_, base::MessageLoop::current()); |
412 if (browsers_.size() == 0) { | 172 if (browsers_.size() == 0) { |
413 NextDevice(); | 173 NextDevice(); |
414 return; | 174 return; |
415 } | 175 } |
416 | 176 |
(...skipping 20 matching lines...) Expand all Loading... | |
437 if (dict->GetString("Browser", &browser)) { | 197 if (dict->GetString("Browser", &browser)) { |
438 std::vector<std::string> parts; | 198 std::vector<std::string> parts; |
439 Tokenize(browser, "/", &parts); | 199 Tokenize(browser, "/", &parts); |
440 if (parts.size() == 2) | 200 if (parts.size() == 2) |
441 current_browser()->set_version(parts[1]); | 201 current_browser()->set_version(parts[1]); |
442 else | 202 else |
443 current_browser()->set_version(browser); | 203 current_browser()->set_version(browser); |
444 } | 204 } |
445 std::string package; | 205 std::string package; |
446 if (dict->GetString("Android-Package", &package)) { | 206 if (dict->GetString("Android-Package", &package)) { |
447 const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); | 207 std::string display_name = |
448 if (descriptor) | 208 AdbDeviceInfoQuery::FindDisplayNameByPackage(package); |
pfeldman
2014/05/13 12:44:58
This is confusing. Why do you need to convert pack
Vladislav Kaznacheev
2014/05/15 13:56:34
Newer versions of Chrome on Android report their p
| |
449 current_browser()->set_display_name(descriptor->display_name); | 209 if (!display_name.empty()) |
210 current_browser()->set_display_name(display_name); | |
450 } | 211 } |
451 } | 212 } |
452 | 213 |
453 device_manager_->HttpQuery( | 214 device_manager_->HttpQuery( |
454 current_serial(), | 215 current_serial(), |
455 current_browser()->socket(), | 216 current_browser()->socket(), |
456 kPageListRequest, | 217 kPageListRequest, |
457 base::Bind(&DiscoveryRequest::ReceivedPages, this)); | 218 base::Bind(&DiscoveryRequest::ReceivedPages, this)); |
458 } | 219 } |
459 | 220 |
(...skipping 16 matching lines...) Expand all Loading... | |
476 | 237 |
477 void DiscoveryRequest::NextDevice() { | 238 void DiscoveryRequest::NextDevice() { |
478 serials_.pop_back(); | 239 serials_.pop_back(); |
479 ProcessSerials(); | 240 ProcessSerials(); |
480 } | 241 } |
481 | 242 |
482 void DiscoveryRequest::Respond() { | 243 void DiscoveryRequest::Respond() { |
483 callback_.Run(remote_devices_.release()); | 244 callback_.Run(remote_devices_.release()); |
484 } | 245 } |
485 | 246 |
486 void DiscoveryRequest::CreateBrowsers( | |
487 const std::string& packages_response, | |
488 const std::string& processes_response, | |
489 const std::string& sockets_response) { | |
490 DescriptorMap package_to_descriptor = | |
491 FindInstalledBrowserPackages(packages_response); | |
492 | |
493 StringMap pid_to_package; | |
494 StringMap package_to_pid; | |
495 MapProcessesToPackages(processes_response, pid_to_package, package_to_pid); | |
496 | |
497 const std::string channel_pattern = | |
498 base::StringPrintf(kDevToolsChannelNameFormat, ""); | |
499 | |
500 StringMap socket_to_pid = MapSocketsToProcesses(sockets_response, | |
501 channel_pattern); | |
502 | |
503 scoped_refptr<DevToolsAndroidBridge::RemoteDevice> remote_device = | |
504 remote_devices_->back(); | |
505 | |
506 // Create RemoteBrowser instances. | |
507 BrowserMap package_to_running_browser; | |
508 BrowserMap socket_to_unnamed_browser; | |
509 for (StringMap::iterator it = socket_to_pid.begin(); | |
510 it != socket_to_pid.end(); ++it) { | |
511 std::string socket = it->first; | |
512 std::string pid = it->second; | |
513 | |
514 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser = | |
515 new DevToolsAndroidBridge::RemoteBrowser( | |
516 android_bridge_, current_serial(), socket); | |
517 | |
518 StringMap::iterator pit = pid_to_package.find(pid); | |
519 if (pit != pid_to_package.end()) { | |
520 std::string package = pit->second; | |
521 package_to_running_browser[package] = browser; | |
522 const BrowserDescriptor* descriptor = FindBrowserDescriptor(package); | |
523 if (descriptor) { | |
524 browser->set_display_name(descriptor->display_name); | |
525 } else if (socket.find(kWebViewSocketPrefix) == 0) { | |
526 browser->set_display_name( | |
527 base::StringPrintf(kWebViewNameTemplate, package.c_str())); | |
528 } else { | |
529 browser->set_display_name(package); | |
530 } | |
531 } else { | |
532 // Set fallback display name. | |
533 std::string name = socket.substr(0, socket.find(channel_pattern)); | |
534 name[0] = base::ToUpperASCII(name[0]); | |
535 browser->set_display_name(name); | |
536 | |
537 socket_to_unnamed_browser[socket] = browser; | |
538 } | |
539 remote_device->AddBrowser(browser); | |
540 } | |
541 | |
542 browsers_ = remote_device->browsers(); | |
543 | |
544 // Find installed packages not mapped to browsers. | |
545 typedef std::multimap<std::string, const BrowserDescriptor*> | |
546 DescriptorMultimap; | |
547 DescriptorMultimap socket_to_descriptor; | |
548 for (DescriptorMap::iterator it = package_to_descriptor.begin(); | |
549 it != package_to_descriptor.end(); ++it) { | |
550 std::string package = it->first; | |
551 const BrowserDescriptor* descriptor = it->second; | |
552 | |
553 if (package_to_running_browser.find(package) != | |
554 package_to_running_browser.end()) | |
555 continue; // This package is already mapped to a browser. | |
556 | |
557 if (package_to_pid.find(package) != package_to_pid.end()) { | |
558 // This package is running but not mapped to a browser. | |
559 socket_to_descriptor.insert( | |
560 DescriptorMultimap::value_type(descriptor->socket, descriptor)); | |
561 continue; | |
562 } | |
563 } | |
564 | |
565 // Try naming remaining unnamed browsers. | |
566 for (DescriptorMultimap::iterator it = socket_to_descriptor.begin(); | |
567 it != socket_to_descriptor.end(); ++it) { | |
568 std::string socket = it->first; | |
569 const BrowserDescriptor* descriptor = it->second; | |
570 | |
571 if (socket_to_descriptor.count(socket) != 1) | |
572 continue; // No definitive match. | |
573 | |
574 BrowserMap::iterator bit = socket_to_unnamed_browser.find(socket); | |
575 if (bit != socket_to_unnamed_browser.end()) | |
576 bit->second->set_display_name(descriptor->display_name); | |
577 } | |
578 } | |
579 | |
580 void DiscoveryRequest::ParseDumpsysResponse(const std::string& response) { | |
581 std::vector<std::string> lines; | |
582 Tokenize(response, "\r", &lines); | |
583 for (size_t i = 0; i < lines.size(); ++i) { | |
584 std::string line = lines[i]; | |
585 size_t pos = line.find(kDumpsysScreenSizePrefix); | |
586 if (pos != std::string::npos) { | |
587 ParseScreenSize( | |
588 line.substr(pos + std::string(kDumpsysScreenSizePrefix).size())); | |
589 break; | |
590 } | |
591 } | |
592 } | |
593 | |
594 void DiscoveryRequest::ParseScreenSize(const std::string& str) { | |
595 std::vector<std::string> pairs; | |
596 Tokenize(str, "-", &pairs); | |
597 if (pairs.size() != 2) | |
598 return; | |
599 | |
600 int width; | |
601 int height; | |
602 std::vector<std::string> numbers; | |
603 Tokenize(pairs[1].substr(1, pairs[1].size() - 2), ",", &numbers); | |
604 if (numbers.size() != 2 || | |
605 !base::StringToInt(numbers[0], &width) || | |
606 !base::StringToInt(numbers[1], &height)) | |
607 return; | |
608 | |
609 remote_devices_->back()->set_screen_size(gfx::Size(width, height)); | |
610 } | |
611 | |
612 | |
613 // ProtocolCommand ------------------------------------------------------------ | 247 // ProtocolCommand ------------------------------------------------------------ |
614 | 248 |
615 class ProtocolCommand | 249 class ProtocolCommand |
616 : public DevToolsAndroidBridge::AndroidWebSocket::Delegate { | 250 : public DevToolsAndroidBridge::AndroidWebSocket::Delegate { |
617 public: | 251 public: |
618 ProtocolCommand( | 252 ProtocolCommand( |
619 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, | 253 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, |
620 const std::string& debug_url, | 254 const std::string& debug_url, |
621 const std::string& command, | 255 const std::string& command, |
622 const base::Closure callback); | 256 const base::Closure callback); |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
755 return delegate->proxy_->GetAgentHost(); | 389 return delegate->proxy_->GetAgentHost(); |
756 } | 390 } |
757 | 391 |
758 AgentHostDelegate::AgentHostDelegate( | 392 AgentHostDelegate::AgentHostDelegate( |
759 const std::string& id, | 393 const std::string& id, |
760 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, | 394 scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser, |
761 const std::string& debug_url) | 395 const std::string& debug_url) |
762 : id_(id), | 396 : id_(id), |
763 socket_opened_(false), | 397 socket_opened_(false), |
764 detached_(false), | 398 detached_(false), |
765 is_web_view_(browser->socket().find(kWebViewSocketPrefix) == 0), | 399 is_web_view_(browser->IsWebView()), |
766 web_socket_(browser->CreateWebSocket(debug_url, this)), | 400 web_socket_(browser->CreateWebSocket(debug_url, this)), |
767 proxy_(content::DevToolsExternalAgentProxy::Create(this)) { | 401 proxy_(content::DevToolsExternalAgentProxy::Create(this)) { |
768 g_host_delegates.Get()[id] = this; | 402 g_host_delegates.Get()[id] = this; |
769 } | 403 } |
770 | 404 |
771 AgentHostDelegate::~AgentHostDelegate() { | 405 AgentHostDelegate::~AgentHostDelegate() { |
772 g_host_delegates.Get().erase(id_); | 406 g_host_delegates.Get().erase(id_); |
773 } | 407 } |
774 | 408 |
775 void AgentHostDelegate::Attach() { | 409 void AgentHostDelegate::Attach() { |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
944 params.SetString(kUrlParam, url); | 578 params.SetString(kUrlParam, url); |
945 browser_->SendProtocolCommand(debug_url_, kPageNavigateCommand, ¶ms, | 579 browser_->SendProtocolCommand(debug_url_, kPageNavigateCommand, ¶ms, |
946 callback); | 580 callback); |
947 } | 581 } |
948 | 582 |
949 // DevToolsAndroidBridge::RemoteBrowser --------------------------------------- | 583 // DevToolsAndroidBridge::RemoteBrowser --------------------------------------- |
950 | 584 |
951 DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser( | 585 DevToolsAndroidBridge::RemoteBrowser::RemoteBrowser( |
952 scoped_refptr<DevToolsAndroidBridge> android_bridge, | 586 scoped_refptr<DevToolsAndroidBridge> android_bridge, |
953 const std::string& serial, | 587 const std::string& serial, |
954 const std::string& socket) | 588 const AndroidDeviceManager::BrowserInfo& browser_info) |
955 : android_bridge_(android_bridge), | 589 : android_bridge_(android_bridge), |
956 serial_(serial), | 590 serial_(serial), |
957 socket_(socket), | 591 socket_(browser_info.socket), |
592 display_name_(browser_info.display_name), | |
593 type_(browser_info.type), | |
958 page_descriptors_(new base::ListValue()) { | 594 page_descriptors_(new base::ListValue()) { |
959 } | 595 } |
960 | 596 |
961 bool DevToolsAndroidBridge::RemoteBrowser::IsChrome() const { | 597 bool DevToolsAndroidBridge::RemoteBrowser::IsChrome() const { |
962 return socket_.find(kChromeDefaultSocket) == 0; | 598 return type_ == AndroidDeviceManager::BrowserInfo::kTypeChrome; |
599 } | |
600 | |
601 bool DevToolsAndroidBridge::RemoteBrowser::IsWebView() const { | |
602 return type_ == AndroidDeviceManager::BrowserInfo::kTypeWebView; | |
963 } | 603 } |
964 | 604 |
965 DevToolsAndroidBridge::RemoteBrowser::ParsedVersion | 605 DevToolsAndroidBridge::RemoteBrowser::ParsedVersion |
966 DevToolsAndroidBridge::RemoteBrowser::GetParsedVersion() const { | 606 DevToolsAndroidBridge::RemoteBrowser::GetParsedVersion() const { |
967 ParsedVersion result; | 607 ParsedVersion result; |
968 std::vector<std::string> parts; | 608 std::vector<std::string> parts; |
969 Tokenize(version_, ".", &parts); | 609 Tokenize(version_, ".", &parts); |
970 for (size_t i = 0; i != parts.size(); ++i) { | 610 for (size_t i = 0; i != parts.size(); ++i) { |
971 int value = 0; | 611 int value = 0; |
972 base::StringToInt(parts[i], &value); | 612 base::StringToInt(parts[i], &value); |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1112 | 752 |
1113 DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() { | 753 DevToolsAndroidBridge::RemoteBrowser::~RemoteBrowser() { |
1114 } | 754 } |
1115 | 755 |
1116 | 756 |
1117 // DevToolsAndroidBridge::RemoteDevice ---------------------------------------- | 757 // DevToolsAndroidBridge::RemoteDevice ---------------------------------------- |
1118 | 758 |
1119 DevToolsAndroidBridge::RemoteDevice::RemoteDevice( | 759 DevToolsAndroidBridge::RemoteDevice::RemoteDevice( |
1120 scoped_refptr<DevToolsAndroidBridge> android_bridge, | 760 scoped_refptr<DevToolsAndroidBridge> android_bridge, |
1121 const std::string& serial, | 761 const std::string& serial, |
1122 const std::string& model, | 762 const AndroidDeviceManager::DeviceInfo& device_info, |
1123 bool connected) | 763 bool connected) |
1124 : android_bridge_(android_bridge), | 764 : android_bridge_(android_bridge), |
1125 serial_(serial), | 765 serial_(serial), |
1126 model_(model), | 766 model_(device_info.model), |
1127 connected_(connected) { | 767 connected_(connected), |
1128 } | 768 screen_size_(device_info.screen_size) { |
1129 | 769 for (std::vector<AndroidDeviceManager::BrowserInfo>::const_iterator it = |
1130 void DevToolsAndroidBridge::RemoteDevice::AddBrowser( | 770 device_info.browser_info.begin(); |
1131 scoped_refptr<RemoteBrowser> browser) { | 771 it != device_info.browser_info.end(); |
1132 browsers_.push_back(browser); | 772 ++it) { |
773 browsers_.push_back(new DevToolsAndroidBridge::RemoteBrowser( | |
774 android_bridge_, serial_, *it)); | |
775 } | |
1133 } | 776 } |
1134 | 777 |
1135 void DevToolsAndroidBridge::RemoteDevice::OpenSocket( | 778 void DevToolsAndroidBridge::RemoteDevice::OpenSocket( |
1136 const std::string& socket_name, | 779 const std::string& socket_name, |
1137 const AndroidDeviceManager::SocketCallback& callback) { | 780 const AndroidDeviceManager::SocketCallback& callback) { |
1138 android_bridge_->device_message_loop()->PostTask(FROM_HERE, | 781 android_bridge_->device_message_loop()->PostTask(FROM_HERE, |
1139 base::Bind(&AndroidDeviceManager::OpenSocket, | 782 base::Bind(&AndroidDeviceManager::OpenSocket, |
1140 android_bridge_->device_manager(), | 783 android_bridge_->device_manager(), |
1141 serial_, | 784 serial_, |
1142 socket_name, | 785 socket_name, |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1350 PrefService* service = profile_->GetPrefs(); | 993 PrefService* service = profile_->GetPrefs(); |
1351 const PrefService::Preference* pref = | 994 const PrefService::Preference* pref = |
1352 service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled); | 995 service->FindPreference(prefs::kDevToolsDiscoverUsbDevicesEnabled); |
1353 const base::Value* pref_value = pref->GetValue(); | 996 const base::Value* pref_value = pref->GetValue(); |
1354 | 997 |
1355 bool enabled; | 998 bool enabled; |
1356 if (pref_value->GetAsBoolean(&enabled) && enabled) { | 999 if (pref_value->GetAsBoolean(&enabled) && enabled) { |
1357 device_providers_.push_back(new UsbDeviceProvider(profile_)); | 1000 device_providers_.push_back(new UsbDeviceProvider(profile_)); |
1358 } | 1001 } |
1359 } | 1002 } |
OLD | NEW |