Merge changes from topic "adb_bp" am: 9ee373ac2c

am: ca6ec5c48b

Change-Id: I1a9a4bc92bf48d1d0af6bf74f6f84d20d43d10c9
This commit is contained in:
Josh Gao 2018-03-06 01:36:57 +00:00 committed by android-build-merger
commit 360cf3703b
34 changed files with 541 additions and 694 deletions

View File

@ -12,6 +12,322 @@
// See the License for the specific language governing permissions and
// limitations under the License.
cc_defaults {
name: "adb_defaults",
cflags: [
"-Wall",
"-Wextra",
"-Werror",
"-Wno-unused-parameter",
"-Wno-missing-field-initializers",
"-Wvla",
],
rtti: true,
clang_cflags: [
"-Wexit-time-destructors",
"-Wthread-safety",
],
use_version_lib: true,
compile_multilib: "first",
product_variables: {
debuggable: {
cflags: [
"-DALLOW_ADBD_ROOT",
"-DALLOW_ADBD_DISABLE_VERITY",
"-DALLOW_ADBD_NO_AUTH",
],
},
},
target: {
android: {
cflags: ["-DADB_HOST=0"],
},
host: {
cflags: ["-DADB_HOST=1"],
},
darwin: {
host_ldlibs: [
"-lpthread",
"-framework CoreFoundation",
"-framework IOKit",
"-lobjc",
],
},
windows: {
cflags: [
// Define windows.h and tchar.h Unicode preprocessor symbols so that
// CreateFile(), _tfopen(), etc. map to versions that take wchar_t*, breaking the
// build if you accidentally pass char*. Fix by calling like:
// std::wstring path_wide;
// if (!android::base::UTF8ToWide(path_utf8, &path_wide)) { /* error handling */ }
// CreateFileW(path_wide.c_str());
"-DUNICODE=1",
"-D_UNICODE=1",
// -std=gnu++14 doesn't set _GNU_SOURCE on Windows.
"-D_GNU_SOURCE",
],
},
},
}
// libadb
// =========================================================
// These files are compiled for both the host and the device.
libadb_srcs = [
"adb.cpp",
"adb_io.cpp",
"adb_listeners.cpp",
"adb_trace.cpp",
"adb_utils.cpp",
"fdevent.cpp",
"services.cpp",
"sockets.cpp",
"socket_spec.cpp",
"sysdeps/errno.cpp",
"transport.cpp",
"transport_local.cpp",
"transport_usb.cpp",
]
libadb_posix_srcs = [
"sysdeps_unix.cpp",
"sysdeps/posix/network.cpp",
]
libadb_test_srcs = [
"adb_io_test.cpp",
"adb_listeners_test.cpp",
"adb_utils_test.cpp",
"fdevent_test.cpp",
"socket_spec_test.cpp",
"socket_test.cpp",
"sysdeps_test.cpp",
"sysdeps/stat_test.cpp",
"transport_test.cpp",
]
cc_library_host_static {
name: "libadb_host",
defaults: ["adb_defaults"],
srcs: libadb_srcs + [
"client/auth.cpp",
"client/usb_libusb.cpp",
"client/usb_dispatch.cpp",
"client/transport_mdns.cpp",
],
target: {
linux: {
srcs: ["client/usb_linux.cpp"],
},
darwin: {
srcs: ["client/usb_osx.cpp"],
},
not_windows: {
srcs: libadb_posix_srcs,
},
windows: {
enabled: true,
srcs: [
"client/usb_windows.cpp",
"sysdeps_win32.cpp",
"sysdeps/win32/errno.cpp",
"sysdeps/win32/stat.cpp",
],
shared_libs: ["AdbWinApi"],
},
},
static_libs: [
"libbase",
"libcrypto_utils",
"libcrypto",
"libdiagnose_usb",
"libmdnssd",
"libusb",
],
}
cc_test_host {
name: "adb_test",
defaults: ["adb_defaults"],
srcs: libadb_test_srcs,
static_libs: [
"libadb_host",
"libbase",
"libcutils",
"libcrypto_utils",
"libcrypto",
"libmdnssd",
"libdiagnose_usb",
"libusb",
],
}
cc_binary_host {
name: "adb",
tags: ["debug"],
defaults: ["adb_defaults"],
srcs: [
"client/adb_client.cpp",
"client/bugreport.cpp",
"client/commandline.cpp",
"client/file_sync_client.cpp",
"client/main.cpp",
"client/console.cpp",
"client/line_printer.cpp",
"shell_service_protocol.cpp",
],
static_libs: [
"libadb_host",
"libbase",
"libcutils",
"libcrypto_utils",
"libcrypto",
"libdiagnose_usb",
"liblog",
"libmdnssd",
"libusb",
],
stl: "libc++_static",
// Don't add anything here, we don't want additional shared dependencies
// on the host adb tool, and shared libraries that link against libc++
// will violate ODR
shared_libs: [],
target: {
darwin: {
cflags: [
"-Wno-sizeof-pointer-memaccess",
],
},
windows: {
enabled: true,
ldflags: ["-municode"],
host_ldlibs: [
"-lws2_32",
"-lgdi32",
],
shared_libs: ["AdbWinApi"],
required: [
"AdbWinUsbApi",
],
},
},
}
cc_library_static {
name: "libadbd",
defaults: ["adb_defaults"],
// libminadbd wants both, for some reason.
compile_multilib: "both",
srcs: libadb_srcs + libadb_posix_srcs + [
"daemon/auth.cpp",
"daemon/usb.cpp",
"daemon/jdwp_service.cpp",
],
static_libs: [
"libasyncio",
"libbootloader_message",
"libcrypto_utils",
"libcrypto",
"libdiagnose_usb",
"libqemu_pipe",
"libbase",
],
}
cc_binary {
name: "adbd",
defaults: ["adb_defaults"],
srcs: [
"daemon/main.cpp",
"daemon/mdns.cpp",
"daemon/file_sync_service.cpp",
"daemon/framebuffer_service.cpp",
"daemon/remount_service.cpp",
"daemon/set_verity_enable_state_service.cpp",
"daemon/shell_service.cpp",
"shell_service_protocol.cpp",
],
cflags: [
"-D_GNU_SOURCE",
"-Wno-deprecated-declarations",
],
strip: {
keep_symbols: true,
},
static_libs: [
"libadbd",
"libasyncio",
"libavb_user",
"libbootloader_message",
"libcrypto_utils",
"libcrypto",
"libdiagnose_usb",
"libfec",
"libfec_rs",
"libfs_mgr",
"liblog",
"libext4_utils",
"libmdnssd",
"libminijail",
"libselinux",
"libsquashfs_utils",
"libqemu_pipe",
"libdebuggerd_handler",
"libbase",
"libcutils",
],
}
cc_test {
name: "adbd_test",
defaults: ["adb_defaults"],
srcs: libadb_test_srcs + [
"daemon/shell_service.cpp",
"daemon/shell_service_test.cpp",
"shell_service_protocol.cpp",
"shell_service_protocol_test.cpp",
],
static_libs: [
"libadbd",
"libbase",
"libcutils",
"libcrypto_utils",
"libcrypto",
"libdiagnose_usb",
"liblog",
"libusb",
"libmdnssd",
],
}
python_binary_host {
name: "adb_integration_test_adb",
main: "test_adb.py",

View File

@ -1,387 +0,0 @@
# Copyright 2005 The Android Open Source Project
#
# Android.mk for adb
#
LOCAL_PATH:= $(call my-dir)
include $(LOCAL_PATH)/../platform_tools_tool_version.mk
adb_host_sanitize :=
adb_target_sanitize :=
ADB_COMMON_CFLAGS := \
-frtti \
-Wall -Wextra -Werror \
-Wno-unused-parameter \
-Wno-missing-field-initializers \
-Wvla \
-DADB_VERSION="\"$(tool_version)\"" \
ADB_COMMON_posix_CFLAGS := \
-Wexit-time-destructors \
-Wthread-safety \
ADB_COMMON_linux_CFLAGS := \
$(ADB_COMMON_posix_CFLAGS) \
ADB_COMMON_darwin_CFLAGS := \
$(ADB_COMMON_posix_CFLAGS) \
# Define windows.h and tchar.h Unicode preprocessor symbols so that
# CreateFile(), _tfopen(), etc. map to versions that take wchar_t*, breaking the
# build if you accidentally pass char*. Fix by calling like:
# std::wstring path_wide;
# if (!android::base::UTF8ToWide(path_utf8, &path_wide)) { /* error handling */ }
# CreateFileW(path_wide.c_str());
ADB_COMMON_windows_CFLAGS := \
-DUNICODE=1 -D_UNICODE=1 \
# libadb
# =========================================================
# Much of adb is duplicated in bootable/recovery/minadb and fastboot. Changes
# made to adb rarely get ported to the other two, so the trees have diverged a
# bit. We'd like to stop this because it is a maintenance nightmare, but the
# divergence makes this difficult to do all at once. For now, we will start
# small by moving common files into a static library. Hopefully some day we can
# get enough of adb in here that we no longer need minadb. https://b/17626262
LIBADB_SRC_FILES := \
adb.cpp \
adb_io.cpp \
adb_listeners.cpp \
adb_trace.cpp \
adb_utils.cpp \
fdevent.cpp \
sockets.cpp \
socket_spec.cpp \
sysdeps/errno.cpp \
transport.cpp \
transport_local.cpp \
transport_usb.cpp \
LIBADB_TEST_SRCS := \
adb_io_test.cpp \
adb_listeners_test.cpp \
adb_utils_test.cpp \
fdevent_test.cpp \
socket_spec_test.cpp \
socket_test.cpp \
sysdeps_test.cpp \
sysdeps/stat_test.cpp \
transport_test.cpp \
LIBADB_CFLAGS := \
$(ADB_COMMON_CFLAGS) \
-fvisibility=hidden \
LIBADB_linux_CFLAGS := \
$(ADB_COMMON_linux_CFLAGS) \
LIBADB_darwin_CFLAGS := \
$(ADB_COMMON_darwin_CFLAGS) \
LIBADB_windows_CFLAGS := \
$(ADB_COMMON_windows_CFLAGS) \
LIBADB_darwin_SRC_FILES := \
sysdeps_unix.cpp \
sysdeps/posix/network.cpp \
client/usb_dispatch.cpp \
client/usb_libusb.cpp \
client/usb_osx.cpp \
LIBADB_linux_SRC_FILES := \
sysdeps_unix.cpp \
sysdeps/posix/network.cpp \
client/usb_dispatch.cpp \
client/usb_libusb.cpp \
client/usb_linux.cpp \
LIBADB_windows_SRC_FILES := \
sysdeps_win32.cpp \
sysdeps/win32/errno.cpp \
sysdeps/win32/stat.cpp \
client/usb_dispatch.cpp \
client/usb_libusb.cpp \
client/usb_windows.cpp \
LIBADB_TEST_windows_SRCS := \
sysdeps/win32/errno_test.cpp \
sysdeps_win32_test.cpp \
include $(CLEAR_VARS)
LOCAL_MODULE := libadbd_usb
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0
LOCAL_SRC_FILES := daemon/usb.cpp
LOCAL_SANITIZE := $(adb_target_sanitize)
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the includes to our path.
LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libbase libasyncio
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libadbd
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0
LOCAL_SRC_FILES := \
$(LIBADB_SRC_FILES) \
adbd_auth.cpp \
jdwp_service.cpp \
sysdeps/posix/network.cpp \
LOCAL_SANITIZE := $(adb_target_sanitize)
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the includes to our path.
LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libqemu_pipe libbase
LOCAL_WHOLE_STATIC_LIBRARIES := libadbd_usb
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libadb
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=1
LOCAL_CFLAGS_windows := $(LIBADB_windows_CFLAGS)
LOCAL_CFLAGS_linux := $(LIBADB_linux_CFLAGS)
LOCAL_CFLAGS_darwin := $(LIBADB_darwin_CFLAGS)
LOCAL_SRC_FILES := \
$(LIBADB_SRC_FILES) \
adb_auth_host.cpp \
transport_mdns.cpp \
LOCAL_SRC_FILES_darwin := $(LIBADB_darwin_SRC_FILES)
LOCAL_SRC_FILES_linux := $(LIBADB_linux_SRC_FILES)
LOCAL_SRC_FILES_windows := $(LIBADB_windows_SRC_FILES)
LOCAL_SANITIZE := $(adb_host_sanitize)
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the includes to our path.
LOCAL_STATIC_LIBRARIES := libcrypto_utils libcrypto libbase libmdnssd libusb
LOCAL_C_INCLUDES_windows := development/host/windows/usb/api/
LOCAL_MULTILIB := first
include $(BUILD_HOST_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := adbd_test
LOCAL_CFLAGS := -DADB_HOST=0 $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := \
$(LIBADB_TEST_SRCS) \
$(LIBADB_TEST_linux_SRCS) \
shell_service.cpp \
shell_service_protocol.cpp \
shell_service_protocol_test.cpp \
shell_service_test.cpp \
LOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_STATIC_LIBRARIES := libadbd libcrypto_utils libcrypto libusb libmdnssd
LOCAL_SHARED_LIBRARIES := liblog libbase libcutils
include $(BUILD_NATIVE_TEST)
# libdiagnose_usb
# =========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := libdiagnose_usb
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := $(LIBADB_CFLAGS)
LOCAL_SRC_FILES := diagnose_usb.cpp
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the includes to our path.
LOCAL_STATIC_LIBRARIES := libbase
include $(BUILD_HOST_STATIC_LIBRARY)
# adb_test
# =========================================================
include $(CLEAR_VARS)
LOCAL_MODULE := adb_test
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
LOCAL_CFLAGS_windows := $(LIBADB_windows_CFLAGS)
LOCAL_CFLAGS_linux := $(LIBADB_linux_CFLAGS)
LOCAL_CFLAGS_darwin := $(LIBADB_darwin_CFLAGS)
LOCAL_SRC_FILES := \
$(LIBADB_TEST_SRCS) \
adb_client.cpp \
bugreport.cpp \
bugreport_test.cpp \
line_printer.cpp \
services.cpp \
shell_service_protocol.cpp \
shell_service_protocol_test.cpp \
LOCAL_SRC_FILES_linux := $(LIBADB_TEST_linux_SRCS)
LOCAL_SRC_FILES_darwin := $(LIBADB_TEST_darwin_SRCS)
LOCAL_SRC_FILES_windows := $(LIBADB_TEST_windows_SRCS)
LOCAL_SANITIZE := $(adb_host_sanitize)
LOCAL_STATIC_LIBRARIES := \
libadb \
libbase \
libcrypto_utils \
libcrypto \
libcutils \
libdiagnose_usb \
libmdnssd \
libgmock_host \
libusb \
# Set entrypoint to wmain from sysdeps_win32.cpp instead of main
LOCAL_LDFLAGS_windows := -municode
LOCAL_LDLIBS_linux := -lrt -ldl -lpthread
LOCAL_LDLIBS_darwin := -framework CoreFoundation -framework IOKit -lobjc
LOCAL_LDLIBS_windows := -lws2_32 -luserenv
LOCAL_SHARED_LIBRARIES_windows := AdbWinApi
LOCAL_MULTILIB := first
include $(BUILD_HOST_NATIVE_TEST)
# adb host tool
# =========================================================
include $(CLEAR_VARS)
LOCAL_LDLIBS_linux := -lrt -ldl -lpthread
LOCAL_LDLIBS_darwin := -lpthread -framework CoreFoundation -framework IOKit -framework Carbon -lobjc
# Use wmain instead of main
LOCAL_LDFLAGS_windows := -municode
LOCAL_LDLIBS_windows := -lws2_32 -lgdi32
LOCAL_SHARED_LIBRARIES_windows := AdbWinApi
LOCAL_REQUIRED_MODULES_windows := AdbWinUsbApi
LOCAL_SRC_FILES := \
adb_client.cpp \
bugreport.cpp \
client/main.cpp \
console.cpp \
commandline.cpp \
file_sync_client.cpp \
line_printer.cpp \
services.cpp \
shell_service_protocol.cpp \
LOCAL_CFLAGS += \
$(ADB_COMMON_CFLAGS) \
-D_GNU_SOURCE \
-DADB_HOST=1 \
LOCAL_CFLAGS_windows := \
$(ADB_COMMON_windows_CFLAGS)
LOCAL_CFLAGS_linux := \
$(ADB_COMMON_linux_CFLAGS) \
LOCAL_CFLAGS_darwin := \
$(ADB_COMMON_darwin_CFLAGS) \
-Wno-sizeof-pointer-memaccess -Wno-unused-parameter \
LOCAL_MODULE := adb
LOCAL_MODULE_TAGS := debug
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_SANITIZE := $(adb_host_sanitize)
LOCAL_STATIC_LIBRARIES := \
libadb \
libbase \
libcrypto_utils \
libcrypto \
libdiagnose_usb \
liblog \
libmdnssd \
libusb \
# Don't use libcutils on Windows.
LOCAL_STATIC_LIBRARIES_darwin := libcutils
LOCAL_STATIC_LIBRARIES_linux := libcutils
LOCAL_CXX_STL := libc++_static
# Don't add anything here, we don't want additional shared dependencies
# on the host adb tool, and shared libraries that link against libc++
# will violate ODR
LOCAL_SHARED_LIBRARIES :=
include $(BUILD_HOST_EXECUTABLE)
$(call dist-for-goals,dist_files sdk win_sdk,$(LOCAL_BUILT_MODULE))
ifdef HOST_CROSS_OS
# Archive adb.exe for win_sdk build.
$(call dist-for-goals,win_sdk,$(ALL_MODULES.host_cross_adb.BUILT))
endif
# adbd device daemon
# =========================================================
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
daemon/main.cpp \
daemon/mdns.cpp \
services.cpp \
file_sync_service.cpp \
framebuffer_service.cpp \
remount_service.cpp \
set_verity_enable_state_service.cpp \
shell_service.cpp \
shell_service_protocol.cpp \
LOCAL_CFLAGS := \
$(ADB_COMMON_CFLAGS) \
$(ADB_COMMON_linux_CFLAGS) \
-DADB_HOST=0 \
-D_GNU_SOURCE \
-Wno-deprecated-declarations \
LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endif
LOCAL_MODULE := adbd
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_SANITIZE := $(adb_target_sanitize)
LOCAL_STRIP_MODULE := keep_symbols
LOCAL_STATIC_LIBRARIES := \
libadbd \
libasyncio \
libavb_user \
libbase \
libqemu_pipe \
libbootloader_message \
libfs_mgr \
libfec \
libfec_rs \
libselinux \
liblog \
libext4_utils \
libsquashfs_utils \
libcutils \
libbase \
libcrypto_utils \
libcrypto \
libminijail \
libmdnssd \
libdebuggerd_handler \
include $(BUILD_EXECUTABLE)
# adb integration test
# =========================================================
$(call dist-for-goals,sdk,$(ALL_MODULES.adb_integration_test_adb.BUILT))
$(call dist-for-goals,sdk,$(ALL_MODULES.adb_integration_test_device.BUILT))
include $(call first-makefiles-under,$(LOCAL_PATH))

View File

@ -1,2 +0,0 @@
set noparent
filter=-build/header_guard,-build/include,-readability/function,-whitespace/indent

View File

@ -44,6 +44,7 @@
#include <android-base/parsenetaddress.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <build/version.h>
#include "adb_auth.h"
#include "adb_io.h"
@ -66,8 +67,8 @@ std::string adb_version() {
"Android Debug Bridge version %d.%d.%d\n"
"Version %s\n"
"Installed as %s\n",
ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION, ADB_VERSION,
android::base::GetExecutablePath().c_str());
ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION,
android::build::GetBuildNumber().c_str(), android::base::GetExecutablePath().c_str());
}
void fatal(const char *fmt, ...) {
@ -135,8 +136,16 @@ void handle_online(atransport *t)
void handle_offline(atransport *t)
{
D("adb: offline");
//Close the associated usb
if (t->GetConnectionState() == kCsOffline) {
LOG(INFO) << t->serial_name() << ": already offline";
return;
}
LOG(INFO) << t->serial_name() << ": offline";
t->SetConnectionState(kCsOffline);
// Close the associated usb
t->online = 0;
// This is necessary to avoid a race condition that occurred when a transport closes
@ -317,10 +326,7 @@ void parse_banner(const std::string& banner, atransport* t) {
}
static void handle_new_connection(atransport* t, apacket* p) {
if (t->GetConnectionState() != kCsOffline) {
t->SetConnectionState(kCsOffline);
handle_offline(t);
}
handle_offline(t);
t->update_version(p->msg.arg0, p->msg.arg1);
parse_banner(p->payload, t);
@ -349,19 +355,6 @@ void handle_packet(apacket *p, atransport *t)
CHECK_EQ(p->payload.size(), p->msg.data_length);
switch(p->msg.command){
case A_SYNC:
if (p->msg.arg0){
send_packet(p, t);
#if ADB_HOST
send_connect(t);
#endif
} else {
t->SetConnectionState(kCsOffline);
handle_offline(t);
send_packet(p, t);
}
return;
case A_CNXN: // CONNECT(version, maxdata, "system-id-string")
handle_new_connection(t, p);
break;

View File

@ -128,7 +128,7 @@ static void jdwp_process_event(int socket, unsigned events, void* _proc);
static void jdwp_process_list_updated(void);
struct JdwpProcess;
static std::list<std::unique_ptr<JdwpProcess>> _jdwp_list;
static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>();
struct JdwpProcess {
explicit JdwpProcess(int socket) {
@ -511,7 +511,7 @@ struct JdwpTracker : public asocket {
bool need_initial;
};
static std::vector<std::unique_ptr<JdwpTracker>> _jdwp_trackers;
static auto& _jdwp_trackers = *new std::vector<std::unique_ptr<JdwpTracker>>();
static void jdwp_process_list_updated(void) {
std::string data;

View File

@ -158,9 +158,9 @@ int adbd_main(int server_port) {
// descriptor will always be open.
adbd_cloexec_auth_socket();
if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) {
auth_required = false;
}
#if defined(ALLOW_ADBD_NO_AUTH)
auth_required = android::base::GetBoolProperty("ro.adb.secure", true);
#endif
adbd_auth_init();

View File

@ -183,9 +183,11 @@ requirement, since they will be ignored.
Command constant: A_SYNC
The SYNC message is used by the io pump to make sure that stale
*** obsolete, no longer used ***
The SYNC message was used by the io pump to make sure that stale
outbound messages are discarded when the connection to the remote side
is broken. It is only used internally to the bridge and never valid
is broken. It was only used internally to the bridge and never valid
to send across the wire.
* when the connection to the remote side goes offline, the io pump

View File

@ -28,6 +28,7 @@
#include <unistd.h>
#include <algorithm>
#include <deque>
#include <list>
#include <mutex>
#include <thread>
@ -38,12 +39,13 @@
#include <android-base/strings.h>
#include <android-base/thread_annotations.h>
#include <diagnose_usb.h>
#include "adb.h"
#include "adb_auth.h"
#include "adb_io.h"
#include "adb_trace.h"
#include "adb_utils.h"
#include "diagnose_usb.h"
#include "fdevent.h"
static void transport_unref(atransport *t);
@ -65,6 +67,82 @@ TransportId NextTransportId() {
return next++;
}
BlockingConnectionAdapter::BlockingConnectionAdapter(std::unique_ptr<BlockingConnection> connection)
: underlying_(std::move(connection)) {}
BlockingConnectionAdapter::~BlockingConnectionAdapter() {
LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): destructing";
Stop();
}
void BlockingConnectionAdapter::Start() {
read_thread_ = std::thread([this]() {
LOG(INFO) << this->transport_name_ << ": read thread spawning";
while (true) {
std::unique_ptr<apacket> packet(new apacket());
if (!underlying_->Read(packet.get())) {
PLOG(INFO) << this->transport_name_ << ": read failed";
break;
}
read_callback_(this, std::move(packet));
}
std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "read failed"); });
});
write_thread_ = std::thread([this]() {
LOG(INFO) << this->transport_name_ << ": write thread spawning";
while (true) {
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this]() { return this->stopped_ || !this->write_queue_.empty(); });
if (this->stopped_) {
return;
}
std::unique_ptr<apacket> packet = std::move(this->write_queue_.front());
this->write_queue_.pop_front();
lock.unlock();
if (!this->underlying_->Write(packet.get())) {
break;
}
}
std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "write failed"); });
});
}
void BlockingConnectionAdapter::Stop() {
std::unique_lock<std::mutex> lock(mutex_);
if (stopped_) {
LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): already stopped";
return;
}
stopped_ = true;
lock.unlock();
LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): stopping";
this->underlying_->Close();
this->cv_.notify_one();
read_thread_.join();
write_thread_.join();
LOG(INFO) << "BlockingConnectionAdapter(" << this->transport_name_ << "): stopped";
std::call_once(this->error_flag_, [this]() { this->error_callback_(this, "requested stop"); });
}
bool BlockingConnectionAdapter::Write(std::unique_ptr<apacket> packet) {
{
std::unique_lock<std::mutex> lock(this->mutex_);
write_queue_.emplace_back(std::move(packet));
}
cv_.notify_one();
return true;
}
bool FdConnection::Read(apacket* packet) {
if (!ReadFdExactly(fd_.get(), &packet->msg, sizeof(amessage))) {
D("remote local: read terminated (message)");
@ -143,67 +221,6 @@ static std::string dump_packet(const char* name, const char* func, apacket* p) {
return result;
}
static int read_packet(int fd, const char* name, apacket** ppacket) {
ATRACE_NAME("read_packet");
char buff[8];
if (!name) {
snprintf(buff, sizeof buff, "fd=%d", fd);
name = buff;
}
char* p = reinterpret_cast<char*>(ppacket); /* really read a packet address */
int len = sizeof(apacket*);
while (len > 0) {
int r = adb_read(fd, p, len);
if (r > 0) {
len -= r;
p += r;
} else {
D("%s: read_packet (fd=%d), error ret=%d: %s", name, fd, r, strerror(errno));
return -1;
}
}
VLOG(TRANSPORT) << dump_packet(name, "from remote", *ppacket);
return 0;
}
static int write_packet(int fd, const char* name, apacket** ppacket) {
ATRACE_NAME("write_packet");
char buff[8];
if (!name) {
snprintf(buff, sizeof buff, "fd=%d", fd);
name = buff;
}
VLOG(TRANSPORT) << dump_packet(name, "to remote", *ppacket);
char* p = reinterpret_cast<char*>(ppacket); /* we really write the packet address */
int len = sizeof(apacket*);
while (len > 0) {
int r = adb_write(fd, p, len);
if (r > 0) {
len -= r;
p += r;
} else {
D("%s: write_packet (fd=%d) error ret=%d: %s", name, fd, r, strerror(errno));
return -1;
}
}
return 0;
}
static void transport_socket_events(int fd, unsigned events, void* _t) {
atransport* t = reinterpret_cast<atransport*>(_t);
D("transport_socket_events(fd=%d, events=%04x,...)", fd, events);
if (events & FDE_READ) {
apacket* p = 0;
if (read_packet(fd, t->serial, &p)) {
D("%s: failed to read packet from transport socket on fd %d", t->serial, fd);
return;
}
handle_packet(p, (atransport*)_t);
}
}
void send_packet(apacket* p, atransport* t) {
p->msg.magic = p->msg.command ^ 0xffffffff;
// compute a checksum for connection/auth packets for compatibility reasons
@ -213,162 +230,18 @@ void send_packet(apacket* p, atransport* t) {
p->msg.data_check = calculate_apacket_checksum(p);
}
print_packet("send", p);
VLOG(TRANSPORT) << dump_packet(t->serial, "to remote", p);
if (t == NULL) {
fatal("Transport is null");
}
if (write_packet(t->transport_socket, t->serial, &p)) {
fatal_errno("cannot enqueue packet on transport socket");
if (t->Write(p) != 0) {
D("%s: failed to enqueue packet, closing transport", t->serial);
t->Kick();
}
}
// The transport is opened by transport_register_func before
// the read_transport and write_transport threads are started.
//
// The read_transport thread issues a SYNC(1, token) message to let
// the write_transport thread know to start things up. In the event
// of transport IO failure, the read_transport thread will post a
// SYNC(0,0) message to ensure shutdown.
//
// The transport will not actually be closed until both threads exit, but the threads
// will kick the transport on their way out to disconnect the underlying device.
//
// read_transport thread reads data from a transport (representing a usb/tcp connection),
// and makes the main thread call handle_packet().
static void read_transport_thread(void* _t) {
atransport* t = reinterpret_cast<atransport*>(_t);
apacket* p;
adb_thread_setname(
android::base::StringPrintf("<-%s", (t->serial != nullptr ? t->serial : "transport")));
D("%s: starting read_transport thread on fd %d, SYNC online (%d)", t->serial, t->fd,
t->sync_token + 1);
p = get_apacket();
p->msg.command = A_SYNC;
p->msg.arg0 = 1;
p->msg.arg1 = ++(t->sync_token);
p->msg.magic = A_SYNC ^ 0xffffffff;
D("sending SYNC packet (len = %u, payload.size() = %zu)", p->msg.data_length, p->payload.size());
if (write_packet(t->fd, t->serial, &p)) {
put_apacket(p);
D("%s: failed to write SYNC packet", t->serial);
goto oops;
}
D("%s: data pump started", t->serial);
for (;;) {
ATRACE_NAME("read_transport loop");
p = get_apacket();
{
ATRACE_NAME("read_transport read_remote");
if (!t->connection->Read(p)) {
D("%s: remote read failed for transport", t->serial);
put_apacket(p);
break;
}
if (!check_header(p, t)) {
D("%s: remote read: bad header", t->serial);
put_apacket(p);
break;
}
#if ADB_HOST
if (p->msg.command == 0) {
put_apacket(p);
continue;
}
#endif
}
D("%s: received remote packet, sending to transport", t->serial);
if (write_packet(t->fd, t->serial, &p)) {
put_apacket(p);
D("%s: failed to write apacket to transport", t->serial);
goto oops;
}
}
D("%s: SYNC offline for transport", t->serial);
p = get_apacket();
p->msg.command = A_SYNC;
p->msg.arg0 = 0;
p->msg.arg1 = 0;
p->msg.magic = A_SYNC ^ 0xffffffff;
if (write_packet(t->fd, t->serial, &p)) {
put_apacket(p);
D("%s: failed to write SYNC apacket to transport", t->serial);
}
oops:
D("%s: read_transport thread is exiting", t->serial);
kick_transport(t);
transport_unref(t);
}
// write_transport thread gets packets sent by the main thread (through send_packet()),
// and writes to a transport (representing a usb/tcp connection).
static void write_transport_thread(void* _t) {
atransport* t = reinterpret_cast<atransport*>(_t);
apacket* p;
int active = 0;
adb_thread_setname(
android::base::StringPrintf("->%s", (t->serial != nullptr ? t->serial : "transport")));
D("%s: starting write_transport thread, reading from fd %d", t->serial, t->fd);
for (;;) {
ATRACE_NAME("write_transport loop");
if (read_packet(t->fd, t->serial, &p)) {
D("%s: failed to read apacket from transport on fd %d", t->serial, t->fd);
break;
}
if (p->msg.command == A_SYNC) {
if (p->msg.arg0 == 0) {
D("%s: transport SYNC offline", t->serial);
put_apacket(p);
break;
} else {
if (p->msg.arg1 == t->sync_token) {
D("%s: transport SYNC online", t->serial);
active = 1;
} else {
D("%s: transport ignoring SYNC %d != %d", t->serial, p->msg.arg1, t->sync_token);
}
}
} else {
if (active) {
D("%s: transport got packet, sending to remote", t->serial);
ATRACE_NAME("write_transport write_remote");
// Allow sending the payload's implicit null terminator.
if (p->msg.data_length != p->payload.size()) {
LOG(FATAL) << "packet data length doesn't match payload: msg.data_length = "
<< p->msg.data_length << ", payload.size() = " << p->payload.size();
}
if (t->Write(p) != 0) {
D("%s: remote write failed for transport", t->serial);
put_apacket(p);
break;
}
} else {
D("%s: transport ignoring packet while offline", t->serial);
}
}
put_apacket(p);
}
D("%s: write_transport thread is exiting, fd %d", t->serial, t->fd);
kick_transport(t);
transport_unref(t);
}
void kick_transport(atransport* t) {
std::lock_guard<std::recursive_mutex> lock(transport_lock);
// As kick_transport() can be called from threads without guarantee that t is valid,
@ -559,9 +432,10 @@ static int transport_write_action(int fd, struct tmsg* m) {
return 0;
}
static void transport_registration_func(int _fd, unsigned ev, void* data) {
static void remove_transport(atransport*);
static void transport_registration_func(int _fd, unsigned ev, void*) {
tmsg m;
int s[2];
atransport* t;
if (!(ev & FDE_READ)) {
@ -575,13 +449,7 @@ static void transport_registration_func(int _fd, unsigned ev, void* data) {
t = m.transport;
if (m.action == 0) {
D("transport: %s removing and free'ing %d", t->serial, t->transport_socket);
/* IMPORTANT: the remove closes one half of the
** socket pair. The close closes the other half.
*/
fdevent_remove(&(t->transport_fde));
adb_close(t->fd);
D("transport: %s deleting", t->serial);
{
std::lock_guard<std::recursive_mutex> lock(transport_lock);
@ -603,23 +471,33 @@ static void transport_registration_func(int _fd, unsigned ev, void* data) {
/* don't create transport threads for inaccessible devices */
if (t->GetConnectionState() != kCsNoPerm) {
/* initial references are the two threads */
t->ref_count = 2;
t->ref_count = 1;
t->connection->SetTransportName(t->serial_name());
t->connection->SetReadCallback([t](Connection*, std::unique_ptr<apacket> p) {
if (!check_header(p.get(), t)) {
D("%s: remote read: bad header", t->serial);
return false;
}
if (adb_socketpair(s)) {
fatal_errno("cannot open transport socketpair");
}
VLOG(TRANSPORT) << dump_packet(t->serial, "from remote", p.get());
apacket* packet = p.release();
D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]);
// TODO: Does this need to run on the main thread?
fdevent_run_on_main_thread([packet, t]() { handle_packet(packet, t); });
return true;
});
t->connection->SetErrorCallback([t](Connection*, const std::string& error) {
D("%s: connection terminated: %s", t->serial, error.c_str());
fdevent_run_on_main_thread([t]() {
handle_offline(t);
transport_unref(t);
});
});
t->transport_socket = s[0];
t->fd = s[1];
fdevent_install(&(t->transport_fde), t->transport_socket, transport_socket_events, t);
fdevent_set(&(t->transport_fde), FDE_READ);
std::thread(write_transport_thread, t).detach();
std::thread(read_transport_thread, t).detach();
t->connection->Start();
#if ADB_HOST
send_connect(t);
#endif
}
{
@ -685,7 +563,7 @@ static void transport_unref(atransport* t) {
t->ref_count--;
if (t->ref_count == 0) {
D("transport: %s unref (kicking and closing)", t->serial);
t->connection->Close();
t->connection->Stop();
remove_transport(t);
} else {
D("transport: %s unref (count=%zu)", t->serial, t->ref_count);
@ -736,9 +614,7 @@ atransport* acquire_one_transport(TransportType type, const char* serial, Transp
std::unique_lock<std::recursive_mutex> lock(transport_lock);
for (const auto& t : transport_list) {
if (t->GetConnectionState() == kCsNoPerm) {
#if ADB_HOST
*error_out = UsbNoPermissionsLongHelpText();
#endif
continue;
}
@ -813,14 +689,14 @@ atransport* acquire_one_transport(TransportType type, const char* serial, Transp
}
int atransport::Write(apacket* p) {
return this->connection->Write(p) ? 0 : -1;
return this->connection->Write(std::unique_ptr<apacket>(p)) ? 0 : -1;
}
void atransport::Kick() {
if (!kicked_) {
D("kicking transport %s", this->serial);
kicked_ = true;
this->connection->Close();
this->connection->Stop();
}
}
@ -833,7 +709,7 @@ void atransport::SetConnectionState(ConnectionState state) {
connection_state_ = state;
}
const std::string atransport::connection_state_name() const {
std::string atransport::connection_state_name() const {
ConnectionState state = GetConnectionState();
switch (state) {
case kCsOffline:

View File

@ -20,12 +20,14 @@
#include <sys/types.h>
#include <atomic>
#include <condition_variable>
#include <deque>
#include <functional>
#include <list>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <unordered_set>
#include <openssl/rsa.h>
@ -57,15 +59,47 @@ extern const char* const kFeaturePushSync;
TransportId NextTransportId();
// Abstraction for a blocking packet transport.
// Abstraction for a non-blocking packet transport.
struct Connection {
Connection() = default;
Connection(const Connection& copy) = delete;
Connection(Connection&& move) = delete;
// Destroy a Connection. Formerly known as 'Close' in atransport.
virtual ~Connection() = default;
void SetTransportName(std::string transport_name) {
transport_name_ = std::move(transport_name);
}
using ReadCallback = std::function<bool(Connection*, std::unique_ptr<apacket>)>;
void SetReadCallback(ReadCallback callback) {
CHECK(!read_callback_);
read_callback_ = callback;
}
// Called after the Connection has terminated, either by an error or because Stop was called.
using ErrorCallback = std::function<void(Connection*, const std::string&)>;
void SetErrorCallback(ErrorCallback callback) {
CHECK(!error_callback_);
error_callback_ = callback;
}
virtual bool Write(std::unique_ptr<apacket> packet) = 0;
virtual void Start() = 0;
virtual void Stop() = 0;
std::string transport_name_;
ReadCallback read_callback_;
ErrorCallback error_callback_;
};
// Abstraction for a blocking packet transport.
struct BlockingConnection {
BlockingConnection() = default;
BlockingConnection(const BlockingConnection& copy) = delete;
BlockingConnection(BlockingConnection&& move) = delete;
// Destroy a BlockingConnection. Formerly known as 'Close' in atransport.
virtual ~BlockingConnection() = default;
// Read/Write a packet. These functions are concurrently called from a transport's reader/writer
// threads.
virtual bool Read(apacket* packet) = 0;
@ -77,7 +111,30 @@ struct Connection {
virtual void Close() = 0;
};
struct FdConnection : public Connection {
struct BlockingConnectionAdapter : public Connection {
explicit BlockingConnectionAdapter(std::unique_ptr<BlockingConnection> connection);
virtual ~BlockingConnectionAdapter();
virtual bool Write(std::unique_ptr<apacket> packet) override final;
virtual void Start() override final;
virtual void Stop() override final;
bool stopped_ = false;
std::unique_ptr<BlockingConnection> underlying_;
std::thread read_thread_;
std::thread write_thread_;
std::deque<std::unique_ptr<apacket>> write_queue_;
std::mutex mutex_;
std::condition_variable cv_;
std::once_flag error_flag_;
};
struct FdConnection : public BlockingConnection {
explicit FdConnection(unique_fd fd) : fd_(std::move(fd)) {}
bool Read(apacket* packet) override final;
@ -89,7 +146,7 @@ struct FdConnection : public Connection {
unique_fd fd_;
};
struct UsbConnection : public Connection {
struct UsbConnection : public BlockingConnection {
explicit UsbConnection(usb_handle* handle) : handle_(handle) {}
~UsbConnection();
@ -110,7 +167,6 @@ class atransport {
atransport(ConnectionState state = kCsOffline)
: id(NextTransportId()), connection_state_(state) {
transport_fde = {};
// Initialize protocol to min version for compatibility with older versions.
// Version will be updated post-connect.
protocol_version = A_VERSION_MIN;
@ -126,11 +182,7 @@ class atransport {
void SetConnectionState(ConnectionState state);
const TransportId id;
int fd = -1;
int transport_socket = -1;
fdevent transport_fde;
size_t ref_count = 0;
uint32_t sync_token = 0;
bool online = false;
TransportType type = kTransportAny;
@ -152,8 +204,8 @@ class atransport {
char token[TOKEN_SIZE] = {};
size_t failed_auth_attempts = 0;
const std::string serial_name() const { return serial ? serial : "<unknown>"; }
const std::string connection_state_name() const;
std::string serial_name() const { return serial ? serial : "<unknown>"; }
std::string connection_state_name() const;
void update_version(int version, size_t payload);
int get_protocol_version() const;

View File

@ -445,13 +445,14 @@ int init_socket_transport(atransport* t, int s, int adb_port, int local) {
int fail = 0;
unique_fd fd(s);
t->sync_token = 1;
t->type = kTransportLocal;
#if ADB_HOST
// Emulator connection.
if (local) {
t->connection.reset(new EmulatorConnection(std::move(fd), adb_port));
std::unique_ptr<BlockingConnection> emulator_connection(
new EmulatorConnection(std::move(fd), adb_port));
t->connection.reset(new BlockingConnectionAdapter(std::move(emulator_connection)));
std::lock_guard<std::mutex> lock(local_transports_lock);
atransport* existing_transport = find_emulator_transport_by_adb_port_locked(adb_port);
if (existing_transport != NULL) {
@ -470,6 +471,7 @@ int init_socket_transport(atransport* t, int s, int adb_port, int local) {
#endif
// Regular tcp connection.
t->connection.reset(new FdConnection(std::move(fd)));
std::unique_ptr<BlockingConnection> fd_connection(new FdConnection(std::move(fd)));
t->connection.reset(new BlockingConnectionAdapter(std::move(fd_connection)));
return fail;
}

View File

@ -1,18 +0,0 @@
/*
* Copyright (C) 2016 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.
*/
/* For when mDNS discovery is unsupported */
void init_mdns_transport_discovery(void) {}

View File

@ -174,8 +174,8 @@ void UsbConnection::Close() {
void init_usb_transport(atransport* t, usb_handle* h) {
D("transport: usb");
t->connection.reset(new UsbConnection(h));
t->sync_token = 1;
std::unique_ptr<BlockingConnection> connection(new UsbConnection(h));
t->connection.reset(new BlockingConnectionAdapter(std::move(connection)));
t->type = kTransportUsb;
}

13
diagnose_usb/Android.bp Normal file
View File

@ -0,0 +1,13 @@
cc_library_static {
name: "libdiagnose_usb",
cflags: ["-Wall", "-Wextra", "-Werror"],
host_supported: true,
target: {
windows: {
enabled: true,
},
},
srcs: ["diagnose_usb.cpp"],
export_include_dirs: ["include"],
static_libs: ["libbase"],
}

View File

@ -33,7 +33,7 @@ static const char kPermissionsHelpUrl[] = "http://developer.android.com/tools/de
// Returns a message describing any potential problems we find with udev, or an empty string if we
// can't find plugdev information (i.e. udev is not installed).
static std::string GetUdevProblem() {
#if defined(__linux__)
#if defined(__linux__) && !defined(__BIONIC__)
errno = 0;
group* plugdev_group = getgrnam("plugdev");