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

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

Issue 18635005: Reland "Add --serial-id option to host_forwarder." (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 5 months 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/daemon.cc ('k') | tools/android/forwarder2/host_forwarder_main.cc » ('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>
7 #include <stdlib.h> 6 #include <stdlib.h>
8 7
8 #include <iostream>
9 #include <string> 9 #include <string>
10 10
11 #include "base/at_exit.h" 11 #include "base/at_exit.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/strings/string_piece.h" 16 #include "base/strings/string_piece.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
19 #include "tools/android/forwarder2/common.h" 19 #include "tools/android/forwarder2/common.h"
20 #include "tools/android/forwarder2/daemon.h" 20 #include "tools/android/forwarder2/daemon.h"
21 #include "tools/android/forwarder2/device_controller.h" 21 #include "tools/android/forwarder2/device_controller.h"
22 #include "tools/android/forwarder2/pipe_notifier.h" 22 #include "tools/android/forwarder2/pipe_notifier.h"
23 23
24 namespace forwarder2 { 24 namespace forwarder2 {
25 namespace { 25 namespace {
26 26
27 // Leaky global instance, accessed from the signal handler. 27 // Leaky global instance, accessed from the signal handler.
28 forwarder2::PipeNotifier* g_notifier = NULL; 28 forwarder2::PipeNotifier* g_notifier = NULL;
29 29
30 const int kBufSize = 256; 30 const int kBufSize = 256;
31 31
32 const char kUnixDomainSocketPath[] = "chrome_device_forwarder";
32 const char kDaemonIdentifier[] = "chrome_device_forwarder_daemon"; 33 const char kDaemonIdentifier[] = "chrome_device_forwarder_daemon";
33 34
34 const char kKillServerCommand[] = "kill-server";
35 const char kStartCommand[] = "start";
36
37 void KillHandler(int /* unused */) { 35 void KillHandler(int /* unused */) {
38 CHECK(g_notifier); 36 CHECK(g_notifier);
39 if (!g_notifier->Notify()) 37 if (!g_notifier->Notify())
40 exit(1); 38 exit(1);
41 } 39 }
42 40
43 // Lets the daemon fetch the exit notifier file descriptor. 41 // Lets the daemon fetch the exit notifier file descriptor.
44 int GetExitNotifierFD() { 42 int GetExitNotifierFD() {
45 DCHECK(g_notifier); 43 DCHECK(g_notifier);
46 return g_notifier->receiver_fd(); 44 return g_notifier->receiver_fd();
47 } 45 }
48 46
49 class ServerDelegate : public Daemon::ServerDelegate { 47 class ServerDelegate : public Daemon::ServerDelegate {
50 public: 48 public:
49 ServerDelegate() : initialized_(false) {}
50
51 // Daemon::ServerDelegate: 51 // Daemon::ServerDelegate:
52 virtual void Init() OVERRIDE { 52 virtual void Init() OVERRIDE {
53 DCHECK(!g_notifier); 53 DCHECK(!g_notifier);
54 g_notifier = new forwarder2::PipeNotifier(); 54 g_notifier = new forwarder2::PipeNotifier();
55 signal(SIGTERM, KillHandler); 55 signal(SIGTERM, KillHandler);
56 signal(SIGINT, KillHandler); 56 signal(SIGINT, KillHandler);
57 controller_thread_.reset(new base::Thread("controller_thread")); 57 controller_thread_.reset(new base::Thread("controller_thread"));
58 controller_thread_->Start(); 58 controller_thread_->Start();
59 } 59 }
60 60
61 virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE { 61 virtual void OnClientConnected(scoped_ptr<Socket> client_socket) OVERRIDE {
62 char buf[kBufSize]; 62 if (initialized_) {
63 const int bytes_read = client_socket->Read(buf, sizeof(buf));
64 if (bytes_read <= 0) {
65 if (client_socket->DidReceiveEvent())
66 return;
67 PError("Read()");
68 return;
69 }
70 const std::string adb_socket_path(buf, bytes_read);
71 if (adb_socket_path == adb_socket_path_) {
72 client_socket->WriteString("OK"); 63 client_socket->WriteString("OK");
73 return; 64 return;
74 } 65 }
75 if (!adb_socket_path_.empty()) {
76 client_socket->WriteString(
77 base::StringPrintf(
78 "ERROR: Device controller already running (adb_socket_path=%s)",
79 adb_socket_path_.c_str()));
80 return;
81 }
82 adb_socket_path_ = adb_socket_path;
83 controller_thread_->message_loop()->PostTask( 66 controller_thread_->message_loop()->PostTask(
84 FROM_HERE, 67 FROM_HERE,
85 base::Bind(&ServerDelegate::StartController, adb_socket_path, 68 base::Bind(&ServerDelegate::StartController, GetExitNotifierFD(),
86 GetExitNotifierFD(), base::Passed(&client_socket))); 69 base::Passed(&client_socket)));
70 initialized_ = true;
87 } 71 }
88 72
89 virtual void OnServerExited() OVERRIDE {} 73 virtual void OnServerExited() OVERRIDE {}
90 74
91 private: 75 private:
92 static void StartController(const std::string& adb_socket_path, 76 static void StartController(int exit_notifier_fd,
93 int exit_notifier_fd,
94 scoped_ptr<Socket> client_socket) { 77 scoped_ptr<Socket> client_socket) {
95 forwarder2::DeviceController controller(exit_notifier_fd); 78 forwarder2::DeviceController controller(exit_notifier_fd);
96 if (!controller.Init(adb_socket_path)) { 79 if (!controller.Init(kUnixDomainSocketPath)) {
97 client_socket->WriteString( 80 client_socket->WriteString(
98 base::StringPrintf("ERROR: Could not initialize device controller " 81 base::StringPrintf("ERROR: Could not initialize device controller "
99 "with ADB socket path: %s", 82 "with ADB socket path: %s",
100 adb_socket_path.c_str())); 83 kUnixDomainSocketPath));
101 return; 84 return;
102 } 85 }
103 client_socket->WriteString("OK"); 86 client_socket->WriteString("OK");
104 client_socket->Close(); 87 client_socket->Close();
105 // Note that the following call is blocking which explains why the device 88 // Note that the following call is blocking which explains why the device
106 // controller has to live on a separate thread (so that the daemon command 89 // controller has to live on a separate thread (so that the daemon command
107 // server is not blocked). 90 // server is not blocked).
108 controller.Start(); 91 controller.Start();
109 } 92 }
110 93
111 base::AtExitManager at_exit_manager_; // Used by base::Thread. 94 base::AtExitManager at_exit_manager_; // Used by base::Thread.
112 scoped_ptr<base::Thread> controller_thread_; 95 scoped_ptr<base::Thread> controller_thread_;
113 std::string adb_socket_path_; 96 bool initialized_;
114 }; 97 };
115 98
116 class ClientDelegate : public Daemon::ClientDelegate { 99 class ClientDelegate : public Daemon::ClientDelegate {
117 public: 100 public:
118 ClientDelegate(const std::string& adb_socket) 101 ClientDelegate() : has_failed_(false) {}
119 : adb_socket_(adb_socket),
120 has_failed_(false) {
121 }
122 102
123 bool has_failed() const { return has_failed_; } 103 bool has_failed() const { return has_failed_; }
124 104
125 // Daemon::ClientDelegate: 105 // Daemon::ClientDelegate:
126 virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE { 106 virtual void OnDaemonReady(Socket* daemon_socket) OVERRIDE {
127 // Send the adb socket path to the daemon.
128 CHECK(daemon_socket->Write(adb_socket_.c_str(),
129 adb_socket_.length()));
130 char buf[kBufSize]; 107 char buf[kBufSize];
131 const int bytes_read = daemon_socket->Read( 108 const int bytes_read = daemon_socket->Read(
132 buf, sizeof(buf) - 1 /* leave space for null terminator */); 109 buf, sizeof(buf) - 1 /* leave space for null terminator */);
133 CHECK_GT(bytes_read, 0); 110 CHECK_GT(bytes_read, 0);
134 DCHECK(bytes_read < sizeof(buf)); 111 DCHECK(bytes_read < sizeof(buf));
135 buf[bytes_read] = 0; 112 buf[bytes_read] = 0;
136 base::StringPiece msg(buf, bytes_read); 113 base::StringPiece msg(buf, bytes_read);
137 if (msg.starts_with("ERROR")) { 114 if (msg.starts_with("ERROR")) {
138 LOG(ERROR) << msg; 115 LOG(ERROR) << msg;
139 has_failed_ = true; 116 has_failed_ = true;
140 return; 117 return;
141 } 118 }
142 } 119 }
143 120
144 private: 121 private:
145 const std::string adb_socket_;
146 bool has_failed_; 122 bool has_failed_;
147 }; 123 };
148 124
149 int RunDeviceForwarder(int argc, char** argv) { 125 int RunDeviceForwarder(int argc, char** argv) {
150 if (argc != 2) { 126 CommandLine::Init(argc, argv); // Needed by logging.
151 fprintf(stderr, 127 const bool kill_server = CommandLine::ForCurrentProcess()->HasSwitch(
152 "Usage: %s kill-server|<adb_socket>\n" 128 "kill-server");
153 " <adb_socket> is the abstract Unix Domain Socket path " 129 if ((kill_server && argc != 2) || (!kill_server && argc != 1)) {
154 "where Adb is configured to forward from.\n", argv[0]); 130 std::cerr << "Usage: device_forwarder [--kill-server]" << std::endl;
155 return 1; 131 return 1;
156 } 132 }
157 CommandLine::Init(argc, argv); // Needed by logging. 133 ClientDelegate client_delegate;
158 const char* const command =
159 !strcmp(argv[1], kKillServerCommand) ? kKillServerCommand : kStartCommand;
160 ClientDelegate client_delegate(argv[1]);
161 ServerDelegate daemon_delegate; 134 ServerDelegate daemon_delegate;
162 const char kLogFilePath[] = ""; // Log to logcat. 135 const char kLogFilePath[] = ""; // Log to logcat.
163 Daemon daemon(kLogFilePath, kDaemonIdentifier, &client_delegate, 136 Daemon daemon(kLogFilePath, kDaemonIdentifier, &client_delegate,
164 &daemon_delegate, &GetExitNotifierFD); 137 &daemon_delegate, &GetExitNotifierFD);
165 138
166 if (command == kKillServerCommand) 139 if (kill_server)
167 return !daemon.Kill(); 140 return !daemon.Kill();
168 141
169 DCHECK(command == kStartCommand);
170 if (!daemon.SpawnIfNeeded()) 142 if (!daemon.SpawnIfNeeded())
171 return 1; 143 return 1;
172 return client_delegate.has_failed(); 144 return client_delegate.has_failed();
173 } 145 }
174 146
175 } // namespace 147 } // namespace
176 } // namespace forwarder2 148 } // namespace forwarder2
177 149
178 int main(int argc, char** argv) { 150 int main(int argc, char** argv) {
179 return forwarder2::RunDeviceForwarder(argc, argv); 151 return forwarder2::RunDeviceForwarder(argc, argv);
180 } 152 }
OLDNEW
« no previous file with comments | « tools/android/forwarder2/daemon.cc ('k') | tools/android/forwarder2/host_forwarder_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698