Merge "adbd: compile for host."
am: b42946a6d3
Change-Id: Ib47212e298198fcd7f2a4be7f158c313a6e321d5
This commit is contained in:
commit
134576deba
18 changed files with 578 additions and 308 deletions
131
adb/Android.bp
131
adb/Android.bp
|
|
@ -22,35 +22,16 @@ cc_defaults {
|
||||||
"-Wexit-time-destructors",
|
"-Wexit-time-destructors",
|
||||||
"-Wno-unused-parameter",
|
"-Wno-unused-parameter",
|
||||||
"-Wno-missing-field-initializers",
|
"-Wno-missing-field-initializers",
|
||||||
|
"-Wthread-safety",
|
||||||
"-Wvla",
|
"-Wvla",
|
||||||
|
"-DADB_HOST=1", // overridden by adbd_defaults
|
||||||
],
|
],
|
||||||
cpp_std: "experimental",
|
cpp_std: "experimental",
|
||||||
|
|
||||||
use_version_lib: true,
|
use_version_lib: true,
|
||||||
|
|
||||||
compile_multilib: "first",
|
compile_multilib: "first",
|
||||||
product_variables: {
|
|
||||||
debuggable: {
|
|
||||||
cflags: [
|
|
||||||
"-DALLOW_ADBD_ROOT",
|
|
||||||
"-DALLOW_ADBD_DISABLE_VERITY",
|
|
||||||
"-DALLOW_ADBD_NO_AUTH",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
target: {
|
target: {
|
||||||
android: {
|
|
||||||
cflags: [
|
|
||||||
"-DADB_HOST=0",
|
|
||||||
"-Wthread-safety",
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
host: {
|
|
||||||
cflags: ["-DADB_HOST=1"],
|
|
||||||
},
|
|
||||||
|
|
||||||
darwin: {
|
darwin: {
|
||||||
host_ldlibs: [
|
host_ldlibs: [
|
||||||
"-lpthread",
|
"-lpthread",
|
||||||
|
|
@ -76,6 +57,9 @@ cc_defaults {
|
||||||
|
|
||||||
// MinGW hides some things behind _POSIX_SOURCE.
|
// MinGW hides some things behind _POSIX_SOURCE.
|
||||||
"-D_POSIX_SOURCE",
|
"-D_POSIX_SOURCE",
|
||||||
|
|
||||||
|
// Not supported yet.
|
||||||
|
"-Wno-thread-safety",
|
||||||
],
|
],
|
||||||
|
|
||||||
host_ldlibs: [
|
host_ldlibs: [
|
||||||
|
|
@ -84,15 +68,46 @@ cc_defaults {
|
||||||
"-luserenv",
|
"-luserenv",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
not_windows: {
|
cc_defaults {
|
||||||
|
name: "adbd_defaults",
|
||||||
|
defaults: ["adb_defaults"],
|
||||||
|
|
||||||
|
cflags: ["-UADB_HOST", "-DADB_HOST=0"],
|
||||||
|
product_variables: {
|
||||||
|
debuggable: {
|
||||||
cflags: [
|
cflags: [
|
||||||
"-Wthread-safety",
|
"-DALLOW_ADBD_ROOT",
|
||||||
|
"-DALLOW_ADBD_DISABLE_VERITY",
|
||||||
|
"-DALLOW_ADBD_NO_AUTH",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_defaults {
|
||||||
|
name: "host_adbd_supported",
|
||||||
|
|
||||||
|
host_supported: true,
|
||||||
|
target: {
|
||||||
|
linux: {
|
||||||
|
enabled: true,
|
||||||
|
host_ldlibs: [
|
||||||
|
"-lresolv", // b64_pton
|
||||||
|
"-lutil", // forkpty
|
||||||
|
],
|
||||||
|
},
|
||||||
|
darwin: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
windows: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// libadb
|
// libadb
|
||||||
// =========================================================
|
// =========================================================
|
||||||
// These files are compiled for both the host and the device.
|
// These files are compiled for both the host and the device.
|
||||||
|
|
@ -313,7 +328,7 @@ cc_binary_host {
|
||||||
// libadbd_core contains the common sources to build libadbd and libadbd_services.
|
// libadbd_core contains the common sources to build libadbd and libadbd_services.
|
||||||
cc_library_static {
|
cc_library_static {
|
||||||
name: "libadbd_core",
|
name: "libadbd_core",
|
||||||
defaults: ["adb_defaults"],
|
defaults: ["adbd_defaults", "host_adbd_supported"],
|
||||||
recovery_available: true,
|
recovery_available: true,
|
||||||
|
|
||||||
// libminadbd wants both, as it's used to build native tests.
|
// libminadbd wants both, as it's used to build native tests.
|
||||||
|
|
@ -322,9 +337,6 @@ cc_library_static {
|
||||||
srcs: libadb_srcs + libadb_posix_srcs + [
|
srcs: libadb_srcs + libadb_posix_srcs + [
|
||||||
"daemon/auth.cpp",
|
"daemon/auth.cpp",
|
||||||
"daemon/jdwp_service.cpp",
|
"daemon/jdwp_service.cpp",
|
||||||
"daemon/usb.cpp",
|
|
||||||
"daemon/usb_ffs.cpp",
|
|
||||||
"daemon/usb_legacy.cpp",
|
|
||||||
],
|
],
|
||||||
|
|
||||||
local_include_dirs: [
|
local_include_dirs: [
|
||||||
|
|
@ -335,7 +347,6 @@ cc_library_static {
|
||||||
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"libdiagnose_usb",
|
"libdiagnose_usb",
|
||||||
"libqemu_pipe",
|
|
||||||
],
|
],
|
||||||
|
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
|
|
@ -346,22 +357,36 @@ cc_library_static {
|
||||||
"libcutils",
|
"libcutils",
|
||||||
"liblog",
|
"liblog",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
target: {
|
||||||
|
android: {
|
||||||
|
whole_static_libs: [
|
||||||
|
"libqemu_pipe",
|
||||||
|
],
|
||||||
|
srcs: [
|
||||||
|
"daemon/transport_qemu.cpp",
|
||||||
|
"daemon/usb.cpp",
|
||||||
|
"daemon/usb_ffs.cpp",
|
||||||
|
"daemon/usb_legacy.cpp",
|
||||||
|
]
|
||||||
|
},
|
||||||
|
linux_glibc: {
|
||||||
|
srcs: [
|
||||||
|
"daemon/usb_dummy.cpp",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_library {
|
cc_library {
|
||||||
name: "libadbd_services",
|
name: "libadbd_services",
|
||||||
defaults: ["adb_defaults"],
|
defaults: ["adbd_defaults", "host_adbd_supported"],
|
||||||
recovery_available: true,
|
recovery_available: true,
|
||||||
compile_multilib: "both",
|
compile_multilib: "both",
|
||||||
|
|
||||||
srcs: [
|
srcs: [
|
||||||
"daemon/abb_service.cpp",
|
|
||||||
"daemon/file_sync_service.cpp",
|
"daemon/file_sync_service.cpp",
|
||||||
"daemon/framebuffer_service.cpp",
|
|
||||||
"daemon/mdns.cpp",
|
|
||||||
"daemon/remount_service.cpp",
|
|
||||||
"daemon/services.cpp",
|
"daemon/services.cpp",
|
||||||
"daemon/set_verity_enable_state_service.cpp",
|
|
||||||
"daemon/shell_service.cpp",
|
"daemon/shell_service.cpp",
|
||||||
"shell_service_protocol.cpp",
|
"shell_service_protocol.cpp",
|
||||||
],
|
],
|
||||||
|
|
@ -373,27 +398,41 @@ cc_library {
|
||||||
|
|
||||||
static_libs: [
|
static_libs: [
|
||||||
"libadbd_core",
|
"libadbd_core",
|
||||||
"libavb_user",
|
|
||||||
"libdiagnose_usb",
|
"libdiagnose_usb",
|
||||||
"libqemu_pipe",
|
|
||||||
],
|
],
|
||||||
|
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libasyncio",
|
"libasyncio",
|
||||||
"libbase",
|
"libbase",
|
||||||
"libbootloader_message",
|
|
||||||
"libcrypto",
|
"libcrypto",
|
||||||
"libcrypto_utils",
|
"libcrypto_utils",
|
||||||
"libcutils",
|
"libcutils",
|
||||||
"libext4_utils",
|
|
||||||
"libfec",
|
|
||||||
"libfs_mgr",
|
|
||||||
"liblog",
|
"liblog",
|
||||||
"libmdnssd",
|
|
||||||
"libselinux",
|
|
||||||
],
|
],
|
||||||
|
|
||||||
target: {
|
target: {
|
||||||
|
android: {
|
||||||
|
srcs: [
|
||||||
|
"daemon/abb_service.cpp",
|
||||||
|
"daemon/framebuffer_service.cpp",
|
||||||
|
"daemon/mdns.cpp",
|
||||||
|
"daemon/reboot_service.cpp",
|
||||||
|
"daemon/remount_service.cpp",
|
||||||
|
"daemon/restart_service.cpp",
|
||||||
|
"daemon/set_verity_enable_state_service.cpp",
|
||||||
|
],
|
||||||
|
static_libs: [
|
||||||
|
"libavb_user",
|
||||||
|
],
|
||||||
|
shared_libs: [
|
||||||
|
"libbootloader_message",
|
||||||
|
"libmdnssd",
|
||||||
|
"libext4_utils",
|
||||||
|
"libfec",
|
||||||
|
"libfs_mgr",
|
||||||
|
"libselinux",
|
||||||
|
],
|
||||||
|
},
|
||||||
recovery: {
|
recovery: {
|
||||||
exclude_srcs: [
|
exclude_srcs: [
|
||||||
"daemon/abb_service.cpp",
|
"daemon/abb_service.cpp",
|
||||||
|
|
@ -404,7 +443,7 @@ cc_library {
|
||||||
|
|
||||||
cc_library {
|
cc_library {
|
||||||
name: "libadbd",
|
name: "libadbd",
|
||||||
defaults: ["adb_defaults"],
|
defaults: ["adbd_defaults", "host_adbd_supported"],
|
||||||
recovery_available: true,
|
recovery_available: true,
|
||||||
|
|
||||||
// Avoid getting duplicate symbol of android::build::GetBuildNumber().
|
// Avoid getting duplicate symbol of android::build::GetBuildNumber().
|
||||||
|
|
@ -435,7 +474,7 @@ cc_library {
|
||||||
|
|
||||||
cc_binary {
|
cc_binary {
|
||||||
name: "adbd",
|
name: "adbd",
|
||||||
defaults: ["adb_defaults"],
|
defaults: ["adbd_defaults", "host_adbd_supported"],
|
||||||
recovery_available: true,
|
recovery_available: true,
|
||||||
|
|
||||||
srcs: [
|
srcs: [
|
||||||
|
|
@ -467,7 +506,7 @@ cc_binary {
|
||||||
cc_binary {
|
cc_binary {
|
||||||
name: "abb",
|
name: "abb",
|
||||||
|
|
||||||
defaults: ["adb_defaults"],
|
defaults: ["adbd_defaults"],
|
||||||
recovery_available: false,
|
recovery_available: false,
|
||||||
|
|
||||||
srcs: [
|
srcs: [
|
||||||
|
|
@ -500,7 +539,7 @@ cc_binary {
|
||||||
|
|
||||||
cc_test {
|
cc_test {
|
||||||
name: "adbd_test",
|
name: "adbd_test",
|
||||||
defaults: ["adb_defaults"],
|
defaults: ["adbd_defaults"],
|
||||||
srcs: libadb_test_srcs + [
|
srcs: libadb_test_srcs + [
|
||||||
"daemon/services.cpp",
|
"daemon/services.cpp",
|
||||||
"daemon/shell_service.cpp",
|
"daemon/shell_service.cpp",
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,9 @@
|
||||||
|
|
||||||
#if !ADB_HOST
|
#if !ADB_HOST
|
||||||
const char* adb_device_banner = "device";
|
const char* adb_device_banner = "device";
|
||||||
|
#if defined(__ANDROID__)
|
||||||
static android::base::LogdLogger gLogdLogger;
|
static android::base::LogdLogger gLogdLogger;
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
const char* adb_device_banner = "host";
|
const char* adb_device_banner = "host";
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -46,7 +48,7 @@ void AdbLogger(android::base::LogId id, android::base::LogSeverity severity,
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !ADB_HOST
|
#if !ADB_HOST && defined(__ANDROID__)
|
||||||
// Only print logs of INFO or higher to logcat, so that `adb logcat` with adbd tracing on
|
// Only print logs of INFO or higher to logcat, so that `adb logcat` with adbd tracing on
|
||||||
// doesn't result in exponential logging.
|
// doesn't result in exponential logging.
|
||||||
if (severity >= android::base::INFO) {
|
if (severity >= android::base::INFO) {
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ bool adbd_auth_verify(const char* token, size_t token_size, const std::string& s
|
||||||
// b64_pton requires one additional byte in the target buffer for
|
// b64_pton requires one additional byte in the target buffer for
|
||||||
// decoding to succeed. See http://b/28035006 for details.
|
// decoding to succeed. See http://b/28035006 for details.
|
||||||
uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
|
uint8_t keybuf[ANDROID_PUBKEY_ENCODED_SIZE + 1];
|
||||||
if (__b64_pton(line.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) {
|
if (b64_pton(line.c_str(), keybuf, sizeof(keybuf)) != ANDROID_PUBKEY_ENCODED_SIZE) {
|
||||||
LOG(ERROR) << "Invalid base64 key " << line.c_str() << " in " << path;
|
LOG(ERROR) << "Invalid base64 key " << line.c_str() << " in " << path;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,11 @@
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <linux/xattr.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/xattr.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
|
|
||||||
|
|
@ -37,11 +35,17 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <android-base/file.h>
|
#include <android-base/file.h>
|
||||||
|
#include <android-base/macros.h>
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
|
|
||||||
#include <private/android_filesystem_config.h>
|
#include <private/android_filesystem_config.h>
|
||||||
#include <private/android_logger.h>
|
#include <private/android_logger.h>
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
#include <selinux/android.h>
|
#include <selinux/android.h>
|
||||||
|
#include <sys/xattr.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
#include "adb_io.h"
|
#include "adb_io.h"
|
||||||
|
|
@ -55,11 +59,17 @@ using android::base::Dirname;
|
||||||
using android::base::StringPrintf;
|
using android::base::StringPrintf;
|
||||||
|
|
||||||
static bool should_use_fs_config(const std::string& path) {
|
static bool should_use_fs_config(const std::string& path) {
|
||||||
|
#if defined(__ANDROID__)
|
||||||
// TODO: use fs_config to configure permissions on /data too.
|
// TODO: use fs_config to configure permissions on /data too.
|
||||||
return !android::base::StartsWith(path, "/data/");
|
return !android::base::StartsWith(path, "/data/");
|
||||||
|
#else
|
||||||
|
UNUSED(path);
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool update_capabilities(const char* path, uint64_t capabilities) {
|
static bool update_capabilities(const char* path, uint64_t capabilities) {
|
||||||
|
#if defined(__ANDROID__)
|
||||||
if (capabilities == 0) {
|
if (capabilities == 0) {
|
||||||
// Ensure we clean up in case the capabilities weren't 0 in the past.
|
// Ensure we clean up in case the capabilities weren't 0 in the past.
|
||||||
removexattr(path, XATTR_NAME_CAPS);
|
removexattr(path, XATTR_NAME_CAPS);
|
||||||
|
|
@ -73,6 +83,10 @@ static bool update_capabilities(const char* path, uint64_t capabilities) {
|
||||||
cap_data.data[1].permitted = (capabilities >> 32);
|
cap_data.data[1].permitted = (capabilities >> 32);
|
||||||
cap_data.data[1].inheritable = 0;
|
cap_data.data[1].inheritable = 0;
|
||||||
return setxattr(path, XATTR_NAME_CAPS, &cap_data, sizeof(cap_data), 0) != -1;
|
return setxattr(path, XATTR_NAME_CAPS, &cap_data, sizeof(cap_data), 0) != -1;
|
||||||
|
#else
|
||||||
|
UNUSED(path, capabilities);
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool secure_mkdirs(const std::string& path) {
|
static bool secure_mkdirs(const std::string& path) {
|
||||||
|
|
@ -105,8 +119,10 @@ static bool secure_mkdirs(const std::string& path) {
|
||||||
} else {
|
} else {
|
||||||
if (chown(partial_path.c_str(), uid, gid) == -1) return false;
|
if (chown(partial_path.c_str(), uid, gid) == -1) return false;
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
// Not all filesystems support setting SELinux labels. http://b/23530370.
|
// Not all filesystems support setting SELinux labels. http://b/23530370.
|
||||||
selinux_android_restorecon(partial_path.c_str(), 0);
|
selinux_android_restorecon(partial_path.c_str(), 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!update_capabilities(partial_path.c_str(), capabilities)) return false;
|
if (!update_capabilities(partial_path.c_str(), capabilities)) return false;
|
||||||
}
|
}
|
||||||
|
|
@ -242,8 +258,10 @@ static bool handle_send_file(int s, const char* path, uid_t uid, gid_t gid, uint
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
// Not all filesystems support setting SELinux labels. http://b/23530370.
|
// Not all filesystems support setting SELinux labels. http://b/23530370.
|
||||||
selinux_android_restorecon(path, 0);
|
selinux_android_restorecon(path, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
// fchown clears the setuid bit - restore it if present.
|
// fchown clears the setuid bit - restore it if present.
|
||||||
// Ignore the result of calling fchmod. It's not supported
|
// Ignore the result of calling fchmod. It's not supported
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,6 @@
|
||||||
|
|
||||||
#include "adb_unique_fd.h"
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
void framebuffer_service(unique_fd fd);
|
void framebuffer_service(unique_fd fd);
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,10 @@
|
||||||
|
|
||||||
#include "sysdeps.h"
|
#include "sysdeps.h"
|
||||||
|
|
||||||
|
#if defined(__BIONIC__)
|
||||||
#include <android/fdsan.h>
|
#include <android/fdsan.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
@ -34,12 +37,15 @@
|
||||||
#include <android-base/macros.h>
|
#include <android-base/macros.h>
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
#include <libminijail.h>
|
#include <libminijail.h>
|
||||||
#include <log/log_properties.h>
|
#include <log/log_properties.h>
|
||||||
#include <scoped_minijail.h>
|
#include <scoped_minijail.h>
|
||||||
|
|
||||||
#include <private/android_filesystem_config.h>
|
#include <private/android_filesystem_config.h>
|
||||||
#include "selinux/android.h"
|
#include "selinux/android.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
#include "adb_auth.h"
|
#include "adb_auth.h"
|
||||||
|
|
@ -49,6 +55,7 @@
|
||||||
|
|
||||||
#include "mdns.h"
|
#include "mdns.h"
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
static const char* root_seclabel = nullptr;
|
static const char* root_seclabel = nullptr;
|
||||||
|
|
||||||
static bool should_drop_capabilities_bounding_set() {
|
static bool should_drop_capabilities_bounding_set() {
|
||||||
|
|
@ -167,10 +174,14 @@ static void drop_privileges(int server_port) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void setup_port(int port) {
|
static void setup_port(int port) {
|
||||||
|
LOG(INFO) << "adbd listening on port " << port;
|
||||||
local_init(port);
|
local_init(port);
|
||||||
|
#if defined(__ANDROID__)
|
||||||
setup_mdns(port);
|
setup_mdns(port);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int adbd_main(int server_port) {
|
int adbd_main(int server_port) {
|
||||||
|
|
@ -178,10 +189,12 @@ int adbd_main(int server_port) {
|
||||||
|
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
#if defined(__BIONIC__)
|
||||||
auto fdsan_level = android_fdsan_get_error_level();
|
auto fdsan_level = android_fdsan_get_error_level();
|
||||||
if (fdsan_level == ANDROID_FDSAN_ERROR_LEVEL_DISABLED) {
|
if (fdsan_level == ANDROID_FDSAN_ERROR_LEVEL_DISABLED) {
|
||||||
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
|
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_WARN_ONCE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
init_transport_registration();
|
init_transport_registration();
|
||||||
|
|
||||||
|
|
@ -206,14 +219,19 @@ int adbd_main(int server_port) {
|
||||||
" unchanged.\n");
|
" unchanged.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
drop_privileges(server_port);
|
drop_privileges(server_port);
|
||||||
|
#endif
|
||||||
|
|
||||||
bool is_usb = false;
|
bool is_usb = false;
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
|
if (access(USB_FFS_ADB_EP0, F_OK) == 0) {
|
||||||
// Listen on USB.
|
// Listen on USB.
|
||||||
usb_init();
|
usb_init();
|
||||||
is_usb = true;
|
is_usb = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// If one of these properties is set, also listen on that port.
|
// If one of these properties is set, also listen on that port.
|
||||||
// If one of the properties isn't set and we couldn't listen on usb, listen
|
// If one of the properties isn't set and we couldn't listen on usb, listen
|
||||||
|
|
@ -244,8 +262,10 @@ int adbd_main(int server_port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
#if defined(__BIONIC__)
|
||||||
// Set M_DECAY_TIME so that our allocations aren't immediately purged on free.
|
// Set M_DECAY_TIME so that our allocations aren't immediately purged on free.
|
||||||
mallopt(M_DECAY_TIME, 1);
|
mallopt(M_DECAY_TIME, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
static struct option opts[] = {
|
static struct option opts[] = {
|
||||||
|
|
@ -261,19 +281,21 @@ int main(int argc, char** argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 's':
|
#if defined(__ANDROID__)
|
||||||
root_seclabel = optarg;
|
case 's':
|
||||||
break;
|
root_seclabel = optarg;
|
||||||
case 'b':
|
break;
|
||||||
adb_device_banner = optarg;
|
#endif
|
||||||
break;
|
case 'b':
|
||||||
case 'v':
|
adb_device_banner = optarg;
|
||||||
printf("Android Debug Bridge Daemon version %d.%d.%d\n", ADB_VERSION_MAJOR,
|
break;
|
||||||
ADB_VERSION_MINOR, ADB_SERVER_VERSION);
|
case 'v':
|
||||||
return 0;
|
printf("Android Debug Bridge Daemon version %d.%d.%d\n", ADB_VERSION_MAJOR,
|
||||||
default:
|
ADB_VERSION_MINOR, ADB_SERVER_VERSION);
|
||||||
// getopt already prints "adbd: invalid option -- %c" for us.
|
return 0;
|
||||||
return 1;
|
default:
|
||||||
|
// getopt already prints "adbd: invalid option -- %c" for us.
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
84
adb/daemon/reboot_service.cpp
Normal file
84
adb/daemon/reboot_service.cpp
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 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 SERVICES
|
||||||
|
|
||||||
|
#include "sysdeps.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <android-base/logging.h>
|
||||||
|
#include <android-base/properties.h>
|
||||||
|
#include <android-base/stringprintf.h>
|
||||||
|
#include <bootloader_message/bootloader_message.h>
|
||||||
|
#include <cutils/android_reboot.h>
|
||||||
|
|
||||||
|
#include "adb_io.h"
|
||||||
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
void reboot_service(unique_fd fd, const std::string& arg) {
|
||||||
|
std::string reboot_arg = arg;
|
||||||
|
sync();
|
||||||
|
|
||||||
|
if (reboot_arg.empty()) reboot_arg = "adb";
|
||||||
|
std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());
|
||||||
|
|
||||||
|
if (reboot_arg == "fastboot" &&
|
||||||
|
android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
|
||||||
|
access("/dev/socket/recovery", F_OK) == 0) {
|
||||||
|
LOG(INFO) << "Recovery specific reboot fastboot";
|
||||||
|
/*
|
||||||
|
* The socket is created to allow switching between recovery and
|
||||||
|
* fastboot.
|
||||||
|
*/
|
||||||
|
android::base::unique_fd sock(socket(AF_UNIX, SOCK_STREAM, 0));
|
||||||
|
if (sock < 0) {
|
||||||
|
WriteFdFmt(fd, "reboot (%s) create\n", strerror(errno));
|
||||||
|
PLOG(ERROR) << "Creating recovery socket failed";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_un addr = {.sun_family = AF_UNIX};
|
||||||
|
strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1);
|
||||||
|
if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
|
||||||
|
WriteFdFmt(fd, "reboot (%s) connect\n", strerror(errno));
|
||||||
|
PLOG(ERROR) << "Couldn't connect to recovery socket";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const char msg_switch_to_fastboot = 'f';
|
||||||
|
auto ret = adb_write(sock, &msg_switch_to_fastboot, sizeof(msg_switch_to_fastboot));
|
||||||
|
if (ret != sizeof(msg_switch_to_fastboot)) {
|
||||||
|
WriteFdFmt(fd, "reboot (%s) write\n", strerror(errno));
|
||||||
|
PLOG(ERROR) << "Couldn't write message to recovery socket to switch to fastboot";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
|
||||||
|
WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't return early. Give the reboot command time to take effect
|
||||||
|
// to avoid messing up scripts which do "adb reboot && adb wait-for-device"
|
||||||
|
while (true) {
|
||||||
|
pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
25
adb/daemon/reboot_service.h
Normal file
25
adb/daemon/reboot_service.h
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
void reboot_service(unique_fd fd, const std::string& arg);
|
||||||
|
#endif
|
||||||
|
|
@ -20,5 +20,7 @@
|
||||||
|
|
||||||
#include "adb_unique_fd.h"
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
bool make_block_device_writable(const std::string&);
|
bool make_block_device_writable(const std::string&);
|
||||||
void remount_service(unique_fd, const std::string&);
|
void remount_service(unique_fd, const std::string&);
|
||||||
|
#endif
|
||||||
|
|
|
||||||
66
adb/daemon/restart_service.cpp
Normal file
66
adb/daemon/restart_service.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 SERVICES
|
||||||
|
|
||||||
|
#include "sysdeps.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <android-base/properties.h>
|
||||||
|
#include <android-base/stringprintf.h>
|
||||||
|
#include <log/log_properties.h>
|
||||||
|
|
||||||
|
#include "adb_io.h"
|
||||||
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
void restart_root_service(unique_fd fd) {
|
||||||
|
if (getuid() == 0) {
|
||||||
|
WriteFdExactly(fd.get(), "adbd is already running as root\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!__android_log_is_debuggable()) {
|
||||||
|
WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
android::base::SetProperty("service.adb.root", "1");
|
||||||
|
WriteFdExactly(fd.get(), "restarting adbd as root\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void restart_unroot_service(unique_fd fd) {
|
||||||
|
if (getuid() != 0) {
|
||||||
|
WriteFdExactly(fd.get(), "adbd not running as root\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
android::base::SetProperty("service.adb.root", "0");
|
||||||
|
WriteFdExactly(fd.get(), "restarting adbd as non root\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void restart_tcp_service(unique_fd fd, int port) {
|
||||||
|
if (port <= 0) {
|
||||||
|
WriteFdFmt(fd.get(), "invalid port %d\n", port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port));
|
||||||
|
WriteFdFmt(fd.get(), "restarting in TCP mode port: %d\n", port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void restart_usb_service(unique_fd fd) {
|
||||||
|
android::base::SetProperty("service.adb.tcp.port", "0");
|
||||||
|
WriteFdExactly(fd.get(), "restarting in USB mode\n");
|
||||||
|
}
|
||||||
26
adb/daemon/restart_service.h
Normal file
26
adb/daemon/restart_service.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
void restart_root_service(unique_fd fd);
|
||||||
|
void restart_unroot_service(unique_fd fd);
|
||||||
|
void restart_tcp_service(unique_fd fd, int port);
|
||||||
|
void restart_usb_service(unique_fd fd);
|
||||||
|
#endif
|
||||||
|
|
@ -39,8 +39,6 @@
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
#include <android-base/unique_fd.h>
|
#include <android-base/unique_fd.h>
|
||||||
#include <bootloader_message/bootloader_message.h>
|
|
||||||
#include <cutils/android_reboot.h>
|
|
||||||
#include <cutils/sockets.h>
|
#include <cutils/sockets.h>
|
||||||
#include <log/log_properties.h>
|
#include <log/log_properties.h>
|
||||||
|
|
||||||
|
|
@ -55,96 +53,12 @@
|
||||||
|
|
||||||
#include "daemon/file_sync_service.h"
|
#include "daemon/file_sync_service.h"
|
||||||
#include "daemon/framebuffer_service.h"
|
#include "daemon/framebuffer_service.h"
|
||||||
|
#include "daemon/reboot_service.h"
|
||||||
#include "daemon/remount_service.h"
|
#include "daemon/remount_service.h"
|
||||||
|
#include "daemon/restart_service.h"
|
||||||
#include "daemon/set_verity_enable_state_service.h"
|
#include "daemon/set_verity_enable_state_service.h"
|
||||||
#include "daemon/shell_service.h"
|
#include "daemon/shell_service.h"
|
||||||
|
|
||||||
void restart_root_service(unique_fd fd) {
|
|
||||||
if (getuid() == 0) {
|
|
||||||
WriteFdExactly(fd.get(), "adbd is already running as root\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!__android_log_is_debuggable()) {
|
|
||||||
WriteFdExactly(fd.get(), "adbd cannot run as root in production builds\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
android::base::SetProperty("service.adb.root", "1");
|
|
||||||
WriteFdExactly(fd.get(), "restarting adbd as root\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void restart_unroot_service(unique_fd fd) {
|
|
||||||
if (getuid() != 0) {
|
|
||||||
WriteFdExactly(fd.get(), "adbd not running as root\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
android::base::SetProperty("service.adb.root", "0");
|
|
||||||
WriteFdExactly(fd.get(), "restarting adbd as non root\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void restart_tcp_service(unique_fd fd, int port) {
|
|
||||||
if (port <= 0) {
|
|
||||||
WriteFdFmt(fd.get(), "invalid port %d\n", port);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
android::base::SetProperty("service.adb.tcp.port", android::base::StringPrintf("%d", port));
|
|
||||||
WriteFdFmt(fd.get(), "restarting in TCP mode port: %d\n", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
void restart_usb_service(unique_fd fd) {
|
|
||||||
android::base::SetProperty("service.adb.tcp.port", "0");
|
|
||||||
WriteFdExactly(fd.get(), "restarting in USB mode\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void reboot_service(unique_fd fd, const std::string& arg) {
|
|
||||||
std::string reboot_arg = arg;
|
|
||||||
sync();
|
|
||||||
|
|
||||||
if (reboot_arg.empty()) reboot_arg = "adb";
|
|
||||||
std::string reboot_string = android::base::StringPrintf("reboot,%s", reboot_arg.c_str());
|
|
||||||
|
|
||||||
if (reboot_arg == "fastboot" &&
|
|
||||||
android::base::GetBoolProperty("ro.boot.dynamic_partitions", false) &&
|
|
||||||
access("/dev/socket/recovery", F_OK) == 0) {
|
|
||||||
LOG(INFO) << "Recovery specific reboot fastboot";
|
|
||||||
/*
|
|
||||||
* The socket is created to allow switching between recovery and
|
|
||||||
* fastboot.
|
|
||||||
*/
|
|
||||||
android::base::unique_fd sock(socket(AF_UNIX, SOCK_STREAM, 0));
|
|
||||||
if (sock < 0) {
|
|
||||||
WriteFdFmt(fd, "reboot (%s) create\n", strerror(errno));
|
|
||||||
PLOG(ERROR) << "Creating recovery socket failed";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sockaddr_un addr = {.sun_family = AF_UNIX};
|
|
||||||
strncpy(addr.sun_path, "/dev/socket/recovery", sizeof(addr.sun_path) - 1);
|
|
||||||
if (connect(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == -1) {
|
|
||||||
WriteFdFmt(fd, "reboot (%s) connect\n", strerror(errno));
|
|
||||||
PLOG(ERROR) << "Couldn't connect to recovery socket";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const char msg_switch_to_fastboot = 'f';
|
|
||||||
auto ret = adb_write(sock, &msg_switch_to_fastboot, sizeof(msg_switch_to_fastboot));
|
|
||||||
if (ret != sizeof(msg_switch_to_fastboot)) {
|
|
||||||
WriteFdFmt(fd, "reboot (%s) write\n", strerror(errno));
|
|
||||||
PLOG(ERROR) << "Couldn't write message to recovery socket to switch to fastboot";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!android::base::SetProperty(ANDROID_RB_PROPERTY, reboot_string)) {
|
|
||||||
WriteFdFmt(fd.get(), "reboot (%s) failed\n", reboot_string.c_str());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Don't return early. Give the reboot command time to take effect
|
|
||||||
// to avoid messing up scripts which do "adb reboot && adb wait-for-device"
|
|
||||||
while (true) {
|
|
||||||
pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void reconnect_service(unique_fd fd, atransport* t) {
|
void reconnect_service(unique_fd fd, atransport* t) {
|
||||||
WriteFdExactly(fd.get(), "done");
|
WriteFdExactly(fd.get(), "done");
|
||||||
|
|
@ -221,7 +135,8 @@ static void spin_service(unique_fd fd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fdevent_run_on_main_thread([fd = pipe_read.release()]() {
|
fdevent_run_on_main_thread([fd = pipe_read.release()]() {
|
||||||
fdevent* fde = fdevent_create(fd, [](int, unsigned, void*) {}, nullptr);
|
fdevent* fde = fdevent_create(
|
||||||
|
fd, [](int, unsigned, void*) {}, nullptr);
|
||||||
fdevent_add(fde, FDE_READ);
|
fdevent_add(fde, FDE_READ);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -328,31 +243,16 @@ asocket* daemon_service_to_socket(std::string_view name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
|
unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
|
||||||
#ifndef __ANDROID_RECOVERY__
|
#if defined(__ANDROID__) && !defined(__ANDROID_RECOVERY__)
|
||||||
if (name.starts_with("abb:")) {
|
if (name.starts_with("abb:")) {
|
||||||
name.remove_prefix(strlen("abb:"));
|
name.remove_prefix(strlen("abb:"));
|
||||||
return execute_binder_command(name);
|
return execute_binder_command(name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (name.starts_with("dev:")) {
|
#if defined(__ANDROID__)
|
||||||
name.remove_prefix(strlen("dev:"));
|
if (name.starts_with("framebuffer:")) {
|
||||||
return unique_fd{unix_open(name, O_RDWR | O_CLOEXEC)};
|
|
||||||
} else if (name.starts_with("framebuffer:")) {
|
|
||||||
return create_service_thread("fb", framebuffer_service);
|
return create_service_thread("fb", framebuffer_service);
|
||||||
} else if (name.starts_with("jdwp:")) {
|
|
||||||
name.remove_prefix(strlen("jdwp:"));
|
|
||||||
std::string str(name);
|
|
||||||
return create_jdwp_connection_fd(atoi(str.c_str()));
|
|
||||||
} else if (name.starts_with("shell")) {
|
|
||||||
name.remove_prefix(strlen("shell"));
|
|
||||||
return ShellService(name, transport);
|
|
||||||
} else if (name.starts_with("exec:")) {
|
|
||||||
name.remove_prefix(strlen("exec:"));
|
|
||||||
return StartSubprocess(std::string(name), nullptr, SubprocessType::kRaw,
|
|
||||||
SubprocessProtocol::kNone);
|
|
||||||
} else if (name.starts_with("sync:")) {
|
|
||||||
return create_service_thread("sync", file_sync_service);
|
|
||||||
} else if (name.starts_with("remount:")) {
|
} else if (name.starts_with("remount:")) {
|
||||||
std::string arg(name.begin() + strlen("remount:"), name.end());
|
std::string arg(name.begin() + strlen("remount:"), name.end());
|
||||||
return create_service_thread("remount",
|
return create_service_thread("remount",
|
||||||
|
|
@ -373,6 +273,12 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
|
||||||
} else if (name.starts_with("restore:")) {
|
} else if (name.starts_with("restore:")) {
|
||||||
return StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
|
return StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw,
|
||||||
SubprocessProtocol::kNone);
|
SubprocessProtocol::kNone);
|
||||||
|
} else if (name.starts_with("disable-verity:")) {
|
||||||
|
return create_service_thread("verity-on", std::bind(set_verity_enabled_state_service,
|
||||||
|
std::placeholders::_1, false));
|
||||||
|
} else if (name.starts_with("enable-verity:")) {
|
||||||
|
return create_service_thread("verity-off", std::bind(set_verity_enabled_state_service,
|
||||||
|
std::placeholders::_1, true));
|
||||||
} else if (name.starts_with("tcpip:")) {
|
} else if (name.starts_with("tcpip:")) {
|
||||||
name.remove_prefix(strlen("tcpip:"));
|
name.remove_prefix(strlen("tcpip:"));
|
||||||
std::string str(name);
|
std::string str(name);
|
||||||
|
|
@ -385,15 +291,28 @@ unique_fd daemon_service_to_fd(std::string_view name, atransport* transport) {
|
||||||
std::bind(restart_tcp_service, std::placeholders::_1, port));
|
std::bind(restart_tcp_service, std::placeholders::_1, port));
|
||||||
} else if (name.starts_with("usb:")) {
|
} else if (name.starts_with("usb:")) {
|
||||||
return create_service_thread("usb", restart_usb_service);
|
return create_service_thread("usb", restart_usb_service);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (name.starts_with("dev:")) {
|
||||||
|
name.remove_prefix(strlen("dev:"));
|
||||||
|
return unique_fd{unix_open(name, O_RDWR | O_CLOEXEC)};
|
||||||
|
} else if (name.starts_with("jdwp:")) {
|
||||||
|
name.remove_prefix(strlen("jdwp:"));
|
||||||
|
std::string str(name);
|
||||||
|
return create_jdwp_connection_fd(atoi(str.c_str()));
|
||||||
|
} else if (name.starts_with("shell")) {
|
||||||
|
name.remove_prefix(strlen("shell"));
|
||||||
|
return ShellService(name, transport);
|
||||||
|
} else if (name.starts_with("exec:")) {
|
||||||
|
name.remove_prefix(strlen("exec:"));
|
||||||
|
return StartSubprocess(std::string(name), nullptr, SubprocessType::kRaw,
|
||||||
|
SubprocessProtocol::kNone);
|
||||||
|
} else if (name.starts_with("sync:")) {
|
||||||
|
return create_service_thread("sync", file_sync_service);
|
||||||
} else if (name.starts_with("reverse:")) {
|
} else if (name.starts_with("reverse:")) {
|
||||||
name.remove_prefix(strlen("reverse:"));
|
name.remove_prefix(strlen("reverse:"));
|
||||||
return reverse_service(name, transport);
|
return reverse_service(name, transport);
|
||||||
} else if (name.starts_with("disable-verity:")) {
|
|
||||||
return create_service_thread("verity-on", std::bind(set_verity_enabled_state_service,
|
|
||||||
std::placeholders::_1, false));
|
|
||||||
} else if (name.starts_with("enable-verity:")) {
|
|
||||||
return create_service_thread("verity-off", std::bind(set_verity_enabled_state_service,
|
|
||||||
std::placeholders::_1, true));
|
|
||||||
} else if (name == "reconnect") {
|
} else if (name == "reconnect") {
|
||||||
return create_service_thread(
|
return create_service_thread(
|
||||||
"reconnect", std::bind(reconnect_service, std::placeholders::_1, transport));
|
"reconnect", std::bind(reconnect_service, std::placeholders::_1, transport));
|
||||||
|
|
|
||||||
|
|
@ -18,4 +18,6 @@
|
||||||
|
|
||||||
#include "adb_unique_fd.h"
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
void set_verity_enabled_state_service(unique_fd fd, bool enable);
|
void set_verity_enabled_state_service(unique_fd fd, bool enable);
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,10 @@
|
||||||
#include <android-base/properties.h>
|
#include <android-base/properties.h>
|
||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
#include <private/android_logger.h>
|
#include <private/android_logger.h>
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
#include <selinux/android.h>
|
#include <selinux/android.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "adb.h"
|
#include "adb.h"
|
||||||
#include "adb_io.h"
|
#include "adb_io.h"
|
||||||
|
|
|
||||||
136
adb/daemon/transport_qemu.cpp
Normal file
136
adb/daemon/transport_qemu.cpp
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 qemu_pipe.h before sysdeps, since it has inlined references to open, read, write.
|
||||||
|
#include <qemu_pipe.h>
|
||||||
|
|
||||||
|
#define TRACE_TAG TRANSPORT
|
||||||
|
#include "sysdeps.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
|
#include <android-base/properties.h>
|
||||||
|
|
||||||
|
#include "adb_io.h"
|
||||||
|
#include "adb_trace.h"
|
||||||
|
#include "adb_unique_fd.h"
|
||||||
|
|
||||||
|
/* A worker thread that monitors host connections, and registers a transport for
|
||||||
|
* every new host connection. This thread replaces server_socket_thread on
|
||||||
|
* condition that adbd daemon runs inside the emulator, and emulator uses QEMUD
|
||||||
|
* pipe to communicate with adbd daemon inside the guest. This is done in order
|
||||||
|
* to provide more robust communication channel between ADB host and guest. The
|
||||||
|
* main issue with server_socket_thread approach is that it runs on top of TCP,
|
||||||
|
* and thus is sensitive to network disruptions. For instance, the
|
||||||
|
* ConnectionManager may decide to reset all network connections, in which case
|
||||||
|
* the connection between ADB host and guest will be lost. To make ADB traffic
|
||||||
|
* independent from the network, we use here 'adb' QEMUD service to transfer data
|
||||||
|
* between the host, and the guest. See external/qemu/android/adb-*.* that
|
||||||
|
* implements the emulator's side of the protocol. Another advantage of using
|
||||||
|
* QEMUD approach is that ADB will be up much sooner, since it doesn't depend
|
||||||
|
* anymore on network being set up.
|
||||||
|
* The guest side of the protocol contains the following phases:
|
||||||
|
* - Connect with adb QEMUD service. In this phase a handle to 'adb' QEMUD service
|
||||||
|
* is opened, and it becomes clear whether or not emulator supports that
|
||||||
|
* protocol.
|
||||||
|
* - Wait for the ADB host to create connection with the guest. This is done by
|
||||||
|
* sending an 'accept' request to the adb QEMUD service, and waiting on
|
||||||
|
* response.
|
||||||
|
* - When new ADB host connection is accepted, the connection with adb QEMUD
|
||||||
|
* service is registered as the transport, and a 'start' request is sent to the
|
||||||
|
* adb QEMUD service, indicating that the guest is ready to receive messages.
|
||||||
|
* Note that the guest will ignore messages sent down from the emulator before
|
||||||
|
* the transport registration is completed. That's why we need to send the
|
||||||
|
* 'start' request after the transport is registered.
|
||||||
|
*/
|
||||||
|
void qemu_socket_thread(int port) {
|
||||||
|
/* 'accept' request to the adb QEMUD service. */
|
||||||
|
static const char _accept_req[] = "accept";
|
||||||
|
/* 'start' request to the adb QEMUD service. */
|
||||||
|
static const char _start_req[] = "start";
|
||||||
|
/* 'ok' reply from the adb QEMUD service. */
|
||||||
|
static const char _ok_resp[] = "ok";
|
||||||
|
|
||||||
|
char tmp[256];
|
||||||
|
char con_name[32];
|
||||||
|
|
||||||
|
adb_thread_setname("qemu socket");
|
||||||
|
D("transport: qemu_socket_thread() starting");
|
||||||
|
|
||||||
|
/* adb QEMUD service connection request. */
|
||||||
|
snprintf(con_name, sizeof(con_name), "pipe:qemud:adb:%d", port);
|
||||||
|
|
||||||
|
/* Connect to the adb QEMUD service. */
|
||||||
|
unique_fd fd(qemu_pipe_open(con_name));
|
||||||
|
if (fd < 0) {
|
||||||
|
/* This could be an older version of the emulator, that doesn't
|
||||||
|
* implement adb QEMUD service. Fall back to the old TCP way. */
|
||||||
|
D("adb service is not available. Falling back to TCP socket.");
|
||||||
|
std::thread(server_socket_thread, port).detach();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
/*
|
||||||
|
* Wait till the host creates a new connection.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Send the 'accept' request. */
|
||||||
|
if (WriteFdExactly(fd.get(), _accept_req, strlen(_accept_req))) {
|
||||||
|
/* Wait for the response. In the response we expect 'ok' on success,
|
||||||
|
* or 'ko' on failure. */
|
||||||
|
if (!ReadFdExactly(fd.get(), tmp, 2) || memcmp(tmp, _ok_resp, 2)) {
|
||||||
|
D("Accepting ADB host connection has failed.");
|
||||||
|
} else {
|
||||||
|
/* Host is connected. Register the transport, and start the
|
||||||
|
* exchange. */
|
||||||
|
std::string serial = android::base::StringPrintf("host-%d", fd.get());
|
||||||
|
WriteFdExactly(fd.get(), _start_req, strlen(_start_req));
|
||||||
|
register_socket_transport(std::move(fd), std::move(serial), port, 1,
|
||||||
|
[](atransport*) { return ReconnectResult::Abort; });
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare for accepting of the next ADB host connection. */
|
||||||
|
fd.reset(qemu_pipe_open(con_name));
|
||||||
|
if (fd < 0) {
|
||||||
|
D("adb service become unavailable.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
D("Unable to send the '%s' request to ADB service.", _accept_req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
D("transport: qemu_socket_thread() exiting");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If adbd is running inside the emulator, it will normally use QEMUD pipe (aka
|
||||||
|
// goldfish) as the transport. This can either be explicitly set by the
|
||||||
|
// service.adb.transport property, or be inferred from ro.kernel.qemu that is
|
||||||
|
// set to "1" for ranchu/goldfish.
|
||||||
|
bool use_qemu_goldfish() {
|
||||||
|
// Legacy way to detect if adbd should use the goldfish pipe is to check for
|
||||||
|
// ro.kernel.qemu, keep that behaviour for backward compatibility.
|
||||||
|
if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// If service.adb.transport is present and is set to "goldfish", use the
|
||||||
|
// QEMUD pipe.
|
||||||
|
if (android::base::GetProperty("service.adb.transport", "") == "goldfish") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
38
adb/daemon/usb_dummy.cpp
Normal file
38
adb/daemon/usb_dummy.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 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 <adbd/usb.h>
|
||||||
|
|
||||||
|
#include <android-base/logging.h>
|
||||||
|
|
||||||
|
int usb_write(usb_handle*, const void*, int) {
|
||||||
|
LOG(FATAL) << "unimplemented";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usb_read(usb_handle*, void*, int) {
|
||||||
|
LOG(FATAL) << "unimplemented";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int usb_close(usb_handle*) {
|
||||||
|
LOG(FATAL) << "unimplemented";
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void usb_kick(usb_handle*) {
|
||||||
|
LOG(FATAL) << "unimplemented";
|
||||||
|
}
|
||||||
|
|
@ -399,4 +399,14 @@ void send_packet(apacket* p, atransport* t);
|
||||||
|
|
||||||
asocket* create_device_tracker(bool long_output);
|
asocket* create_device_tracker(bool long_output);
|
||||||
|
|
||||||
|
#if !ADB_HOST
|
||||||
|
void server_socket_thread(int port);
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
void qemu_socket_thread(int port);
|
||||||
|
bool use_qemu_goldfish();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* __TRANSPORT_H */
|
#endif /* __TRANSPORT_H */
|
||||||
|
|
|
||||||
|
|
@ -229,9 +229,9 @@ static void client_socket_thread(int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // ADB_HOST
|
#else // !ADB_HOST
|
||||||
|
|
||||||
static void server_socket_thread(int port) {
|
void server_socket_thread(int port) {
|
||||||
unique_fd serverfd;
|
unique_fd serverfd;
|
||||||
|
|
||||||
adb_thread_setname("server socket");
|
adb_thread_setname("server socket");
|
||||||
|
|
@ -263,143 +263,19 @@ static void server_socket_thread(int port) {
|
||||||
D("transport: server_socket_thread() exiting");
|
D("transport: server_socket_thread() exiting");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is relevant only for ADB daemon running inside the emulator. */
|
#endif
|
||||||
/*
|
|
||||||
* Redefine open and write for qemu_pipe.h that contains inlined references
|
|
||||||
* to those routines. We will redefine them back after qemu_pipe.h inclusion.
|
|
||||||
*/
|
|
||||||
#undef open
|
|
||||||
#undef read
|
|
||||||
#undef write
|
|
||||||
#define open adb_open
|
|
||||||
#define read adb_read
|
|
||||||
#define write adb_write
|
|
||||||
#include <qemu_pipe.h>
|
|
||||||
#undef open
|
|
||||||
#undef read
|
|
||||||
#undef write
|
|
||||||
#define open ___xxx_open
|
|
||||||
#define read ___xxx_read
|
|
||||||
#define write ___xxx_write
|
|
||||||
|
|
||||||
/* A worker thread that monitors host connections, and registers a transport for
|
void local_init(int port) {
|
||||||
* every new host connection. This thread replaces server_socket_thread on
|
|
||||||
* condition that adbd daemon runs inside the emulator, and emulator uses QEMUD
|
|
||||||
* pipe to communicate with adbd daemon inside the guest. This is done in order
|
|
||||||
* to provide more robust communication channel between ADB host and guest. The
|
|
||||||
* main issue with server_socket_thread approach is that it runs on top of TCP,
|
|
||||||
* and thus is sensitive to network disruptions. For instance, the
|
|
||||||
* ConnectionManager may decide to reset all network connections, in which case
|
|
||||||
* the connection between ADB host and guest will be lost. To make ADB traffic
|
|
||||||
* independent from the network, we use here 'adb' QEMUD service to transfer data
|
|
||||||
* between the host, and the guest. See external/qemu/android/adb-*.* that
|
|
||||||
* implements the emulator's side of the protocol. Another advantage of using
|
|
||||||
* QEMUD approach is that ADB will be up much sooner, since it doesn't depend
|
|
||||||
* anymore on network being set up.
|
|
||||||
* The guest side of the protocol contains the following phases:
|
|
||||||
* - Connect with adb QEMUD service. In this phase a handle to 'adb' QEMUD service
|
|
||||||
* is opened, and it becomes clear whether or not emulator supports that
|
|
||||||
* protocol.
|
|
||||||
* - Wait for the ADB host to create connection with the guest. This is done by
|
|
||||||
* sending an 'accept' request to the adb QEMUD service, and waiting on
|
|
||||||
* response.
|
|
||||||
* - When new ADB host connection is accepted, the connection with adb QEMUD
|
|
||||||
* service is registered as the transport, and a 'start' request is sent to the
|
|
||||||
* adb QEMUD service, indicating that the guest is ready to receive messages.
|
|
||||||
* Note that the guest will ignore messages sent down from the emulator before
|
|
||||||
* the transport registration is completed. That's why we need to send the
|
|
||||||
* 'start' request after the transport is registered.
|
|
||||||
*/
|
|
||||||
static void qemu_socket_thread(int port) {
|
|
||||||
/* 'accept' request to the adb QEMUD service. */
|
|
||||||
static const char _accept_req[] = "accept";
|
|
||||||
/* 'start' request to the adb QEMUD service. */
|
|
||||||
static const char _start_req[] = "start";
|
|
||||||
/* 'ok' reply from the adb QEMUD service. */
|
|
||||||
static const char _ok_resp[] = "ok";
|
|
||||||
|
|
||||||
char tmp[256];
|
|
||||||
char con_name[32];
|
|
||||||
|
|
||||||
adb_thread_setname("qemu socket");
|
|
||||||
D("transport: qemu_socket_thread() starting");
|
|
||||||
|
|
||||||
/* adb QEMUD service connection request. */
|
|
||||||
snprintf(con_name, sizeof(con_name), "pipe:qemud:adb:%d", port);
|
|
||||||
|
|
||||||
/* Connect to the adb QEMUD service. */
|
|
||||||
unique_fd fd(qemu_pipe_open(con_name));
|
|
||||||
if (fd < 0) {
|
|
||||||
/* This could be an older version of the emulator, that doesn't
|
|
||||||
* implement adb QEMUD service. Fall back to the old TCP way. */
|
|
||||||
D("adb service is not available. Falling back to TCP socket.");
|
|
||||||
std::thread(server_socket_thread, port).detach();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
/*
|
|
||||||
* Wait till the host creates a new connection.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Send the 'accept' request. */
|
|
||||||
if (WriteFdExactly(fd.get(), _accept_req, strlen(_accept_req))) {
|
|
||||||
/* Wait for the response. In the response we expect 'ok' on success,
|
|
||||||
* or 'ko' on failure. */
|
|
||||||
if (!ReadFdExactly(fd.get(), tmp, 2) || memcmp(tmp, _ok_resp, 2)) {
|
|
||||||
D("Accepting ADB host connection has failed.");
|
|
||||||
} else {
|
|
||||||
/* Host is connected. Register the transport, and start the
|
|
||||||
* exchange. */
|
|
||||||
std::string serial = android::base::StringPrintf("host-%d", fd.get());
|
|
||||||
WriteFdExactly(fd.get(), _start_req, strlen(_start_req));
|
|
||||||
register_socket_transport(std::move(fd), std::move(serial), port, 1,
|
|
||||||
[](atransport*) { return ReconnectResult::Abort; });
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare for accepting of the next ADB host connection. */
|
|
||||||
fd.reset(qemu_pipe_open(con_name));
|
|
||||||
if (fd < 0) {
|
|
||||||
D("adb service become unavailable.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
D("Unable to send the '%s' request to ADB service.", _accept_req);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
D("transport: qemu_socket_thread() exiting");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If adbd is running inside the emulator, it will normally use QEMUD pipe (aka
|
|
||||||
// goldfish) as the transport. This can either be explicitly set by the
|
|
||||||
// service.adb.transport property, or be inferred from ro.kernel.qemu that is
|
|
||||||
// set to "1" for ranchu/goldfish.
|
|
||||||
static bool use_qemu_goldfish() {
|
|
||||||
// Legacy way to detect if adbd should use the goldfish pipe is to check for
|
|
||||||
// ro.kernel.qemu, keep that behaviour for backward compatibility.
|
|
||||||
if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// If service.adb.transport is present and is set to "goldfish", use the
|
|
||||||
// QEMUD pipe.
|
|
||||||
if (android::base::GetProperty("service.adb.transport", "") == "goldfish") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !ADB_HOST
|
|
||||||
|
|
||||||
void local_init(int port)
|
|
||||||
{
|
|
||||||
void (*func)(int);
|
void (*func)(int);
|
||||||
const char* debug_name = "";
|
const char* debug_name = "";
|
||||||
|
|
||||||
#if ADB_HOST
|
#if ADB_HOST
|
||||||
func = client_socket_thread;
|
func = client_socket_thread;
|
||||||
debug_name = "client";
|
debug_name = "client";
|
||||||
|
#elif !defined(__ANDROID__)
|
||||||
|
// Host adbd.
|
||||||
|
func = server_socket_thread;
|
||||||
|
debug_name = "server";
|
||||||
#else
|
#else
|
||||||
// For the adbd daemon in the system image we need to distinguish
|
// For the adbd daemon in the system image we need to distinguish
|
||||||
// between the device, and the emulator.
|
// between the device, and the emulator.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue