OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/devtools_adb_bridge.h" | 5 #include "chrome/browser/devtools/devtools_adb_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 24 matching lines...) Expand all Loading... |
35 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" | 35 #include "content/public/browser/devtools_external_agent_proxy_delegate.h" |
36 #include "content/public/browser/devtools_manager.h" | 36 #include "content/public/browser/devtools_manager.h" |
37 #include "crypto/rsa_private_key.h" | 37 #include "crypto/rsa_private_key.h" |
38 #include "net/base/net_errors.h" | 38 #include "net/base/net_errors.h" |
39 | 39 |
40 using content::BrowserThread; | 40 using content::BrowserThread; |
41 | 41 |
42 namespace { | 42 namespace { |
43 | 43 |
44 const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; | 44 const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread"; |
45 const char kHostDevicesCommand[] = "host:devices"; | |
46 const char kHostTransportCommand[] = "host:transport:%s|%s"; | |
47 const char kLocalAbstractCommand[] = "localabstract:%s"; | |
48 const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; | 45 const char kDeviceModelCommand[] = "shell:getprop ro.product.model"; |
49 const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; | 46 const char kOpenedUnixSocketsCommand[] = "shell:cat /proc/net/unix"; |
50 const char kListProcessesCommand[] = "shell:ps"; | 47 const char kListProcessesCommand[] = "shell:ps"; |
51 const char kDumpsysCommand[] = "shell:dumpsys window policy"; | 48 const char kDumpsysCommand[] = "shell:dumpsys window policy"; |
52 const char kDumpsysScreenSizePrefix[] = "mStable="; | 49 const char kDumpsysScreenSizePrefix[] = "mStable="; |
53 | 50 |
54 const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; | 51 const char kPageListRequest[] = "GET /json HTTP/1.1\r\n\r\n"; |
55 const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; | 52 const char kVersionRequest[] = "GET /json/version HTTP/1.1\r\n\r\n"; |
56 const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n"; | 53 const char kClosePageRequest[] = "GET /json/close/%s HTTP/1.1\r\n\r\n"; |
57 const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n"; | 54 const char kNewPageRequest[] = "GET /json/new HTTP/1.1\r\n\r\n"; |
58 const char kActivatePageRequest[] = | 55 const char kActivatePageRequest[] = |
59 "GET /json/activate/%s HTTP/1.1\r\n\r\n"; | 56 "GET /json/activate/%s HTTP/1.1\r\n\r\n"; |
60 const int kAdbPort = 5037; | |
61 const int kBufferSize = 16 * 1024; | |
62 const int kAdbPollingIntervalMs = 1000; | 57 const int kAdbPollingIntervalMs = 1000; |
63 | 58 |
64 const char kUrlParam[] = "url"; | 59 const char kUrlParam[] = "url"; |
65 const char kPageReloadCommand[] = "Page.reload"; | 60 const char kPageReloadCommand[] = "Page.reload"; |
66 const char kPageNavigateCommand[] = "Page.navigate"; | 61 const char kPageNavigateCommand[] = "Page.navigate"; |
67 | 62 |
68 #if defined(DEBUG_DEVTOOLS) | 63 #if defined(DEBUG_DEVTOOLS) |
69 const char kChrome[] = "Chrome"; | 64 const char kChrome[] = "Chrome"; |
70 const char kLocalChrome[] = "Local Chrome"; | 65 const char kLocalChrome[] = "Local Chrome"; |
71 #endif // defined(DEBUG_DEVTOOLS) | 66 #endif // defined(DEBUG_DEVTOOLS) |
72 | 67 |
73 typedef DevToolsAdbBridge::Callback Callback; | 68 typedef DevToolsAdbBridge::Callback Callback; |
74 typedef std::vector<scoped_refptr<DevToolsAdbBridge::AndroidDevice> > | 69 typedef std::vector<scoped_refptr<AndroidDevice> > |
75 AndroidDevices; | 70 AndroidDevices; |
76 typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback; | 71 typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback; |
77 | 72 |
78 class AdbDeviceImpl : public DevToolsAdbBridge::AndroidDevice { | |
79 public: | |
80 explicit AdbDeviceImpl(const std::string& serial) | |
81 : AndroidDevice(serial) { | |
82 } | |
83 | |
84 virtual void RunCommand(const std::string& command, | |
85 const CommandCallback& callback) OVERRIDE { | |
86 std::string query = base::StringPrintf(kHostTransportCommand, | |
87 serial().c_str(), command.c_str()); | |
88 AdbClientSocket::AdbQuery(kAdbPort, query, callback); | |
89 } | |
90 | |
91 virtual void OpenSocket(const std::string& name, | |
92 const SocketCallback& callback) OVERRIDE { | |
93 std::string socket_name = | |
94 base::StringPrintf(kLocalAbstractCommand, name.c_str()); | |
95 AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback); | |
96 } | |
97 private: | |
98 virtual ~AdbDeviceImpl() {} | |
99 }; | |
100 | |
101 class UsbDeviceImpl : public DevToolsAdbBridge::AndroidDevice { | |
102 public: | |
103 explicit UsbDeviceImpl(AndroidUsbDevice* device) | |
104 : AndroidDevice(device->serial()), | |
105 device_(device) { | |
106 device_->InitOnCallerThread(); | |
107 } | |
108 | |
109 virtual void RunCommand(const std::string& command, | |
110 const CommandCallback& callback) OVERRIDE { | |
111 net::StreamSocket* socket = device_->CreateSocket(command); | |
112 int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand, | |
113 this, callback, socket)); | |
114 if (result != net::ERR_IO_PENDING) | |
115 callback.Run(result, std::string()); | |
116 } | |
117 | |
118 virtual void OpenSocket(const std::string& name, | |
119 const SocketCallback& callback) OVERRIDE { | |
120 std::string socket_name = | |
121 base::StringPrintf(kLocalAbstractCommand, name.c_str()); | |
122 net::StreamSocket* socket = device_->CreateSocket(socket_name); | |
123 int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this, | |
124 callback, socket)); | |
125 if (result != net::ERR_IO_PENDING) | |
126 callback.Run(result, NULL); | |
127 } | |
128 | |
129 private: | |
130 void OnOpenSocket(const SocketCallback& callback, | |
131 net::StreamSocket* socket, | |
132 int result) { | |
133 callback.Run(result, result == net::OK ? socket : NULL); | |
134 } | |
135 | |
136 void OpenedForCommand(const CommandCallback& callback, | |
137 net::StreamSocket* socket, | |
138 int result) { | |
139 if (result != net::OK) { | |
140 callback.Run(result, std::string()); | |
141 return; | |
142 } | |
143 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize); | |
144 result = socket->Read(buffer, kBufferSize, | |
145 base::Bind(&UsbDeviceImpl::OnRead, this, | |
146 socket, buffer, std::string(), callback)); | |
147 if (result != net::ERR_IO_PENDING) | |
148 OnRead(socket, buffer, std::string(), callback, result); | |
149 } | |
150 | |
151 void OnRead(net::StreamSocket* socket, | |
152 scoped_refptr<net::IOBuffer> buffer, | |
153 const std::string& data, | |
154 const CommandCallback& callback, | |
155 int result) { | |
156 if (result <= 0) { | |
157 callback.Run(result, result == 0 ? data : std::string()); | |
158 delete socket; | |
159 return; | |
160 } | |
161 | |
162 std::string new_data = data + std::string(buffer->data(), result); | |
163 result = socket->Read(buffer, kBufferSize, | |
164 base::Bind(&UsbDeviceImpl::OnRead, this, | |
165 socket, buffer, new_data, callback)); | |
166 if (result != net::ERR_IO_PENDING) | |
167 OnRead(socket, buffer, new_data, callback, result); | |
168 } | |
169 | |
170 virtual ~UsbDeviceImpl() {} | |
171 scoped_refptr<AndroidUsbDevice> device_; | |
172 }; | |
173 | |
174 class AdbPagesCommand : public base::RefCountedThreadSafe< | 73 class AdbPagesCommand : public base::RefCountedThreadSafe< |
175 AdbPagesCommand, | 74 AdbPagesCommand, |
176 content::BrowserThread::DeleteOnUIThread> { | 75 content::BrowserThread::DeleteOnUIThread> { |
177 public: | 76 public: |
178 typedef base::Callback<void(DevToolsAdbBridge::RemoteDevices*)> Callback; | 77 typedef base::Callback<void(DevToolsAdbBridge::RemoteDevices*)> Callback; |
179 | 78 |
180 AdbPagesCommand(DevToolsAdbBridge* bridge, | 79 AdbPagesCommand( |
181 crypto::RSAPrivateKey* rsa_key, | 80 scoped_refptr<RefCountedAdbThread> adb_thread, |
182 const Callback& callback) | 81 crypto::RSAPrivateKey* rsa_key, |
183 : bridge_(bridge), | 82 const Callback& callback, |
184 callback_(callback) { | 83 const DevToolsAdbBridge::DeviceProviders& device_providers) |
| 84 : adb_thread_(adb_thread), |
| 85 callback_(callback), |
| 86 device_providers_(device_providers) { |
185 remote_devices_.reset(new DevToolsAdbBridge::RemoteDevices()); | 87 remote_devices_.reset(new DevToolsAdbBridge::RemoteDevices()); |
186 | 88 |
187 if (CommandLine::ForCurrentProcess()->HasSwitch( | 89 DCHECK(!device_providers_.empty()); |
| 90 |
| 91 ProcessDeviceProviders(); |
| 92 |
| 93 // TODO:dzvorygin fix later |
| 94 /* if (CommandLine::ForCurrentProcess()->HasSwitch( |
188 switches::kRemoteDebuggingRawUSB)) { | 95 switches::kRemoteDebuggingRawUSB)) { |
189 AndroidUsbDevice::Enumerate(rsa_key, | 96 AndroidUsbDevice::Enumerate(rsa_key, |
190 base::Bind(&AdbPagesCommand::ReceivedUsbDevices, this)); | 97 base::Bind(&AdbPagesCommand::ReceivedUsbDevices, this)); |
191 } else { | 98 } else { |
192 ReceivedUsbDevices(AndroidUsbDevices()); | 99 ReceivedUsbDevices(AndroidUsbDevices()); |
193 } | 100 }*/ |
194 } | 101 } |
195 | 102 |
196 private: | 103 private: |
197 friend struct content::BrowserThread::DeleteOnThread< | 104 friend struct content::BrowserThread::DeleteOnThread< |
198 content::BrowserThread::UI>; | 105 content::BrowserThread::UI>; |
199 friend class base::DeleteHelper<AdbPagesCommand>; | 106 friend class base::DeleteHelper<AdbPagesCommand>; |
200 | 107 |
201 virtual ~AdbPagesCommand() { | 108 virtual ~AdbPagesCommand() { |
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
203 } | 110 } |
204 | 111 |
205 void ReceivedUsbDevices(const AndroidUsbDevices& usb_devices) { | 112 void ProcessDeviceProviders() { |
206 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 113 if (device_providers_.empty()) { |
207 bridge_->GetAdbMessageLoop()->PostTask( | 114 ProcessSerials(); |
208 FROM_HERE, base::Bind(&AdbPagesCommand::WrapUsbDevices, this, | 115 return; |
209 usb_devices)); | 116 } |
| 117 |
| 118 const scoped_refptr<DevToolsDeviceProvider>& device_provider = |
| 119 device_providers_.back(); |
| 120 |
| 121 device_provider->QueryDevices( |
| 122 base::Bind(&AdbPagesCommand::ReceivedDevices, this)); |
210 } | 123 } |
211 | 124 |
212 void WrapUsbDevices(const AndroidUsbDevices& usb_devices) { | 125 void ReceivedDevices(const AndroidDevices& devices) { |
213 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 126 DCHECK(!device_providers_.empty()); |
| 127 device_providers_.pop_back(); |
214 | 128 |
215 #if defined(DEBUG_DEVTOOLS) | 129 devices_.insert(devices_.end(), devices.begin(), devices.end()); |
216 devices_.push_back(new AdbDeviceImpl("")); // For desktop remote debugging. | |
217 #endif // defined(DEBUG_DEVTOOLS) | |
218 | 130 |
219 for (AndroidUsbDevices::const_iterator it = usb_devices.begin(); | 131 if (!device_providers_.empty()) { |
220 it != usb_devices.end(); ++it) { | 132 ProcessDeviceProviders(); |
221 devices_.push_back(new UsbDeviceImpl(*it)); | 133 } else { |
| 134 ProcessSerials(); |
222 } | 135 } |
223 | |
224 AdbClientSocket::AdbQuery( | |
225 kAdbPort, kHostDevicesCommand, | |
226 base::Bind(&AdbPagesCommand::ReceivedAdbDevices, this)); | |
227 } | |
228 | |
229 void ReceivedAdbDevices( | |
230 int result, | |
231 const std::string& response) { | |
232 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | |
233 std::vector<std::string> serials; | |
234 Tokenize(response, "\n", &serials); | |
235 for (size_t i = 0; i < serials.size(); ++i) { | |
236 std::vector<std::string> tokens; | |
237 Tokenize(serials[i], "\t ", &tokens); | |
238 devices_.push_back(new AdbDeviceImpl(tokens[0])); | |
239 } | |
240 ProcessSerials(); | |
241 } | 136 } |
242 | 137 |
243 void ProcessSerials() { | 138 void ProcessSerials() { |
244 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 139 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); |
245 if (devices_.size() == 0) { | 140 if (devices_.size() == 0) { |
246 BrowserThread::PostTask( | 141 BrowserThread::PostTask( |
247 BrowserThread::UI, FROM_HERE, | 142 BrowserThread::UI, FROM_HERE, |
248 base::Bind(&AdbPagesCommand::Respond, this)); | 143 base::Bind(&AdbPagesCommand::Respond, this)); |
249 return; | 144 return; |
250 } | 145 } |
251 | 146 |
252 #if defined(DEBUG_DEVTOOLS) | 147 #if defined(DEBUG_DEVTOOLS) |
253 // For desktop remote debugging. | 148 // For desktop remote debugging. |
254 if (devices_.back()->serial().empty()) { | 149 if (devices_.back()->serial().empty()) { |
255 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = | 150 scoped_refptr<AndroidDevice> device = |
256 devices_.back(); | 151 devices_.back(); |
257 device->set_model(kLocalChrome); | 152 device->set_model(kLocalChrome); |
258 remote_devices_->push_back( | 153 remote_devices_->push_back( |
259 new DevToolsAdbBridge::RemoteDevice(bridge_, device)); | 154 new DevToolsAdbBridge::RemoteDevice(device)); |
260 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> remote_browser = | 155 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> remote_browser = |
261 new DevToolsAdbBridge::RemoteBrowser(bridge_, device, std::string()); | 156 new DevToolsAdbBridge::RemoteBrowser( |
| 157 adb_thread_, device, std::string()); |
262 remote_browser->set_product(kChrome); | 158 remote_browser->set_product(kChrome); |
263 remote_devices_->back()->AddBrowser(remote_browser); | 159 remote_devices_->back()->AddBrowser(remote_browser); |
264 browsers_.push_back(remote_browser); | 160 browsers_.push_back(remote_browser); |
265 device->HttpQuery( | 161 device->HttpQuery( |
266 std::string(), kVersionRequest, | 162 std::string(), kVersionRequest, |
267 base::Bind(&AdbPagesCommand::ReceivedVersion, this)); | 163 base::Bind(&AdbPagesCommand::ReceivedVersion, this)); |
268 return; | 164 return; |
269 } | 165 } |
270 #endif // defined(DEBUG_DEVTOOLS) | 166 #endif // defined(DEBUG_DEVTOOLS) |
271 | 167 |
272 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back(); | 168 scoped_refptr<AndroidDevice> device = devices_.back(); |
273 device->RunCommand(kDeviceModelCommand, | 169 device->RunCommand(kDeviceModelCommand, |
274 base::Bind(&AdbPagesCommand::ReceivedModel, this)); | 170 base::Bind(&AdbPagesCommand::ReceivedModel, this)); |
275 } | 171 } |
276 | 172 |
277 void ReceivedModel(int result, const std::string& response) { | 173 void ReceivedModel(int result, const std::string& response) { |
278 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 174 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); |
279 if (result < 0) { | 175 if (result < 0) { |
280 devices_.pop_back(); | 176 devices_.pop_back(); |
281 ProcessSerials(); | 177 ProcessSerials(); |
282 return; | 178 return; |
283 } | 179 } |
284 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back(); | 180 scoped_refptr<AndroidDevice> device = devices_.back(); |
285 device->set_model(response); | 181 device->set_model(response); |
286 remote_devices_->push_back( | 182 remote_devices_->push_back( |
287 new DevToolsAdbBridge::RemoteDevice(bridge_, device)); | 183 new DevToolsAdbBridge::RemoteDevice(device)); |
288 device->RunCommand(kOpenedUnixSocketsCommand, | 184 device->RunCommand(kOpenedUnixSocketsCommand, |
289 base::Bind(&AdbPagesCommand::ReceivedSockets, this)); | 185 base::Bind(&AdbPagesCommand::ReceivedSockets, this)); |
290 } | 186 } |
291 | 187 |
292 void ReceivedSockets(int result, const std::string& response) { | 188 void ReceivedSockets(int result, const std::string& response) { |
293 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 189 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); |
294 if (result < 0) { | 190 if (result < 0) { |
295 devices_.pop_back(); | 191 devices_.pop_back(); |
296 ProcessSerials(); | 192 ProcessSerials(); |
297 return; | 193 return; |
298 } | 194 } |
299 | 195 |
300 ParseSocketsList(response); | 196 ParseSocketsList(response); |
301 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back(); | 197 scoped_refptr<AndroidDevice> device = devices_.back(); |
302 device->RunCommand(kDumpsysCommand, | 198 device->RunCommand(kDumpsysCommand, |
303 base::Bind(&AdbPagesCommand::ReceivedDumpsys, this)); | 199 base::Bind(&AdbPagesCommand::ReceivedDumpsys, this)); |
304 } | 200 } |
305 | 201 |
306 void ReceivedDumpsys(int result, const std::string& response) { | 202 void ReceivedDumpsys(int result, const std::string& response) { |
307 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 203 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); |
308 if (result >= 0) | 204 if (result >= 0) |
309 ParseDumpsysResponse(response); | 205 ParseDumpsysResponse(response); |
310 | 206 |
311 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back(); | 207 scoped_refptr<AndroidDevice> device = devices_.back(); |
312 device->RunCommand(kListProcessesCommand, | 208 device->RunCommand(kListProcessesCommand, |
313 base::Bind(&AdbPagesCommand::ReceivedProcesses, this)); | 209 base::Bind(&AdbPagesCommand::ReceivedProcesses, this)); |
314 } | 210 } |
315 | 211 |
316 void ReceivedProcesses(int result, const std::string& response) { | 212 void ReceivedProcesses(int result, const std::string& response) { |
317 if (result >= 0) | 213 if (result >= 0) |
318 ParseProcessList(response); | 214 ParseProcessList(response); |
319 | 215 |
320 if (browsers_.size() == 0) { | 216 if (browsers_.size() == 0) { |
321 devices_.pop_back(); | 217 devices_.pop_back(); |
322 ProcessSerials(); | 218 ProcessSerials(); |
323 } else { | 219 } else { |
324 ProcessSockets(); | 220 ProcessSockets(); |
325 } | 221 } |
326 } | 222 } |
327 | 223 |
328 void ProcessSockets() { | 224 void ProcessSockets() { |
329 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 225 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); |
330 if (browsers_.size() == 0) { | 226 if (browsers_.size() == 0) { |
331 devices_.pop_back(); | 227 devices_.pop_back(); |
332 ProcessSerials(); | 228 ProcessSerials(); |
333 } else { | 229 } else { |
334 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back(); | 230 scoped_refptr<AndroidDevice> device = devices_.back(); |
335 device->HttpQuery(browsers_.back()->socket(), kVersionRequest, | 231 device->HttpQuery(browsers_.back()->socket(), kVersionRequest, |
336 base::Bind(&AdbPagesCommand::ReceivedVersion, this)); | 232 base::Bind(&AdbPagesCommand::ReceivedVersion, this)); |
337 } | 233 } |
338 } | 234 } |
339 | 235 |
340 void ReceivedVersion(int result, | 236 void ReceivedVersion(int result, |
341 const std::string& response) { | 237 const std::string& response) { |
342 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 238 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); |
343 if (result < 0) { | 239 if (result < 0) { |
344 browsers_.pop_back(); | 240 browsers_.pop_back(); |
345 ProcessSockets(); | 241 ProcessSockets(); |
346 return; | 242 return; |
347 } | 243 } |
348 | 244 |
349 // Parse version, append to package name if available, | 245 // Parse version, append to package name if available, |
350 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); | 246 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); |
351 base::DictionaryValue* dict; | 247 base::DictionaryValue* dict; |
352 if (value && value->GetAsDictionary(&dict)) { | 248 if (value && value->GetAsDictionary(&dict)) { |
353 std::string browser; | 249 std::string browser; |
354 if (dict->GetString("Browser", &browser)) { | 250 if (dict->GetString("Browser", &browser)) { |
355 std::vector<std::string> parts; | 251 std::vector<std::string> parts; |
356 Tokenize(browser, "/", &parts); | 252 Tokenize(browser, "/", &parts); |
357 if (parts.size() == 2) { | 253 if (parts.size() == 2) { |
358 if (parts[0] != "Version") // WebView has this for legacy reasons. | 254 if (parts[0] != "Version") // WebView has this for legacy reasons. |
359 browsers_.back()->set_product(parts[0]); | 255 browsers_.back()->set_product(parts[0]); |
360 browsers_.back()->set_version(parts[1]); | 256 browsers_.back()->set_version(parts[1]); |
361 } else { | 257 } else { |
362 browsers_.back()->set_version(browser); | 258 browsers_.back()->set_version(browser); |
363 } | 259 } |
364 } | 260 } |
365 } | 261 } |
366 | 262 |
367 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device = devices_.back(); | 263 scoped_refptr<AndroidDevice> device = devices_.back(); |
368 device->HttpQuery(browsers_.back()->socket(), kPageListRequest, | 264 device->HttpQuery(browsers_.back()->socket(), kPageListRequest, |
369 base::Bind(&AdbPagesCommand::ReceivedPages, this)); | 265 base::Bind(&AdbPagesCommand::ReceivedPages, this)); |
370 } | 266 } |
371 | 267 |
372 void ReceivedPages(int result, | 268 void ReceivedPages(int result, |
373 const std::string& response) { | 269 const std::string& response) { |
374 DCHECK_EQ(bridge_->GetAdbMessageLoop(), base::MessageLoop::current()); | 270 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current()); |
375 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser = browsers_.back(); | 271 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> browser = browsers_.back(); |
376 browsers_.pop_back(); | 272 browsers_.pop_back(); |
377 if (result < 0) { | 273 if (result < 0) { |
378 ProcessSockets(); | 274 ProcessSockets(); |
379 return; | 275 return; |
380 } | 276 } |
381 | 277 |
382 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); | 278 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); |
383 base::ListValue* list_value; | 279 base::ListValue* list_value; |
384 if (!value || !value->GetAsList(&list_value)) { | 280 if (!value || !value->GetAsList(&list_value)) { |
385 ProcessSockets(); | 281 ProcessSockets(); |
386 return; | 282 return; |
387 } | 283 } |
388 | 284 |
389 base::Value* item; | 285 base::Value* item; |
390 | 286 |
391 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 287 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
392 list_value->Get(i, &item); | 288 list_value->Get(i, &item); |
393 base::DictionaryValue* dict; | 289 base::DictionaryValue* dict; |
394 if (!item || !item->GetAsDictionary(&dict)) | 290 if (!item || !item->GetAsDictionary(&dict)) |
395 continue; | 291 continue; |
396 browser->AddPage(new DevToolsAdbBridge::RemotePage( | 292 browser->AddPage(new DevToolsAdbBridge::RemotePage( |
397 bridge_, browser->device(), browser->socket(), *dict)); | 293 adb_thread_, browser->device(), browser->socket(), *dict)); |
398 } | 294 } |
399 ProcessSockets(); | 295 ProcessSockets(); |
400 } | 296 } |
401 | 297 |
402 void Respond() { | 298 void Respond() { |
403 callback_.Run(remote_devices_.release()); | 299 callback_.Run(remote_devices_.release()); |
404 } | 300 } |
405 | 301 |
406 void ParseSocketsList(const std::string& response) { | 302 void ParseSocketsList(const std::string& response) { |
407 // On Android, '/proc/net/unix' looks like this: | 303 // On Android, '/proc/net/unix' looks like this: |
(...skipping 24 matching lines...) Expand all Loading... |
432 std::string path_field = fields[7]; | 328 std::string path_field = fields[7]; |
433 if (path_field.size() < 1 || path_field[0] != '@') | 329 if (path_field.size() < 1 || path_field[0] != '@') |
434 continue; | 330 continue; |
435 size_t socket_name_pos = path_field.find(channel_pattern); | 331 size_t socket_name_pos = path_field.find(channel_pattern); |
436 if (socket_name_pos == std::string::npos) | 332 if (socket_name_pos == std::string::npos) |
437 continue; | 333 continue; |
438 | 334 |
439 std::string socket = path_field.substr(1); | 335 std::string socket = path_field.substr(1); |
440 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> remote_browser = | 336 scoped_refptr<DevToolsAdbBridge::RemoteBrowser> remote_browser = |
441 new DevToolsAdbBridge::RemoteBrowser( | 337 new DevToolsAdbBridge::RemoteBrowser( |
442 bridge_, remote_device->device(), socket); | 338 adb_thread_, remote_device->device(), socket); |
443 | 339 |
444 std::string product = path_field.substr(1, socket_name_pos - 1); | 340 std::string product = path_field.substr(1, socket_name_pos - 1); |
445 product[0] = base::ToUpperASCII(product[0]); | 341 product[0] = base::ToUpperASCII(product[0]); |
446 remote_browser->set_product(product); | 342 remote_browser->set_product(product); |
447 | 343 |
448 size_t socket_name_end = socket_name_pos + channel_pattern.size(); | 344 size_t socket_name_end = socket_name_pos + channel_pattern.size(); |
449 if (socket_name_end < path_field.size() && | 345 if (socket_name_end < path_field.size() && |
450 path_field[socket_name_end] == '_') { | 346 path_field[socket_name_end] == '_') { |
451 remote_browser->set_pid(path_field.substr(socket_name_end + 1)); | 347 remote_browser->set_pid(path_field.substr(socket_name_end + 1)); |
452 } | 348 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 std::vector<std::string> numbers; | 400 std::vector<std::string> numbers; |
505 Tokenize(pairs[1].substr(1, pairs[1].size() - 2), ",", &numbers); | 401 Tokenize(pairs[1].substr(1, pairs[1].size() - 2), ",", &numbers); |
506 if (numbers.size() != 2 || | 402 if (numbers.size() != 2 || |
507 !base::StringToInt(numbers[0], &width) || | 403 !base::StringToInt(numbers[0], &width) || |
508 !base::StringToInt(numbers[1], &height)) | 404 !base::StringToInt(numbers[1], &height)) |
509 return; | 405 return; |
510 | 406 |
511 remote_devices_->back()->SetScreenSize(gfx::Size(width, height)); | 407 remote_devices_->back()->SetScreenSize(gfx::Size(width, height)); |
512 } | 408 } |
513 | 409 |
514 scoped_refptr<DevToolsAdbBridge> bridge_; | 410 scoped_refptr<RefCountedAdbThread> adb_thread_; |
515 Callback callback_; | 411 Callback callback_; |
516 AndroidDevices devices_; | 412 AndroidDevices devices_; |
| 413 DevToolsAdbBridge::DeviceProviders device_providers_; |
517 DevToolsAdbBridge::RemoteBrowsers browsers_; | 414 DevToolsAdbBridge::RemoteBrowsers browsers_; |
518 scoped_ptr<DevToolsAdbBridge::RemoteDevices> remote_devices_; | 415 scoped_ptr<DevToolsAdbBridge::RemoteDevices> remote_devices_; |
519 }; | 416 }; |
520 | 417 |
521 // AdbProtocolCommand --------------------------------------------------------- | 418 // AdbProtocolCommand --------------------------------------------------------- |
522 | 419 |
523 class AdbProtocolCommand : public AdbWebSocket::Delegate { | 420 class AdbProtocolCommand : public AdbWebSocket::Delegate { |
524 public: | 421 public: |
525 AdbProtocolCommand( | 422 AdbProtocolCommand( |
526 scoped_refptr<DevToolsAdbBridge> bridge_, | 423 scoped_refptr<RefCountedAdbThread> adb_thread, |
527 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, | 424 scoped_refptr<AndroidDevice> device, |
528 const std::string& socket_name, | 425 const std::string& socket_name, |
529 const std::string& debug_url, | 426 const std::string& debug_url, |
530 const std::string& command); | 427 const std::string& command); |
531 | 428 |
532 private: | 429 private: |
533 virtual void OnSocketOpened() OVERRIDE; | 430 virtual void OnSocketOpened() OVERRIDE; |
534 virtual void OnFrameRead(const std::string& message) OVERRIDE; | 431 virtual void OnFrameRead(const std::string& message) OVERRIDE; |
535 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE; | 432 virtual void OnSocketClosed(bool closed_by_device) OVERRIDE; |
536 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE; | 433 virtual bool ProcessIncomingMessage(const std::string& message) OVERRIDE; |
537 | 434 |
538 scoped_refptr<DevToolsAdbBridge> bridge_; | 435 scoped_refptr<RefCountedAdbThread> adb_thread_; |
539 const std::string command_; | 436 const std::string command_; |
540 scoped_refptr<AdbWebSocket> web_socket_; | 437 scoped_refptr<AdbWebSocket> web_socket_; |
541 | 438 |
542 DISALLOW_COPY_AND_ASSIGN(AdbProtocolCommand); | 439 DISALLOW_COPY_AND_ASSIGN(AdbProtocolCommand); |
543 }; | 440 }; |
544 | 441 |
545 AdbProtocolCommand::AdbProtocolCommand( | 442 AdbProtocolCommand::AdbProtocolCommand( |
546 scoped_refptr<DevToolsAdbBridge> bridge, | 443 scoped_refptr<RefCountedAdbThread> adb_thread, |
547 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, | 444 scoped_refptr<AndroidDevice> device, |
548 const std::string& socket_name, | 445 const std::string& socket_name, |
549 const std::string& debug_url, | 446 const std::string& debug_url, |
550 const std::string& command) | 447 const std::string& command) |
551 : bridge_(bridge), | 448 : adb_thread_(adb_thread), |
552 command_(command) { | 449 command_(command) { |
553 web_socket_ = new AdbWebSocket( | 450 web_socket_ = new AdbWebSocket( |
554 device, socket_name, debug_url, bridge_->GetAdbMessageLoop(), this); | 451 device, socket_name, debug_url, adb_thread_->message_loop(), this); |
555 } | 452 } |
556 | 453 |
557 void AdbProtocolCommand::OnSocketOpened() { | 454 void AdbProtocolCommand::OnSocketOpened() { |
558 web_socket_->SendFrame(command_); | 455 web_socket_->SendFrame(command_); |
559 web_socket_->Disconnect(); | 456 web_socket_->Disconnect(); |
560 } | 457 } |
561 | 458 |
562 void AdbProtocolCommand::OnFrameRead(const std::string& message) {} | 459 void AdbProtocolCommand::OnFrameRead(const std::string& message) {} |
563 | 460 |
564 void AdbProtocolCommand::OnSocketClosed(bool closed_by_device) { | 461 void AdbProtocolCommand::OnSocketClosed(bool closed_by_device) { |
565 delete this; | 462 delete this; |
566 } | 463 } |
567 | 464 |
568 bool AdbProtocolCommand::ProcessIncomingMessage(const std::string& message) { | 465 bool AdbProtocolCommand::ProcessIncomingMessage(const std::string& message) { |
569 return false; | 466 return false; |
570 } | 467 } |
571 | 468 |
572 } // namespace | 469 } // namespace |
573 | 470 |
574 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; | 471 const char kDevToolsChannelNameFormat[] = "%s_devtools_remote"; |
575 | 472 |
576 class AgentHostDelegate; | 473 class AgentHostDelegate; |
577 | 474 |
578 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates; | 475 typedef std::map<std::string, AgentHostDelegate*> AgentHostDelegates; |
579 | 476 |
580 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates = | 477 base::LazyInstance<AgentHostDelegates>::Leaky g_host_delegates = |
581 LAZY_INSTANCE_INITIALIZER; | 478 LAZY_INSTANCE_INITIALIZER; |
582 | 479 |
583 DevToolsAdbBridge::Wrapper::Wrapper(Profile* profile) | 480 DevToolsAdbBridge::Wrapper::Wrapper(Profile* profile, |
584 : bridge_(new DevToolsAdbBridge(profile)) { | 481 const DeviceProviders& device_providers) |
| 482 : bridge_(new DevToolsAdbBridge(profile, device_providers)) { |
585 } | 483 } |
586 | 484 |
587 DevToolsAdbBridge::Wrapper::~Wrapper() { | 485 DevToolsAdbBridge::Wrapper::~Wrapper() { |
588 } | 486 } |
589 | 487 |
590 DevToolsAdbBridge* DevToolsAdbBridge::Wrapper::Get() { | 488 DevToolsAdbBridge* DevToolsAdbBridge::Wrapper::Get() { |
591 return bridge_.get(); | 489 return bridge_.get(); |
592 } | 490 } |
593 | 491 |
594 // static | 492 // static |
(...skipping 13 matching lines...) Expand all Loading... |
608 DevToolsAdbBridge::Factory::Factory() | 506 DevToolsAdbBridge::Factory::Factory() |
609 : BrowserContextKeyedServiceFactory( | 507 : BrowserContextKeyedServiceFactory( |
610 "DevToolsAdbBridge", | 508 "DevToolsAdbBridge", |
611 BrowserContextDependencyManager::GetInstance()) {} | 509 BrowserContextDependencyManager::GetInstance()) {} |
612 | 510 |
613 DevToolsAdbBridge::Factory::~Factory() {} | 511 DevToolsAdbBridge::Factory::~Factory() {} |
614 | 512 |
615 BrowserContextKeyedService* | 513 BrowserContextKeyedService* |
616 DevToolsAdbBridge::Factory::BuildServiceInstanceFor( | 514 DevToolsAdbBridge::Factory::BuildServiceInstanceFor( |
617 content::BrowserContext* context) const { | 515 content::BrowserContext* context) const { |
618 return new DevToolsAdbBridge::Wrapper(Profile::FromBrowserContext(context)); | 516 Profile* profile = Profile::FromBrowserContext(context); |
| 517 |
| 518 DeviceProviders device_providers; |
| 519 device_providers.push_back( |
| 520 new UsbDeviceProvider(profile, RefCountedAdbThread::GetInstance())); |
| 521 device_providers.push_back( |
| 522 new AdbDeviceProvider(RefCountedAdbThread::GetInstance())); |
| 523 |
| 524 return new DevToolsAdbBridge::Wrapper(profile, device_providers); |
619 } | 525 } |
620 | 526 |
621 DevToolsAdbBridge::AndroidDevice::AndroidDevice(const std::string& serial) | |
622 : serial_(serial) { | |
623 } | |
624 | |
625 void DevToolsAdbBridge::AndroidDevice::HttpQuery( | |
626 const std::string& la_name, | |
627 const std::string& request, | |
628 const CommandCallback& callback) { | |
629 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this, | |
630 request, callback)); | |
631 } | |
632 | |
633 void DevToolsAdbBridge::AndroidDevice::HttpUpgrade( | |
634 const std::string& la_name, | |
635 const std::string& request, | |
636 const SocketCallback& callback) { | |
637 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened2, this, | |
638 request, callback)); | |
639 } | |
640 | |
641 DevToolsAdbBridge::AndroidDevice::~AndroidDevice() { | |
642 } | |
643 | |
644 void DevToolsAdbBridge::AndroidDevice::OnHttpSocketOpened( | |
645 const std::string& request, | |
646 const CommandCallback& callback, | |
647 int result, | |
648 net::StreamSocket* socket) { | |
649 if (result != net::OK) { | |
650 callback.Run(result, std::string()); | |
651 return; | |
652 } | |
653 AdbClientSocket::HttpQuery(socket, request, callback); | |
654 } | |
655 | |
656 void DevToolsAdbBridge::AndroidDevice::OnHttpSocketOpened2( | |
657 const std::string& request, | |
658 const SocketCallback& callback, | |
659 int result, | |
660 net::StreamSocket* socket) { | |
661 if (result != net::OK) { | |
662 callback.Run(result, NULL); | |
663 return; | |
664 } | |
665 AdbClientSocket::HttpQuery(socket, request, callback); | |
666 } | |
667 | 527 |
668 class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, | 528 class AgentHostDelegate : public content::DevToolsExternalAgentProxyDelegate, |
669 public AdbWebSocket::Delegate { | 529 public AdbWebSocket::Delegate { |
670 public: | 530 public: |
671 AgentHostDelegate( | 531 AgentHostDelegate( |
672 const std::string& id, | 532 const std::string& id, |
673 scoped_refptr<DevToolsAdbBridge::AndroidDevice> device, | 533 scoped_refptr<AndroidDevice> device, |
674 const std::string& socket_name, | 534 const std::string& socket_name, |
675 const std::string& debug_url, | 535 const std::string& debug_url, |
676 const std::string& frontend_url, | 536 const std::string& frontend_url, |
677 base::MessageLoop* adb_message_loop, | 537 base::MessageLoop* adb_message_loop, |
678 Profile* profile) | 538 Profile* profile) |
679 : id_(id), | 539 : id_(id), |
680 serial_(device->serial()), | 540 serial_(device->serial()), |
681 frontend_url_(frontend_url), | 541 frontend_url_(frontend_url), |
682 adb_message_loop_(adb_message_loop), | 542 adb_message_loop_(adb_message_loop), |
683 profile_(profile) { | 543 profile_(profile) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 const std::string frontend_url_; | 592 const std::string frontend_url_; |
733 base::MessageLoop* adb_message_loop_; | 593 base::MessageLoop* adb_message_loop_; |
734 Profile* profile_; | 594 Profile* profile_; |
735 | 595 |
736 scoped_ptr<content::DevToolsExternalAgentProxy> proxy_; | 596 scoped_ptr<content::DevToolsExternalAgentProxy> proxy_; |
737 scoped_refptr<AdbWebSocket> web_socket_; | 597 scoped_refptr<AdbWebSocket> web_socket_; |
738 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); | 598 DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); |
739 }; | 599 }; |
740 | 600 |
741 DevToolsAdbBridge::RemotePage::RemotePage( | 601 DevToolsAdbBridge::RemotePage::RemotePage( |
742 scoped_refptr<DevToolsAdbBridge> bridge, | 602 scoped_refptr<RefCountedAdbThread> adb_thread, |
743 scoped_refptr<AndroidDevice> device, | 603 scoped_refptr<AndroidDevice> device, |
744 const std::string& socket, | 604 const std::string& socket, |
745 const base::DictionaryValue& value) | 605 const base::DictionaryValue& value) |
746 : bridge_(bridge), | 606 : adb_thread_(adb_thread), |
747 device_(device), | 607 device_(device), |
748 socket_(socket) { | 608 socket_(socket) { |
749 value.GetString("id", &id_); | 609 value.GetString("id", &id_); |
750 value.GetString("url", &url_); | 610 value.GetString("url", &url_); |
751 value.GetString("title", &title_); | 611 value.GetString("title", &title_); |
752 value.GetString("description", &description_); | 612 value.GetString("description", &description_); |
753 value.GetString("faviconUrl", &favicon_url_); | 613 value.GetString("faviconUrl", &favicon_url_); |
754 value.GetString("webSocketDebuggerUrl", &debug_url_); | 614 value.GetString("webSocketDebuggerUrl", &debug_url_); |
755 value.GetString("devtoolsFrontendUrl", &frontend_url_); | 615 value.GetString("devtoolsFrontendUrl", &frontend_url_); |
756 | 616 |
(...skipping 28 matching lines...) Expand all Loading... |
785 void DevToolsAdbBridge::RemotePage::Activate() { | 645 void DevToolsAdbBridge::RemotePage::Activate() { |
786 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 646 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
787 RequestActivate(base::Bind(&Noop)); | 647 RequestActivate(base::Bind(&Noop)); |
788 } | 648 } |
789 | 649 |
790 void DevToolsAdbBridge::RemotePage::Close() { | 650 void DevToolsAdbBridge::RemotePage::Close() { |
791 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 651 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
792 if (attached()) | 652 if (attached()) |
793 return; | 653 return; |
794 std::string request = base::StringPrintf(kClosePageRequest, id_.c_str()); | 654 std::string request = base::StringPrintf(kClosePageRequest, id_.c_str()); |
795 bridge_->GetAdbMessageLoop()->PostTask(FROM_HERE, | 655 adb_thread_->message_loop()->PostTask(FROM_HERE, |
796 base::Bind(&AndroidDevice::HttpQuery, | 656 base::Bind(&AndroidDevice::HttpQuery, |
797 device_, socket_, request, base::Bind(&Noop))); | 657 device_, socket_, request, base::Bind(&Noop))); |
798 } | 658 } |
799 | 659 |
800 void DevToolsAdbBridge::RemotePage::Reload() { | 660 void DevToolsAdbBridge::RemotePage::Reload() { |
801 SendProtocolCommand(kPageReloadCommand, NULL); | 661 SendProtocolCommand(kPageReloadCommand, NULL); |
802 } | 662 } |
803 | 663 |
804 void DevToolsAdbBridge::RemotePage::SendProtocolCommand( | 664 void DevToolsAdbBridge::RemotePage::SendProtocolCommand( |
805 const std::string& method, | 665 const std::string& method, |
806 base::DictionaryValue* params) { | 666 base::DictionaryValue* params) { |
807 if (attached()) | 667 if (attached()) |
808 return; | 668 return; |
809 DevToolsProtocol::Command command(1, method, params); | 669 DevToolsProtocol::Command command(1, method, params); |
810 new AdbProtocolCommand( | 670 new AdbProtocolCommand( |
811 bridge_, device_, socket_, debug_url_, command.Serialize()); | 671 adb_thread_, device_, socket_, debug_url_, command.Serialize()); |
812 } | 672 } |
813 | 673 |
814 DevToolsAdbBridge::RemotePage::~RemotePage() { | 674 DevToolsAdbBridge::RemotePage::~RemotePage() { |
815 } | 675 } |
816 | 676 |
817 void DevToolsAdbBridge::RemotePage::RequestActivate( | 677 void DevToolsAdbBridge::RemotePage::RequestActivate( |
818 const CommandCallback& callback) { | 678 const CommandCallback& callback) { |
819 std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str()); | 679 std::string request = base::StringPrintf(kActivatePageRequest, id_.c_str()); |
820 bridge_->GetAdbMessageLoop()->PostTask(FROM_HERE, | 680 adb_thread_->message_loop()->PostTask(FROM_HERE, |
821 base::Bind(&AndroidDevice::HttpQuery, | 681 base::Bind(&AndroidDevice::HttpQuery, |
822 device_, socket_, request, callback)); | 682 device_, socket_, request, callback)); |
823 } | 683 } |
824 | 684 |
825 void DevToolsAdbBridge::RemotePage::InspectOnHandlerThread( | 685 void DevToolsAdbBridge::RemotePage::InspectOnHandlerThread( |
826 Profile* profile, int result, const std::string& response) { | 686 Profile* profile, int result, const std::string& response) { |
827 BrowserThread::PostTask( | 687 BrowserThread::PostTask( |
828 BrowserThread::UI, FROM_HERE, | 688 BrowserThread::UI, FROM_HERE, |
829 base::Bind(&RemotePage::InspectOnUIThread, this, profile)); | 689 base::Bind(&RemotePage::InspectOnUIThread, this, profile)); |
830 } | 690 } |
831 | 691 |
832 void DevToolsAdbBridge::RemotePage::InspectOnUIThread(Profile* profile) { | 692 void DevToolsAdbBridge::RemotePage::InspectOnUIThread(Profile* profile) { |
833 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 693 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
834 std::string agent_id = base::StringPrintf("%s:%s:%s", | 694 std::string agent_id = base::StringPrintf("%s:%s:%s", |
835 device_->serial().c_str(), socket_.c_str(), id_.c_str()); | 695 device_->serial().c_str(), socket_.c_str(), id_.c_str()); |
836 AgentHostDelegates::iterator it = | 696 AgentHostDelegates::iterator it = |
837 g_host_delegates.Get().find(agent_id); | 697 g_host_delegates.Get().find(agent_id); |
838 if (it != g_host_delegates.Get().end()) { | 698 if (it != g_host_delegates.Get().end()) { |
839 it->second->OpenFrontend(); | 699 it->second->OpenFrontend(); |
840 } else if (!attached()) { | 700 } else if (!attached()) { |
841 new AgentHostDelegate( | 701 new AgentHostDelegate( |
842 agent_id, device_, socket_, debug_url_, | 702 agent_id, device_, socket_, debug_url_, |
843 frontend_url_, bridge_->GetAdbMessageLoop(), profile); | 703 frontend_url_, adb_thread_->message_loop(), profile); |
844 } | 704 } |
845 } | 705 } |
846 | 706 |
847 DevToolsAdbBridge::RemoteBrowser::RemoteBrowser( | 707 DevToolsAdbBridge::RemoteBrowser::RemoteBrowser( |
848 scoped_refptr<DevToolsAdbBridge> bridge, | 708 scoped_refptr<RefCountedAdbThread> adb_thread, |
849 scoped_refptr<AndroidDevice> device, | 709 scoped_refptr<AndroidDevice> device, |
850 const std::string& socket) | 710 const std::string& socket) |
851 : bridge_(bridge), | 711 : adb_thread_(adb_thread), |
852 device_(device), | 712 device_(device), |
853 socket_(socket) { | 713 socket_(socket) { |
854 } | 714 } |
855 | 715 |
856 void DevToolsAdbBridge::RemoteBrowser::Open(const std::string& url) { | 716 void DevToolsAdbBridge::RemoteBrowser::Open(const std::string& url) { |
857 bridge_->GetAdbMessageLoop()->PostTask(FROM_HERE, | 717 adb_thread_->message_loop()->PostTask(FROM_HERE, |
858 base::Bind(&AndroidDevice::HttpQuery, | 718 base::Bind(&AndroidDevice::HttpQuery, |
859 device_, socket_, kNewPageRequest, | 719 device_, socket_, kNewPageRequest, |
860 base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url))); | 720 base::Bind(&RemoteBrowser::PageCreatedOnHandlerThread, this, url))); |
861 } | 721 } |
862 | 722 |
863 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnHandlerThread( | 723 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnHandlerThread( |
864 const std::string& url, int result, const std::string& response) { | 724 const std::string& url, int result, const std::string& response) { |
865 if (result < 0) | 725 if (result < 0) |
866 return; | 726 return; |
867 BrowserThread::PostTask( | 727 BrowserThread::PostTask( |
868 BrowserThread::UI, FROM_HERE, | 728 BrowserThread::UI, FROM_HERE, |
869 base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, response, url)); | 729 base::Bind(&RemoteBrowser::PageCreatedOnUIThread, this, response, url)); |
870 } | 730 } |
871 | 731 |
872 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread( | 732 void DevToolsAdbBridge::RemoteBrowser::PageCreatedOnUIThread( |
873 const std::string& response, const std::string& url) { | 733 const std::string& response, const std::string& url) { |
874 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); | 734 scoped_ptr<base::Value> value(base::JSONReader::Read(response)); |
875 base::DictionaryValue* dict; | 735 base::DictionaryValue* dict; |
876 if (value && value->GetAsDictionary(&dict)) { | 736 if (value && value->GetAsDictionary(&dict)) { |
877 scoped_refptr<RemotePage> new_page = | 737 scoped_refptr<RemotePage> new_page = |
878 new RemotePage(bridge_, device_, socket_, *dict); | 738 new RemotePage(adb_thread_, device_, socket_, *dict); |
879 base::DictionaryValue params; | 739 base::DictionaryValue params; |
880 params.SetString(kUrlParam, url); | 740 params.SetString(kUrlParam, url); |
881 new_page->SendProtocolCommand(kPageNavigateCommand, ¶ms); | 741 new_page->SendProtocolCommand(kPageNavigateCommand, ¶ms); |
882 } | 742 } |
883 } | 743 } |
884 | 744 |
885 DevToolsAdbBridge::RemoteBrowser::~RemoteBrowser() { | 745 DevToolsAdbBridge::RemoteBrowser::~RemoteBrowser() { |
886 } | 746 } |
887 | 747 |
888 DevToolsAdbBridge::RemoteDevice::RemoteDevice( | 748 DevToolsAdbBridge::RemoteDevice::RemoteDevice( |
889 scoped_refptr<DevToolsAdbBridge> bridge, | |
890 scoped_refptr<AndroidDevice> device) | 749 scoped_refptr<AndroidDevice> device) |
891 : bridge_(bridge), | 750 : device_(device) { |
892 device_(device) { | |
893 } | 751 } |
894 | 752 |
895 DevToolsAdbBridge::RemoteDevice::~RemoteDevice() { | 753 DevToolsAdbBridge::RemoteDevice::~RemoteDevice() { |
896 } | 754 } |
897 | 755 |
898 | 756 |
899 DevToolsAdbBridge::RefCountedAdbThread* | |
900 DevToolsAdbBridge::RefCountedAdbThread::instance_ = NULL; | |
901 | 757 |
902 // static | 758 DevToolsAdbBridge::DevToolsAdbBridge(Profile* profile, |
903 scoped_refptr<DevToolsAdbBridge::RefCountedAdbThread> | 759 const DeviceProviders& device_providers) |
904 DevToolsAdbBridge::RefCountedAdbThread::GetInstance() { | 760 : adb_thread_(RefCountedAdbThread::GetInstance()), |
905 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 761 device_providers_(device_providers), |
906 if (!instance_) | |
907 new RefCountedAdbThread(); | |
908 return instance_; | |
909 } | |
910 | |
911 DevToolsAdbBridge::RefCountedAdbThread::RefCountedAdbThread() { | |
912 instance_ = this; | |
913 thread_ = new base::Thread(kDevToolsAdbBridgeThreadName); | |
914 base::Thread::Options options; | |
915 options.message_loop_type = base::MessageLoop::TYPE_IO; | |
916 if (!thread_->StartWithOptions(options)) { | |
917 delete thread_; | |
918 thread_ = NULL; | |
919 } | |
920 } | |
921 | |
922 base::MessageLoop* DevToolsAdbBridge::RefCountedAdbThread::message_loop() { | |
923 return thread_ ? thread_->message_loop() : NULL; | |
924 } | |
925 | |
926 // static | |
927 void DevToolsAdbBridge::RefCountedAdbThread::StopThread(base::Thread* thread) { | |
928 thread->Stop(); | |
929 } | |
930 | |
931 DevToolsAdbBridge::RefCountedAdbThread::~RefCountedAdbThread() { | |
932 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
933 instance_ = NULL; | |
934 if (!thread_) | |
935 return; | |
936 // Shut down thread on FILE thread to join into IO. | |
937 BrowserThread::PostTask( | |
938 BrowserThread::FILE, FROM_HERE, | |
939 base::Bind(&RefCountedAdbThread::StopThread, thread_)); | |
940 } | |
941 | |
942 DevToolsAdbBridge::DevToolsAdbBridge(Profile* profile) | |
943 : profile_(profile), | |
944 adb_thread_(RefCountedAdbThread::GetInstance()), | |
945 has_message_loop_(adb_thread_->message_loop() != NULL) { | 762 has_message_loop_(adb_thread_->message_loop() != NULL) { |
946 rsa_key_.reset(AndroidRSAPrivateKey(profile)); | 763 rsa_key_.reset(AndroidRSAPrivateKey(profile)); |
947 } | 764 } |
948 | 765 |
949 void DevToolsAdbBridge::AddListener(Listener* listener) { | 766 void DevToolsAdbBridge::AddListener(Listener* listener) { |
950 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 767 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
951 if (listeners_.empty()) | 768 if (listeners_.empty()) |
952 RequestRemoteDevices(); | 769 RequestRemoteDevices(); |
953 listeners_.push_back(listener); | 770 listeners_.push_back(listener); |
954 } | 771 } |
955 | 772 |
956 void DevToolsAdbBridge::RemoveListener(Listener* listener) { | 773 void DevToolsAdbBridge::RemoveListener(Listener* listener) { |
957 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 774 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
958 Listeners::iterator it = | 775 Listeners::iterator it = |
959 std::find(listeners_.begin(), listeners_.end(), listener); | 776 std::find(listeners_.begin(), listeners_.end(), listener); |
960 DCHECK(it != listeners_.end()); | 777 DCHECK(it != listeners_.end()); |
961 listeners_.erase(it); | 778 listeners_.erase(it); |
962 } | 779 } |
963 | 780 |
964 base::MessageLoop* DevToolsAdbBridge::GetAdbMessageLoop() { | |
965 return adb_thread_->message_loop(); | |
966 } | |
967 | |
968 DevToolsAdbBridge::~DevToolsAdbBridge() { | 781 DevToolsAdbBridge::~DevToolsAdbBridge() { |
969 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 782 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
970 DCHECK(listeners_.empty()); | 783 DCHECK(listeners_.empty()); |
971 } | 784 } |
972 | 785 |
973 void DevToolsAdbBridge::RequestRemoteDevices() { | 786 void DevToolsAdbBridge::RequestRemoteDevices() { |
974 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 787 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
975 if (!has_message_loop_) | 788 if (!has_message_loop_) |
976 return; | 789 return; |
977 | 790 |
978 new AdbPagesCommand( | 791 new AdbPagesCommand( |
979 this, rsa_key_.get(), | 792 adb_thread_, rsa_key_.get(), |
980 base::Bind(&DevToolsAdbBridge::ReceivedRemoteDevices, this)); | 793 base::Bind(&DevToolsAdbBridge::ReceivedRemoteDevices, this), |
| 794 device_providers_); |
981 } | 795 } |
982 | 796 |
983 void DevToolsAdbBridge::ReceivedRemoteDevices(RemoteDevices* devices_ptr) { | 797 void DevToolsAdbBridge::ReceivedRemoteDevices(RemoteDevices* devices_ptr) { |
984 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 798 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
985 | 799 |
986 scoped_ptr<RemoteDevices> devices(devices_ptr); | 800 scoped_ptr<RemoteDevices> devices(devices_ptr); |
987 | 801 |
988 Listeners copy(listeners_); | 802 Listeners copy(listeners_); |
989 for (Listeners::iterator it = copy.begin(); it != copy.end(); ++it) | 803 for (Listeners::iterator it = copy.begin(); it != copy.end(); ++it) |
990 (*it)->RemoteDevicesChanged(devices.get()); | 804 (*it)->RemoteDevicesChanged(devices.get()); |
991 | 805 |
992 if (listeners_.empty()) | 806 if (listeners_.empty()) |
993 return; | 807 return; |
994 | 808 |
995 BrowserThread::PostDelayedTask( | 809 BrowserThread::PostDelayedTask( |
996 BrowserThread::UI, | 810 BrowserThread::UI, |
997 FROM_HERE, | 811 FROM_HERE, |
998 base::Bind(&DevToolsAdbBridge::RequestRemoteDevices, this), | 812 base::Bind(&DevToolsAdbBridge::RequestRemoteDevices, this), |
999 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); | 813 base::TimeDelta::FromMilliseconds(kAdbPollingIntervalMs)); |
1000 } | 814 } |
OLD | NEW |