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