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()); |
} |
} |
} |