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

Side by Side Diff: chrome/browser/devtools/android_device_provider.cc

Issue 26568004: Introduced AndroidDeviceProvider to simplify testing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed all the comments. Created 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/devtools/android_device_provider.h"
6
7 #include "base/strings/string_util.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/threading/thread.h"
10 #include "chrome/browser/devtools/adb/android_rsa.h"
11 #include "chrome/browser/devtools/adb/android_usb_device.h"
12 #include "chrome/browser/devtools/adb_client_socket.h"
13 #include "net/base/net_errors.h"
14
15 using content::BrowserThread;
16
17 const char kDevToolsAdbBridgeThreadName[] = "Chrome_DevToolsADBThread";
18 const char kHostTransportCommand[] = "host:transport:%s|%s";
19 const char kHostDevicesCommand[] = "host:devices";
20 const char kLocalAbstractCommand[] = "localabstract:%s";
21
22 const int kAdbPort = 5037;
23 const int kBufferSize = 16 * 1024;
24
25 // AndroidDevice -------------------------------------------
26
27 AndroidDevice::AndroidDevice(const std::string& serial)
28 : serial_(serial) {
29 }
30
31 void AndroidDevice::HttpQuery(
32 const std::string& la_name,
33 const std::string& request,
34 const CommandCallback& callback) {
35 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened, this,
36 request, callback));
37 }
38
39 void AndroidDevice::HttpUpgrade(
40 const std::string& la_name,
41 const std::string& request,
42 const SocketCallback& callback) {
43 OpenSocket(la_name, base::Bind(&AndroidDevice::OnHttpSocketOpened2, this,
44 request, callback));
45 }
46
47 AndroidDevice::~AndroidDevice() {
48 }
49
50 void AndroidDevice::OnHttpSocketOpened(
51 const std::string& request,
52 const CommandCallback& callback,
53 int result,
54 net::StreamSocket* socket) {
55 if (result != net::OK) {
56 callback.Run(result, std::string());
57 return;
58 }
59 AdbClientSocket::HttpQuery(socket, request, callback);
60 }
61
62 void AndroidDevice::OnHttpSocketOpened2(
63 const std::string& request,
64 const SocketCallback& callback,
65 int result,
66 net::StreamSocket* socket) {
67 if (result != net::OK) {
68 callback.Run(result, NULL);
69 return;
70 }
71 AdbClientSocket::HttpQuery(socket, request, callback);
72 }
73
74 namespace {
Vladislav Kaznacheev 2013/10/21 10:09:01 Please move the namespace to the top of the file a
Dmitry Zvorygin 2013/10/21 10:22:35 Done.
75
76 // AdbDeviceImpl --------------------------------------------------------------
77
78 class AdbDeviceImpl : public AndroidDevice {
79 public:
80 explicit AdbDeviceImpl(const std::string& serial);
81 virtual void RunCommand(const std::string& command,
82 const CommandCallback& callback) OVERRIDE;
83 virtual void OpenSocket(const std::string& name,
84 const SocketCallback& callback) OVERRIDE;
85 virtual bool IsConnected() OVERRIDE;
86
87 private:
88 virtual ~AdbDeviceImpl() {}
89 };
90
91 AdbDeviceImpl::AdbDeviceImpl(const std::string& serial)
92 : AndroidDevice(serial) {
93 }
94
95 void AdbDeviceImpl::RunCommand(const std::string& command,
96 const CommandCallback& callback) {
97 std::string query = base::StringPrintf(kHostTransportCommand,
98 serial().c_str(), command.c_str());
99 AdbClientSocket::AdbQuery(kAdbPort, query, callback);
100 }
101
102 void AdbDeviceImpl::OpenSocket(const std::string& name,
103 const SocketCallback& callback) {
104 std::string socket_name =
105 base::StringPrintf(kLocalAbstractCommand, name.c_str());
106 AdbClientSocket::TransportQuery(kAdbPort, serial(), socket_name, callback);
107 }
108
109 bool AdbDeviceImpl::IsConnected() {
110 return true;
111 }
112
113 // UsbDeviceImpl --------------------------------------------------------------
114
115 class UsbDeviceImpl : public AndroidDevice {
116 public:
117 explicit UsbDeviceImpl(AndroidUsbDevice* device);
118 virtual void RunCommand(const std::string& command,
119 const CommandCallback& callback) OVERRIDE;
120 virtual void OpenSocket(const std::string& name,
121 const SocketCallback& callback) OVERRIDE;
122 virtual bool IsConnected() OVERRIDE;
123
124 private:
125 void OnOpenSocket(const SocketCallback& callback,
126 net::StreamSocket* socket,
127 int result);
128 void OpenedForCommand(const CommandCallback& callback,
129 net::StreamSocket* socket,
130 int result);
131 void OnRead(net::StreamSocket* socket,
132 scoped_refptr<net::IOBuffer> buffer,
133 const std::string& data,
134 const CommandCallback& callback,
135 int result);
136
137 virtual ~UsbDeviceImpl() {}
138 scoped_refptr<AndroidUsbDevice> device_;
139 };
140
141
142 UsbDeviceImpl::UsbDeviceImpl(AndroidUsbDevice* device)
143 : AndroidDevice(device->serial()),
144 device_(device) {
145 device_->InitOnCallerThread();
146 }
147
148 void UsbDeviceImpl::RunCommand(const std::string& command,
149 const CommandCallback& callback) {
150 net::StreamSocket* socket = device_->CreateSocket(command);
151 int result = socket->Connect(base::Bind(&UsbDeviceImpl::OpenedForCommand,
152 this, callback, socket));
153 if (result != net::ERR_IO_PENDING)
154 callback.Run(result, std::string());
155 }
156
157 void UsbDeviceImpl::OpenSocket(const std::string& name,
158 const SocketCallback& callback) {
159 std::string socket_name =
160 base::StringPrintf(kLocalAbstractCommand, name.c_str());
161 net::StreamSocket* socket = device_->CreateSocket(socket_name);
162 int result = socket->Connect(base::Bind(&UsbDeviceImpl::OnOpenSocket, this,
163 callback, socket));
164 if (result != net::ERR_IO_PENDING)
165 callback.Run(result, NULL);
166 }
167
168 void UsbDeviceImpl::OnOpenSocket(const SocketCallback& callback,
169 net::StreamSocket* socket,
170 int result) {
171 callback.Run(result, result == net::OK ? socket : NULL);
172 }
173
174 void UsbDeviceImpl::OpenedForCommand(const CommandCallback& callback,
175 net::StreamSocket* socket,
176 int result) {
177 if (result != net::OK) {
178 callback.Run(result, std::string());
179 return;
180 }
181 scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kBufferSize);
182 result = socket->Read(buffer, kBufferSize,
183 base::Bind(&UsbDeviceImpl::OnRead, this,
184 socket, buffer, std::string(), callback));
185 if (result != net::ERR_IO_PENDING)
186 OnRead(socket, buffer, std::string(), callback, result);
187 }
188
189 void UsbDeviceImpl::OnRead(net::StreamSocket* socket,
190 scoped_refptr<net::IOBuffer> buffer,
191 const std::string& data,
192 const CommandCallback& callback,
193 int result) {
194 if (result <= 0) {
195 callback.Run(result, result == 0 ? data : std::string());
196 delete socket;
197 return;
198 }
199
200 std::string new_data = data + std::string(buffer->data(), result);
201 result = socket->Read(buffer, kBufferSize,
202 base::Bind(&UsbDeviceImpl::OnRead, this,
203 socket, buffer, new_data, callback));
204 if (result != net::ERR_IO_PENDING)
205 OnRead(socket, buffer, new_data, callback, result);
206 }
207
208 bool UsbDeviceImpl::IsConnected() {
209 return device_->is_connected();
210 }
211
212 // UsbDeviceProvider -------------------------------------------
213
214 class UsbDeviceProvider: public AndroidDeviceProvider {
215 public:
216 explicit UsbDeviceProvider(Profile* profile);
217
218 virtual void QueryDevices(const QueryDeviceCallback& callback) OVERRIDE;
219 private:
220 virtual ~UsbDeviceProvider();
221 void WrapDevicesOnAdbThread(const QueryDeviceCallback& callback,
222 const AndroidUsbDevices& devices);
223 void EnumeratedDevices(const QueryDeviceCallback& callback,
224 const AndroidUsbDevices& devices);
225
226 scoped_ptr<crypto::RSAPrivateKey> rsa_key_;
227 };
228
229 UsbDeviceProvider::UsbDeviceProvider(Profile* profile){
230 rsa_key_.reset(AndroidRSAPrivateKey(profile));
231 }
232
233 UsbDeviceProvider::~UsbDeviceProvider() {
234 }
235
236 void UsbDeviceProvider::QueryDevices(const QueryDeviceCallback& callback) {
237 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
238 AndroidUsbDevice::Enumerate(rsa_key_.get(),
239 base::Bind(&UsbDeviceProvider::EnumeratedDevices,
240 this, callback));
241 }
242
243 void UsbDeviceProvider::EnumeratedDevices(const QueryDeviceCallback& callback,
244 const AndroidUsbDevices& devices) {
245 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
246 adb_thread_->message_loop()->PostTask(FROM_HERE,
247 base::Bind(&UsbDeviceProvider::WrapDevicesOnAdbThread,
248 this, callback, devices));
249 }
250
251 void UsbDeviceProvider::WrapDevicesOnAdbThread(
252 const QueryDeviceCallback& callback,const AndroidUsbDevices& devices) {
253 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
254 AndroidDevices result;
255 for (AndroidUsbDevices::const_iterator it = devices.begin();
256 it != devices.end(); ++it)
257 result.push_back(new UsbDeviceImpl(*it));
258
259 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
260 base::Bind(&UsbDeviceProvider::RunCallbackOnUIThread,
261 this, callback, result));
262 }
263
264 // AdbDeviceProvider -------------------------------------------
265
266 class AdbDeviceProvider: public AndroidDeviceProvider {
267 public:
268 virtual void QueryDevices(const QueryDeviceCallback& callback) OVERRIDE;
269 private:
270 void QueryDevicesOnAdbThread(const QueryDeviceCallback& callback);
271 void ReceivedAdbDevices(const QueryDeviceCallback& callback, int result,
272 const std::string& response);
273
274 virtual ~AdbDeviceProvider();
275 };
276
277 AdbDeviceProvider::~AdbDeviceProvider() {
278 }
279
280 void AdbDeviceProvider::QueryDevices(const QueryDeviceCallback& callback) {
281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
282
283 adb_thread_->message_loop()->PostTask(
284 FROM_HERE, base::Bind(&AdbDeviceProvider::QueryDevicesOnAdbThread,
285 this, callback));
286 }
287
288 void AdbDeviceProvider::QueryDevicesOnAdbThread(
289 const QueryDeviceCallback& callback) {
290 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
291
292 AdbClientSocket::AdbQuery(
293 kAdbPort, kHostDevicesCommand,
294 base::Bind(&AdbDeviceProvider::ReceivedAdbDevices, this, callback));
295 }
296
297 void AdbDeviceProvider::ReceivedAdbDevices(const QueryDeviceCallback& callback,
298 int result_code,
299 const std::string& response) {
300 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
301
302 AndroidDevices result;
303
304 #if defined(DEBUG_DEVTOOLS)
305 result.push_back(new AdbDeviceImpl("")); // For desktop remote debugging.
306 #endif // defined(DEBUG_DEVTOOLS)
307
308
309 std::vector<std::string> serials;
310 Tokenize(response, "\n", &serials);
311 for (size_t i = 0; i < serials.size(); ++i) {
312 std::vector<std::string> tokens;
313 Tokenize(serials[i], "\t ", &tokens);
314 result.push_back(new AdbDeviceImpl(tokens[0]));
315 }
316
317 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
318 base::Bind(&AdbDeviceProvider::RunCallbackOnUIThread,
319 this, callback, result));
320 }
321
322 } // namespace
323
324 // AdbCountDevicesCommand -----------------------------------------------------
325
326 class AdbCountDevicesCommand :public base::RefCountedThreadSafe<
Vladislav Kaznacheev 2013/10/21 10:09:01 This should live in the anonymous namespace as wel
327 AdbCountDevicesCommand, BrowserThread::DeleteOnUIThread> {
328 public:
329 typedef base::Callback<void(int)> Callback;
330
331 AdbCountDevicesCommand(
332 scoped_refptr<RefCountedAdbThread> adb_thread,
333 const Callback& callback);
334
335 private:
336 friend struct BrowserThread::DeleteOnThread<
337 BrowserThread::UI>;
338 friend class base::DeleteHelper<AdbCountDevicesCommand>;
339
340 virtual ~AdbCountDevicesCommand();
341 void RequestAdbDeviceCount();
342 void ReceivedAdbDeviceCount(int result, const std::string& response);
343 void Respond(int count);
344
345 scoped_refptr<RefCountedAdbThread> adb_thread_;
346 Callback callback_;
347 };
348
349 AdbCountDevicesCommand::AdbCountDevicesCommand(
350 scoped_refptr<RefCountedAdbThread> adb_thread,
351 const Callback& callback)
352 : adb_thread_(adb_thread),
353 callback_(callback) {
354 adb_thread_->message_loop()->PostTask(
355 FROM_HERE, base::Bind(&AdbCountDevicesCommand::RequestAdbDeviceCount,
356 this));
357 }
358
359 AdbCountDevicesCommand::~AdbCountDevicesCommand() {
360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
361 }
362
363 void AdbCountDevicesCommand::RequestAdbDeviceCount() {
364 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
365 AdbClientSocket::AdbQuery(
366 kAdbPort, kHostDevicesCommand,
367 base::Bind(&AdbCountDevicesCommand::ReceivedAdbDeviceCount, this));
368 }
369
370 void AdbCountDevicesCommand::ReceivedAdbDeviceCount(
371 int result,
372 const std::string& response) {
373 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
374 std::vector<std::string> serials;
375 Tokenize(response, "\n", &serials);
376 BrowserThread::PostTask(
377 BrowserThread::UI, FROM_HERE,
378 base::Bind(&AdbCountDevicesCommand::Respond, this, serials.size()));
379 }
380
381 void AdbCountDevicesCommand::Respond(int count) {
382 callback_.Run(count);
383 }
384
385 // AndroidDeviceProvider ---------------------------------------------------
386
387 AndroidDeviceProvider::AndroidDeviceProvider()
388 : adb_thread_(RefCountedAdbThread::GetInstance()) {
389
390 }
391
392 AndroidDeviceProvider::~AndroidDeviceProvider() {
393 }
394
395 void AndroidDeviceProvider::RunCallbackOnUIThread(
396 const QueryDeviceCallback& callback,
397 const AndroidDevices& result) {
398 callback.Run(result);
399 }
400
401 // static
402 void AndroidDeviceProvider::CountDevices(bool discover_usb_devices,
403 const base::Callback<void(int)>& callback) {
404 if (discover_usb_devices) {
405 AndroidUsbDevice::CountDevices(callback);
406 return;
407 }
408
409 new AdbCountDevicesCommand(RefCountedAdbThread::GetInstance(), callback);
410 }
411
412 // static
413 scoped_refptr<AndroidDeviceProvider>
414 AndroidDeviceProvider::GetUsbDeviceProvider(Profile* profile) {
415 return new UsbDeviceProvider(profile);
416 }
417
418 // static
419 scoped_refptr<AndroidDeviceProvider>
420 AndroidDeviceProvider::GetAdbDeviceProvider() {
421 return new AdbDeviceProvider();
422 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698