Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7bb1b3e authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Adding Android Binder Bridge (abb) utility launched from adbd."

parents 789d905b 640407d6
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
@@ -355,6 +355,7 @@ cc_library {
    compile_multilib: "both",

    srcs: [
        "daemon/abb_service.cpp",
        "daemon/file_sync_service.cpp",
        "daemon/framebuffer_service.cpp",
        "daemon/mdns.cpp",
@@ -391,6 +392,14 @@ cc_library {
        "libmdnssd",
        "libselinux",
    ],

    target: {
        recovery: {
            exclude_srcs: [
                "daemon/abb_service.cpp",
            ],
        },
    },
}

cc_library {
@@ -455,6 +464,40 @@ cc_binary {
    ],
}

cc_binary {
    name: "abb",

    defaults: ["adb_defaults"],
    recovery_available: false,

    srcs: [
        "daemon/abb.cpp",
    ],

    cflags: [
        "-D_GNU_SOURCE",
        "-Wno-deprecated-declarations",
    ],

    strip: {
        keep_symbols: true,
    },

    static_libs: [
        "libadbd_core",
        "libadbd_services",
        "libcmd",
    ],

    shared_libs: [
        "libbase",
        "libbinder",
        "liblog",
        "libutils",
        "libselinux",
    ],
}

cc_test {
    name: "adbd_test",
    defaults: ["adb_defaults"],
+7 −0
Original line number Diff line number Diff line
@@ -152,6 +152,10 @@ asocket* host_service_to_socket(const char* name, const char* serial, TransportI
asocket* daemon_service_to_socket(std::string_view name);
#endif

#if !ADB_HOST
unique_fd execute_binder_command(std::string_view command);
#endif

#if !ADB_HOST
int init_jdwp(void);
asocket* create_jdwp_service_socket();
@@ -202,6 +206,9 @@ extern const char* adb_device_banner;

#define CHUNK_SIZE (64 * 1024)

// Argument delimeter for adb abb command.
#define ABB_ARG_DELIMETER ('\0')

#if !ADB_HOST
#define USB_FFS_ADB_PATH "/dev/usb-ffs/adb/"
#define USB_FFS_ADB_EP(x) USB_FFS_ADB_PATH #x
+81 −0
Original line number Diff line number Diff line
@@ -20,6 +20,11 @@

#include <unistd.h>

#if !ADB_HOST
#include <sys/socket.h>
#include <sys/un.h>
#endif

#include <thread>

#include <android-base/stringprintf.h>
@@ -182,3 +187,79 @@ bool ReadOrderlyShutdown(int fd) {
        return false;
    }
}

#if defined(__linux__)
bool SendFileDescriptor(int socket_fd, int fd) {
    struct msghdr msg;
    struct iovec iov;
    char dummy = '!';
    union {
        cmsghdr cm;
        char buffer[CMSG_SPACE(sizeof(int))];
    } cm_un;

    iov.iov_base = &dummy;
    iov.iov_len = 1;
    msg.msg_name = nullptr;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_flags = 0;
    msg.msg_control = cm_un.buffer;
    msg.msg_controllen = sizeof(cm_un.buffer);

    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    ((int*)CMSG_DATA(cmsg))[0] = fd;

    int ret = TEMP_FAILURE_RETRY(sendmsg(socket_fd, &msg, 0));
    if (ret < 0) {
        D("sending file descriptor via socket %d failed: %s", socket_fd, strerror(errno));
        return false;
    }

    D("sent file descriptor %d to via socket %d", fd, socket_fd);
    return true;
}

bool ReceiveFileDescriptor(int socket_fd, unique_fd* fd, std::string* error) {
    char dummy = '!';
    union {
        cmsghdr cm;
        char buffer[CMSG_SPACE(sizeof(int))];
    } cm_un;

    iovec iov;
    iov.iov_base = &dummy;
    iov.iov_len = 1;

    msghdr msg;
    msg.msg_name = nullptr;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;
    msg.msg_flags = 0;
    msg.msg_control = cm_un.buffer;
    msg.msg_controllen = sizeof(cm_un.buffer);

    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_len = CMSG_LEN(sizeof(int));
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    ((int*)(CMSG_DATA(cmsg)))[0] = -1;

    int rc = TEMP_FAILURE_RETRY(recvmsg(socket_fd, &msg, 0));
    if (rc <= 0) {
        *error = perror_str("receiving file descriptor via socket failed");
        D("receiving file descriptor via socket %d failed: %s", socket_fd, strerror(errno));
        return false;
    }

    fd->reset(((int*)(CMSG_DATA(cmsg)))[0]);
    D("received file descriptor %d to via socket %d", fd->get(), socket_fd);

    return true;
}
#endif
+10 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@

#include <string>

#include "adb_unique_fd.h"

// Sends the protocol "OKAY" message.
bool SendOkay(int fd);

@@ -73,4 +75,12 @@ bool WriteFdExactly(int fd, const std::string& s);
// Same as above, but formats the string to send.
bool WriteFdFmt(int fd, const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));

#if !ADB_HOST
// Sends an FD via Unix domain socket.
bool SendFileDescriptor(int socket_fd, int fd);

// Receives an FD via Unix domain socket.
bool ReceiveFileDescriptor(int socket_fd, unique_fd* fd, std::string* error);
#endif

#endif /* ADB_IO_H */
+48 −46
Original line number Diff line number Diff line
@@ -579,12 +579,8 @@ static std::string ShellServiceString(bool use_shell_protocol,
//
// On success returns the remote exit code if |use_shell_protocol| is true,
// 0 otherwise. On failure returns 1.
static int RemoteShell(bool use_shell_protocol, const std::string& type_arg,
                       char escape_char,
                       const std::string& command) {
    std::string service_string = ShellServiceString(use_shell_protocol,
                                                    type_arg, command);

static int RemoteShell(bool use_shell_protocol, const std::string& type_arg, char escape_char,
                       bool empty_command, const std::string& service_string) {
    // Old devices can't handle a service string that's longer than MAX_PAYLOAD_V1.
    // Use |use_shell_protocol| to determine whether to allow a command longer than that.
    if (service_string.size() > MAX_PAYLOAD_V1 && !use_shell_protocol) {
@@ -595,8 +591,7 @@ static int RemoteShell(bool use_shell_protocol, const std::string& type_arg,
    // Make local stdin raw if the device allocates a PTY, which happens if:
    //   1. We are explicitly asking for a PTY shell, or
    //   2. We don't specify shell type and are starting an interactive session.
    bool raw_stdin = (type_arg == kShellServiceArgPty ||
                      (type_arg.empty() && command.empty()));
    bool raw_stdin = (type_arg == kShellServiceArgPty || (type_arg.empty() && empty_command));

    std::string error;
    int fd = adb_connect(service_string, &error);
@@ -756,7 +751,29 @@ static int adb_shell(int argc, const char** argv) {
        command = android::base::Join(std::vector<const char*>(argv + optind, argv + argc), ' ');
    }

    return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command);
    std::string service_string = ShellServiceString(use_shell_protocol, shell_type_arg, command);
    return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command.empty(),
                       service_string);
}

static int adb_abb(int argc, const char** argv) {
    // Defaults.
    constexpr char escape_char = '~';  // -e
    constexpr bool use_shell_protocol = true;
    constexpr auto shell_type_arg = kShellServiceArgRaw;
    constexpr bool empty_command = false;

    std::string service_string("abb:");
    for (auto i = optind; i < argc; ++i) {
        service_string.append(argv[i]);
        service_string.push_back(ABB_ARG_DELIMETER);
    }

    D("abb -e 0x%x [%*.s]\n", escape_char, static_cast<int>(service_string.size()),
      service_string.data());

    return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, empty_command,
                       service_string);
}

static int adb_sideload_legacy(const char* filename, int in_fd, int size) {
@@ -1546,14 +1563,13 @@ int adb_commandline(int argc, const char** argv) {
        std::string query = android::base::StringPrintf("host:disconnect:%s",
                                                        (argc == 2) ? argv[1] : "");
        return adb_query_command(query);
    }
    else if (!strcmp(argv[0], "emu")) {
    } else if (!strcmp(argv[0], "abb")) {
        return adb_abb(argc, argv);
    } else if (!strcmp(argv[0], "emu")) {
        return adb_send_emulator_command(argc, argv, serial);
    }
    else if (!strcmp(argv[0], "shell")) {
    } else if (!strcmp(argv[0], "shell")) {
        return adb_shell(argc, argv);
    }
    else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
    } else if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
        int exec_in = !strcmp(argv[0], "exec-in");

        if (argc < 2) error_exit("usage: adb %s command", argv[0]);
@@ -1581,11 +1597,9 @@ int adb_commandline(int argc, const char** argv) {

        adb_close(fd);
        return 0;
    }
    else if (!strcmp(argv[0], "kill-server")) {
    } else if (!strcmp(argv[0], "kill-server")) {
        return adb_kill_server() ? 0 : 1;
    }
    else if (!strcmp(argv[0], "sideload")) {
    } else if (!strcmp(argv[0], "sideload")) {
        if (argc != 2) error_exit("sideload requires an argument");
        if (adb_sideload_host(argv[1])) {
            return 1;
@@ -1695,8 +1709,7 @@ int adb_commandline(int argc, const char** argv) {
    else if (!strcmp(argv[0], "ls")) {
        if (argc != 2) error_exit("ls requires an argument");
        return do_sync_ls(argv[1]) ? 0 : 1;
    }
    else if (!strcmp(argv[0], "push")) {
    } else if (!strcmp(argv[0], "push")) {
        bool copy_attrs = false;
        bool sync = false;
        std::vector<const char*> srcs;
@@ -1705,8 +1718,7 @@ int adb_commandline(int argc, const char** argv) {
        parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs, &sync);
        if (srcs.empty() || !dst) error_exit("push requires an argument");
        return do_sync_push(srcs, dst, sync) ? 0 : 1;
    }
    else if (!strcmp(argv[0], "pull")) {
    } else if (!strcmp(argv[0], "pull")) {
        bool copy_attrs = false;
        std::vector<const char*> srcs;
        const char* dst = ".";
@@ -1714,20 +1726,16 @@ int adb_commandline(int argc, const char** argv) {
        parse_push_pull_args(&argv[1], argc - 1, &srcs, &dst, &copy_attrs, nullptr);
        if (srcs.empty()) error_exit("pull requires an argument");
        return do_sync_pull(srcs, dst, copy_attrs) ? 0 : 1;
    }
    else if (!strcmp(argv[0], "install")) {
    } else if (!strcmp(argv[0], "install")) {
        if (argc < 2) error_exit("install requires an argument");
        return install_app(argc, argv);
    }
    else if (!strcmp(argv[0], "install-multiple")) {
    } else if (!strcmp(argv[0], "install-multiple")) {
        if (argc < 2) error_exit("install-multiple requires an argument");
        return install_multiple_app(argc, argv);
    }
    else if (!strcmp(argv[0], "uninstall")) {
    } else if (!strcmp(argv[0], "uninstall")) {
        if (argc < 2) error_exit("uninstall requires an argument");
        return uninstall_app(argc, argv);
    }
    else if (!strcmp(argv[0], "sync")) {
    } else if (!strcmp(argv[0], "sync")) {
        std::string src;
        bool list_only = false;
        if (argc < 2) {
@@ -1757,34 +1765,28 @@ int adb_commandline(int argc, const char** argv) {
        return 0;
    }
    /* passthrough commands */
    else if (!strcmp(argv[0],"get-state") ||
        !strcmp(argv[0],"get-serialno") ||
        !strcmp(argv[0],"get-devpath"))
    {
    else if (!strcmp(argv[0], "get-state") || !strcmp(argv[0], "get-serialno") ||
             !strcmp(argv[0], "get-devpath")) {
        return adb_query_command(format_host_command(argv[0]));
    }
    /* other commands */
    else if (!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat") || !strcmp(argv[0],"longcat")) {
    else if (!strcmp(argv[0], "logcat") || !strcmp(argv[0], "lolcat") ||
             !strcmp(argv[0], "longcat")) {
        return logcat(argc, argv);
    }
    else if (!strcmp(argv[0],"ppp")) {
    } else if (!strcmp(argv[0], "ppp")) {
        return ppp(argc, argv);
    }
    else if (!strcmp(argv[0], "start-server")) {
    } else if (!strcmp(argv[0], "start-server")) {
        std::string error;
        const int result = adb_connect("host:start-server", &error);
        if (result < 0) {
            fprintf(stderr, "error: %s\n", error.c_str());
        }
        return result;
    }
    else if (!strcmp(argv[0], "backup")) {
    } else if (!strcmp(argv[0], "backup")) {
        return backup(argc, argv);
    }
    else if (!strcmp(argv[0], "restore")) {
    } else if (!strcmp(argv[0], "restore")) {
        return restore(argc, argv);
    }
    else if (!strcmp(argv[0], "keygen")) {
    } else if (!strcmp(argv[0], "keygen")) {
        if (argc != 2) error_exit("keygen requires an argument");
        // Always print key generation information for keygen command.
        adb_trace_enable(AUTH);
Loading