summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvkuzkokov <vkuzkokov@chromium.org>2014-09-26 05:57:11 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-26 12:57:31 +0000
commit346b47f09a946c42fbcbdab789cee14682738169 (patch)
tree109237f63bbd0ded7e9084ac50b4716813901927
parent41b57b9b5f7e0eaad8a3ed0f2d11800953e3ec01 (diff)
downloadchromium_src-346b47f09a946c42fbcbdab789cee14682738169.zip
chromium_src-346b47f09a946c42fbcbdab789cee14682738169.tar.gz
chromium_src-346b47f09a946c42fbcbdab789cee14682738169.tar.bz2
DevTools: Removed refcounting from AndroidWebSocket
Issue 387067 can be resolved by having port forwarding socket dependent on all other references to AndroidDeviceManager::Device. This requires for lifetime of AWS to be manageable in the first place. BUG=387067 Review URL: https://codereview.chromium.org/449883002 Cr-Commit-Position: refs/heads/master@{#296927}
-rw-r--r--chrome/browser/devtools/device/adb/adb_client_socket.cc7
-rw-r--r--chrome/browser/devtools/device/adb/adb_client_socket.h2
-rw-r--r--chrome/browser/devtools/device/android_device_manager.cc42
-rw-r--r--chrome/browser/devtools/device/android_device_manager.h22
-rw-r--r--chrome/browser/devtools/device/android_web_socket.cc233
-rw-r--r--chrome/browser/devtools/device/devtools_android_bridge.cc51
-rw-r--r--chrome/browser/devtools/device/devtools_android_bridge.h2
-rw-r--r--chrome/browser/devtools/device/port_forwarding_controller.cc80
-rw-r--r--chrome/browser/devtools/device/port_forwarding_controller.h1
-rw-r--r--chrome/browser/devtools/device/self_device_provider.cc11
-rw-r--r--chrome/browser/devtools/device/usb/usb_device_provider.cc18
11 files changed, 246 insertions, 223 deletions
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket.cc b/chrome/browser/devtools/device/adb/adb_client_socket.cc
index 0845f92..41b3c9b 100644
--- a/chrome/browser/devtools/device/adb/adb_client_socket.cc
+++ b/chrome/browser/devtools/device/adb/adb_client_socket.cc
@@ -20,9 +20,6 @@ const char kOkayResponse[] = "OKAY";
const char kHostTransportCommand[] = "host:transport:%s";
const char kLocalhost[] = "127.0.0.1";
-typedef base::Callback<void(int, const std::string&)> CommandCallback;
-typedef base::Callback<void(int, net::StreamSocket*)> SocketCallback;
-
std::string EncodeMessage(const std::string& message) {
static const char kHexChars[] = "0123456789ABCDEF";
@@ -73,14 +70,14 @@ class AdbTransportSocket : public AdbClientSocket {
void OnSocketAvailable(int result, const std::string& response) {
if (!CheckNetResultOrDie(result))
return;
- callback_.Run(net::OK, socket_.release());
+ callback_.Run(net::OK, socket_.Pass());
delete this;
}
bool CheckNetResultOrDie(int result) {
if (result >= 0)
return true;
- callback_.Run(result, NULL);
+ callback_.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
delete this;
return false;
}
diff --git a/chrome/browser/devtools/device/adb/adb_client_socket.h b/chrome/browser/devtools/device/adb/adb_client_socket.h
index f0d26ad..f331b02 100644
--- a/chrome/browser/devtools/device/adb/adb_client_socket.h
+++ b/chrome/browser/devtools/device/adb/adb_client_socket.h
@@ -13,7 +13,7 @@ class AdbClientSocket {
public:
typedef base::Callback<void(int, const std::string&)> CommandCallback;
typedef base::Callback<void(int result,
- net::StreamSocket*)> SocketCallback;
+ scoped_ptr<net::StreamSocket>)> SocketCallback;
static void AdbQuery(int port,
const std::string& query,
diff --git a/chrome/browser/devtools/device/android_device_manager.cc b/chrome/browser/devtools/device/android_device_manager.cc
index 10978be..df99de7 100644
--- a/chrome/browser/devtools/device/android_device_manager.cc
+++ b/chrome/browser/devtools/device/android_device_manager.cc
@@ -50,9 +50,9 @@ static void PostSocketCallback(
scoped_refptr<base::MessageLoopProxy> response_message_loop,
const AndroidDeviceManager::SocketCallback& callback,
int result,
- net::StreamSocket* socket) {
- response_message_loop->PostTask(FROM_HERE,
- base::Bind(callback, result, socket));
+ scoped_ptr<net::StreamSocket> socket) {
+ response_message_loop->PostTask(
+ FROM_HERE, base::Bind(callback, result, base::Passed(&socket)));
}
class HttpRequest {
@@ -61,39 +61,41 @@ class HttpRequest {
typedef AndroidDeviceManager::SocketCallback SocketCallback;
static void CommandRequest(const std::string& request,
- const CommandCallback& callback,
- int result,
- net::StreamSocket* socket) {
+ const CommandCallback& callback,
+ int result,
+ scoped_ptr<net::StreamSocket> socket) {
if (result != net::OK) {
callback.Run(result, std::string());
return;
}
- new HttpRequest(socket, request, callback);
+ new HttpRequest(socket.Pass(), request, callback);
}
static void SocketRequest(const std::string& request,
- const SocketCallback& callback,
- int result,
- net::StreamSocket* socket) {
+ const SocketCallback& callback,
+ int result,
+ scoped_ptr<net::StreamSocket> socket) {
if (result != net::OK) {
- callback.Run(result, NULL);
+ callback.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
return;
}
- new HttpRequest(socket, request, callback);
+ new HttpRequest(socket.Pass(), request, callback);
}
private:
- HttpRequest(net::StreamSocket* socket,
+ HttpRequest(scoped_ptr<net::StreamSocket> socket,
const std::string& request,
const CommandCallback& callback)
- : socket_(socket), command_callback_(callback), body_pos_(0) {
+ : socket_(socket.Pass()),
+ command_callback_(callback),
+ body_pos_(0) {
SendRequest(request);
}
- HttpRequest(net::StreamSocket* socket,
- const std::string& request,
- const SocketCallback& callback)
- : socket_(socket),
+ HttpRequest(scoped_ptr<net::StreamSocket> socket,
+ const std::string& request,
+ const SocketCallback& callback)
+ : socket_(socket.Pass()),
socket_callback_(callback),
body_pos_(0) {
SendRequest(request);
@@ -169,7 +171,7 @@ class HttpRequest {
if (!command_callback_.is_null())
command_callback_.Run(net::OK, response_.substr(body_pos_));
else
- socket_callback_.Run(net::OK, socket_.release());
+ socket_callback_.Run(net::OK, socket_.Pass());
delete this;
return;
}
@@ -191,7 +193,7 @@ class HttpRequest {
if (!command_callback_.is_null())
command_callback_.Run(result, std::string());
else
- socket_callback_.Run(result, NULL);
+ socket_callback_.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
delete this;
return false;
}
diff --git a/chrome/browser/devtools/device/android_device_manager.h b/chrome/browser/devtools/device/android_device_manager.h
index 219e5ce..fbc00cd 100644
--- a/chrome/browser/devtools/device/android_device_manager.h
+++ b/chrome/browser/devtools/device/android_device_manager.h
@@ -24,7 +24,8 @@ class AndroidDeviceManager
public base::NonThreadSafe {
public:
typedef base::Callback<void(int, const std::string&)> CommandCallback;
- typedef base::Callback<void(int result, net::StreamSocket*)> SocketCallback;
+ typedef base::Callback<void(int result, scoped_ptr<net::StreamSocket>)>
+ SocketCallback;
typedef base::Callback<void(const std::vector<std::string>&)> SerialsCallback;
struct BrowserInfo {
@@ -53,32 +54,21 @@ class AndroidDeviceManager
typedef base::Callback<void(const DeviceInfo&)> DeviceInfoCallback;
- class AndroidWebSocket : public base::RefCountedThreadSafe<AndroidWebSocket> {
+ class AndroidWebSocket {
public:
class Delegate {
public:
virtual void OnSocketOpened() = 0;
virtual void OnFrameRead(const std::string& message) = 0;
- virtual void OnSocketClosed(bool closed_by_device) = 0;
+ virtual void OnSocketClosed() = 0;
protected:
virtual ~Delegate() {}
};
- AndroidWebSocket() {}
-
- virtual void Connect() = 0;
- virtual void Disconnect() = 0;
- virtual void SendFrame(const std::string& message) = 0;
- virtual void ClearDelegate() = 0;
-
- protected:
virtual ~AndroidWebSocket() {}
- private:
- friend class base::RefCountedThreadSafe<AndroidWebSocket>;
-
- DISALLOW_COPY_AND_ASSIGN(AndroidWebSocket);
+ virtual void SendFrame(const std::string& message) = 0;
};
class DeviceProvider;
@@ -103,7 +93,7 @@ class AndroidDeviceManager
const std::string& url,
const SocketCallback& callback);
- scoped_refptr<AndroidWebSocket> CreateWebSocket(
+ AndroidWebSocket* CreateWebSocket(
const std::string& socket_name,
const std::string& url,
AndroidWebSocket::Delegate* delegate);
diff --git a/chrome/browser/devtools/device/android_web_socket.cc b/chrome/browser/devtools/device/android_web_socket.cc
index 7635889..2a3886b 100644
--- a/chrome/browser/devtools/device/android_web_socket.cc
+++ b/chrome/browser/devtools/device/android_web_socket.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/rand_util.h"
#include "chrome/browser/devtools/device/android_device_manager.h"
@@ -18,85 +19,127 @@ namespace {
const int kBufferSize = 16 * 1024;
-class WebSocketImpl : public AndroidDeviceManager::AndroidWebSocket {
+class WebSocketImpl {
public:
- typedef AndroidDeviceManager::Device Device;
- WebSocketImpl(scoped_refptr<base::MessageLoopProxy> device_message_loop,
- scoped_refptr<Device> device,
- const std::string& socket_name,
- const std::string& url,
- Delegate* delegate);
-
- virtual void Connect() OVERRIDE;
- virtual void Disconnect() OVERRIDE;
- virtual void SendFrame(const std::string& message) OVERRIDE;
- virtual void ClearDelegate() OVERRIDE;
-
- private:
- friend class base::RefCountedThreadSafe<AndroidWebSocket>;
+ typedef AndroidDeviceManager::AndroidWebSocket::Delegate Delegate;
- virtual ~WebSocketImpl();
+ WebSocketImpl(Delegate* delegate,
+ scoped_ptr<net::StreamSocket> socket);
+ void StartListening();
+ void SendFrame(const std::string& message);
- void Connected(int result, net::StreamSocket* socket);
- void StartListeningOnHandlerThread();
+ private:
void OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer, int result);
- void SendFrameOnHandlerThread(const std::string& message);
void SendPendingRequests(int result);
- void DisconnectOnHandlerThread(bool closed_by_device);
+ void Disconnect();
+
+ Delegate* delegate_;
+ scoped_ptr<net::StreamSocket> socket_;
+ std::string response_buffer_;
+ std::string request_buffer_;
+ base::ThreadChecker thread_checker_;
+ DISALLOW_COPY_AND_ASSIGN(WebSocketImpl);
+};
+
+class DelegateWrapper
+ : public AndroidDeviceManager::AndroidWebSocket::Delegate {
+ public:
+ DelegateWrapper(base::WeakPtr<Delegate> weak_delegate,
+ scoped_refptr<base::MessageLoopProxy> message_loop)
+ : weak_delegate_(weak_delegate),
+ message_loop_(message_loop) {
+ }
- void OnSocketOpened();
- void OnFrameRead(const std::string& message);
- void OnSocketClosed(bool closed_by_device);
+ virtual ~DelegateWrapper() {}
+
+ // AndroidWebSocket::Delegate implementation
+ virtual void OnSocketOpened() OVERRIDE {
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&Delegate::OnSocketOpened, weak_delegate_));
+ }
+
+ virtual void OnFrameRead(const std::string& message) OVERRIDE {
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&Delegate::OnFrameRead, weak_delegate_, message));
+ }
+
+ virtual void OnSocketClosed() OVERRIDE {
+ message_loop_->PostTask(FROM_HERE,
+ base::Bind(&Delegate::OnSocketClosed, weak_delegate_));
+ }
+
+ private:
+ base::WeakPtr<Delegate> weak_delegate_;
+ scoped_refptr<base::MessageLoopProxy> message_loop_;
+};
+
+class AndroidWebSocketImpl
+ : public AndroidDeviceManager::AndroidWebSocket,
+ public AndroidDeviceManager::AndroidWebSocket::Delegate {
+ public:
+ typedef AndroidDeviceManager::Device Device;
+ AndroidWebSocketImpl(
+ scoped_refptr<base::MessageLoopProxy> device_message_loop,
+ scoped_refptr<Device> device,
+ const std::string& socket_name,
+ const std::string& url,
+ AndroidWebSocket::Delegate* delegate);
+
+ virtual ~AndroidWebSocketImpl();
+
+ // AndroidWebSocket implementation
+ virtual void SendFrame(const std::string& message) OVERRIDE;
+
+ // AndroidWebSocket::Delegate implementation
+ virtual void OnSocketOpened() OVERRIDE;
+ virtual void OnFrameRead(const std::string& message) OVERRIDE;
+ virtual void OnSocketClosed() OVERRIDE;
+
+ private:
+ void Connected(int result, scoped_ptr<net::StreamSocket> socket);
scoped_refptr<base::MessageLoopProxy> device_message_loop_;
scoped_refptr<Device> device_;
std::string socket_name_;
std::string url_;
- scoped_ptr<net::StreamSocket> socket_;
- Delegate* delegate_;
- std::string response_buffer_;
- std::string request_buffer_;
+ WebSocketImpl* connection_;
+ DelegateWrapper* delegate_wrapper_;
+ AndroidWebSocket::Delegate* delegate_;
+ base::WeakPtrFactory<AndroidWebSocketImpl> weak_factory_;
+ DISALLOW_COPY_AND_ASSIGN(AndroidWebSocketImpl);
};
-WebSocketImpl::WebSocketImpl(
+AndroidWebSocketImpl::AndroidWebSocketImpl(
scoped_refptr<base::MessageLoopProxy> device_message_loop,
scoped_refptr<Device> device,
const std::string& socket_name,
const std::string& url,
- Delegate* delegate)
+ AndroidWebSocket::Delegate* delegate)
: device_message_loop_(device_message_loop),
device_(device),
socket_name_(socket_name),
url_(url),
- delegate_(delegate) {
-}
-
-void WebSocketImpl::Connect() {
+ delegate_(delegate),
+ weak_factory_(this) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(delegate_);
device_->HttpUpgrade(
- socket_name_, url_, base::Bind(&WebSocketImpl::Connected, this));
+ socket_name_, url_,
+ base::Bind(&AndroidWebSocketImpl::Connected, weak_factory_.GetWeakPtr()));
}
-void WebSocketImpl::Disconnect() {
+void AndroidWebSocketImpl::SendFrame(const std::string& message) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
device_message_loop_->PostTask(
FROM_HERE,
- base::Bind(&WebSocketImpl::DisconnectOnHandlerThread, this, false));
+ base::Bind(&WebSocketImpl::SendFrame,
+ base::Unretained(connection_), message));
}
void WebSocketImpl::SendFrame(const std::string& message) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- device_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&WebSocketImpl::SendFrameOnHandlerThread, this, message));
-}
-
-void WebSocketImpl::ClearDelegate() {
- delegate_ = NULL;
-}
-
-void WebSocketImpl::SendFrameOnHandlerThread(const std::string& message) {
- DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
+ DCHECK(thread_checker_.CalledOnValidThread());
+ if (!socket_)
+ return;
int mask = base::RandInt(0, 0x7FFFFFFF);
std::string encoded_frame = WebSocket::EncodeFrameHybi17(message, mask);
request_buffer_ += encoded_frame;
@@ -104,43 +147,55 @@ void WebSocketImpl::SendFrameOnHandlerThread(const std::string& message) {
SendPendingRequests(0);
}
-WebSocketImpl::~WebSocketImpl() {
+AndroidWebSocketImpl::~AndroidWebSocketImpl() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ device_message_loop_->DeleteSoon(FROM_HERE, connection_);
+ device_message_loop_->DeleteSoon(FROM_HERE, delegate_wrapper_);
+}
+
+WebSocketImpl::WebSocketImpl(Delegate* delegate,
+ scoped_ptr<net::StreamSocket> socket)
+ : delegate_(delegate),
+ socket_(socket.Pass()) {
+ thread_checker_.DetachFromThread();
}
-void WebSocketImpl::Connected(int result, net::StreamSocket* socket) {
+void AndroidWebSocketImpl::Connected(int result,
+ scoped_ptr<net::StreamSocket> socket) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (result != net::OK || socket == NULL) {
- OnSocketClosed(true);
+ OnSocketClosed();
return;
}
- socket_.reset(socket);
+ delegate_wrapper_ = new DelegateWrapper(weak_factory_.GetWeakPtr(),
+ base::MessageLoopProxy::current());
+ connection_ = new WebSocketImpl(delegate_wrapper_, socket.Pass());
device_message_loop_->PostTask(
FROM_HERE,
- base::Bind(&WebSocketImpl::StartListeningOnHandlerThread, this));
+ base::Bind(&WebSocketImpl::StartListening,
+ base::Unretained(connection_)));
OnSocketOpened();
}
-void WebSocketImpl::StartListeningOnHandlerThread() {
- DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
+void WebSocketImpl::StartListening() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(socket_);
scoped_refptr<net::IOBuffer> response_buffer =
new net::IOBuffer(kBufferSize);
int result = socket_->Read(
response_buffer.get(),
kBufferSize,
- base::Bind(&WebSocketImpl::OnBytesRead, this, response_buffer));
+ base::Bind(&WebSocketImpl::OnBytesRead,
+ base::Unretained(this), response_buffer));
if (result != net::ERR_IO_PENDING)
OnBytesRead(response_buffer, result);
}
-void WebSocketImpl::OnBytesRead(
- scoped_refptr<net::IOBuffer> response_buffer, int result) {
- DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
- if (!socket_)
- return;
-
+void WebSocketImpl::OnBytesRead(scoped_refptr<net::IOBuffer> response_buffer,
+ int result) {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (result <= 0) {
- DisconnectOnHandlerThread(true);
+ Disconnect();
return;
}
@@ -153,32 +208,30 @@ void WebSocketImpl::OnBytesRead(
while (parse_result == WebSocket::FRAME_OK) {
response_buffer_ = response_buffer_.substr(bytes_consumed);
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&WebSocketImpl::OnFrameRead, this, output));
+ delegate_->OnFrameRead(output);
parse_result = WebSocket::DecodeFrameHybi17(
response_buffer_, false, &bytes_consumed, &output);
}
if (parse_result == WebSocket::FRAME_ERROR ||
parse_result == WebSocket::FRAME_CLOSE) {
- DisconnectOnHandlerThread(true);
+ Disconnect();
return;
}
result = socket_->Read(
response_buffer.get(),
kBufferSize,
- base::Bind(&WebSocketImpl::OnBytesRead, this, response_buffer));
+ base::Bind(&WebSocketImpl::OnBytesRead,
+ base::Unretained(this), response_buffer));
if (result != net::ERR_IO_PENDING)
OnBytesRead(response_buffer, result);
}
void WebSocketImpl::SendPendingRequests(int result) {
- DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
- if (!socket_)
- return;
+ DCHECK(thread_checker_.CalledOnValidThread());
if (result < 0) {
- DisconnectOnHandlerThread(true);
+ Disconnect();
return;
}
request_buffer_ = request_buffer_.substr(result);
@@ -189,43 +242,39 @@ void WebSocketImpl::SendPendingRequests(int result) {
new net::StringIOBuffer(request_buffer_);
result = socket_->Write(buffer.get(), buffer->size(),
base::Bind(&WebSocketImpl::SendPendingRequests,
- this));
+ base::Unretained(this)));
if (result != net::ERR_IO_PENDING)
SendPendingRequests(result);
}
-void WebSocketImpl::DisconnectOnHandlerThread(bool closed_by_device) {
- DCHECK_EQ(device_message_loop_, base::MessageLoopProxy::current());
- if (!socket_)
- return;
- // Wipe out socket_ first since Disconnect can re-enter this method.
- scoped_ptr<net::StreamSocket> socket(socket_.release());
- socket->Disconnect();
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&WebSocketImpl::OnSocketClosed, this, closed_by_device));
+void WebSocketImpl::Disconnect() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ socket_.reset();
+ delegate_->OnSocketClosed();
}
-void WebSocketImpl::OnSocketOpened() {
- if (delegate_)
- delegate_->OnSocketOpened();
+void AndroidWebSocketImpl::OnSocketOpened() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ delegate_->OnSocketOpened();
}
-void WebSocketImpl::OnFrameRead(const std::string& message) {
- if (delegate_)
- delegate_->OnFrameRead(message);
+void AndroidWebSocketImpl::OnFrameRead(const std::string& message) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ delegate_->OnFrameRead(message);
}
-void WebSocketImpl::OnSocketClosed(bool closed_by_device) {
- if (delegate_)
- delegate_->OnSocketClosed(closed_by_device);
+void AndroidWebSocketImpl::OnSocketClosed() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ delegate_->OnSocketClosed();
}
} // namespace
-scoped_refptr<AndroidDeviceManager::AndroidWebSocket>
+AndroidDeviceManager::AndroidWebSocket*
AndroidDeviceManager::Device::CreateWebSocket(
const std::string& socket,
const std::string& url,
AndroidDeviceManager::AndroidWebSocket::Delegate* delegate) {
- return new WebSocketImpl(device_message_loop_, this, socket, url, delegate);
+ return new AndroidWebSocketImpl(
+ device_message_loop_, this, socket, url, delegate);
}
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.cc b/chrome/browser/devtools/device/devtools_android_bridge.cc
index e36e785..16d173b 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.cc
+++ b/chrome/browser/devtools/device/devtools_android_bridge.cc
@@ -187,11 +187,12 @@ class ProtocolCommand
private:
virtual void OnSocketOpened() OVERRIDE;
virtual void OnFrameRead(const std::string& message) OVERRIDE;
- virtual void OnSocketClosed(bool closed_by_device) OVERRIDE;
+ virtual void OnSocketClosed() OVERRIDE;
+ virtual ~ProtocolCommand();
const std::string command_;
const base::Closure callback_;
- scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
+ scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
DISALLOW_COPY_AND_ASSIGN(ProtocolCommand);
};
@@ -202,9 +203,8 @@ ProtocolCommand::ProtocolCommand(
const std::string& command,
const base::Closure callback)
: command_(command),
- callback_(callback){
- web_socket_ = browser->CreateWebSocket(debug_url, this);
- web_socket_->Connect();
+ callback_(callback),
+ web_socket_(browser->CreateWebSocket(debug_url, this)) {
}
void ProtocolCommand::OnSocketOpened() {
@@ -212,16 +212,18 @@ void ProtocolCommand::OnSocketOpened() {
}
void ProtocolCommand::OnFrameRead(const std::string& message) {
- web_socket_->Disconnect();
+ delete this;
}
-void ProtocolCommand::OnSocketClosed(bool closed_by_device) {
- if (!callback_.is_null()) {
- callback_.Run();
- }
+void ProtocolCommand::OnSocketClosed() {
delete this;
}
+ProtocolCommand::~ProtocolCommand() {
+ if (!callback_.is_null())
+ callback_.Run();
+}
+
} // namespace
class AgentHostDelegate;
@@ -292,14 +294,15 @@ class AgentHostDelegate
const std::string& message) OVERRIDE;
virtual void OnSocketOpened() OVERRIDE;
virtual void OnFrameRead(const std::string& message) OVERRIDE;
- virtual void OnSocketClosed(bool closed_by_device) OVERRIDE;
+ virtual void OnSocketClosed() OVERRIDE;
const std::string id_;
+ scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_;
+ const std::string debug_url_;
bool socket_opened_;
- bool detached_;
bool is_web_view_;
std::vector<std::string> pending_messages_;
- scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
+ scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
content::DevToolsAgentHost* agent_host_;
content::DevToolsExternalAgentProxy* proxy_;
DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate);
@@ -328,10 +331,10 @@ AgentHostDelegate::AgentHostDelegate(
scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
const std::string& debug_url)
: id_(id),
+ browser_(browser),
+ debug_url_(debug_url),
socket_opened_(false),
- detached_(false),
is_web_view_(browser->IsWebView()),
- web_socket_(browser->CreateWebSocket(debug_url, this)),
agent_host_(NULL),
proxy_(NULL) {
g_host_delegates.Get()[id] = this;
@@ -339,20 +342,17 @@ AgentHostDelegate::AgentHostDelegate(
AgentHostDelegate::~AgentHostDelegate() {
g_host_delegates.Get().erase(id_);
- web_socket_->ClearDelegate();
}
void AgentHostDelegate::Attach(content::DevToolsExternalAgentProxy* proxy) {
proxy_ = proxy;
content::RecordAction(base::UserMetricsAction(is_web_view_ ?
"DevTools_InspectAndroidWebView" : "DevTools_InspectAndroidPage"));
- web_socket_->Connect();
+ web_socket_.reset(browser_->CreateWebSocket(debug_url_, this));
}
void AgentHostDelegate::Detach() {
- detached_ = true;
- if (socket_opened_)
- web_socket_->Disconnect();
+ web_socket_.reset();
}
void AgentHostDelegate::SendMessageToBackend(const std::string& message) {
@@ -363,11 +363,6 @@ void AgentHostDelegate::SendMessageToBackend(const std::string& message) {
}
void AgentHostDelegate::OnSocketOpened() {
- if (detached_) {
- web_socket_->Disconnect();
- return;
- }
-
socket_opened_ = true;
for (std::vector<std::string>::iterator it = pending_messages_.begin();
it != pending_messages_.end(); ++it) {
@@ -381,8 +376,8 @@ void AgentHostDelegate::OnFrameRead(const std::string& message) {
proxy_->DispatchOnClientHost(message);
}
-void AgentHostDelegate::OnSocketClosed(bool closed_by_device) {
- if (proxy_ && closed_by_device)
+void AgentHostDelegate::OnSocketClosed() {
+ if (proxy_)
proxy_->ConnectionClosed();
}
@@ -621,7 +616,7 @@ DevToolsAndroidBridge::RemoteBrowser::GetAgentHost() {
"adb:" + device_->serial() + ":" + socket_, this, kBrowserTargetSocket);
}
-scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket>
+DevToolsAndroidBridge::AndroidWebSocket*
DevToolsAndroidBridge::RemoteBrowser::CreateWebSocket(
const std::string& url,
DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate) {
diff --git a/chrome/browser/devtools/device/devtools_android_bridge.h b/chrome/browser/devtools/device/devtools_android_bridge.h
index 651d1aa..2f283a1 100644
--- a/chrome/browser/devtools/device/devtools_android_bridge.h
+++ b/chrome/browser/devtools/device/devtools_android_bridge.h
@@ -122,7 +122,7 @@ class DevToolsAndroidBridge
scoped_refptr<content::DevToolsAgentHost> GetAgentHost();
- scoped_refptr<AndroidWebSocket> CreateWebSocket(
+ AndroidWebSocket* CreateWebSocket(
const std::string& url,
DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate);
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc
index 775fb6c..0bc9c17 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.cc
+++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -56,11 +56,11 @@ class SocketTunnel : public base::NonThreadSafe {
int port,
const CounterCallback& callback,
int result,
- net::StreamSocket* socket) {
+ scoped_ptr<net::StreamSocket> socket) {
if (result < 0)
return;
SocketTunnel* tunnel = new SocketTunnel(callback);
- tunnel->Start(socket, host, port);
+ tunnel->Start(socket.Pass(), host, port);
}
private:
@@ -72,8 +72,9 @@ class SocketTunnel : public base::NonThreadSafe {
callback_.Run(1);
}
- void Start(net::StreamSocket* socket, const std::string& host, int port) {
- remote_socket_.reset(socket);
+ void Start(scoped_ptr<net::StreamSocket> socket,
+ const std::string& host, int port) {
+ remote_socket_.swap(socket);
host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL);
net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port));
@@ -251,28 +252,23 @@ FindBestBrowserForTethering(
} // namespace
class PortForwardingController::Connection
- : public DevToolsAndroidBridge::AndroidWebSocket::Delegate,
- public base::RefCountedThreadSafe<
- Connection,
- content::BrowserThread::DeleteOnUIThread> {
+ : public DevToolsAndroidBridge::AndroidWebSocket::Delegate {
public:
Connection(Registry* registry,
scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device,
scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser,
const ForwardingMap& forwarding_map);
+ virtual ~Connection();
const PortStatusMap& GetPortStatusMap();
void UpdateForwardingMap(const ForwardingMap& new_forwarding_map);
- void Shutdown();
-
private:
friend struct content::BrowserThread::DeleteOnThread<
content::BrowserThread::UI>;
friend class base::DeleteHelper<Connection>;
- virtual ~Connection();
typedef std::map<int, std::string> ForwardingMap;
@@ -289,23 +285,25 @@ class PortForwardingController::Connection
void ProcessBindResponse(int port, PortStatus status);
void ProcessUnbindResponse(int port, PortStatus status);
- void UpdateSocketCountOnHandlerThread(int port, int increment);
+ static void UpdateSocketCountOnHandlerThread(
+ base::WeakPtr<Connection> weak_connection, int port, int increment);
void UpdateSocketCount(int port, int increment);
// DevToolsAndroidBridge::AndroidWebSocket::Delegate implementation:
virtual void OnSocketOpened() OVERRIDE;
virtual void OnFrameRead(const std::string& message) OVERRIDE;
- virtual void OnSocketClosed(bool closed_by_device) OVERRIDE;
+ virtual void OnSocketClosed() OVERRIDE;
PortForwardingController::Registry* registry_;
scoped_refptr<DevToolsAndroidBridge::RemoteDevice> device_;
scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> browser_;
- scoped_refptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
+ scoped_ptr<DevToolsAndroidBridge::AndroidWebSocket> web_socket_;
int command_id_;
bool connected_;
ForwardingMap forwarding_map_;
CommandCallbackMap pending_responses_;
PortStatusMap port_status_;
+ base::WeakPtrFactory<Connection> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Connection);
};
@@ -320,27 +318,18 @@ PortForwardingController::Connection::Connection(
browser_(browser),
command_id_(0),
connected_(false),
- forwarding_map_(forwarding_map) {
+ forwarding_map_(forwarding_map),
+ weak_factory_(this) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
(*registry_)[device_->serial()] = this;
- web_socket_ = browser->CreateWebSocket(kDevToolsRemoteBrowserTarget, this);
- web_socket_->Connect();
- AddRef(); // Balanced in OnSocketClosed();
-}
-
-void PortForwardingController::Connection::Shutdown() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- registry_ = NULL;
- // This will have no effect if the socket is not connected yet.
- web_socket_->Disconnect();
+ web_socket_.reset(
+ browser->CreateWebSocket(kDevToolsRemoteBrowserTarget, this));
}
PortForwardingController::Connection::~Connection() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (registry_) {
- DCHECK(registry_->find(device_->serial()) != registry_->end());
- registry_->erase(device_->serial());
- }
+ DCHECK(registry_->find(device_->serial()) != registry_->end());
+ registry_->erase(device_->serial());
}
void PortForwardingController::Connection::UpdateForwardingMap(
@@ -442,10 +431,12 @@ void PortForwardingController::Connection::ProcessUnbindResponse(
port_status_.erase(it);
}
+// static
void PortForwardingController::Connection::UpdateSocketCountOnHandlerThread(
- int port, int increment) {
+ base::WeakPtr<Connection> weak_connection, int port, int increment) {
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- base::Bind(&Connection::UpdateSocketCount, this, port, increment));
+ base::Bind(&Connection::UpdateSocketCount,
+ weak_connection, port, increment));
}
void PortForwardingController::Connection::UpdateSocketCount(
@@ -469,19 +460,12 @@ PortForwardingController::Connection::GetPortStatusMap() {
void PortForwardingController::Connection::OnSocketOpened() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!registry_) {
- // Socket was created after Shutdown was called. Disconnect immediately.
- web_socket_->Disconnect();
- return;
- }
connected_ = true;
SerializeChanges(tethering::bind::kName, ForwardingMap(), forwarding_map_);
}
-void PortForwardingController::Connection::OnSocketClosed(
- bool closed_by_device) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- Release(); // Balanced in the constructor.
+void PortForwardingController::Connection::OnSocketClosed() {
+ delete this;
}
void PortForwardingController::Connection::OnFrameRead(
@@ -522,7 +506,8 @@ void PortForwardingController::Connection::OnFrameRead(
std::string destination_host = tokens[0];
SocketTunnel::CounterCallback callback =
- base::Bind(&Connection::UpdateSocketCountOnHandlerThread, this, port);
+ base::Bind(&Connection::UpdateSocketCountOnHandlerThread,
+ weak_factory_.GetWeakPtr(), port);
device_->OpenSocket(
connection_id.c_str(),
@@ -591,7 +576,12 @@ void PortForwardingController::OnPrefsChange() {
if (!forwarding_map_.empty()) {
UpdateConnections();
} else {
- ShutdownConnections();
+ std::vector<Connection*> registry_copy;
+ for (Registry::iterator it = registry_.begin();
+ it != registry_.end(); ++it) {
+ registry_copy.push_back(it->second);
+ }
+ STLDeleteElements(&registry_copy);
}
}
@@ -599,9 +589,3 @@ void PortForwardingController::UpdateConnections() {
for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it)
it->second->UpdateForwardingMap(forwarding_map_);
}
-
-void PortForwardingController::ShutdownConnections() {
- for (Registry::iterator it = registry_.begin(); it != registry_.end(); ++it)
- it->second->Shutdown();
- registry_.clear();
-}
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.h b/chrome/browser/devtools/device/port_forwarding_controller.h
index 290c268..c1074bf 100644
--- a/chrome/browser/devtools/device/port_forwarding_controller.h
+++ b/chrome/browser/devtools/device/port_forwarding_controller.h
@@ -35,7 +35,6 @@ class PortForwardingController {
void OnPrefsChange();
void UpdateConnections();
- void ShutdownConnections();
Profile* profile_;
PrefService* pref_service_;
diff --git a/chrome/browser/devtools/device/self_device_provider.cc b/chrome/browser/devtools/device/self_device_provider.cc
index ee0f043..f6930b5 100644
--- a/chrome/browser/devtools/device/self_device_provider.cc
+++ b/chrome/browser/devtools/device/self_device_provider.cc
@@ -17,9 +17,9 @@ const char kSerial[] = "local";
static void RunSocketCallback(
const AndroidDeviceManager::SocketCallback& callback,
- net::StreamSocket* socket,
+ scoped_ptr<net::StreamSocket> socket,
int result) {
- callback.Run(result, socket);
+ callback.Run(result, socket.Pass());
}
} // namespace
@@ -61,7 +61,8 @@ void SelfAsDeviceProvider::OpenSocket(const std::string& serial,
base::StringToInt(socket_name, &port);
net::AddressList address_list =
net::AddressList::CreateFromIPAddress(ip_number, port);
- net::TCPClientSocket* socket = new net::TCPClientSocket(
- address_list, NULL, net::NetLog::Source());
- socket->Connect(base::Bind(&RunSocketCallback, callback, socket));
+ scoped_ptr<net::StreamSocket> socket(new net::TCPClientSocket(
+ address_list, NULL, net::NetLog::Source()));
+ socket->Connect(
+ base::Bind(&RunSocketCallback, callback, base::Passed(&socket)));
}
diff --git a/chrome/browser/devtools/device/usb/usb_device_provider.cc b/chrome/browser/devtools/device/usb/usb_device_provider.cc
index a67d60c..258365c 100644
--- a/chrome/browser/devtools/device/usb/usb_device_provider.cc
+++ b/chrome/browser/devtools/device/usb/usb_device_provider.cc
@@ -19,9 +19,12 @@ const char kLocalAbstractCommand[] = "localabstract:%s";
const int kBufferSize = 16 * 1024;
void OnOpenSocket(const UsbDeviceProvider::SocketCallback& callback,
- net::StreamSocket* socket,
+ net::StreamSocket* socket_raw,
int result) {
- callback.Run(result, result == net::OK ? socket : NULL);
+ scoped_ptr<net::StreamSocket> socket(socket_raw);
+ if (result != net::OK)
+ socket.reset();
+ callback.Run(result, socket.Pass());
}
void OnRead(net::StreamSocket* socket,
@@ -68,7 +71,8 @@ void RunCommand(scoped_refptr<AndroidUsbDevice> device,
callback.Run(net::ERR_CONNECTION_FAILED, std::string());
return;
}
- int result = socket->Connect(base::Bind(&OpenedForCommand, callback, socket));
+ int result = socket->Connect(
+ base::Bind(&OpenedForCommand, callback, socket));
if (result != net::ERR_IO_PENDING)
callback.Run(result, std::string());
}
@@ -107,19 +111,21 @@ void UsbDeviceProvider::OpenSocket(const std::string& serial,
const SocketCallback& callback) {
UsbDeviceMap::iterator it = device_map_.find(serial);
if (it == device_map_.end()) {
- callback.Run(net::ERR_CONNECTION_FAILED, NULL);
+ callback.Run(net::ERR_CONNECTION_FAILED,
+ make_scoped_ptr<net::StreamSocket>(NULL));
return;
}
std::string socket_name =
base::StringPrintf(kLocalAbstractCommand, name.c_str());
net::StreamSocket* socket = it->second->CreateSocket(socket_name);
if (!socket) {
- callback.Run(net::ERR_CONNECTION_FAILED, NULL);
+ callback.Run(net::ERR_CONNECTION_FAILED,
+ make_scoped_ptr<net::StreamSocket>(NULL));
return;
}
int result = socket->Connect(base::Bind(&OnOpenSocket, callback, socket));
if (result != net::ERR_IO_PENDING)
- callback.Run(result, NULL);
+ callback.Run(result, make_scoped_ptr<net::StreamSocket>(NULL));
}
void UsbDeviceProvider::ReleaseDevice(const std::string& serial) {