blob: 639bb463a410c1c673fe1ac8a2094c2651b6c596 [file] [log] [blame]
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Yabin Cui19bec5b2015-09-22 15:52:57 -070017#define TRACE_TAG SERVICES
Dan Albertdb6fe642015-03-19 15:21:08 -070018
19#include "sysdeps.h"
20
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080021#include <errno.h>
Dan Albertb302d122015-02-24 15:51:19 -080022#include <stddef.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#ifndef _WIN32
28#include <netdb.h>
29#include <netinet/in.h>
30#include <sys/ioctl.h>
31#include <unistd.h>
32#endif
33
Josh Gao0f3312a2017-04-12 17:00:49 -070034#include <thread>
35
Elliott Hughesf55ead92015-12-04 22:00:26 -080036#include <android-base/file.h>
David Pursella17d2722016-01-21 08:40:59 -080037#include <android-base/parsenetaddress.h>
Elliott Hughesf55ead92015-12-04 22:00:26 -080038#include <android-base/stringprintf.h>
39#include <android-base/strings.h>
Elliott Hughes43df1092015-07-23 17:12:58 -070040#include <cutils/sockets.h>
Elliott Hughese4b64792015-04-17 20:11:08 -070041
Dan Albertb302d122015-02-24 15:51:19 -080042#if !ADB_HOST
Elliott Hughes8b249d22016-09-23 15:40:03 -070043#include <android-base/properties.h>
Tao Baoa8c21dc2017-01-05 18:01:01 -080044#include <bootloader_message/bootloader_message.h>
Mark Salyzync75f65f2016-03-28 15:52:13 -070045#include <cutils/android_reboot.h>
Steven Morelandb087d302017-04-13 23:48:57 -070046#include <log/log_properties.h>
Dan Albertb302d122015-02-24 15:51:19 -080047#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080048
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080049#include "adb.h"
Dan Albert66a91b02015-02-24 21:26:58 -080050#include "adb_io.h"
Josh Gao4c28dde2018-07-25 16:51:59 -070051#include "adb_unique_fd.h"
Elliott Hughes09ccf1f2015-07-18 12:21:30 -070052#include "adb_utils.h"
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070053#if !ADB_HOST
Josh Gaoc7b74592018-07-25 15:55:25 -070054#include "daemon/file_sync_service.h"
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070055#include "daemon/framebuffer_service.h"
Josh Gao977e5262018-07-25 16:07:51 -070056#include "daemon/remount_service.h"
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070057#include "daemon/set_verity_enable_state_service.h"
Josh Gao076b5ba2018-07-25 16:07:26 -070058#include "daemon/shell_service.h"
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070059#endif
David Pursell22fc5e92015-09-30 13:35:42 -070060#include "services.h"
Josh Gao4a5a95d2016-08-24 18:38:44 -070061#include "socket_spec.h"
Josh Gaoc1fab362016-02-19 10:42:40 -080062#include "sysdeps.h"
Dan Albertb302d122015-02-24 15:51:19 -080063#include "transport.h"
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080064
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070065namespace {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080066
Josh Gao4c28dde2018-07-25 16:51:59 -070067void service_bootstrap_func(std::string service_name, std::function<void(unique_fd)> func,
68 unique_fd fd) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070069 adb_thread_setname(android::base::StringPrintf("%s svc %d", service_name.c_str(), fd.get()));
70 func(std::move(fd));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080071}
72
Benoit Goby12dc3692013-02-20 15:04:53 -080073#if !ADB_HOST
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -080074
Josh Gao4c28dde2018-07-25 16:51:59 -070075void restart_root_service(unique_fd fd) {
The Android Open Source Project9c753402009-03-13 13:04:37 -070076 if (getuid() == 0) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070077 WriteFdExactly(fd.get(), "adbd is already running as root\n");
78 return;
The Android Open Source Project9c753402009-03-13 13:04:37 -070079 }
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070080 if (!__android_log_is_debuggable()) {
81 WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
82 return;
83 }
84
85 android::base::SetProperty("service.adb.root", "1");
86 WriteFdExactly(fd.get(), "restarting adbd as root\n");
The Android Open Source Project9c753402009-03-13 13:04:37 -070087}
88
Josh Gao4c28dde2018-07-25 16:51:59 -070089void restart_unroot_service(unique_fd fd) {
Dan Pasanenfb787d92014-10-06 12:57:20 -050090 if (getuid() != 0) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070091 WriteFdExactly(fd.get(), "adbd not running as root\n");
92 return;
Dan Pasanenfb787d92014-10-06 12:57:20 -050093 }
Luis Hector Chavezce7a2842018-07-18 19:40:12 -070094 android::base::SetProperty("service.adb.root", "0");
95 WriteFdExactly(fd.get(), "restarting adbd as non root\n");
Dan Pasanenfb787d92014-10-06 12:57:20 -050096}
97
Josh Gao4c28dde2018-07-25 16:51:59 -070098void restart_tcp_service(unique_fd fd, int port) {
Mike Lockwood26b88e32009-08-24 15:58:40 -070099 if (port <= 0) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700100 WriteFdFmt(fd.get(), "invalid port %d\n", port);
Mike Lockwood26b88e32009-08-24 15:58:40 -0700101 return;
102 }
103
Elliott Hughes8b249d22016-09-23 15:40:03 -0700104 android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port));
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700105 WriteFdFmt(fd.get(), "restarting in TCP mode port: %d\n", port);
Mike Lockwood26b88e32009-08-24 15:58:40 -0700106}
107
Josh Gao4c28dde2018-07-25 16:51:59 -0700108void restart_usb_service(unique_fd fd) {
Elliott Hughes8b249d22016-09-23 15:40:03 -0700109 android::base::SetProperty("service.adb.tcp.port", "0");
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700110 WriteFdExactly(fd.get(), "restarting in USB mode\n");
Mike Lockwood26b88e32009-08-24 15:58:40 -0700111}
112
Josh Gao4c28dde2018-07-25 16:51:59 -0700113bool reboot_service_impl(unique_fd fd, const std::string& arg) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700114 std::string reboot_arg = arg;
Tao Bao0db67642015-03-29 11:22:34 -0700115 bool auto_reboot = false;
116
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700117 if (reboot_arg == "sideload-auto-reboot") {
Tao Bao0db67642015-03-29 11:22:34 -0700118 auto_reboot = true;
119 reboot_arg = "sideload";
120 }
121
Tao Bao0db67642015-03-29 11:22:34 -0700122 // It reboots into sideload mode by setting "--sideload" or "--sideload_auto_reboot"
123 // in the command file.
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700124 if (reboot_arg == "sideload") {
Tao Bao0db67642015-03-29 11:22:34 -0700125 if (getuid() != 0) {
Elliott Hughes88b4c852015-04-30 17:32:03 -0700126 WriteFdExactly(fd, "'adb root' is required for 'adb reboot sideload'.\n");
Tao Bao0db67642015-03-29 11:22:34 -0700127 return false;
128 }
129
Tao Baoa8c21dc2017-01-05 18:01:01 -0800130 const std::vector<std::string> options = {
131 auto_reboot ? "--sideload_auto_reboot" : "--sideload"
132 };
133 std::string err;
134 if (!write_bootloader_message(options, &err)) {
135 D("Failed to set bootloader message: %s", err.c_str());
Tao Bao0db67642015-03-29 11:22:34 -0700136 return false;
137 }
138
139 reboot_arg = "recovery";
140 }
Mike Lockwood12a35ea2009-08-04 20:37:51 -0400141
142 sync();
Mike Lockwoodd49e9eb2010-02-24 16:07:23 -0500143
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700144 if (reboot_arg.empty()) reboot_arg = "adb";
145 std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());
Elliott Hughes8b249d22016-09-23 15:40:03 -0700146 if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
147 WriteFdFmt(fd, "reboot (%s) failed\n", reboot_string.c_str());
Tao Bao0db67642015-03-29 11:22:34 -0700148 return false;
Mike Lockwood12a35ea2009-08-04 20:37:51 -0400149 }
Tao Bao0db67642015-03-29 11:22:34 -0700150
151 return true;
152}
153
Josh Gao4c28dde2018-07-25 16:51:59 -0700154void reboot_service(unique_fd fd, const std::string& arg) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700155 if (!reboot_service_impl(std::move(fd), arg)) {
156 return;
Tao Bao0db67642015-03-29 11:22:34 -0700157 }
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700158 // Don't return early. Give the reboot command time to take effect
159 // to avoid messing up scripts which do "adb reboot && adb wait-for-device"
160 while (true) {
161 pause();
162 }
Mike Lockwood12a35ea2009-08-04 20:37:51 -0400163}
164
Josh Gao4c28dde2018-07-25 16:51:59 -0700165void reconnect_service(unique_fd fd, atransport* t) {
Yabin Cuid78ed222016-04-05 13:50:44 -0700166 WriteFdExactly(fd, "done");
Yabin Cuid78ed222016-04-05 13:50:44 -0700167 kick_transport(t);
168}
169
Josh Gaoebc1c312018-04-13 12:17:03 -0700170int reverse_service(const char* command, atransport* transport) {
Yabin Cuidf852632015-10-30 18:37:26 -0700171 int s[2];
172 if (adb_socketpair(s)) {
173 PLOG(ERROR) << "cannot create service socket pair.";
174 return -1;
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100175 }
Yabin Cuidf852632015-10-30 18:37:26 -0700176 VLOG(SERVICES) << "service socketpair: " << s[0] << ", " << s[1];
Josh Gaoebc1c312018-04-13 12:17:03 -0700177 if (handle_forward_request(command, transport, s[1]) < 0) {
Yabin Cuidf852632015-10-30 18:37:26 -0700178 SendFail(s[1], "not a reverse forwarding command");
179 }
180 adb_close(s[1]);
181 return s[0];
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100182}
183
David Pursella07dbad2015-09-22 10:43:08 -0700184// Shell service string can look like:
David Pursell22fc5e92015-09-30 13:35:42 -0700185// shell[,arg1,arg2,...]:[command]
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700186int ShellService(const std::string& args, const atransport* transport) {
David Pursella07dbad2015-09-22 10:43:08 -0700187 size_t delimiter_index = args.find(':');
188 if (delimiter_index == std::string::npos) {
189 LOG(ERROR) << "No ':' found in shell service arguments: " << args;
190 return -1;
191 }
David Pursell22fc5e92015-09-30 13:35:42 -0700192
David Pursella07dbad2015-09-22 10:43:08 -0700193 const std::string service_args = args.substr(0, delimiter_index);
194 const std::string command = args.substr(delimiter_index + 1);
195
David Pursell22fc5e92015-09-30 13:35:42 -0700196 // Defaults:
197 // PTY for interactive, raw for non-interactive.
198 // No protocol.
Elliott Hughesff444562015-11-16 10:55:34 -0800199 // $TERM set to "dumb".
David Pursell22fc5e92015-09-30 13:35:42 -0700200 SubprocessType type(command.empty() ? SubprocessType::kPty
201 : SubprocessType::kRaw);
202 SubprocessProtocol protocol = SubprocessProtocol::kNone;
Elliott Hughesff444562015-11-16 10:55:34 -0800203 std::string terminal_type = "dumb";
David Pursella07dbad2015-09-22 10:43:08 -0700204
David Pursell22fc5e92015-09-30 13:35:42 -0700205 for (const std::string& arg : android::base::Split(service_args, ",")) {
206 if (arg == kShellServiceArgRaw) {
207 type = SubprocessType::kRaw;
208 } else if (arg == kShellServiceArgPty) {
209 type = SubprocessType::kPty;
210 } else if (arg == kShellServiceArgShellProtocol) {
211 protocol = SubprocessProtocol::kShell;
Elliott Hughesff444562015-11-16 10:55:34 -0800212 } else if (android::base::StartsWith(arg, "TERM=")) {
213 terminal_type = arg.substr(5);
214 } else if (!arg.empty()) {
215 // This is not an error to allow for future expansion.
216 LOG(WARNING) << "Ignoring unknown shell service argument: " << arg;
David Pursell22fc5e92015-09-30 13:35:42 -0700217 }
218 }
David Pursella07dbad2015-09-22 10:43:08 -0700219
Elliott Hughesff444562015-11-16 10:55:34 -0800220 return StartSubprocess(command.c_str(), terminal_type.c_str(), type, protocol);
David Pursella07dbad2015-09-22 10:43:08 -0700221}
222
223#endif // !ADB_HOST
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800224
Josh Gao4c28dde2018-07-25 16:51:59 -0700225unique_fd create_service_thread(const char* service_name, std::function<void(unique_fd)> func) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800226 int s[2];
Dan Albertf30d73c2015-02-25 17:51:28 -0800227 if (adb_socketpair(s)) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800228 printf("cannot create service socket pair\n");
Josh Gao4c28dde2018-07-25 16:51:59 -0700229 return unique_fd();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800230 }
Yabin Cui815ad882015-09-02 17:44:28 -0700231 D("socketpair: (%d,%d)", s[0], s[1]);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800232
Jerry Zhangf0e239c2017-02-10 17:45:27 -0800233#if !ADB_HOST
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700234 if (strcmp(service_name, "sync") == 0) {
Jerry Zhangf0e239c2017-02-10 17:45:27 -0800235 // Set file sync service socket to maximum size
236 int max_buf = LINUX_MAX_SOCKET_SIZE;
237 adb_setsockopt(s[0], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
238 adb_setsockopt(s[1], SOL_SOCKET, SO_SNDBUF, &max_buf, sizeof(max_buf));
239 }
240#endif // !ADB_HOST
241
Josh Gao4c28dde2018-07-25 16:51:59 -0700242 std::thread(service_bootstrap_func, service_name, func, unique_fd(s[1])).detach();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800243
Yabin Cui815ad882015-09-02 17:44:28 -0700244 D("service thread started, %d:%d",s[0], s[1]);
Josh Gao4c28dde2018-07-25 16:51:59 -0700245 return unique_fd(s[0]);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800246}
247
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700248} // namespace
249
Josh Gaoebc1c312018-04-13 12:17:03 -0700250int service_to_fd(const char* name, atransport* transport) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800251 int ret = -1;
252
Josh Gao4a5a95d2016-08-24 18:38:44 -0700253 if (is_socket_spec(name)) {
254 std::string error;
255 ret = socket_spec_connect(name, &error);
256 if (ret < 0) {
257 LOG(ERROR) << "failed to connect to socket '" << name << "': " << error;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800258 }
Benoit Goby12dc3692013-02-20 15:04:53 -0800259#if !ADB_HOST
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800260 } else if(!strncmp("dev:", name, 4)) {
Nick Kralevich777523e2014-07-18 20:57:35 -0700261 ret = unix_open(name + 4, O_RDWR | O_CLOEXEC);
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700262 } else if (!strncmp(name, "framebuffer:", 12)) {
263 ret = create_service_thread("fb", framebuffer_service).release();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800264 } else if (!strncmp(name, "jdwp:", 5)) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700265 ret = create_jdwp_connection_fd(atoi(name + 5));
266 } else if (!strncmp(name, "shell", 5)) {
David Pursella07dbad2015-09-22 10:43:08 -0700267 ret = ShellService(name + 5, transport);
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700268 } else if (!strncmp(name, "exec:", 5)) {
Elliott Hughesff444562015-11-16 10:55:34 -0800269 ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700270 } else if (!strncmp(name, "sync:", 5)) {
271 ret = create_service_thread("sync", file_sync_service).release();
272 } else if (!strncmp(name, "remount:", 8)) {
273 std::string options(name + strlen("remount:"));
274 ret = create_service_thread("remount",
275 std::bind(remount_service, std::placeholders::_1, options))
276 .release();
277 } else if (!strncmp(name, "reboot:", 7)) {
278 std::string arg(name + strlen("reboot:"));
279 ret = create_service_thread("reboot", std::bind(reboot_service, std::placeholders::_1, arg))
280 .release();
281 } else if (!strncmp(name, "root:", 5)) {
282 ret = create_service_thread("root", restart_root_service).release();
283 } else if (!strncmp(name, "unroot:", 7)) {
284 ret = create_service_thread("unroot", restart_unroot_service).release();
285 } else if (!strncmp(name, "backup:", 7)) {
286 ret = StartSubprocess(
287 android::base::StringPrintf("/system/bin/bu backup %s", (name + 7)).c_str(),
288 nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone);
289 } else if (!strncmp(name, "restore:", 8)) {
Elliott Hughesff444562015-11-16 10:55:34 -0800290 ret = StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
David Pursell8da19a42015-08-31 10:42:13 -0700291 SubprocessProtocol::kNone);
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700292 } else if (!strncmp(name, "tcpip:", 6)) {
Mike Lockwood26b88e32009-08-24 15:58:40 -0700293 int port;
Spencer Low29a029c2015-01-25 17:38:36 -0800294 if (sscanf(name + 6, "%d", &port) != 1) {
Elliott Hughesd94e8ba2015-07-21 16:13:40 -0700295 return -1;
Mike Lockwood26b88e32009-08-24 15:58:40 -0700296 }
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700297 ret = create_service_thread("tcp",
298 std::bind(restart_tcp_service, std::placeholders::_1, port))
299 .release();
300 } else if (!strncmp(name, "usb:", 4)) {
301 ret = create_service_thread("usb", restart_usb_service).release();
David 'Digit' Turner963a4492013-03-21 21:07:42 +0100302 } else if (!strncmp(name, "reverse:", 8)) {
Josh Gaoebc1c312018-04-13 12:17:03 -0700303 ret = reverse_service(name + 8, transport);
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700304 } else if (!strncmp(name, "disable-verity:", 15)) {
305 ret = create_service_thread("verity-on", std::bind(set_verity_enabled_state_service,
306 std::placeholders::_1, false))
307 .release();
308 } else if (!strncmp(name, "enable-verity:", 15)) {
309 ret = create_service_thread("verity-off", std::bind(set_verity_enabled_state_service,
310 std::placeholders::_1, true))
311 .release();
Yabin Cuid78ed222016-04-05 13:50:44 -0700312 } else if (!strcmp(name, "reconnect")) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700313 ret = create_service_thread("reconnect",
314 std::bind(reconnect_service, std::placeholders::_1, transport))
315 .release();
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800316#endif
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800317 }
318 if (ret >= 0) {
319 close_on_exec(ret);
320 }
321 return ret;
322}
323
324#if ADB_HOST
325struct state_info {
Elliott Hughes3aec2ba2015-05-05 13:10:43 -0700326 TransportType transport_type;
Leo Sartre6cd9bc32015-11-27 18:56:48 +0100327 std::string serial;
Josh Gaob39e4152017-08-16 16:57:01 -0700328 TransportId transport_id;
Dan Albert9a50f4c2015-05-18 16:43:57 -0700329 ConnectionState state;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800330};
331
Leo Sartre6cd9bc32015-11-27 18:56:48 +0100332static void wait_for_state(int fd, void* data) {
333 std::unique_ptr<state_info> sinfo(reinterpret_cast<state_info*>(data));
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800334
Yabin Cui815ad882015-09-02 17:44:28 -0700335 D("wait_for_state %d", sinfo->state);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800336
Elliott Hughes67943d12015-10-07 14:55:10 -0700337 while (true) {
338 bool is_ambiguous = false;
339 std::string error = "unknown error";
Yi Kong86e67182018-07-13 18:15:16 -0700340 const char* serial = sinfo->serial.length() ? sinfo->serial.c_str() : nullptr;
Josh Gaob39e4152017-08-16 16:57:01 -0700341 atransport* t = acquire_one_transport(sinfo->transport_type, serial, sinfo->transport_id,
342 &is_ambiguous, &error);
Yabin Cui3cf1b362017-03-10 16:01:01 -0800343 if (t != nullptr && (sinfo->state == kCsAny || sinfo->state == t->GetConnectionState())) {
Elliott Hughes67943d12015-10-07 14:55:10 -0700344 SendOkay(fd);
345 break;
346 } else if (!is_ambiguous) {
Josh Gaoc1fab362016-02-19 10:42:40 -0800347 adb_pollfd pfd = {.fd = fd, .events = POLLIN };
348 int rc = adb_poll(&pfd, 1, 1000);
349 if (rc < 0) {
350 SendFail(fd, error);
351 break;
352 } else if (rc > 0 && (pfd.revents & POLLHUP) != 0) {
353 // The other end of the socket is closed, probably because the other side was
354 // terminated, bail out.
355 break;
356 }
357
Elliott Hughes67943d12015-10-07 14:55:10 -0700358 // Try again...
359 } else {
360 SendFail(fd, error);
361 break;
362 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800363 }
364
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800365 adb_close(fd);
Yabin Cui815ad882015-09-02 17:44:28 -0700366 D("wait_for_state is done");
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800367}
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700368
Elliott Hughes88b4c852015-04-30 17:32:03 -0700369void connect_emulator(const std::string& port_spec, std::string* response) {
370 std::vector<std::string> pieces = android::base::Split(port_spec, ",");
371 if (pieces.size() != 2) {
372 *response = android::base::StringPrintf("unable to parse '%s' as <console port>,<adb port>",
373 port_spec.c_str());
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700374 return;
375 }
376
Yi Kong86e67182018-07-13 18:15:16 -0700377 int console_port = strtol(pieces[0].c_str(), nullptr, 0);
378 int adb_port = strtol(pieces[1].c_str(), nullptr, 0);
Elliott Hughes88b4c852015-04-30 17:32:03 -0700379 if (console_port <= 0 || adb_port <= 0) {
380 *response = android::base::StringPrintf("Invalid port numbers: %s", port_spec.c_str());
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700381 return;
382 }
383
Elliott Hughes88b4c852015-04-30 17:32:03 -0700384 // Check if the emulator is already known.
385 // Note: There's a small but harmless race condition here: An emulator not
386 // present just yet could be registered by another invocation right
387 // after doing this check here. However, local_connect protects
388 // against double-registration too. From here, a better error message
389 // can be produced. In the case of the race condition, the very specific
390 // error message won't be shown, but the data doesn't get corrupted.
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700391 atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port);
Elliott Hughes88b4c852015-04-30 17:32:03 -0700392 if (known_emulator != nullptr) {
393 *response = android::base::StringPrintf("Emulator already registered on port %d", adb_port);
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700394 return;
395 }
396
Elliott Hughes88b4c852015-04-30 17:32:03 -0700397 // Preconditions met, try to connect to the emulator.
Elliott Hughes43df1092015-07-23 17:12:58 -0700398 std::string error;
399 if (!local_connect_arbitrary_ports(console_port, adb_port, &error)) {
Elliott Hughes88b4c852015-04-30 17:32:03 -0700400 *response = android::base::StringPrintf("Connected to emulator on ports %d,%d",
401 console_port, adb_port);
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700402 } else {
Elliott Hughes43df1092015-07-23 17:12:58 -0700403 *response = android::base::StringPrintf("Could not connect to emulator on ports %d,%d: %s",
404 console_port, adb_port, error.c_str());
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700405 }
406}
407
Josh Gao4c28dde2018-07-25 16:51:59 -0700408static void connect_service(unique_fd fd, std::string host) {
Elliott Hughes88b4c852015-04-30 17:32:03 -0700409 std::string response;
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700410 if (!strncmp(host.c_str(), "emu:", 4)) {
411 connect_emulator(host.c_str() + 4, &response);
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700412 } else {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700413 connect_device(host.c_str(), &response);
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700414 }
415
416 // Send response for emulator and device
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700417 SendProtocolString(fd.get(), response);
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700418}
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800419#endif
420
421#if ADB_HOST
Josh Gaob39e4152017-08-16 16:57:01 -0700422asocket* host_service_to_socket(const char* name, const char* serial, TransportId transport_id) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800423 if (!strcmp(name,"track-devices")) {
Josh Gao32124632017-08-14 18:57:54 -0700424 return create_device_tracker(false);
425 } else if (!strcmp(name, "track-devices-l")) {
426 return create_device_tracker(true);
Leo Sartre6cd9bc32015-11-27 18:56:48 +0100427 } else if (android::base::StartsWith(name, "wait-for-")) {
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800428 name += strlen("wait-for-");
429
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700430 std::unique_ptr<state_info> sinfo = std::make_unique<state_info>();
Leo Sartre6cd9bc32015-11-27 18:56:48 +0100431 if (sinfo == nullptr) {
432 fprintf(stderr, "couldn't allocate state_info: %s", strerror(errno));
433 return nullptr;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800434 }
435
Leo Sartre6cd9bc32015-11-27 18:56:48 +0100436 if (serial) sinfo->serial = serial;
Josh Gaob39e4152017-08-16 16:57:01 -0700437 sinfo->transport_id = transport_id;
Leo Sartre6cd9bc32015-11-27 18:56:48 +0100438
439 if (android::base::StartsWith(name, "local")) {
440 name += strlen("local");
441 sinfo->transport_type = kTransportLocal;
442 } else if (android::base::StartsWith(name, "usb")) {
443 name += strlen("usb");
444 sinfo->transport_type = kTransportUsb;
445 } else if (android::base::StartsWith(name, "any")) {
446 name += strlen("any");
447 sinfo->transport_type = kTransportAny;
448 } else {
449 return nullptr;
450 }
451
452 if (!strcmp(name, "-device")) {
453 sinfo->state = kCsDevice;
454 } else if (!strcmp(name, "-recovery")) {
455 sinfo->state = kCsRecovery;
456 } else if (!strcmp(name, "-sideload")) {
457 sinfo->state = kCsSideload;
458 } else if (!strcmp(name, "-bootloader")) {
459 sinfo->state = kCsBootloader;
Josh Gao071328d2016-04-13 12:18:58 -0700460 } else if (!strcmp(name, "-any")) {
461 sinfo->state = kCsAny;
Leo Sartre6cd9bc32015-11-27 18:56:48 +0100462 } else {
463 return nullptr;
464 }
465
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700466 int fd = create_service_thread(
467 "wait", std::bind(wait_for_state, std::placeholders::_1, sinfo.get()))
468 .release();
Ting-Yuan Huangaa923c12017-08-15 15:07:21 -0700469 if (fd != -1) {
470 sinfo.release();
471 }
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800472 return create_local_socket(fd);
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700473 } else if (!strncmp(name, "connect:", 8)) {
Luis Hector Chavezce7a2842018-07-18 19:40:12 -0700474 std::string host(name + strlen("connect:"));
475 int fd = create_service_thread("connect",
476 std::bind(connect_service, std::placeholders::_1, host))
477 .release();
Benoit Goby3f9f9ce2013-03-29 18:22:36 -0700478 return create_local_socket(fd);
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800479 }
Yi Kong86e67182018-07-13 18:15:16 -0700480 return nullptr;
The Android Open Source Project9ca14dc2009-03-03 19:32:55 -0800481}
482#endif /* ADB_HOST */