1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_
6#define TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_
7
8#include "base/basictypes.h"
9#include "base/callback.h"
10#include "base/compiler_specific.h"
11#include "base/logging.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/threading/thread.h"
15#include "tools/android/forwarder2/forwarders_manager.h"
16#include "tools/android/forwarder2/pipe_notifier.h"
17#include "tools/android/forwarder2/self_deleter_helper.h"
18#include "tools/android/forwarder2/socket.h"
19
20namespace base {
21class SingleThreadTaskRunner;
22}  // namespace base
23
24namespace forwarder2 {
25
26class Forwarder;
27
28// A DeviceListener instance is used in the device_forwarder program to bind to
29// a specific device-side |port| and wait for client connections. When a
30// connection happens, it informs the corresponding HostController instance
31// running on the host, through |host_socket|. Then the class expects a call to
32// its SetAdbDataSocket() method (performed by the device controller) once the
33// host opened a new connection to the device. When this happens, a new internal
34// Forwarder instance is started.
35// Note that instances of this class are owned by the device controller which
36// creates and destroys them on the same thread. In case an internal error
37// happens on the DeviceListener's internal thread, the DeviceListener
38// can also self-delete by executing the user-provided callback on the thread
39// the DeviceListener was created on.
40// Note that the DeviceListener's destructor joins its internal thread (i.e.
41// waits for its completion) which means that the internal thread is guaranteed
42// not to be running anymore once the object is deleted.
43class DeviceListener {
44 public:
45  // Callback that is used for self-deletion on error to let the device
46  // controller perform some additional cleanup work (e.g. removing the device
47  // listener instance from its internal map before deleting it).
48  typedef base::Callback<void (scoped_ptr<DeviceListener>)> ErrorCallback;
49
50  static scoped_ptr<DeviceListener> Create(scoped_ptr<Socket> host_socket,
51                                           int port,
52                                           const ErrorCallback& error_callback);
53
54  ~DeviceListener();
55
56  void Start();
57
58  void SetAdbDataSocket(scoped_ptr<Socket> adb_data_socket);
59
60  int listener_port() const { return listener_port_; }
61
62 private:
63  DeviceListener(scoped_ptr<Socket> listener_socket,
64                 scoped_ptr<Socket> host_socket,
65                 int port,
66                 const ErrorCallback& error_callback);
67
68  // Pushes an AcceptClientOnInternalThread() task to the internal thread's
69  // message queue in order to wait for a new client soon.
70  void AcceptNextClientSoon();
71
72  void AcceptClientOnInternalThread();
73
74  void OnAdbDataSocketReceivedOnInternalThread(
75      scoped_ptr<Socket> adb_data_socket);
76
77  void OnInternalThreadError();
78
79  SelfDeleterHelper<DeviceListener> self_deleter_helper_;
80  // Used for the listener thread to be notified on destruction. We have one
81  // notifier per Listener thread since each Listener thread may be requested to
82  // exit for different reasons independently from each other and independent
83  // from the main program, ex. when the host requests to forward/listen the
84  // same port again.  Both the |host_socket_| and |listener_socket_| must share
85  // the same receiver file descriptor from |deletion_notifier_| and it is set
86  // in the constructor.
87  PipeNotifier deletion_notifier_;
88  // The local device listener socket for accepting connections from the local
89  // port (listener_port_).
90  const scoped_ptr<Socket> listener_socket_;
91  // The listener socket for sending control commands.
92  const scoped_ptr<Socket> host_socket_;
93  scoped_ptr<Socket> device_data_socket_;
94  const int listener_port_;
95  // Task runner used for deletion set at construction time (i.e. the object is
96  // deleted on the same thread it is created on).
97  scoped_refptr<base::SingleThreadTaskRunner> deletion_task_runner_;
98  base::Thread thread_;
99  ForwardersManager forwarders_manager_;
100
101  DISALLOW_COPY_AND_ASSIGN(DeviceListener);
102};
103
104}  // namespace forwarder
105
106#endif  // TOOLS_ANDROID_FORWARDER2_DEVICE_LISTENER_H_
107