Merge "Using ABB for install-multi."
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index c8dbf77..dcf92be 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -3,3 +3,6 @@
[Builtin Hooks Options]
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+
+[Hook Scripts]
+aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "."
diff --git a/adb/Android.bp b/adb/Android.bp
index 19e921f..432770c 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -165,17 +165,26 @@
"adb_unique_fd.cpp",
"adb_utils.cpp",
"fdevent/fdevent.cpp",
- "fdevent/fdevent_poll.cpp",
"services.cpp",
"sockets.cpp",
"socket_spec.cpp",
"sysdeps/errno.cpp",
"transport.cpp",
"transport_fd.cpp",
- "transport_local.cpp",
"types.cpp",
]
+libadb_darwin_srcs = [
+ "fdevent/fdevent_poll.cpp",
+]
+
+libadb_windows_srcs = [
+ "fdevent/fdevent_poll.cpp",
+ "sysdeps_win32.cpp",
+ "sysdeps/win32/errno.cpp",
+ "sysdeps/win32/stat.cpp",
+]
+
libadb_posix_srcs = [
"sysdeps_unix.cpp",
"sysdeps/posix/network.cpp",
@@ -207,6 +216,7 @@
"client/adb_wifi.cpp",
"client/usb_libusb.cpp",
"client/usb_dispatch.cpp",
+ "client/transport_local.cpp",
"client/transport_mdns.cpp",
"client/transport_usb.cpp",
"client/pairing/pairing_client.cpp",
@@ -219,7 +229,7 @@
srcs: ["client/usb_linux.cpp"] + libadb_linux_srcs,
},
darwin: {
- srcs: ["client/usb_osx.cpp"],
+ srcs: ["client/usb_osx.cpp"] + libadb_darwin_srcs,
},
not_windows: {
srcs: libadb_posix_srcs,
@@ -228,10 +238,7 @@
enabled: true,
srcs: [
"client/usb_windows.cpp",
- "sysdeps_win32.cpp",
- "sysdeps/win32/errno.cpp",
- "sysdeps/win32/stat.cpp",
- ],
+ ] + libadb_windows_srcs,
shared_libs: ["AdbWinApi"],
},
},
@@ -383,10 +390,11 @@
compile_multilib: "both",
srcs: libadb_srcs + libadb_linux_srcs + libadb_posix_srcs + [
+ "daemon/adb_wifi.cpp",
"daemon/auth.cpp",
"daemon/jdwp_service.cpp",
"daemon/logging.cpp",
- "daemon/adb_wifi.cpp",
+ "daemon/transport_local.cpp",
],
generated_headers: ["platform_tools_version"],
@@ -585,7 +593,6 @@
cc_binary {
name: "adbd",
defaults: ["adbd_defaults", "host_adbd_supported", "libadbd_binary_dependencies"],
- stl: "libc++_static",
recovery_available: true,
apex_available: ["com.android.adbd"],
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 06fdb69..dcec0ba 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -1076,6 +1076,25 @@
g_reject_kill_server = value;
}
+static bool handle_mdns_request(std::string_view service, int reply_fd) {
+ if (!android::base::ConsumePrefix(&service, "mdns:")) {
+ return false;
+ }
+
+ if (service == "check") {
+ std::string check = mdns_check();
+ SendOkay(reply_fd, check);
+ return true;
+ }
+ if (service == "services") {
+ std::string services_list = mdns_list_discovered_services();
+ SendOkay(reply_fd, services_list);
+ return true;
+ }
+
+ return false;
+}
+
HostRequestResult handle_host_request(std::string_view service, TransportType type,
const char* serial, TransportId transport_id, int reply_fd,
asocket* s) {
@@ -1320,6 +1339,10 @@
return HostRequestResult::Handled;
}
+ if (handle_mdns_request(service, reply_fd)) {
+ return HostRequestResult::Handled;
+ }
+
return HostRequestResult::Unhandled;
}
diff --git a/adb/adb_trace.cpp b/adb/adb_trace.cpp
index cea24fe..c579dde 100644
--- a/adb/adb_trace.cpp
+++ b/adb/adb_trace.cpp
@@ -89,18 +89,13 @@
int adb_trace_mask;
-std::string get_trace_setting_from_env() {
+std::string get_trace_setting() {
+#if ADB_HOST
const char* setting = getenv("ADB_TRACE");
if (setting == nullptr) {
setting = "";
}
-
- return std::string(setting);
-}
-
-std::string get_trace_setting() {
-#if ADB_HOST
- return get_trace_setting_from_env();
+ return setting;
#else
return android::base::GetProperty("persist.adb.trace_mask", "");
#endif
diff --git a/adb/adb_wifi.h b/adb/adb_wifi.h
index 585748c..3a6b0b1 100644
--- a/adb/adb_wifi.h
+++ b/adb/adb_wifi.h
@@ -27,6 +27,9 @@
std::string& response);
bool adb_wifi_is_known_host(const std::string& host);
+std::string mdns_check();
+std::string mdns_list_discovered_services();
+
#else // !ADB_HOST
struct AdbdAuthContext;
diff --git a/adb/client/adb_client.h b/adb/client/adb_client.h
index 27be28f..caf4e86 100644
--- a/adb/client/adb_client.h
+++ b/adb/client/adb_client.h
@@ -90,8 +90,9 @@
// ADB Secure DNS service interface. Used to query what ADB Secure DNS services have been
// resolved, and to run some kind of callback for each one.
-using adb_secure_foreach_service_callback = std::function<void(
- const char* _Nonnull service_name, const char* _Nonnull ip_address, uint16_t port)>;
+using adb_secure_foreach_service_callback =
+ std::function<void(const char* _Nonnull service_name, const char* _Nonnull reg_type,
+ const char* _Nonnull ip_address, uint16_t port)>;
// Queries pairing/connect services that have been discovered and resolved.
// If |host_name| is not null, run |cb| only for services
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 29f9dc1..d565e01 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -127,6 +127,8 @@
" localfilesystem:<unix domain socket name>\n"
" reverse --remove REMOTE remove specific reverse socket connection\n"
" reverse --remove-all remove all reverse socket connections from device\n"
+ " mdns check check if mdns discovery is available\n"
+ " mdns services list all discovered services\n"
"\n"
"file transfer:\n"
" push [--sync] [-z ALGORITHM] [-Z] LOCAL... REMOTE\n"
@@ -1910,6 +1912,29 @@
ReadOrderlyShutdown(fd);
return 0;
+ } else if (!strcmp(argv[0], "mdns")) {
+ --argc;
+ if (argc < 1) error_exit("mdns requires an argument");
+ ++argv;
+
+ std::string error;
+ if (!adb_check_server_version(&error)) {
+ error_exit("failed to check server version: %s", error.c_str());
+ }
+
+ std::string query = "host:mdns:";
+ if (!strcmp(argv[0], "check")) {
+ if (argc != 1) error_exit("mdns %s doesn't take any arguments", argv[0]);
+ query += "check";
+ } else if (!strcmp(argv[0], "services")) {
+ if (argc != 1) error_exit("mdns %s doesn't take any arguments", argv[0]);
+ query += "services";
+ printf("List of discovered mdns services\n");
+ } else {
+ error_exit("unknown mdns command [%s]", argv[0]);
+ }
+
+ return adb_query_command(query);
}
/* do_sync_*() commands */
else if (!strcmp(argv[0], "ls")) {
diff --git a/adb/transport_local.cpp b/adb/client/transport_local.cpp
similarity index 78%
rename from adb/transport_local.cpp
rename to adb/client/transport_local.cpp
index 5ec8e16..15a0724 100644
--- a/adb/transport_local.cpp
+++ b/adb/client/transport_local.cpp
@@ -38,10 +38,6 @@
#include <android-base/thread_annotations.h>
#include <cutils/sockets.h>
-#if !ADB_HOST
-#include <android-base/properties.h>
-#endif
-
#include "adb.h"
#include "adb_io.h"
#include "adb_unique_fd.h"
@@ -49,8 +45,6 @@
#include "socket_spec.h"
#include "sysdeps/chrono.h"
-#if ADB_HOST
-
// Android Wear has been using port 5601 in all of its documentation/tooling,
// but we search for emulators on ports [5554, 5555 + ADB_LOCAL_TRANSPORT_MAX].
// Avoid stomping on their port by restricting the active scanning range.
@@ -76,9 +70,8 @@
// We keep a map from emulator port to transport.
// TODO: weak_ptr?
-static auto& local_transports GUARDED_BY(local_transports_lock) =
- *new std::unordered_map<int, atransport*>();
-#endif /* ADB_HOST */
+static std::unordered_map<int, atransport*> local_transports
+ [[clang::no_destroy]] GUARDED_BY(local_transports_lock);
bool local_connect(int port) {
std::string dummy;
@@ -140,21 +133,19 @@
}
}
-
int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error) {
unique_fd fd;
-#if ADB_HOST
if (find_emulator_transport_by_adb_port(adb_port) != nullptr ||
find_emulator_transport_by_console_port(console_port) != nullptr) {
return -1;
}
- const char *host = getenv("ADBHOST");
+ const char* host = getenv("ADBHOST");
if (host) {
fd.reset(network_connect(host, adb_port, SOCK_STREAM, 0, error));
}
-#endif
+
if (fd < 0) {
fd.reset(network_loopback_client(adb_port, SOCK_STREAM, error));
}
@@ -173,8 +164,6 @@
return -1;
}
-#if ADB_HOST
-
static void PollAllLocalPortsForEmulator() {
// Try to connect to any number of running emulator instances.
for (int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; port <= adb_local_transport_max_port;
@@ -194,8 +183,8 @@
// Retry emulators just kicked.
static std::vector<RetryPort>& retry_ports = *new std::vector<RetryPort>;
-std::mutex &retry_ports_lock = *new std::mutex;
-std::condition_variable &retry_ports_cond = *new std::condition_variable;
+std::mutex& retry_ports_lock = *new std::mutex;
+std::condition_variable& retry_ports_cond = *new std::condition_variable;
static void client_socket_thread(std::string_view) {
adb_thread_setname("client_socket_thread");
@@ -220,7 +209,7 @@
std::vector<RetryPort> next_ports;
for (auto& port : ports) {
VLOG(TRANSPORT) << "retry port " << port.port << ", last retry_count "
- << port.retry_count;
+ << port.retry_count;
if (local_connect(port.port)) {
VLOG(TRANSPORT) << "retry port " << port.port << " successfully";
continue;
@@ -240,77 +229,12 @@
}
}
-#else // !ADB_HOST
-
-void server_socket_thread(std::function<unique_fd(std::string_view, std::string*)> listen_func,
- std::string_view addr) {
- adb_thread_setname("server socket");
-
- unique_fd serverfd;
- std::string error;
-
- while (serverfd == -1) {
- errno = 0;
- serverfd = listen_func(addr, &error);
- if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) {
- D("unrecoverable error: '%s'", error.c_str());
- return;
- } else if (serverfd < 0) {
- D("server: cannot bind socket yet: %s", error.c_str());
- std::this_thread::sleep_for(1s);
- continue;
- }
- close_on_exec(serverfd.get());
- }
-
- while (true) {
- D("server: trying to get new connection from fd %d", serverfd.get());
- unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));
- if (fd >= 0) {
- D("server: new connection on fd %d", fd.get());
- close_on_exec(fd.get());
- disable_tcp_nagle(fd.get());
- std::string serial = android::base::StringPrintf("host-%d", fd.get());
- // We don't care about port value in "register_socket_transport" as it is used
- // only from ADB_HOST. "server_socket_thread" is never called from ADB_HOST.
- register_socket_transport(
- std::move(fd), std::move(serial), 0, 1,
- [](atransport*) { return ReconnectResult::Abort; }, false);
- }
- }
- D("transport: server_socket_thread() exiting");
-}
-
-#endif
-
-#if !ADB_HOST
-unique_fd adb_listen(std::string_view addr, std::string* error) {
- return unique_fd{socket_spec_listen(addr, error, nullptr)};
-}
-#endif
-
void local_init(const std::string& addr) {
-#if ADB_HOST
D("transport: local client init");
std::thread(client_socket_thread, addr).detach();
adb_local_transport_max_port_env_override();
-#elif !defined(__ANDROID__)
- // Host adbd.
- D("transport: local server init");
- std::thread(server_socket_thread, adb_listen, addr).detach();
-#else
- D("transport: local server init");
- // For the adbd daemon in the system image we need to distinguish
- // between the device, and the emulator.
- if (addr.starts_with("tcp:") && use_qemu_goldfish()) {
- std::thread(qemu_socket_thread, addr).detach();
- } else {
- std::thread(server_socket_thread, adb_listen, addr).detach();
- }
-#endif // !ADB_HOST
}
-#if ADB_HOST
struct EmulatorConnection : public FdConnection {
EmulatorConnection(unique_fd fd, int local_port)
: FdConnection(std::move(fd)), local_port_(local_port) {}
@@ -336,7 +260,7 @@
/* Only call this function if you already hold local_transports_lock. */
static atransport* find_emulator_transport_by_adb_port_locked(int adb_port)
- REQUIRES(local_transports_lock) {
+ REQUIRES(local_transports_lock) {
auto it = local_transports.find(adb_port);
if (it == local_transports.end()) {
return nullptr;
@@ -352,7 +276,6 @@
atransport* find_emulator_transport_by_console_port(int console_port) {
return find_transport(getEmulatorSerialString(console_port).c_str());
}
-#endif
std::string getEmulatorSerialString(int console_port) {
return android::base::StringPrintf("emulator-%d", console_port);
@@ -363,7 +286,6 @@
t->type = kTransportLocal;
-#if ADB_HOST
// Emulator connection.
if (local) {
auto emulator_connection = std::make_unique<EmulatorConnection>(std::move(fd), adb_port);
@@ -380,7 +302,6 @@
return fail;
}
-#endif
// Regular tcp connection.
auto fd_connection = std::make_unique<FdConnection>(std::move(fd));
diff --git a/adb/client/transport_mdns.cpp b/adb/client/transport_mdns.cpp
index 22b9b18..2bf062f 100644
--- a/adb/client/transport_mdns.cpp
+++ b/adb/client/transport_mdns.cpp
@@ -216,6 +216,9 @@
int adbSecureServiceType = serviceIndex();
switch (adbSecureServiceType) {
+ case kADBTransportServiceRefIndex:
+ sAdbTransportServices->push_back(this);
+ break;
case kADBSecurePairingServiceRefIndex:
sAdbSecurePairingServices->push_back(this);
break;
@@ -233,16 +236,21 @@
std::string serviceName() const { return serviceName_; }
+ std::string regType() const { return regType_; }
+
std::string ipAddress() const { return ip_addr_; }
uint16_t port() const { return port_; }
using ServiceRegistry = std::vector<ResolvedService*>;
+ // unencrypted tcp connections
+ static ServiceRegistry* sAdbTransportServices;
+
static ServiceRegistry* sAdbSecurePairingServices;
static ServiceRegistry* sAdbSecureConnectServices;
- static void initAdbSecure();
+ static void initAdbServiceRegistries();
static void forEachService(const ServiceRegistry& services, const std::string& hostname,
adb_secure_foreach_service_callback cb);
@@ -264,13 +272,19 @@
};
// static
+std::vector<ResolvedService*>* ResolvedService::sAdbTransportServices = NULL;
+
+// static
std::vector<ResolvedService*>* ResolvedService::sAdbSecurePairingServices = NULL;
// static
std::vector<ResolvedService*>* ResolvedService::sAdbSecureConnectServices = NULL;
// static
-void ResolvedService::initAdbSecure() {
+void ResolvedService::initAdbServiceRegistries() {
+ if (!sAdbTransportServices) {
+ sAdbTransportServices = new ServiceRegistry;
+ }
if (!sAdbSecurePairingServices) {
sAdbSecurePairingServices = new ServiceRegistry;
}
@@ -283,17 +297,18 @@
void ResolvedService::forEachService(const ServiceRegistry& services,
const std::string& wanted_service_name,
adb_secure_foreach_service_callback cb) {
- initAdbSecure();
+ initAdbServiceRegistries();
for (auto service : services) {
auto service_name = service->serviceName();
+ auto reg_type = service->regType();
auto ip = service->ipAddress();
auto port = service->port();
if (wanted_service_name == "") {
- cb(service_name.c_str(), ip.c_str(), port);
+ cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
} else if (service_name == wanted_service_name) {
- cb(service_name.c_str(), ip.c_str(), port);
+ cb(service_name.c_str(), reg_type.c_str(), ip.c_str(), port);
}
}
}
@@ -301,7 +316,7 @@
// static
bool ResolvedService::connectByServiceName(const ServiceRegistry& services,
const std::string& service_name) {
- initAdbSecure();
+ initAdbServiceRegistries();
for (auto service : services) {
if (service_name == service->serviceName()) {
D("Got service_name match [%s]", service->serviceName().c_str());
@@ -398,6 +413,9 @@
int index = adb_DNSServiceIndexByName(regType);
ResolvedService::ServiceRegistry* services;
switch (index) {
+ case kADBTransportServiceRefIndex:
+ services = ResolvedService::sAdbTransportServices;
+ break;
case kADBSecurePairingServiceRefIndex:
services = ResolvedService::sAdbSecurePairingServices;
break;
@@ -542,6 +560,34 @@
}
void init_mdns_transport_discovery(void) {
- ResolvedService::initAdbSecure();
+ ResolvedService::initAdbServiceRegistries();
std::thread(init_mdns_transport_discovery_thread).detach();
}
+
+std::string mdns_check() {
+ uint32_t daemon_version;
+ uint32_t sz = sizeof(daemon_version);
+
+ auto dnserr = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &daemon_version, &sz);
+ std::string result = "ERROR: mdns daemon unavailable";
+ if (dnserr != kDNSServiceErr_NoError) {
+ return result;
+ }
+
+ result = android::base::StringPrintf("mdns daemon version [%u]", daemon_version);
+ return result;
+}
+
+std::string mdns_list_discovered_services() {
+ std::string result;
+ auto cb = [&](const char* service_name, const char* reg_type, const char* ip_addr,
+ uint16_t port) {
+ result += android::base::StringPrintf("%s\t%s\t%s:%u\n", service_name, reg_type, ip_addr,
+ port);
+ };
+
+ ResolvedService::forEachService(*ResolvedService::sAdbTransportServices, "", cb);
+ ResolvedService::forEachService(*ResolvedService::sAdbSecureConnectServices, "", cb);
+ ResolvedService::forEachService(*ResolvedService::sAdbSecurePairingServices, "", cb);
+ return result;
+}
diff --git a/adb/coverage/.gitignore b/adb/coverage/.gitignore
new file mode 100644
index 0000000..b6a2582
--- /dev/null
+++ b/adb/coverage/.gitignore
@@ -0,0 +1,2 @@
+/adbd.profdata
+/report
diff --git a/adb/coverage/gen_coverage.sh b/adb/coverage/gen_coverage.sh
new file mode 100755
index 0000000..cced62a
--- /dev/null
+++ b/adb/coverage/gen_coverage.sh
@@ -0,0 +1,114 @@
+#!/bin/bash
+
+set -euxo pipefail
+
+OUTPUT_DIR=$(dirname "$0")
+. "$OUTPUT_DIR"/include.sh
+
+TRACEDIR=`mktemp -d`
+
+### Make sure we can connect to the device.
+
+# Get the device's wlan0 address.
+IP_ADDR=$(adb shell ip route get 0.0.0.0 oif wlan0 | sed -En -e 's/.*src (\S+)\s.*/\1/p')
+REMOTE_PORT=5555
+REMOTE=$IP_ADDR:$REMOTE_PORT
+LOCAL_SERIAL=$(adb shell getprop ro.serialno)
+
+# Check that we can connect to it.
+adb disconnect
+adb tcpip $REMOTE_PORT
+
+# TODO: Add `adb transport-id` and wait-for-offline on it.
+sleep 5
+
+adb connect $REMOTE
+
+REMOTE_FETCHED_SERIAL=$(adb -s $REMOTE shell getprop ro.serialno)
+
+if [[ "$LOCAL_SERIAL" != "$REMOTE_FETCHED_SERIAL" ]]; then
+ echo "Mismatch: local serial = $LOCAL_SERIAL, remote serial = $REMOTE_FETCHED_SERIAL"
+ exit 1
+fi
+
+# Back to USB, and make sure adbd is root.
+adb disconnect $REMOTE
+
+adb root
+adb wait-for-device usb
+
+# TODO: Add `adb transport-id` and wait-for-offline on it.
+sleep 5
+
+adb wait-for-device
+
+### Run the adb unit tests and fetch traces from them.
+mkdir "$TRACEDIR"/test_traces
+adb shell rm -rf /data/local/tmp/adb_coverage
+adb shell mkdir /data/local/tmp/adb_coverage
+
+for TEST in $ADB_TESTS; do
+ adb shell LLVM_PROFILE_FILE=/data/local/tmp/adb_coverage/$TEST.profraw /data/nativetest64/$TEST/$TEST
+ adb pull /data/local/tmp/adb_coverage/$TEST.profraw "$TRACEDIR"/test_traces/
+done
+
+adb pull /data/local/tmp/adb_coverage "$TRACEDIR"/test_traces
+
+# Clear logcat and increase the buffer to something ridiculous so we can fetch the pids of adbd later.
+adb shell logcat -c -G128M
+
+# Turn on extremely verbose logging so as to not count debug logging against us.
+adb shell setprop persist.adb.trace_mask 1
+
+### Run test_device.py over USB.
+adb shell killall adbd
+
+# TODO: Add `adb transport-id` and wait-for-offline on it.
+sleep 5
+
+adb wait-for-device shell rm -rf "/data/misc/trace/*" /data/local/tmp/adb_coverage/
+"$OUTPUT_DIR"/../test_device.py
+
+# Do a usb reset to exercise the disconnect code.
+adb_usbreset
+adb wait-for-device
+
+# Dump traces from the currently running adbd.
+adb shell killall -37 adbd
+
+echo Waiting for adbd to finish dumping traces
+sleep 5
+
+# Restart adbd in tcp mode.
+adb tcpip $REMOTE_PORT
+sleep 5
+adb connect $REMOTE
+adb -s $REMOTE wait-for-device
+
+# Run test_device.py again.
+ANDROID_SERIAL=$REMOTE "$OUTPUT_DIR"/../test_device.py
+
+# Dump traces again.
+adb disconnect $REMOTE
+adb shell killall -37 adbd
+
+echo Waiting for adbd to finish dumping traces
+sleep 5
+
+adb pull /data/misc/trace "$TRACEDIR"/
+echo Pulled traces to $TRACEDIR
+
+# Identify which of the trace files are actually adbd, in case something else exited simultaneously.
+ADBD_PIDS=$(adb shell "logcat -d -s adbd --format=process | grep 'adbd started' | cut -c 3-7 | tr -d ' ' | sort | uniq")
+mkdir "$TRACEDIR"/adbd_traces
+
+adb shell 'setprop persist.adb.trace_mask 0; killall adbd'
+
+IFS=$'\n'
+for PID in $ADBD_PIDS; do
+ cp "$TRACEDIR"/trace/clang-$PID-*.profraw "$TRACEDIR"/adbd_traces 2>/dev/null || true
+done
+unset IFS
+
+### Merge the traces.
+llvm-profdata merge --output="$OUTPUT_DIR"/adbd.profdata "$TRACEDIR"/adbd_traces/* "$TRACEDIR"/test_traces/*
diff --git a/adb/coverage/include.sh b/adb/coverage/include.sh
new file mode 100644
index 0000000..45ebc34
--- /dev/null
+++ b/adb/coverage/include.sh
@@ -0,0 +1,5 @@
+ADB_TESTS="adbd_test adb_crypto_test adb_pairing_auth_test adb_pairing_connection_test adb_tls_connection_test"
+ADB_TEST_BINARIES=""
+for TEST in $ADB_TESTS; do
+ ADB_TEST_BINARIES="--object=$ANDROID_PRODUCT_OUT/data/nativetest64/$TEST/$TEST $ADB_TEST_BINARIES"
+done
diff --git a/adb/coverage/report.sh b/adb/coverage/report.sh
new file mode 100755
index 0000000..257310c
--- /dev/null
+++ b/adb/coverage/report.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -euxo pipefail
+
+OUTPUT_DIR=$(realpath $(dirname "$0"))
+. "$OUTPUT_DIR"/include.sh
+
+rm -rf "$OUTPUT_DIR"/report
+
+cd $ANDROID_BUILD_TOP
+llvm-cov show --instr-profile="$OUTPUT_DIR"/adbd.profdata \
+ $ANDROID_PRODUCT_OUT/apex/com.android.adbd/bin/adbd \
+ /proc/self/cwd/system/core/adb \
+ $ADB_TEST_BINARIES \
+ --show-region-summary=false \
+ --format=html -o "$OUTPUT_DIR"/report
+
+llvm-cov report --instr-profile="$OUTPUT_DIR"/adbd.profdata \
+ $ANDROID_PRODUCT_OUT/apex/com.android.adbd/bin/adbd \
+ /proc/self/cwd/system/core/adb \
+ $ADB_TEST_BINARIES \
+ --show-region-summary=false
diff --git a/adb/coverage/show.sh b/adb/coverage/show.sh
new file mode 100755
index 0000000..3b2faa3
--- /dev/null
+++ b/adb/coverage/show.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -euxo pipefail
+
+OUTPUT_DIR=$(realpath $(dirname "$0"))
+. "$OUTPUT_DIR"/include.sh
+
+BASE_PATH=/proc/self/cwd/system/core/adb
+PATHS=""
+if [[ $# == 0 ]]; then
+ PATHS=$BASE_PATH
+else
+ for arg in "$@"; do
+ PATHS="$PATHS $BASE_PATH/$arg"
+ done
+fi
+
+cd $ANDROID_BUILD_TOP
+llvm-cov show --instr-profile="$OUTPUT_DIR"/adbd.profdata \
+ $ANDROID_PRODUCT_OUT/apex/com.android.adbd/bin/adbd \
+ $PATHS \
+ $ADB_TEST_BINARIES
diff --git a/adb/daemon/transport_local.cpp b/adb/daemon/transport_local.cpp
new file mode 100644
index 0000000..9e0b887
--- /dev/null
+++ b/adb/daemon/transport_local.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define TRACE_TAG TRANSPORT
+
+#include "sysdeps.h"
+#include "transport.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include <condition_variable>
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <thread>
+#include <unordered_map>
+#include <vector>
+
+#include <android-base/parsenetaddress.h>
+#include <android-base/stringprintf.h>
+#include <android-base/thread_annotations.h>
+#include <cutils/sockets.h>
+
+#if !ADB_HOST
+#include <android-base/properties.h>
+#endif
+
+#include "adb.h"
+#include "adb_io.h"
+#include "adb_unique_fd.h"
+#include "adb_utils.h"
+#include "socket_spec.h"
+#include "sysdeps/chrono.h"
+
+void server_socket_thread(std::function<unique_fd(std::string_view, std::string*)> listen_func,
+ std::string_view addr) {
+ adb_thread_setname("server socket");
+
+ unique_fd serverfd;
+ std::string error;
+
+ while (serverfd == -1) {
+ errno = 0;
+ serverfd = listen_func(addr, &error);
+ if (errno == EAFNOSUPPORT || errno == EINVAL || errno == EPROTONOSUPPORT) {
+ D("unrecoverable error: '%s'", error.c_str());
+ return;
+ } else if (serverfd < 0) {
+ D("server: cannot bind socket yet: %s", error.c_str());
+ std::this_thread::sleep_for(1s);
+ continue;
+ }
+ close_on_exec(serverfd.get());
+ }
+
+ while (true) {
+ D("server: trying to get new connection from fd %d", serverfd.get());
+ unique_fd fd(adb_socket_accept(serverfd, nullptr, nullptr));
+ if (fd >= 0) {
+ D("server: new connection on fd %d", fd.get());
+ close_on_exec(fd.get());
+ disable_tcp_nagle(fd.get());
+ std::string serial = android::base::StringPrintf("host-%d", fd.get());
+ // We don't care about port value in "register_socket_transport" as it is used
+ // only from ADB_HOST. "server_socket_thread" is never called from ADB_HOST.
+ register_socket_transport(
+ std::move(fd), std::move(serial), 0, 1,
+ [](atransport*) { return ReconnectResult::Abort; }, false);
+ }
+ }
+ D("transport: server_socket_thread() exiting");
+}
+
+unique_fd adb_listen(std::string_view addr, std::string* error) {
+ return unique_fd{socket_spec_listen(addr, error, nullptr)};
+}
+
+void local_init(const std::string& addr) {
+#if !defined(__ANDROID__)
+ // Host adbd.
+ D("transport: local server init");
+ std::thread(server_socket_thread, adb_listen, addr).detach();
+#else
+ D("transport: local server init");
+ // For the adbd daemon in the system image we need to distinguish
+ // between the device, and the emulator.
+ if (addr.starts_with("tcp:") && use_qemu_goldfish()) {
+ std::thread(qemu_socket_thread, addr).detach();
+ } else {
+ std::thread(server_socket_thread, adb_listen, addr).detach();
+ }
+#endif // !ADB_HOST
+}
+
+int init_socket_transport(atransport* t, unique_fd fd, int adb_port, int local) {
+ t->type = kTransportLocal;
+ auto fd_connection = std::make_unique<FdConnection>(std::move(fd));
+ t->SetConnection(std::make_unique<BlockingConnectionAdapter>(std::move(fd_connection)));
+ return 0;
+}
diff --git a/adb/fdevent/fdevent.cpp b/adb/fdevent/fdevent.cpp
index fd55020..70cb9b3 100644
--- a/adb/fdevent/fdevent.cpp
+++ b/adb/fdevent/fdevent.cpp
@@ -27,7 +27,10 @@
#include "adb_utils.h"
#include "fdevent.h"
#include "fdevent_epoll.h"
+
+#if !defined(__linux__)
#include "fdevent_poll.h"
+#endif
using namespace std::chrono_literals;
using std::chrono::duration_cast;
diff --git a/adb/services.cpp b/adb/services.cpp
index d87948c..19a9030 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -202,11 +202,22 @@
transport_id, &is_ambiguous, &error);
for (const auto& state : states) {
- // wait-for-disconnect uses kCsOffline, we don't actually want to wait for 'offline'.
- if ((t == nullptr && state == kCsOffline) || (t != nullptr && state == kCsAny) ||
- (t != nullptr && state == t->GetConnectionState())) {
- SendOkay(fd);
- return;
+ if (state == kCsOffline) {
+ // Special case for wait-for-disconnect:
+ // We want to wait for USB devices to completely disappear, but TCP devices can
+ // go into the offline state, since we automatically reconnect.
+ if (!t) {
+ SendOkay(fd);
+ return;
+ } else if (!t->GetUsbHandle()) {
+ SendOkay(fd);
+ return;
+ }
+ } else {
+ if (t && (state == kCsAny || state == t->GetConnectionState())) {
+ SendOkay(fd);
+ return;
+ }
}
}
diff --git a/adb/test_adb.py b/adb/test_adb.py
index c872fb0..03bdcbd 100755
--- a/adb/test_adb.py
+++ b/adb/test_adb.py
@@ -32,6 +32,8 @@
import time
import unittest
import warnings
+from importlib import util
+from parameterized import parameterized_class
def find_open_port():
# Find an open port.
@@ -576,6 +578,98 @@
# If the power event was detected, the adb shell command should be broken very quickly.
self.assertLess(end - start, 2)
+"""Use 'adb mdns check' to see if mdns discovery is available."""
+def is_adb_mdns_available():
+ with adb_server() as server_port:
+ output = subprocess.check_output(["adb", "-P", str(server_port),
+ "mdns", "check"]).strip()
+ return output.startswith(b"mdns daemon version")
+
+"""Check if we have zeroconf python library installed"""
+def is_zeroconf_installed():
+ zeroconf_spec = util.find_spec("zeroconf")
+ return zeroconf_spec is not None
+
+@contextlib.contextmanager
+def zeroconf_context(ipversion):
+ from zeroconf import Zeroconf
+ """Context manager for a zeroconf instance
+
+ This creates a zeroconf instance and returns it.
+ """
+
+ try:
+ zeroconf = Zeroconf(ip_version=ipversion)
+ yield zeroconf
+ finally:
+ zeroconf.close()
+
+@contextlib.contextmanager
+def zeroconf_register_service(zeroconf_ctx, info):
+ """Context manager for a zeroconf service
+
+ Registers a service and unregisters it on cleanup. Returns the ServiceInfo
+ supplied.
+ """
+
+ try:
+ zeroconf_ctx.register_service(info)
+ yield info
+ finally:
+ zeroconf_ctx.unregister_service(info)
+
+"""Should match the service names listed in adb_mdns.h"""
+@parameterized_class(('service_name',), [
+ ("adb",),
+ ("adb-tls-connect",),
+ ("adb-tls-pairing",),
+])
+@unittest.skipIf(not is_adb_mdns_available(), "mdns feature not available")
+class MdnsTest(unittest.TestCase):
+ """Tests for adb mdns."""
+
+ @unittest.skipIf(not is_zeroconf_installed(), "zeroconf library not installed")
+ def test_mdns_services_register_unregister(self):
+ """Ensure that `adb mdns services` correctly adds and removes a service
+ """
+ from zeroconf import IPVersion, ServiceInfo
+
+ def _mdns_services(port):
+ output = subprocess.check_output(["adb", "-P", str(port), "mdns", "services"])
+ return [x.split("\t") for x in output.decode("utf8").strip().splitlines()[1:]]
+
+ with adb_server() as server_port:
+ output = subprocess.check_output(["adb", "-P", str(server_port),
+ "mdns", "services"]).strip()
+ self.assertTrue(output.startswith(b"List of discovered mdns services"))
+ print(f"services={_mdns_services(server_port)}")
+
+ """TODO(joshuaduong): Add ipv6 tests once we have it working in adb"""
+ """Register/Unregister a service"""
+ with zeroconf_context(IPVersion.V4Only) as zc:
+ serv_instance = "my_fake_test_service"
+ serv_type = "_" + self.service_name + "._tcp."
+ serv_ipaddr = socket.inet_aton("1.2.3.4")
+ serv_port = 12345
+ service_info = ServiceInfo(
+ serv_type + "local.",
+ name=serv_instance + "." + serv_type + "local.",
+ addresses=[serv_ipaddr],
+ port=serv_port)
+ print(f"Registering {serv_instance}.{serv_type} ...")
+ with zeroconf_register_service(zc, service_info) as info:
+ """Give adb some time to register the service"""
+ time.sleep(0.25)
+ print(f"services={_mdns_services(server_port)}")
+ self.assertTrue(any((serv_instance in line and serv_type in line)
+ for line in _mdns_services(server_port)))
+
+ """Give adb some time to unregister the service"""
+ print("Unregistering mdns service...")
+ time.sleep(0.25)
+ print(f"services={_mdns_services(server_port)}")
+ self.assertFalse(any((serv_instance in line and serv_type in line)
+ for line in _mdns_services(server_port)))
def main():
"""Main entrypoint."""
diff --git a/adb/tools/Android.bp b/adb/tools/Android.bp
index 71e32b7..a7af53c 100644
--- a/adb/tools/Android.bp
+++ b/adb/tools/Android.bp
@@ -34,3 +34,26 @@
],
},
}
+
+cc_binary_host {
+ name: "adb_usbreset",
+
+ defaults: ["adb_defaults"],
+
+ srcs: [
+ "adb_usbreset.cpp",
+ ],
+
+ static_libs: [
+ "libbase",
+ "libusb",
+ ],
+
+ stl: "libc++_static",
+
+ dist: {
+ targets: [
+ "sdk",
+ ],
+ },
+}
diff --git a/adb/tools/adb_usbreset.cpp b/adb/tools/adb_usbreset.cpp
new file mode 100644
index 0000000..6f141bd
--- /dev/null
+++ b/adb/tools/adb_usbreset.cpp
@@ -0,0 +1,188 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <err.h>
+#include <getopt.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <string>
+#include <string_view>
+#include <variant>
+#include <vector>
+
+#include <libusb/libusb.h>
+
+struct AllDevices {};
+struct SingleDevice {};
+struct Serial {
+ std::string_view serial;
+};
+
+using DeviceSelection = std::variant<std::monostate, AllDevices, SingleDevice, Serial>;
+
+[[noreturn]] static void Usage(int rc) {
+ fprintf(stderr, "usage: [ANDROID_SERIAL=SERIAL] usbreset [-d] [-s SERIAL]\n");
+ fprintf(stderr, "\t-a --all\t\tReset all connected devices\n");
+ fprintf(stderr, "\t-d --device\t\tReset the single connected device\n");
+ fprintf(stderr, "\t-s --serial\t\tReset device with specified serial\n");
+ exit(rc);
+}
+
+static void SetOption(DeviceSelection* out, DeviceSelection in) {
+ if (!std::get_if<std::monostate>(out)) {
+ printf("error: multiple device selection options provided\n");
+ Usage(1);
+ }
+
+ *out = in;
+}
+
+static __attribute__((format(printf, 2, 3))) void PrintLibusbError(int err, const char* fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ vprintf(fmt, args);
+ vprintf(fmt, args);
+ va_end(args);
+
+ printf(": %s", libusb_strerror(static_cast<libusb_error>(err)));
+}
+
+static bool IsAdbInterface(const libusb_interface_descriptor* desc) {
+ return desc->bInterfaceClass == 0xFF && desc->bInterfaceSubClass == 0x42 &&
+ desc->bInterfaceProtocol == 0x1;
+}
+
+int main(int argc, char** argv) {
+ std::variant<std::monostate, AllDevices, SingleDevice, Serial> selection;
+
+ static constexpr struct option long_opts[] = {
+ {"all", 0, 0, 'a'}, {"help", 0, 0, 'h'}, {"serial", required_argument, 0, 's'},
+ {"device", 0, 0, 'd'}, {0, 0, 0, 0},
+ };
+
+ int opt;
+ while ((opt = getopt_long(argc, argv, "adhs:", long_opts, nullptr)) != -1) {
+ if (opt == 'h') {
+ Usage(0);
+ } else if (opt == 'a') {
+ SetOption(&selection, AllDevices{});
+ } else if (opt == 's') {
+ SetOption(&selection, Serial{optarg});
+ } else if (opt == 'd') {
+ SetOption(&selection, Serial{optarg});
+ } else {
+ errx(1, "unknown option: '%c'", opt);
+ }
+ }
+
+ if (std::get_if<std::monostate>(&selection)) {
+ const char* env = getenv("ANDROID_SERIAL");
+ if (env) {
+ SetOption(&selection, Serial{env});
+ } else {
+ fprintf(stderr, "adb_usbreset: no device specified\n");
+ Usage(1);
+ }
+ }
+
+ libusb_context* ctx;
+ int rc = libusb_init(&ctx);
+ if (rc != LIBUSB_SUCCESS) {
+ PrintLibusbError(rc, "error: failed to initialize libusb");
+ exit(1);
+ }
+
+ libusb_device** device_list;
+ ssize_t device_count = libusb_get_device_list(ctx, &device_list);
+ if (device_count < 0) {
+ PrintLibusbError(device_count, "error: failed to list devices");
+ exit(1);
+ }
+
+ std::vector<std::pair<std::string, libusb_device_handle*>> selected_devices;
+ for (int i = 0; i < device_count; ++i) {
+ libusb_device* device = device_list[i];
+ libusb_device_descriptor device_desc;
+
+ // Always succeeds for LIBUSB_API_VERSION >= 0x01000102.
+ libusb_get_device_descriptor(device, &device_desc);
+ static_assert(LIBUSB_API_VERSION >= 0x01000102);
+
+ libusb_config_descriptor* config_desc;
+ rc = libusb_get_active_config_descriptor(device, &config_desc);
+ if (rc != 0) {
+ PrintLibusbError(rc, "warning: failed to get config descriptor");
+ continue;
+ }
+
+ bool found_adb_interface = false;
+ for (int i = 0; i < config_desc->bNumInterfaces; ++i) {
+ if (IsAdbInterface(&config_desc->interface[i].altsetting[0])) {
+ found_adb_interface = true;
+ break;
+ }
+ }
+
+ if (found_adb_interface) {
+ libusb_device_handle* device_handle;
+ rc = libusb_open(device, &device_handle);
+ if (rc != 0) {
+ PrintLibusbError(rc, "warning: failed to open device");
+ continue;
+ }
+
+ char buf[128];
+ rc = libusb_get_string_descriptor_ascii(device_handle, device_desc.iSerialNumber,
+ reinterpret_cast<unsigned char*>(buf),
+ sizeof(buf));
+
+ if (rc < 0) {
+ PrintLibusbError(rc, "warning: failed to get device serial");
+ continue;
+ }
+
+ std::string serial(buf, buf + rc);
+ if (auto s = std::get_if<Serial>(&selection)) {
+ if (s->serial == serial) {
+ selected_devices.push_back(std::make_pair(std::move(serial), device_handle));
+ }
+ } else {
+ selected_devices.push_back(std::make_pair(std::move(serial), device_handle));
+ }
+ }
+ }
+
+ if (selected_devices.empty()) {
+ errx(1, "no devices match criteria");
+ } else if (std::get_if<SingleDevice>(&selection) && selected_devices.size() != 1) {
+ errx(1, "more than 1 device connected");
+ }
+
+ bool success = true;
+ for (auto& [serial, device_handle] : selected_devices) {
+ rc = libusb_reset_device(device_handle);
+ // libusb_reset_device will try to restore the previous state, and will return
+ // LIBUSB_ERROR_NOT_FOUND if it can't.
+ if (rc == 0 || rc == LIBUSB_ERROR_NOT_FOUND) {
+ printf("%s: successfully reset\n", serial.c_str());
+ } else {
+ PrintLibusbError(rc, "%s: failed to reset", serial.c_str());
+ success = false;
+ }
+ }
+
+ return !success;
+}
diff --git a/base/include/android-base/expected.h b/base/include/android-base/expected.h
index 9603bb1..38f0d6f 100644
--- a/base/include/android-base/expected.h
+++ b/base/include/android-base/expected.h
@@ -387,13 +387,9 @@
template<class T1, class E1, class T2, class E2>
constexpr bool operator==(const expected<T1, E1>& x, const expected<T2, E2>& y) {
- if (x.has_value() != y.has_value()) {
- return false;
- } else if (!x.has_value()) {
- return x.error() == y.error();
- } else {
- return *x == *y;
- }
+ if (x.has_value() != y.has_value()) return false;
+ if (!x.has_value()) return x.error() == y.error();
+ return *x == *y;
}
template<class T1, class E1, class T2, class E2>
@@ -581,35 +577,23 @@
template<class E1, class E2>
constexpr bool operator==(const expected<void, E1>& x, const expected<void, E2>& y) {
- if (x.has_value() != y.has_value()) {
- return false;
- } else if (!x.has_value()) {
- return x.error() == y.error();
- } else {
- return true;
- }
+ if (x.has_value() != y.has_value()) return false;
+ if (!x.has_value()) return x.error() == y.error();
+ return true;
}
template<class T1, class E1, class E2>
constexpr bool operator==(const expected<T1, E1>& x, const expected<void, E2>& y) {
- if (x.has_value() != y.has_value()) {
- return false;
- } else if (!x.has_value()) {
- return x.error() == y.error();
- } else {
- return false;
- }
+ if (x.has_value() != y.has_value()) return false;
+ if (!x.has_value()) return x.error() == y.error();
+ return false;
}
template<class E1, class T2, class E2>
constexpr bool operator==(const expected<void, E1>& x, const expected<T2, E2>& y) {
- if (x.has_value() != y.has_value()) {
- return false;
- } else if (!x.has_value()) {
- return x.error() == y.error();
- } else {
- return false;
- }
+ if (x.has_value() != y.has_value()) return false;
+ if (!x.has_value()) return x.error() == y.error();
+ return false;
}
template<class E>
diff --git a/base/logging.cpp b/base/logging.cpp
index cd460eb..3c73fea 100644
--- a/base/logging.cpp
+++ b/base/logging.cpp
@@ -195,7 +195,6 @@
return logging_lock;
}
-// Only used for Q fallback.
static LogFunction& Logger() {
#ifdef __ANDROID__
static auto& logger = *new LogFunction(LogdLogger());
@@ -205,7 +204,6 @@
return logger;
}
-// Only used for Q fallback.
static AbortFunction& Aborter() {
static auto& aborter = *new AbortFunction(DefaultAborter);
return aborter;
@@ -416,45 +414,27 @@
}
void SetLogger(LogFunction&& logger) {
+ Logger() = std::move(logger);
+
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {
- // We need to atomically swap the old and new pointers since other threads may be logging.
- // We know all threads will be using the new logger after __android_log_set_logger() returns,
- // so we can delete it then.
- // This leaks one std::function<> per instance of libbase if multiple copies of libbase within a
- // single process call SetLogger(). That is the same cost as having a static
- // std::function<>, which is the not-thread-safe alternative.
- static std::atomic<LogFunction*> logger_function(nullptr);
- auto* old_logger_function = logger_function.exchange(new LogFunction(logger));
liblog_functions->__android_log_set_logger([](const struct __android_log_message* log_message) {
auto log_id = log_id_tToLogId(log_message->buffer_id);
auto severity = PriorityToLogSeverity(log_message->priority);
- auto& function = *logger_function.load(std::memory_order_acquire);
- function(log_id, severity, log_message->tag, log_message->file, log_message->line,
+ Logger()(log_id, severity, log_message->tag, log_message->file, log_message->line,
log_message->message);
});
- delete old_logger_function;
- } else {
- std::lock_guard<std::mutex> lock(LoggingLock());
- Logger() = std::move(logger);
}
}
void SetAborter(AbortFunction&& aborter) {
+ Aborter() = std::move(aborter);
+
static auto& liblog_functions = GetLibLogFunctions();
if (liblog_functions) {
- // See the comment in SetLogger().
- static std::atomic<AbortFunction*> abort_function(nullptr);
- auto* old_abort_function = abort_function.exchange(new AbortFunction(aborter));
- liblog_functions->__android_log_set_aborter([](const char* abort_message) {
- auto& function = *abort_function.load(std::memory_order_acquire);
- function(abort_message);
- });
- delete old_abort_function;
- } else {
- std::lock_guard<std::mutex> lock(LoggingLock());
- Aborter() = std::move(aborter);
+ liblog_functions->__android_log_set_aborter(
+ [](const char* abort_message) { Aborter()(abort_message); });
}
}
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index e0168d5..d6b2e25 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -43,6 +43,7 @@
#include <android-base/unique_fd.h>
#include <android/log.h>
#include <log/log.h>
+#include <log/log_read.h>
#include <log/logprint.h>
#include <private/android_filesystem_config.h>
#include <unwindstack/DexFiles.h>
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index d496466..2f516fa 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -40,6 +40,20 @@
return true;
}
+bool LinearExtent::OverlapsWith(const LinearExtent& other) const {
+ if (device_index_ != other.device_index()) {
+ return false;
+ }
+ return physical_sector() < other.end_sector() && other.physical_sector() < end_sector();
+}
+
+bool LinearExtent::OverlapsWith(const Interval& interval) const {
+ if (device_index_ != interval.device_index) {
+ return false;
+ }
+ return physical_sector() < interval.end && interval.start < end_sector();
+}
+
Interval LinearExtent::AsInterval() const {
return Interval(device_index(), physical_sector(), end_sector());
}
@@ -774,8 +788,7 @@
bool MetadataBuilder::IsAnyRegionCovered(const std::vector<Interval>& regions,
const LinearExtent& candidate) const {
for (const auto& region : regions) {
- if (region.device_index == candidate.device_index() &&
- (candidate.OwnsSector(region.start) || candidate.OwnsSector(region.end))) {
+ if (candidate.OverlapsWith(region)) {
return true;
}
}
@@ -786,11 +799,10 @@
for (const auto& partition : partitions_) {
for (const auto& extent : partition->extents()) {
LinearExtent* linear = extent->AsLinearExtent();
- if (!linear || linear->device_index() != candidate.device_index()) {
+ if (!linear) {
continue;
}
- if (linear->OwnsSector(candidate.physical_sector()) ||
- linear->OwnsSector(candidate.end_sector() - 1)) {
+ if (linear->OverlapsWith(candidate)) {
return true;
}
}
diff --git a/fs_mgr/liblp/builder_test.cpp b/fs_mgr/liblp/builder_test.cpp
index ca8df61..977ebe3 100644
--- a/fs_mgr/liblp/builder_test.cpp
+++ b/fs_mgr/liblp/builder_test.cpp
@@ -937,3 +937,85 @@
EXPECT_EQ(exported->header.header_size, sizeof(LpMetadataHeaderV1_2));
EXPECT_EQ(exported->header.flags, 0x5e5e5e5e);
}
+
+static Interval ToInterval(const std::unique_ptr<Extent>& extent) {
+ if (LinearExtent* le = extent->AsLinearExtent()) {
+ return le->AsInterval();
+ }
+ return {0, 0, 0};
+}
+
+static void AddPartition(const std::unique_ptr<MetadataBuilder>& builder,
+ const std::string& partition_name, uint64_t num_sectors,
+ uint64_t start_sector, std::vector<Interval>* intervals) {
+ Partition* p = builder->AddPartition(partition_name, "group", 0);
+ ASSERT_NE(p, nullptr);
+ ASSERT_TRUE(builder->AddLinearExtent(p, "super", num_sectors, start_sector));
+ ASSERT_EQ(p->extents().size(), 1);
+
+ if (!intervals) {
+ return;
+ }
+
+ auto new_interval = ToInterval(p->extents().back());
+ std::vector<Interval> new_intervals = {new_interval};
+
+ auto overlap = Interval::Intersect(*intervals, new_intervals);
+ ASSERT_TRUE(overlap.empty());
+
+ intervals->push_back(new_interval);
+}
+
+TEST_F(BuilderTest, CollidedExtents) {
+ BlockDeviceInfo super("super", 8_GiB, 786432, 229376, 4096);
+ std::vector<BlockDeviceInfo> block_devices = {super};
+
+ unique_ptr<MetadataBuilder> builder = MetadataBuilder::New(block_devices, "super", 65536, 2);
+ ASSERT_NE(builder, nullptr);
+
+ ASSERT_TRUE(builder->AddGroup("group", 0));
+
+ std::vector<Interval> old_intervals;
+ AddPartition(builder, "system", 10229008, 2048, &old_intervals);
+ AddPartition(builder, "test_a", 648, 12709888, &old_intervals);
+ AddPartition(builder, "test_b", 625184, 12711936, &old_intervals);
+ AddPartition(builder, "test_c", 130912, 13338624, &old_intervals);
+ AddPartition(builder, "test_d", 888, 13469696, &old_intervals);
+ AddPartition(builder, "test_e", 888, 13471744, &old_intervals);
+ AddPartition(builder, "test_f", 888, 13475840, &old_intervals);
+ AddPartition(builder, "test_g", 888, 13477888, &old_intervals);
+
+ // Don't track the first vendor interval, since it will get extended.
+ AddPartition(builder, "vendor", 2477920, 10231808, nullptr);
+
+ std::vector<Interval> new_intervals;
+
+ Partition* p = builder->FindPartition("vendor");
+ ASSERT_NE(p, nullptr);
+ ASSERT_TRUE(builder->ResizePartition(p, 1282031616));
+ ASSERT_GE(p->extents().size(), 1);
+ for (const auto& extent : p->extents()) {
+ new_intervals.push_back(ToInterval(extent));
+ }
+
+ std::vector<Interval> overlap = Interval::Intersect(old_intervals, new_intervals);
+ ASSERT_TRUE(overlap.empty());
+}
+
+TEST_F(BuilderTest, LinearExtentOverlap) {
+ LinearExtent extent(20, 0, 10);
+
+ EXPECT_TRUE(extent.OverlapsWith(LinearExtent{20, 0, 10}));
+ EXPECT_TRUE(extent.OverlapsWith(LinearExtent{50, 0, 10}));
+ EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 0, 30}));
+ EXPECT_FALSE(extent.OverlapsWith(LinearExtent{10, 0, 0}));
+ EXPECT_TRUE(extent.OverlapsWith(LinearExtent{20, 0, 0}));
+ EXPECT_TRUE(extent.OverlapsWith(LinearExtent{40, 0, 0}));
+ EXPECT_TRUE(extent.OverlapsWith(LinearExtent{20, 0, 15}));
+
+ EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 1, 0}));
+ EXPECT_FALSE(extent.OverlapsWith(LinearExtent{50, 1, 10}));
+ EXPECT_FALSE(extent.OverlapsWith(LinearExtent{40, 1, 0}));
+ EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 1, 15}));
+ EXPECT_FALSE(extent.OverlapsWith(LinearExtent{20, 1, 10}));
+}
diff --git a/fs_mgr/liblp/device_test.cpp b/fs_mgr/liblp/device_test.cpp
index 382d53d..99bff6e 100644
--- a/fs_mgr/liblp/device_test.cpp
+++ b/fs_mgr/liblp/device_test.cpp
@@ -56,6 +56,10 @@
// Having an alignment offset > alignment doesn't really make sense.
EXPECT_LT(device_info.alignment_offset, device_info.alignment);
+
+ if (IPropertyFetcher::GetInstance()->GetBoolProperty("ro.virtual_ab.enabled", false)) {
+ EXPECT_EQ(device_info.alignment_offset, 0);
+ }
}
TEST_F(DeviceTest, ReadSuperPartitionCurrentSlot) {
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index f7738fb..bd39150 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -71,9 +71,8 @@
uint64_t end_sector() const { return physical_sector_ + num_sectors_; }
uint32_t device_index() const { return device_index_; }
- bool OwnsSector(uint64_t sector) const {
- return sector >= physical_sector_ && sector < end_sector();
- }
+ bool OverlapsWith(const LinearExtent& other) const;
+ bool OverlapsWith(const Interval& interval) const;
Interval AsInterval() const;
diff --git a/liblog/include/android/log.h b/liblog/include/android/log.h
index 512c7cd..8a0ebf2 100644
--- a/liblog/include/android/log.h
+++ b/liblog/include/android/log.h
@@ -185,14 +185,26 @@
* and sending log messages to user defined loggers specified in __android_log_set_logger().
*/
struct __android_log_message {
- size_t
- struct_size; /** Must be set to sizeof(__android_log_message) and is used for versioning. */
- int32_t buffer_id; /** {@link log_id_t} values. */
- int32_t priority; /** {@link android_LogPriority} values. */
- const char* tag; /** The tag for the log message. */
- const char* file; /** Optional file name, may be set to nullptr. */
- uint32_t line; /** Optional line number, ignore if file is nullptr. */
- const char* message; /** The log message itself. */
+ /** Must be set to sizeof(__android_log_message) and is used for versioning. */
+ size_t struct_size;
+
+ /** {@link log_id_t} values. */
+ int32_t buffer_id;
+
+ /** {@link android_LogPriority} values. */
+ int32_t priority;
+
+ /** The tag for the log message. */
+ const char* tag;
+
+ /** Optional file name, may be set to nullptr. */
+ const char* file;
+
+ /** Optional line number, ignore if file is nullptr. */
+ uint32_t line;
+
+ /** The log message itself. */
+ const char* message;
};
/**
@@ -215,7 +227,7 @@
* buffers, then pass the message to liblog via this function, and therefore we do not want to
* duplicate the loggability check here.
*
- * @param log_message the log message itself, see {@link __android_log_message}.
+ * @param log_message the log message itself, see __android_log_message.
*
* Available since API level 30.
*/
@@ -237,7 +249,7 @@
* Writes the log message to logd. This is an __android_logger_function and can be provided to
* __android_log_set_logger(). It is the default logger when running liblog on a device.
*
- * @param log_message the log message to write, see {@link __android_log_message}.
+ * @param log_message the log message to write, see __android_log_message.
*
* Available since API level 30.
*/
@@ -247,7 +259,7 @@
* Writes the log message to stderr. This is an __android_logger_function and can be provided to
* __android_log_set_logger(). It is the default logger when running liblog on host.
*
- * @param log_message the log message to write, see {@link __android_log_message}.
+ * @param log_message the log message to write, see __android_log_message.
*
* Available since API level 30.
*/
@@ -259,7 +271,7 @@
* user defined aborter function is highly recommended to abort and be noreturn, but is not strictly
* required to.
*
- * @param aborter the new aborter function, see {@link __android_aborter_function}.
+ * @param aborter the new aborter function, see __android_aborter_function.
*
* Available since API level 30.
*/
@@ -297,7 +309,26 @@
* minimum priority needed to log. If only one is set, then that value is used to determine the
* minimum priority needed. If none are set, then default_priority is used.
*
- * @param prio the priority to test, takes {@link android_LogPriority} values.
+ * @param prio the priority to test, takes android_LogPriority values.
+ * @param tag the tag to test.
+ * @param default_prio the default priority to use if no properties or minimum priority are set.
+ * @return an integer where 1 indicates that the message is loggable and 0 indicates that it is not.
+ *
+ * Available since API level 30.
+ */
+int __android_log_is_loggable(int prio, const char* tag, int default_prio) __INTRODUCED_IN(30);
+
+/**
+ * Use the per-tag properties "log.tag.<tagname>" along with the minimum priority from
+ * __android_log_set_minimum_priority() to determine if a log message with a given prio and tag will
+ * be printed. A non-zero result indicates yes, zero indicates false.
+ *
+ * If both a priority for a tag and a minimum priority are set by
+ * __android_log_set_minimum_priority(), then the lowest of the two values are to determine the
+ * minimum priority needed to log. If only one is set, then that value is used to determine the
+ * minimum priority needed. If none are set, then default_priority is used.
+ *
+ * @param prio the priority to test, takes android_LogPriority values.
* @param tag the tag to test.
* @param len the length of the tag.
* @param default_prio the default priority to use if no properties or minimum priority are set.
@@ -305,15 +336,14 @@
*
* Available since API level 30.
*/
-int __android_log_is_loggable(int prio, const char* tag, int default_prio) __INTRODUCED_IN(30);
int __android_log_is_loggable_len(int prio, const char* tag, size_t len, int default_prio)
__INTRODUCED_IN(30);
/**
* Sets the minimum priority that will be logged for this process.
*
- * @param priority the new minimum priority to set, takes @{link android_LogPriority} values.
- * @return the previous set minimum priority as @{link android_LogPriority} values, or
+ * @param priority the new minimum priority to set, takes android_LogPriority values.
+ * @return the previous set minimum priority as android_LogPriority values, or
* ANDROID_LOG_DEFAULT if none was set.
*
* Available since API level 30.
@@ -324,7 +354,7 @@
* Gets the minimum priority that will be logged for this process. If none has been set by a
* previous __android_log_set_minimum_priority() call, this returns ANDROID_LOG_DEFAULT.
*
- * @return the current minimum priority as @{link android_LogPriority} values, or
+ * @return the current minimum priority as android_LogPriority values, or
* ANDROID_LOG_DEFAULT if none is set.
*
* Available since API level 30.
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
index 19edb83..f27b8e6 100644
--- a/liblog/include/log/log.h
+++ b/liblog/include/log/log.h
@@ -29,7 +29,6 @@
#include <log/log_id.h>
#include <log/log_main.h>
#include <log/log_radio.h>
-#include <log/log_read.h>
#include <log/log_safetynet.h>
#include <log/log_system.h>
#include <log/log_time.h>
@@ -65,6 +64,13 @@
#endif
/*
+ * The maximum size of the log entry payload that can be
+ * written to the logger. An attempt to write more than
+ * this amount will result in a truncated log entry.
+ */
+#define LOGGER_ENTRY_MAX_PAYLOAD 4068
+
+/*
* Event logging.
*/
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
index e2bc297..ffd3b52 100644
--- a/liblog/include/log/log_read.h
+++ b/liblog/include/log/log_read.h
@@ -48,13 +48,6 @@
};
/*
- * The maximum size of the log entry payload that can be
- * written to the logger. An attempt to write more than
- * this amount will result in a truncated log entry.
- */
-#define LOGGER_ENTRY_MAX_PAYLOAD 4068
-
-/*
* The maximum size of a log entry which can be read.
* An attempt to read less than this amount may result
* in read() returning EINVAL.
diff --git a/liblog/logger_write.cpp b/liblog/logger_write.cpp
index d15b367..3a75fa3 100644
--- a/liblog/logger_write.cpp
+++ b/liblog/logger_write.cpp
@@ -28,7 +28,6 @@
#endif
#include <atomic>
-#include <shared_mutex>
#include <android-base/errno_restorer.h>
#include <android-base/macros.h>
@@ -38,7 +37,6 @@
#include "android/log.h"
#include "log/log_read.h"
#include "logger.h"
-#include "rwlock.h"
#include "uio.h"
#ifdef __ANDROID__
@@ -142,10 +140,8 @@
static std::string default_tag = getprogname();
return default_tag;
}
-RwLock default_tag_lock;
void __android_log_set_default_tag(const char* tag) {
- auto lock = std::unique_lock{default_tag_lock};
GetDefaultTag().assign(tag, 0, LOGGER_ENTRY_MAX_PAYLOAD);
}
@@ -163,10 +159,8 @@
#else
static __android_logger_function logger_function = __android_log_stderr_logger;
#endif
-static RwLock logger_function_lock;
void __android_log_set_logger(__android_logger_function logger) {
- auto lock = std::unique_lock{logger_function_lock};
logger_function = logger;
}
@@ -180,15 +174,12 @@
}
static __android_aborter_function aborter_function = __android_log_default_aborter;
-static RwLock aborter_function_lock;
void __android_log_set_aborter(__android_aborter_function aborter) {
- auto lock = std::unique_lock{aborter_function_lock};
aborter_function = aborter;
}
void __android_log_call_aborter(const char* abort_message) {
- auto lock = std::shared_lock{aborter_function_lock};
aborter_function(abort_message);
}
@@ -310,9 +301,7 @@
return;
}
- auto tag_lock = std::shared_lock{default_tag_lock, std::defer_lock};
if (log_message->tag == nullptr) {
- tag_lock.lock();
log_message->tag = GetDefaultTag().c_str();
}
@@ -322,7 +311,6 @@
}
#endif
- auto lock = std::shared_lock{logger_function_lock};
logger_function(log_message);
}
diff --git a/liblog/logger_write.h b/liblog/logger_write.h
index 065fd55..eee2778 100644
--- a/liblog/logger_write.h
+++ b/liblog/logger_write.h
@@ -18,7 +18,4 @@
#include <string>
-#include "rwlock.h"
-
-std::string& GetDefaultTag(); // Must read lock default_tag_lock
-extern RwLock default_tag_lock;
\ No newline at end of file
+std::string& GetDefaultTag();
diff --git a/liblog/logprint.cpp b/liblog/logprint.cpp
index 5c69bf8..9e8d277 100644
--- a/liblog/logprint.cpp
+++ b/liblog/logprint.cpp
@@ -19,6 +19,8 @@
#define HAVE_STRSEP
#endif
+#include <log/logprint.h>
+
#include <assert.h>
#include <ctype.h>
#include <errno.h>
@@ -37,7 +39,7 @@
#include <cutils/list.h>
#include <log/log.h>
-#include <log/logprint.h>
+#include <log/log_read.h>
#include <private/android_logger.h>
#define MS_PER_NSEC 1000000
diff --git a/liblog/properties.cpp b/liblog/properties.cpp
index abd48fc..37670ec 100644
--- a/liblog/properties.cpp
+++ b/liblog/properties.cpp
@@ -23,7 +23,6 @@
#include <unistd.h>
#include <algorithm>
-#include <shared_mutex>
#include <private/android_logger.h>
@@ -99,9 +98,7 @@
static const char log_namespace[] = "persist.log.tag.";
static const size_t base_offset = 8; /* skip "persist." */
- auto tag_lock = std::shared_lock{default_tag_lock, std::defer_lock};
if (tag == nullptr || len == 0) {
- tag_lock.lock();
auto& tag_string = GetDefaultTag();
tag = tag_string.c_str();
len = tag_string.size();
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 3a6ed90..f4734b9 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -31,6 +31,7 @@
#include <benchmark/benchmark.h>
#include <cutils/sockets.h>
#include <log/event_tag_map.h>
+#include <log/log_read.h>
#include <private/android_logger.h>
BENCHMARK_MAIN();
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index 048bf61..d3d8e91 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -40,6 +40,7 @@
#include <gtest/gtest.h>
#include <log/log_event_list.h>
#include <log/log_properties.h>
+#include <log/log_read.h>
#include <log/logprint.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
diff --git a/libutils/include/utils/Looper.h b/libutils/include/utils/Looper.h
index c439c5c..466fbb7 100644
--- a/libutils/include/utils/Looper.h
+++ b/libutils/include/utils/Looper.h
@@ -26,6 +26,8 @@
#include <android-base/unique_fd.h>
+#include <utility>
+
namespace android {
/*
@@ -438,9 +440,8 @@
struct MessageEnvelope {
MessageEnvelope() : uptime(0) { }
- MessageEnvelope(nsecs_t u, const sp<MessageHandler> h,
- const Message& m) : uptime(u), handler(h), message(m) {
- }
+ MessageEnvelope(nsecs_t u, sp<MessageHandler> h, const Message& m)
+ : uptime(u), handler(std::move(h)), message(m) {}
nsecs_t uptime;
sp<MessageHandler> handler;
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index b065855..8185f01 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -50,6 +50,7 @@
#include <android/log.h>
#include <log/event_tag_map.h>
#include <log/log_id.h>
+#include <log/log_read.h>
#include <log/logprint.h>
#include <private/android_logger.h>
#include <processgroup/sched_policy.h>
@@ -122,6 +123,18 @@
return fd;
}
+static void closeLogFile(const char* pathname) {
+ int fd = open(pathname, O_WRONLY | O_CLOEXEC);
+ if (fd == -1) {
+ return;
+ }
+
+ // no need to check errors
+ __u32 set = 0;
+ ioctl(fd, F2FS_IOC_SET_PIN_FILE, &set);
+ close(fd);
+}
+
void Logcat::RotateLogs() {
// Can't rotate logs if we're not outputting to a file
if (!output_file_name_) return;
@@ -152,6 +165,8 @@
break;
}
+ closeLogFile(file0.c_str());
+
int err = rename(file0.c_str(), file1.c_str());
if (err < 0 && errno != ENOENT) {
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 3714800..916ed42 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -22,6 +22,7 @@
#include <time.h>
#include <unistd.h>
+#include <log/log_read.h>
#include <private/android_logger.h>
#include "LogBuffer.h"
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index 8299e66..e45cc8a 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -34,6 +34,7 @@
#include <android-base/stringprintf.h>
#include <log/log_event_list.h>
#include <log/log_properties.h>
+#include <log/log_read.h>
#include <private/android_filesystem_config.h>
#include "LogTags.h"
diff --git a/logd/tests/logd_test.cpp b/logd/tests/logd_test.cpp
index d57b79e..b092489 100644
--- a/logd/tests/logd_test.cpp
+++ b/logd/tests/logd_test.cpp
@@ -32,6 +32,7 @@
#include <android-base/stringprintf.h>
#include <cutils/sockets.h>
#include <gtest/gtest.h>
+#include <log/log_read.h>
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
#ifdef __ANDROID__