Chromium Code Reviews| Index: chrome/browser/devtools/tethering_adb_filter.cc |
| diff --git a/chrome/browser/devtools/tethering_adb_filter.cc b/chrome/browser/devtools/tethering_adb_filter.cc |
| index 887ba94d177ec6089594066db30769067cc487b0..53cd55d0d2aa5e17e3888024f45c4386032d0ded 100644 |
| --- a/chrome/browser/devtools/tethering_adb_filter.cc |
| +++ b/chrome/browser/devtools/tethering_adb_filter.cc |
| @@ -31,6 +31,10 @@ namespace { |
| const int kAdbPort = 5037; |
| const int kBufferSize = 16 * 1024; |
| +const int kStatusError = -2; |
| +const int kStatusConnecting = -1; |
| +const int kStatusOK = 0; |
|
pfeldman
2013/08/08 16:43:22
kStatusOk. Is that enum?
Vladislav Kaznacheev
2013/08/09 08:24:58
Done
On 2013/08/08 16:43:22, pfeldman wrote:
|
| + |
| static const char kPortAttribute[] = "port"; |
| static const char kConnectionIdAttribute[] = "connectionId"; |
| static const char kTetheringAccepted[] = "Tethering.accepted"; |
| @@ -43,10 +47,14 @@ static const char kDevToolsRemoteBrowserTarget[] = "/devtools/browser"; |
| class SocketTunnel { |
| public: |
| - explicit SocketTunnel(const std::string& location) |
| + typedef base::Callback<void(int)> CounterCallback; |
| + |
| + SocketTunnel(const std::string& location, const CounterCallback& callback) |
| : location_(location), |
| pending_writes_(0), |
| - pending_destruction_(false) { |
| + pending_destruction_(false), |
| + callback_(callback) { |
| + callback_.Run(1); |
| } |
| void Start(int result, net::StreamSocket* socket) { |
| @@ -95,6 +103,7 @@ class SocketTunnel { |
| host_socket_->Disconnect(); |
| if (remote_socket_) |
| remote_socket_->Disconnect(); |
| + callback_.Run(-1); |
| } |
| void OnConnected(int result) { |
| @@ -190,6 +199,7 @@ class SocketTunnel { |
| net::AddressList address_list_; |
| int pending_writes_; |
| bool pending_destruction_; |
| + CounterCallback callback_; |
| }; |
| } // namespace |
| @@ -276,14 +286,86 @@ void TetheringAdbFilter::SendCommand(const std::string& method, int port) { |
| params.SetInteger(kPortAttribute, port); |
| DevToolsProtocol::Command command(++command_id_, method, ¶ms); |
| web_socket_->SendFrameOnHandlerThread(command.Serialize()); |
| + |
| + if (method == kTetheringBind) { |
| + pending_responses_[command.id()] = |
| + base::Bind(&TetheringAdbFilter::ProcessBindResponseOnUIThread, |
| + weak_factory_.GetWeakPtr(), port); |
| +#if defined(DEBUG_DEVTOOLS) |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| + base::Bind(&TetheringAdbFilter::ProcessBindResponseOnUIThread, |
| + weak_factory_.GetWeakPtr(), port, kStatusConnecting)); |
| +#endif // defined(DEBUG_DEVTOOLS) |
| + } else { |
| + DCHECK_EQ(kTetheringUnbind, method); |
| + pending_responses_[command.id()] = |
| + base::Bind(&TetheringAdbFilter::ProcessUnbindResponseOnUIThread, |
| + weak_factory_.GetWeakPtr(), port); |
| + } |
| +} |
| + |
| +bool TetheringAdbFilter::ProcessResponse(const std::string& message) { |
|
pfeldman
2013/08/08 16:43:22
Sounds like a part of devtools_protocol.
Vladislav Kaznacheev
2013/08/09 08:24:58
You mean move the pending_responses_ part into Dev
|
| + scoped_ptr<DevToolsProtocol::Response> response( |
| + DevToolsProtocol::ParseResponse(message)); |
| + if (!response) |
| + return false; |
| + |
| + CommandCallbackMap::iterator it = pending_responses_.find(response->id()); |
| + if (it == pending_responses_.end()) |
| + return false; |
| + |
| + CommandCallback callback = it->second; |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, |
| + FROM_HERE, |
| + base::Bind(callback, response->error_code() ? kStatusError : kStatusOK)); |
| + pending_responses_.erase(it); |
| + return true; |
| +} |
| + |
| +void TetheringAdbFilter::ProcessBindResponseOnUIThread( |
| + int port, PortStatus status) { |
| + port_status_[port] = status; |
| +} |
| + |
| +void TetheringAdbFilter::ProcessUnbindResponseOnUIThread( |
| + int port, PortStatus status) { |
| + PortStatusMap::iterator it = port_status_.find(port); |
| + if (it == port_status_.end()) |
| + return; |
| + if (status == kStatusError) |
| + it->second = status; |
| + else |
| + port_status_.erase(it); |
| +} |
| + |
| +void TetheringAdbFilter::UpdateSocketCount(int port, int increment) { |
| +#if defined(DEBUG_DEVTOOLS) |
| + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| + base::Bind(&TetheringAdbFilter::UpdateSocketCountOnUIThread, |
| + weak_factory_.GetWeakPtr(), port, increment)); |
| +#endif // defined(DEBUG_DEVTOOLS) |
| +} |
| + |
| +void TetheringAdbFilter::UpdateSocketCountOnUIThread(int port, int increment) { |
| + PortStatusMap::iterator it = port_status_.find(port); |
| + if (it == port_status_.end()) |
| + return; |
| + if (it->second < 0 || (it->second == 0 && increment < 0)) |
| + return; |
| + it->second += increment; |
| } |
| bool TetheringAdbFilter::ProcessIncomingMessage(const std::string& message) { |
| DCHECK_EQ(base::MessageLoop::current(), adb_message_loop_); |
| - // Only parse messages that might be Tethering.accepted event. |
| - if (message.length() > 200 || |
| - message.find(kTetheringAccepted) == std::string::npos) |
| + if (message.length() > 200) |
|
pfeldman
2013/08/08 16:43:22
This check is no longer needed - you are the only
Vladislav Kaznacheev
2013/08/09 08:24:58
Removed this check and the one looking for kTether
|
| + return false; |
| + |
| + if (ProcessResponse(message)) |
| + return true; |
| + |
| + if (message.find(kTetheringAccepted) == std::string::npos) |
| return false; |
| scoped_ptr<DevToolsProtocol::Notification> notification( |
| @@ -310,7 +392,11 @@ bool TetheringAdbFilter::ProcessIncomingMessage(const std::string& message) { |
| std::string location = it->second; |
| - SocketTunnel* tunnel = new SocketTunnel(location); |
| + SocketTunnel* tunnel = new SocketTunnel(location, |
| + base::Bind(&TetheringAdbFilter::UpdateSocketCount, |
| + weak_factory_.GetWeakPtr(), |
| + port)); |
| + |
| std::string command = base::StringPrintf(kLocalAbstractCommand, |
| connection_id.c_str()); |
| AdbClientSocket::TransportQuery( |
| @@ -329,6 +415,8 @@ class PortForwardingController::Connection : public AdbWebSocket::Delegate { |
| void Shutdown(); |
| + TetheringAdbFilter::PortStatusMap port_status(); |
| + |
| private: |
| virtual ~Connection(); |
| @@ -367,6 +455,14 @@ void PortForwardingController::Connection::Shutdown() { |
| web_socket_->Disconnect(); |
| } |
| +TetheringAdbFilter::PortStatusMap |
| +PortForwardingController::Connection::port_status() { |
| + if (tethering_adb_filter_) |
| + return tethering_adb_filter_->port_status(); |
| + else |
| + return TetheringAdbFilter::PortStatusMap(); |
| +} |
| + |
| PortForwardingController::Connection::~Connection() { |
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| if (registry_) { |
| @@ -414,13 +510,16 @@ PortForwardingController::~PortForwardingController() { |
| } |
| void PortForwardingController::UpdateDeviceList( |
| - const DevToolsAdbBridge::RemoteDevices& devices) { |
| - for (DevToolsAdbBridge::RemoteDevices::const_iterator it = devices.begin(); |
| + DevToolsAdbBridge::RemoteDevices& devices) { |
| + for (DevToolsAdbBridge::RemoteDevices::iterator it = devices.begin(); |
| it != devices.end(); ++it) { |
| - if (registry_.find((*it)->serial()) == registry_.end()) { |
| + Registry::iterator rit = registry_.find((*it)->serial()); |
| + if (rit == registry_.end()) { |
| // Will delete itself when disconnected. |
| new Connection( |
| ®istry_, (*it)->device(), adb_message_loop_, pref_service_); |
| + } else { |
| + (*it)->SetPortStatus((*rit).second->port_status()); |
| } |
| } |
| } |