Merge "Setting up a libadbd flag for shared usage across miniadbd (CL 1/2)"
diff --git a/Android.bp b/Android.bp
index 2504f0d..461abb4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -549,6 +549,7 @@
}
},
+ min_sdk_version: "30",
apex_available: [
"//apex_available:platform",
"com.android.adbd",
@@ -629,6 +630,7 @@
},
},
+ min_sdk_version: "30",
apex_available: [
"//apex_available:platform",
"com.android.adbd",
@@ -643,6 +645,7 @@
name: "libadbd",
defaults: ["adbd_defaults", "host_adbd_supported"],
recovery_available: true,
+ min_sdk_version: "30",
apex_available: ["com.android.adbd"],
// avoid getting duplicate symbol of android::build::getbuildnumber().
@@ -701,6 +704,7 @@
name: "adbd",
defaults: ["adbd_defaults", "host_adbd_supported", "libadbd_binary_dependencies"],
recovery_available: true,
+ min_sdk_version: "30",
apex_available: ["com.android.adbd"],
srcs: [
diff --git a/adb.cpp b/adb.cpp
index d0602ec..6813da0 100644
--- a/adb.cpp
+++ b/adb.cpp
@@ -726,7 +726,7 @@
while (static_cast<size_t>(i) < lines.size()) fprintf(stderr, "%s\n", lines[i++].c_str());
}
-int launch_server(const std::string& socket_spec) {
+int launch_server(const std::string& socket_spec, const char* one_device) {
#if defined(_WIN32)
/* we need to start the server in the background */
/* we create a PIPE that will be used to wait for the server's "OK" */
@@ -828,8 +828,14 @@
}
WCHAR args[64];
- snwprintf(args, arraysize(args), L"adb -L %s fork-server server --reply-fd %d",
- socket_spec.c_str(), ack_write_as_int);
+ if (one_device) {
+ snwprintf(args, arraysize(args),
+ L"adb -L %s fork-server server --reply-fd %d --one-device %s",
+ socket_spec.c_str(), ack_write_as_int, one_device);
+ } else {
+ snwprintf(args, arraysize(args), L"adb -L %s fork-server server --reply-fd %d",
+ socket_spec.c_str(), ack_write_as_int);
+ }
PROCESS_INFORMATION pinfo;
ZeroMemory(&pinfo, sizeof(pinfo));
@@ -978,8 +984,14 @@
char reply_fd[30];
snprintf(reply_fd, sizeof(reply_fd), "%d", pipe_write.get());
// child process
- int result = execl(path.c_str(), "adb", "-L", socket_spec.c_str(), "fork-server", "server",
- "--reply-fd", reply_fd, NULL);
+ std::vector<const char*> child_argv = {
+ "adb", "-L", socket_spec.c_str(), "fork-server", "server", "--reply-fd", reply_fd};
+ if (one_device) {
+ child_argv.push_back("--one-device");
+ child_argv.push_back(one_device);
+ }
+ child_argv.push_back(nullptr);
+ int result = execv(path.c_str(), const_cast<char* const*>(child_argv.data()));
// this should not return
fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno));
} else {
diff --git a/adb.h b/adb.h
index 801da1d..9dfaf3e 100644
--- a/adb.h
+++ b/adb.h
@@ -135,8 +135,9 @@
void handle_packet(apacket* p, atransport* t);
-int launch_server(const std::string& socket_spec);
-int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd);
+int launch_server(const std::string& socket_spec, const char* one_device);
+int adb_server_main(int is_daemon, const std::string& socket_spec, const char* one_device,
+ int ack_reply_fd);
/* initialize a transport object's func pointers and state */
int init_socket_transport(atransport* t, unique_fd s, int port, int local);
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
index e6081b0..f687f50 100644
--- a/apex/apex_manifest.json
+++ b/apex/apex_manifest.json
@@ -1,5 +1,5 @@
{
"name": "com.android.adbd",
"version": 319999999,
- "versionName": "319999999.5"
+ "versionName": "319999999.57"
}
diff --git a/client/adb_client.cpp b/client/adb_client.cpp
index 60dd38f..2d3e61f 100644
--- a/client/adb_client.cpp
+++ b/client/adb_client.cpp
@@ -53,6 +53,7 @@
static TransportId __adb_transport_id = 0;
static const char* __adb_server_socket_spec;
+static const char* __adb_client_one_device;
void adb_set_transport(TransportType type, const char* serial, TransportId transport_id) {
__adb_transport = type;
@@ -73,6 +74,10 @@
__adb_server_socket_spec = socket_spec;
}
+void adb_set_one_device(const char* one_device) {
+ __adb_client_one_device = one_device;
+}
+
static std::optional<TransportId> switch_socket_transport(int fd, std::string* error) {
TransportId result;
bool read_transport = true;
@@ -257,7 +262,7 @@
} else if (fd == -2) {
fprintf(stderr, "* daemon not running; starting now at %s\n", __adb_server_socket_spec);
start_server:
- if (launch_server(__adb_server_socket_spec)) {
+ if (launch_server(__adb_server_socket_spec, __adb_client_one_device)) {
fprintf(stderr, "* failed to start daemon\n");
// launch_server() has already printed detailed error info, so just
// return a generic error string about the overall adb_connect()
diff --git a/client/adb_client.h b/client/adb_client.h
index ab559b2..8262d18 100644
--- a/client/adb_client.h
+++ b/client/adb_client.h
@@ -58,6 +58,10 @@
void adb_get_transport(TransportType* _Nullable type, const char* _Nullable* _Nullable serial,
TransportId* _Nullable transport_id);
+// Set the server's "one device" id. This is either null, or a pointer to a serial number
+// or a pointer to a usb device path, the argument must live to the end of the process.
+void adb_set_one_device(const char* _Nullable one_device);
+
// Set the socket specification for the adb server.
// This function can only be called once, and the argument must live to the end of the process.
void adb_set_socket_spec(const char* _Nonnull socket_spec);
diff --git a/client/commandline.cpp b/client/commandline.cpp
index b5dd13f..0f6148e 100644
--- a/client/commandline.cpp
+++ b/client/commandline.cpp
@@ -86,14 +86,18 @@
// clang-format off
fprintf(stdout,
"global options:\n"
- " -a listen on all network interfaces, not just localhost\n"
- " -d use USB device (error if multiple devices connected)\n"
- " -e use TCP/IP device (error if multiple TCP/IP devices available)\n"
- " -s SERIAL use device with given serial (overrides $ANDROID_SERIAL)\n"
- " -t ID use device with given transport id\n"
- " -H name of adb server host [default=localhost]\n"
- " -P port of adb server [default=5037]\n"
- " -L SOCKET listen on given socket for adb server [default=tcp:localhost:5037]\n"
+ " -a listen on all network interfaces, not just localhost\n"
+ " -d use USB device (error if multiple devices connected)\n"
+ " -e use TCP/IP device (error if multiple TCP/IP devices available)\n"
+ " -s SERIAL use device with given serial (overrides $ANDROID_SERIAL)\n"
+ " -t ID use device with given transport id\n"
+ " -H name of adb server host [default=localhost]\n"
+ " -P port of adb server [default=5037]\n"
+ " -L SOCKET listen on given socket for adb server"
+ " [default=tcp:localhost:5037]\n"
+ " --one-device SERIAL|USB only allowed with 'start-server' or 'server nodaemon', server"
+ " will only connect to one USB device, specified by a serial number or USB device"
+ " address.\n"
"\n"
"general commands:\n"
" devices [-l] list connected devices (-l for long output)\n"
@@ -1558,6 +1562,7 @@
const char* server_host_str = nullptr;
const char* server_port_str = nullptr;
const char* server_socket_str = nullptr;
+ const char* one_device_str = nullptr;
// We need to check for -d and -e before we look at $ANDROID_SERIAL.
const char* serial = nullptr;
@@ -1574,21 +1579,26 @@
} else if (!strcmp(argv[0], "--reply-fd")) {
if (argc < 2) error_exit("--reply-fd requires an argument");
const char* reply_fd_str = argv[1];
- argc--;
- argv++;
+ --argc;
+ ++argv;
ack_reply_fd = strtol(reply_fd_str, nullptr, 10);
if (!_is_valid_ack_reply_fd(ack_reply_fd)) {
fprintf(stderr, "adb: invalid reply fd \"%s\"\n", reply_fd_str);
return 1;
}
+ } else if (!strcmp(argv[0], "--one-device")) {
+ if (argc < 2) error_exit("--one-device requires an argument");
+ one_device_str = argv[1];
+ --argc;
+ ++argv;
} else if (!strncmp(argv[0], "-s", 2)) {
if (isdigit(argv[0][2])) {
serial = argv[0] + 2;
} else {
if (argc < 2 || argv[0][2] != '\0') error_exit("-s requires an argument");
serial = argv[1];
- argc--;
- argv++;
+ --argc;
+ ++argv;
}
} else if (!strncmp(argv[0], "-t", 2)) {
const char* id;
@@ -1596,8 +1606,8 @@
id = argv[0] + 2;
} else {
id = argv[1];
- argc--;
- argv++;
+ --argc;
+ ++argv;
}
transport_id = strtoll(id, const_cast<char**>(&id), 10);
if (*id != '\0') {
@@ -1613,8 +1623,8 @@
if (argv[0][2] == '\0') {
if (argc < 2) error_exit("-H requires an argument");
server_host_str = argv[1];
- argc--;
- argv++;
+ --argc;
+ ++argv;
} else {
server_host_str = argv[0] + 2;
}
@@ -1622,22 +1632,22 @@
if (argv[0][2] == '\0') {
if (argc < 2) error_exit("-P requires an argument");
server_port_str = argv[1];
- argc--;
- argv++;
+ --argc;
+ ++argv;
} else {
server_port_str = argv[0] + 2;
}
} else if (!strcmp(argv[0], "-L")) {
if (argc < 2) error_exit("-L requires an argument");
server_socket_str = argv[1];
- argc--;
- argv++;
+ --argc;
+ ++argv;
} else {
/* out of recognized modifiers and flags */
break;
}
- argc--;
- argv++;
+ --argc;
+ ++argv;
}
if ((server_host_str || server_port_str) && server_socket_str) {
@@ -1678,6 +1688,12 @@
server_socket_str = temp;
}
+ bool server_start = is_daemon || is_server || strcmp(argv[0], "start-server") == 0;
+ if (one_device_str && !server_start) {
+ error_exit("--one-device is only allowed when starting a server.");
+ }
+
+ adb_set_one_device(one_device_str);
adb_set_socket_spec(server_socket_str);
// If none of -d, -e, or -s were specified, try $ANDROID_SERIAL.
@@ -1693,9 +1709,9 @@
fprintf(stderr, "reply fd for adb server to client communication not specified.\n");
return 1;
}
- r = adb_server_main(is_daemon, server_socket_str, ack_reply_fd);
+ r = adb_server_main(is_daemon, server_socket_str, one_device_str, ack_reply_fd);
} else {
- r = launch_server(server_socket_str);
+ r = launch_server(server_socket_str, one_device_str);
}
if (r) {
fprintf(stderr,"* could not start server *\n");
@@ -1723,8 +1739,8 @@
}
/* Fall through */
- argc--;
- argv++;
+ --argc;
+ ++argv;
}
/* adb_connect() commands */
diff --git a/client/main.cpp b/client/main.cpp
index 4fa58fa..cc89734 100644
--- a/client/main.cpp
+++ b/client/main.cpp
@@ -81,7 +81,10 @@
LOG(INFO) << "leaking pointer " << p;
}
-int adb_server_main(int is_daemon, const std::string& socket_spec, int ack_reply_fd) {
+// one_device: if null, server owns all devices, else server owns only
+// device where atransport::MatchesTarget(one_device) is true.
+int adb_server_main(int is_daemon, const std::string& socket_spec, const char* one_device,
+ int ack_reply_fd) {
#if defined(_WIN32)
// adb start-server starts us up with stdout and stderr hooked up to
// anonymous pipes. When the C Runtime sees this, it makes stderr and
@@ -108,6 +111,10 @@
fdevent_run_on_main_thread([]() { exit(0); });
});
+ if (one_device) {
+ transport_set_one_device(one_device);
+ }
+
const char* reject_kill_server = getenv("ADB_REJECT_KILL_SERVER");
if (reject_kill_server && strcmp(reject_kill_server, "1") == 0) {
adb_set_reject_kill_server(true);
diff --git a/client/usb_libusb.cpp b/client/usb_libusb.cpp
index 2564c26..e0b0104 100644
--- a/client/usb_libusb.cpp
+++ b/client/usb_libusb.cpp
@@ -469,6 +469,8 @@
return true;
}
+ std::string GetUsbDeviceAddress() const { return std::string("usb:") + device_address_; }
+
std::string GetSerial() {
std::string serial;
@@ -722,10 +724,14 @@
auto device_desc = connection->GetDeviceDescriptor();
if (!device_desc) {
+ LOG(INFO) << "ignoring device " << connection->GetUsbDeviceAddress()
+ << ": not an adb interface. (GetDeviceDescriptor)";
return {};
}
if (!connection->FindInterface(&device_desc.value())) {
+ LOG(INFO) << "ignoring device " << connection->GetUsbDeviceAddress()
+ << ": not an adb interface. (FindInterface)";
return {};
}
@@ -743,11 +749,19 @@
#else
// We need to open the device to get its serial on Windows and OS X.
if (!connection->OpenDevice(nullptr)) {
+ LOG(INFO) << "ignoring device " << connection->GetUsbDeviceAddress()
+ << ": not an adb interface. (OpenDevice)";
return {};
}
connection->serial_ = connection->GetSerial();
connection->CloseDevice();
#endif
+ if (!transport_server_owns_device(connection->GetUsbDeviceAddress(), connection->serial_)) {
+ LOG(INFO) << "ignoring device " << connection->GetUsbDeviceAddress() << " serial "
+ << connection->serial_ << ": this server owns '" << transport_get_one_device()
+ << "'";
+ return {};
+ }
return connection;
}
@@ -792,7 +806,6 @@
unique_device device(libusb_ref_device(device_raw));
auto connection_opt = LibusbConnection::Create(std::move(device));
if (!connection_opt) {
- LOG(INFO) << "ignoring device: not an adb interface";
return;
}
diff --git a/client/usb_linux.cpp b/client/usb_linux.cpp
index f75232f..7f92626 100644
--- a/client/usb_linux.cpp
+++ b/client/usb_linux.cpp
@@ -531,6 +531,24 @@
static void register_device(const char* dev_name, const char* dev_path, unsigned char ep_in,
unsigned char ep_out, int interface, int serial_index,
unsigned zero_mask, size_t max_packet_size) {
+ // Read the device's serial number.
+ std::string serial_path =
+ android::base::StringPrintf("/sys/bus/usb/devices/%s/serial", dev_path + 4);
+ std::string serial;
+ if (!android::base::ReadFileToString(serial_path, &serial)) {
+ D("[ usb read %s failed: %s ]", serial_path.c_str(), strerror(errno));
+ // We don't actually want to treat an unknown serial as an error because
+ // devices aren't able to communicate a serial number in early bringup.
+ // http://b/20883914
+ serial = "";
+ }
+ serial = android::base::Trim(serial);
+
+ if (!transport_server_owns_device(dev_path, serial)) {
+ // We aren't allowed to communicate with this device. Don't open this device.
+ return;
+ }
+
// Since Linux will not reassign the device ID (and dev_name) as long as the
// device is open, we can add to the list here once we open it and remove
// from the list when we're finally closed and everything will work out
@@ -579,19 +597,6 @@
}
}
- // Read the device's serial number.
- std::string serial_path = android::base::StringPrintf(
- "/sys/bus/usb/devices/%s/serial", dev_path + 4);
- std::string serial;
- if (!android::base::ReadFileToString(serial_path, &serial)) {
- D("[ usb read %s failed: %s ]", serial_path.c_str(), strerror(errno));
- // We don't actually want to treat an unknown serial as an error because
- // devices aren't able to communicate a serial number in early bringup.
- // http://b/20883914
- serial = "";
- }
- serial = android::base::Trim(serial);
-
// Add to the end of the active handles.
usb_handle* done_usb = usb.release();
{
diff --git a/client/usb_osx.cpp b/client/usb_osx.cpp
index 42ba812..e72d719 100644
--- a/client/usb_osx.cpp
+++ b/client/usb_osx.cpp
@@ -296,6 +296,13 @@
continue;
}
+ if (!transport_server_owns_device(devpath, serial)) {
+ // We aren't allowed to communicate with this device. Don't open this device.
+ D("ignoring device: not owned by this server dev_path: '%s', serial: '%s'",
+ devpath.c_str(), serial);
+ continue;
+ }
+
std::unique_ptr<usb_handle> handle =
CheckInterface((IOUSBInterfaceInterface550**)iface, vendor, product);
if (handle == nullptr) {
diff --git a/client/usb_windows.cpp b/client/usb_windows.cpp
index 0ffcc09..6581928 100644
--- a/client/usb_windows.cpp
+++ b/client/usb_windows.cpp
@@ -574,6 +574,15 @@
unsigned long serial_number_len = sizeof(serial_number);
if (AdbGetSerialNumber(handle->adb_interface, serial_number, &serial_number_len,
true)) {
+ if (!transport_server_owns_device(serial_number)) {
+ // We aren't allowed to communicate with this device. Don't open this
+ // device.
+ D("ignoring device: not owned by this server serial: '%s'",
+ serial_number);
+ usb_cleanup_handle(handle);
+ free(handle);
+ return;
+ }
// Lets make sure that we don't duplicate this device
if (register_new_device(handle)) {
register_usb_transport(handle, serial_number, nullptr, 1);
diff --git a/crypto/Android.bp b/crypto/Android.bp
index 8fdce89..9628348 100644
--- a/crypto/Android.bp
+++ b/crypto/Android.bp
@@ -69,6 +69,7 @@
name: "libadb_crypto",
defaults: ["libadb_crypto_defaults"],
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
"test_com.android.adbd",
diff --git a/libs/adbconnection/Android.bp b/libs/adbconnection/Android.bp
index da0b5b6..0698a98 100644
--- a/libs/adbconnection/Android.bp
+++ b/libs/adbconnection/Android.bp
@@ -27,6 +27,7 @@
use_version_lib: false,
recovery_available: true,
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
// TODO(b/151398197) remove the below
@@ -50,6 +51,7 @@
"//art:__subpackages__",
"//packages/modules/adb/apex:__subpackages__",
],
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
"test_com.android.adbd",
diff --git a/pairing_auth/Android.bp b/pairing_auth/Android.bp
index e2e9fc4..1d6dd98 100644
--- a/pairing_auth/Android.bp
+++ b/pairing_auth/Android.bp
@@ -71,6 +71,7 @@
name: "libadb_pairing_auth",
defaults: ["libadb_pairing_auth_defaults"],
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
],
diff --git a/pairing_connection/Android.bp b/pairing_connection/Android.bp
index 3c5b0a3..3557810 100644
--- a/pairing_connection/Android.bp
+++ b/pairing_connection/Android.bp
@@ -81,6 +81,7 @@
name: "libadb_pairing_connection",
defaults: ["libadb_pairing_connection_defaults"],
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
],
@@ -163,6 +164,7 @@
name: "libadb_pairing_server",
defaults: ["libadb_pairing_server_defaults"],
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
],
diff --git a/proto/Android.bp b/proto/Android.bp
index c7271fb..fae321f 100644
--- a/proto/Android.bp
+++ b/proto/Android.bp
@@ -65,6 +65,7 @@
name: "libadb_protos",
defaults: ["libadb_protos_defaults"],
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
"test_com.android.adbd",
@@ -121,6 +122,7 @@
name: "libapp_processes_protos_lite",
defaults: ["libapp_processes_protos_defaults"],
+ min_sdk_version: "30",
apex_available: ["//apex_available:platform"],
proto: {
diff --git a/tls/Android.bp b/tls/Android.bp
index 9e850ab..b45fc8d 100644
--- a/tls/Android.bp
+++ b/tls/Android.bp
@@ -64,6 +64,7 @@
name: "libadb_tls_connection",
defaults: ["libadb_tls_connection_defaults"],
+ min_sdk_version: "30",
apex_available: [
"com.android.adbd",
"test_com.android.adbd",
diff --git a/transport.cpp b/transport.cpp
index 3493cc1..0dfad0e 100644
--- a/transport.cpp
+++ b/transport.cpp
@@ -96,6 +96,7 @@
namespace {
#if ADB_HOST
+
// Tracks and handles atransport*s that are attempting reconnection.
class ReconnectHandler {
public:
@@ -948,6 +949,34 @@
return !*ptr;
}
+// Contains either a device serial string or a USB device address like "usb:2-6"
+const char* __transport_server_one_device = nullptr;
+
+void transport_set_one_device(const char* adb_one_device) {
+ __transport_server_one_device = adb_one_device;
+}
+
+const char* transport_get_one_device() {
+ return __transport_server_one_device;
+}
+
+bool transport_server_owns_device(std::string_view serial) {
+ if (!__transport_server_one_device) {
+ // If the server doesn't own one device, server owns all devices.
+ return true;
+ }
+ return serial.compare(__transport_server_one_device) == 0;
+}
+
+bool transport_server_owns_device(std::string_view dev_path, std::string_view serial) {
+ if (!__transport_server_one_device) {
+ // If the server doesn't own one device, server owns all devices.
+ return true;
+ }
+ return serial.compare(__transport_server_one_device) == 0 ||
+ dev_path.compare(__transport_server_one_device) == 0;
+}
+
atransport* acquire_one_transport(TransportType type, const char* serial, TransportId transport_id,
bool* is_ambiguous, std::string* error_out,
bool accept_any_state) {
diff --git a/transport.h b/transport.h
index 35cecf8..8618693 100644
--- a/transport.h
+++ b/transport.h
@@ -422,6 +422,18 @@
DISALLOW_COPY_AND_ASSIGN(atransport);
};
+// --one-device command line parameter is eventually put here.
+void transport_set_one_device(const char* adb_one_device);
+
+// Returns one device owned by this server of nullptr if all devices belong to server.
+const char* transport_get_one_device();
+
+// Returns true if the adb server owns all devices, or `serial`.
+bool transport_server_owns_device(std::string_view serial);
+
+// Returns true if the adb server owns all devices, `serial`, or `dev_path`.
+bool transport_server_owns_device(std::string_view dev_path, std::string_view serial);
+
/*
* Obtain a transport from the available transports.
* If serial is non-null then only the device with that serial will be chosen.