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

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

Powered by Google App Engine
This is Rietveld 408576698