| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_ |
| #define TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_ |
| |
| #include "base/basictypes.h" |
| #include "base/callback.h" |
| #include "base/compiler_specific.h" |
| #include "base/logging.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "base/threading/thread.h" |
| #include "tools/android/forwarder2/forwarders_manager.h" |
| #include "tools/android/forwarder2/pipe_notifier.h" |
| #include "tools/android/forwarder2/self_deleter_helper.h" |
| #include "tools/android/forwarder2/socket.h" |
| |
| namespace base { |
| class SingleThreadTaskRunner; |
| } // namespace base |
| |
| namespace forwarder2 { |
| |
| class Forwarder; |
| |
| // A DeviceListener instance is used in the device_forwarder program to bind to |
| // a specific device-side |port| and wait for client connections. When a |
| // connection happens, it informs the corresponding HostController instance |
| // running on the host, through |host_socket|. Then the class expects a call to |
| // its SetAdbDataSocket() method (performed by the device controller) once the |
| // host opened a new connection to the device. When this happens, a new internal |
| // Forwarder instance is started. |
| // Note that instances of this class are owned by the device controller which |
| // creates and destroys them on the same thread. In case an internal error |
| // happens on the DeviceListener's internal thread, the DeviceListener |
| // can also self-delete by executing the user-provided callback on the thread |
| // the DeviceListener was created on. |
| // Note that the DeviceListener's destructor joins its internal thread (i.e. |
| // waits for its completion) which means that the internal thread is guaranteed |
| // not to be running anymore once the object is deleted. |
| class DeviceListener { |
| public: |
| // Callback that is used for self-deletion on error to let the device |
| // controller perform some additional cleanup work (e.g. removing the device |
| // listener instance from its internal map before deleting it). |
| typedef base::Callback<void (scoped_ptr<DeviceListener>)> ErrorCallback; |
| |
| static scoped_ptr<DeviceListener> Create(scoped_ptr<Socket> host_socket, |
| int port, |
| const ErrorCallback& error_callback); |
| |
| ~DeviceListener(); |
| |
| void Start(); |
| |
| void SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket); |
| |
| int listener_port() const { return listener_port_; } |
| |
| private: |
| DeviceListener(scoped_ptr<Socket> listener_socket, |
| scoped_ptr<Socket> host_socket, |
| int port, |
| const ErrorCallback& error_callback); |
| |
| // Pushes an AcceptClientOnInternalThread() task to the internal thread's |
| // message queue in order to wait for a new client soon. |
| void AcceptNextClientSoon(); |
| |
| void AcceptClientOnInternalThread(); |
| |
| void OnAdbDataSocketReceivedOnInternalThread( |
| scoped_ptr<Socket> adb_data_socket); |
| |
| void OnInternalThreadError(); |
| |
| SelfDeleterHelper<DeviceListener> self_deleter_helper_; |
| // Used for the listener thread to be notified on destruction. We have one |
| // notifier per Listener thread since each Listener thread may be requested to |
| // exit for different reasons independently from each other and independent |
| // from the main program, ex. when the host requests to forward/listen the |
| // same port again. Both the |host_socket_| and |listener_socket_| must share |
| // the same receiver file descriptor from |deletion_notifier_| and it is set |
| // in the constructor. |
| PipeNotifier deletion_notifier_; |
| // The local device listener socket for accepting connections from the local |
| // port (listener_port_). |
| const scoped_ptr<Socket> listener_socket_; |
| // The listener socket for sending control commands. |
| const scoped_ptr<Socket> host_socket_; |
| scoped_ptr<Socket> device_data_socket_; |
| const int listener_port_; |
| // Task runner used for deletion set at construction time (i.e. the object is |
| // deleted on the same thread it is created on). |
| scoped_refptr<base::SingleThreadTaskRunner> deletion_task_runner_; |
| base::Thread thread_; |
| ForwardersManager forwarders_manager_; |
| |
| DISALLOW_COPY_AND_ASSIGN(DeviceListener); |
| }; |
| |
| } // namespace forwarder |
| |
| #endif // TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_ |