Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(230)

Side by Side Diff: tools/android/forwarder2/device_forwarder_main.cc

Issue 11360248: Use the new forwarder2's Daemon implementation in device_forwarder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address David's comments Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/android/forwarder2/device_controller.cc ('k') | tools/android/forwarder2/forwarder.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <signal.h> 5 #include <signal.h>
6 #include <stdio.h> 6 #include <stdio.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 8
9 #include <string> 9 #include <string>
10 10
11 #include "base/at_exit.h"
12 #include "base/bind.h"
11 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/compiler_specific.h"
12 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/string_piece.h"
13 #include "base/stringprintf.h" 17 #include "base/stringprintf.h"
14 #include "tools/android/common/daemon.h" 18 #include "base/threading/thread.h"
19 #include "tools/android/forwarder2/common.h"
20 #include "tools/android/forwarder2/daemon.h"
15 #include "tools/android/forwarder2/device_controller.h" 21 #include "tools/android/forwarder2/device_controller.h"
16 #include "tools/android/forwarder2/pipe_notifier.h" 22 #include "tools/android/forwarder2/pipe_notifier.h"
17 23
24 namespace forwarder2 {
18 namespace { 25 namespace {
19 26
20 // Leaky global instance, accessed from the signal handler. 27 // Leaky global instance, accessed from the signal handler.
21 forwarder2::PipeNotifier* g_notifier = NULL; 28 forwarder2::PipeNotifier* g_notifier = NULL;
22 29
23 // Unix domain socket name for Device Controller. 30 const int kBufSize = 256;
24 const char kDefaultAdbSocket[] = "chrome_device_forwarder"; 31
32 const char kPIDFilePath[] = "/data/local/tmp/chrome_device_forwarder_pid";
33 const char kDaemonIdentifier[] = "chrome_device_forwarder_daemon";
34
35 const char kKillServerCommand[] = "kill-server";
36 const char kStartCommand[] = "start";
25 37
26 void KillHandler(int /* unused */) { 38 void KillHandler(int /* unused */) {
27 CHECK(g_notifier); 39 CHECK(g_notifier);
28 if (!g_notifier->Notify()) 40 if (!g_notifier->Notify())
29 exit(1); 41 exit(1);
30 } 42 }
31 43
44 // Lets the daemon fetch the exit notifier file descriptor.
45 int GetExitNotifierFD() {
46 DCHECK(g_notifier);
47 return g_notifier->receiver_fd();
48 }
49
50 class ServerDelegate : public Daemon::ServerDelegate {
51 public:
52 // Daemon::ServerDelegate:
53 virtual void Init() OVERRIDE {
54 DCHECK(!g_notifier);
55 g_notifier = new forwarder2::PipeNotifier();
56 signal(SIGTERM, KillHandler);
57 signal(SIGINT, KillHandler);
58 controller_thread_.reset(new base::Thread("controller_thread"));
59 controller_thread_->Start();
60 }
61
62 virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
63 char buf[kBufSize];
64 const int bytes_read = client_socket->Read(buf, sizeof(buf));
65 if (bytes_read <= 0) {
66 if (client_socket->exited())
67 return;
68 PError("Read()");
69 return;
70 }
71 const std::string adb_socket_path(buf, bytes_read);
72 if (adb_socket_path == adb_socket_path_) {
73 client_socket->WriteString("OK");
74 return;
75 }
76 if (!adb_socket_path_.empty()) {
77 client_socket->WriteString(
78 base::StringPrintf(
79 "ERROR: Device controller already running (adb_socket_path=%s)",
80 adb_socket_path_.c_str()));
81 return;
82 }
83 adb_socket_path_ = adb_socket_path;
84 controller_thread_->message_loop()->PostTask(
85 FROM_HERE,
86 base::Bind(&ServerDelegate::StartController, adb_socket_path,
87 GetExitNotifierFD(), base::Passed(&client_socket)));
88 }
89
90 virtual void OnServerExited() OVERRIDE {}
91
92 private:
93 static void StartController(const std::string& adb_socket_path,
94 int exit_notifier_fd,
95 scoped_ptr<Socket> client_socket) {
96 forwarder2::DeviceController controller(exit_notifier_fd);
97 if (!controller.Init(adb_socket_path)) {
98 client_socket->WriteString(
99 base::StringPrintf("ERROR: Could not initialize device controller "
100 "with ADB socket path: %s",
101 adb_socket_path.c_str()));
102 return;
103 }
104 client_socket->WriteString("OK");
105 client_socket->Close();
106 // Note that the following call is blocking which explains why the device
107 // controller has to live on a separate thread (so that the daemon command
108 // server is not blocked).
109 controller.Start();
110 }
111
112 base::AtExitManager at_exit_manager_; // Used by base::Thread.
113 scoped_ptr<base::Thread> controller_thread_;
114 std::string adb_socket_path_;
115 };
116
117 class ClientDelegate : public Daemon::ClientDelegate {
118 public:
119 ClientDelegate(const std::string& adb_socket)
120 : adb_socket_(adb_socket),
121 has_failed_(false) {
122 }
123
124 bool has_failed() const { return has_failed_; }
125
126 // Daemon::ClientDelegate:
127 virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
128 // Send the adb socket path to the daemon.
129 CHECK(daemon_socket->Write(adb_socket_.c_str(),
130 adb_socket_.length()));
131 char buf[kBufSize];
132 const int bytes_read = daemon_socket->Read(
133 buf, sizeof(buf) - 1 /* leave space for null terminator */);
134 CHECK_GT(bytes_read, 0);
135 DCHECK(bytes_read < sizeof(buf));
136 buf[bytes_read] = 0;
137 base::StringPiece msg(buf, bytes_read);
138 if (msg.starts_with("ERROR")) {
139 LOG(ERROR) << msg;
140 has_failed_ = true;
141 return;
142 }
143 }
144
145 private:
146 const std::string adb_socket_;
147 bool has_failed_;
148 };
149
150 int RunDeviceForwarder(int argc, char** argv) {
151 if (argc != 2) {
152 fprintf(stderr,
153 "Usage: %s kill-server|<adb_socket>\n"
154 " <adb_socket> is the abstract Unix Domain Socket path "
155 "where Adb is configured to forward from.\n", argv[0]);
156 return 1;
157 }
158 CommandLine::Init(argc, argv); // Needed by logging.
159 const char* const command =
160 !strcmp(argv[1], kKillServerCommand) ? kKillServerCommand : kStartCommand;
161 ClientDelegate client_delegate(argv[1]);
162 ServerDelegate daemon_delegate;
163 const char kLogFilePath[] = ""; // Log to logcat.
164 Daemon daemon(kLogFilePath, kPIDFilePath, kDaemonIdentifier, &client_delegate,
165 &daemon_delegate, &GetExitNotifierFD);
166
167 if (command == kKillServerCommand)
168 return !daemon.Kill();
169
170 DCHECK(command == kStartCommand);
171 if (!daemon.SpawnIfNeeded())
172 return 1;
173 return client_delegate.has_failed();
174 }
175
32 } // namespace 176 } // namespace
177 } // namespace forwarder2
33 178
34 int main(int argc, char** argv) { 179 int main(int argc, char** argv) {
35 printf("Device forwarder to forward connections to the Host machine.\n"); 180 return forwarder2::RunDeviceForwarder(argc, argv);
36 printf("Like 'adb forward' but in the reverse direction\n");
37
38 CommandLine command_line(argc, argv);
39 std::string adb_socket_path = command_line.GetSwitchValueASCII("adb_sock");
40 if (adb_socket_path.empty())
41 adb_socket_path = kDefaultAdbSocket;
42 if (tools::HasHelpSwitch(command_line)) {
43 tools::ShowHelp(
44 argv[0],
45 "[--adb_sock=<adb sock>]",
46 base::StringPrintf(
47 " <adb sock> is the Abstract Unix Domain Socket path "
48 " where Adb is configured to forward from."
49 " Default is %s\n", kDefaultAdbSocket).c_str());
50 return 0;
51 }
52 if (!tools::HasNoSpawnDaemonSwitch(command_line))
53 tools::SpawnDaemon(0);
54
55 g_notifier = new forwarder2::PipeNotifier();
56
57 signal(SIGTERM, KillHandler);
58 signal(SIGINT, KillHandler);
59 CHECK(g_notifier);
60 forwarder2::DeviceController controller(g_notifier->receiver_fd());
61 if (!controller.Init(adb_socket_path))
62 return 1;
63 printf("Starting Device Forwarder.\n");
64 controller.Start();
65 return 0;
66 } 181 }
OLDNEW
« no previous file with comments | « tools/android/forwarder2/device_controller.cc ('k') | tools/android/forwarder2/forwarder.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698