1 /*
2 * Copyright (C) 2019 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
17 // Include qemu_pipe.h before sysdeps, since it has inlined references to open, read, write.
18 #include <qemu_pipe.h>
19
20 #define TRACE_TAG TRANSPORT
21 #include "socket_spec.h"
22 #include "sysdeps.h"
23 #include "transport.h"
24
25 #include <android-base/properties.h>
26
27 #include "adb_io.h"
28 #include "adb_trace.h"
29 #include "adb_unique_fd.h"
30
31 /* A worker thread that monitors host connections, and registers a transport for
32 * every new host connection. This thread replaces server_socket_thread on
33 * condition that adbd daemon runs inside the emulator, and emulator uses QEMUD
34 * pipe to communicate with adbd daemon inside the guest. This is done in order
35 * to provide more robust communication channel between ADB host and guest. The
36 * main issue with server_socket_thread approach is that it runs on top of TCP,
37 * and thus is sensitive to network disruptions. For instance, the
38 * ConnectionManager may decide to reset all network connections, in which case
39 * the connection between ADB host and guest will be lost. To make ADB traffic
40 * independent from the network, we use here 'adb' QEMUD service to transfer data
41 * between the host, and the guest. See external/qemu/android/adb-*.* that
42 * implements the emulator's side of the protocol. Another advantage of using
43 * QEMUD approach is that ADB will be up much sooner, since it doesn't depend
44 * anymore on network being set up.
45 * The guest side of the protocol contains the following phases:
46 * - Connect with adb QEMUD service. In this phase a handle to 'adb' QEMUD service
47 * is opened, and it becomes clear whether or not emulator supports that
48 * protocol.
49 * - Wait for the ADB host to create connection with the guest. This is done by
50 * sending an 'accept' request to the adb QEMUD service, and waiting on
51 * response.
52 * - When new ADB host connection is accepted, the connection with adb QEMUD
53 * service is registered as the transport, and a 'start' request is sent to the
54 * adb QEMUD service, indicating that the guest is ready to receive messages.
55 * Note that the guest will ignore messages sent down from the emulator before
56 * the transport registration is completed. That's why we need to send the
57 * 'start' request after the transport is registered.
58 */
qemu_socket_thread(std::string_view addr)59 void qemu_socket_thread(std::string_view addr) {
60 /* 'accept' request to the adb QEMUD service. */
61 static const char _accept_req[] = "accept";
62 /* 'start' request to the adb QEMUD service. */
63 static const char _start_req[] = "start";
64 /* 'ok' reply from the adb QEMUD service. */
65 static const char _ok_resp[] = "ok";
66
67 char tmp[256];
68 char con_name[32];
69
70 adb_thread_setname("qemu socket");
71 D("transport: qemu_socket_thread() starting");
72
73 std::string error;
74 int port = get_host_socket_spec_port(addr, &error);
75 if (port == -1) {
76 port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
77 }
78
79 /* adb QEMUD service connection request. */
80 snprintf(con_name, sizeof(con_name), "pipe:qemud:adb:%d", port);
81
82 /* Connect to the adb QEMUD service. */
83 unique_fd fd(qemu_pipe_open(con_name));
84 if (fd < 0) {
85 /* This could be an older version of the emulator, that doesn't
86 * implement adb QEMUD service. Fall back to the old TCP way. */
87 D("adb service is not available. Falling back to TCP socket.");
88 std::thread(server_socket_thread, adb_listen, addr).detach();
89 return;
90 }
91
92 while (true) {
93 /*
94 * Wait till the host creates a new connection.
95 */
96
97 /* Send the 'accept' request. */
98 if (WriteFdExactly(fd.get(), _accept_req, strlen(_accept_req))) {
99 /* Wait for the response. In the response we expect 'ok' on success,
100 * or 'ko' on failure. */
101 if (!ReadFdExactly(fd.get(), tmp, 2) || memcmp(tmp, _ok_resp, 2)) {
102 D("Accepting ADB host connection has failed.");
103 } else {
104 /* Host is connected. Register the transport, and start the
105 * exchange. */
106 std::string serial = android::base::StringPrintf("host-%d", fd.get());
107 WriteFdExactly(fd.get(), _start_req, strlen(_start_req));
108 register_socket_transport(
109 std::move(fd), std::move(serial), port, 1,
110 [](atransport*) { return ReconnectResult::Abort; }, false);
111 }
112
113 /* Prepare for accepting of the next ADB host connection. */
114 fd.reset(qemu_pipe_open(con_name));
115 if (fd < 0) {
116 D("adb service become unavailable.");
117 return;
118 }
119 } else {
120 D("Unable to send the '%s' request to ADB service.", _accept_req);
121 return;
122 }
123 }
124 D("transport: qemu_socket_thread() exiting");
125 return;
126 }
127
128 // If adbd is running inside the emulator, it will normally use QEMUD pipe (aka
129 // goldfish) as the transport. This can either be explicitly set by the
130 // service.adb.transport property, or be inferred from ro.kernel.qemu that is
131 // set to "1" for ranchu/goldfish.
use_qemu_goldfish()132 bool use_qemu_goldfish() {
133 // Legacy way to detect if adbd should use the goldfish pipe is to check for
134 // ro.kernel.qemu, keep that behaviour for backward compatibility.
135 if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
136 return true;
137 }
138 // If service.adb.transport is present and is set to "goldfish", use the
139 // QEMUD pipe.
140 if (android::base::GetProperty("service.adb.transport", "") == "goldfish") {
141 return true;
142 }
143 return false;
144 }
145