| 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 |