forked from wsvn53/adb-mobile
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
945 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
/** | ||
* adb.cpp is used to replace original adb.cpp | ||
*/ | ||
|
||
#include <stdio.h> | ||
#include <pthread.h> | ||
|
||
#define launch_server(...) launch_server_unused(__VA_ARGS__) | ||
#include "adb/adb.cpp" | ||
#undef launch_server | ||
|
||
void fdevent_reset_porting(void); | ||
void clear_listener_list(void); | ||
void clear_transport_list(void); | ||
|
||
// replace exit to pthread_exit | ||
void exit(int code) { | ||
pthread_exit(0); | ||
} | ||
|
||
void launch_server_main(int pipe_write, const char *thread_socket_spec) { | ||
// Launch server with pipe | ||
fcntl(pipe_write, F_SETFD, 0); | ||
printf("launch_server_main: %d\n", pipe_write); | ||
|
||
// We don't need to do clear or reset at first time | ||
static bool not_first = false; | ||
if (not_first == true) { | ||
clear_listener_list(); | ||
clear_transport_list(); | ||
fdevent_reset_porting(); | ||
} | ||
not_first = true; | ||
|
||
#ifdef __ANDROID__ | ||
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED); | ||
printf("fdsan_error_level: %d\n", android_fdsan_get_error_level()); | ||
#endif | ||
|
||
// Start main server | ||
adb_server_main(false, thread_socket_spec, pipe_write); | ||
} | ||
|
||
int launch_server(const std::string& socket_spec) { | ||
static char *thread_socket_spec; | ||
static int pipe_server[2]; | ||
|
||
printf("socket %s\n", socket_spec.c_str()); | ||
thread_socket_spec = strdup(socket_spec.c_str()); | ||
|
||
// Reset last used pipe | ||
pipe(pipe_server); | ||
|
||
// set up a pipe so the child can tell us when it is ready. | ||
if (pipe_server[0] < 0 || pipe_server[1] < 0) { | ||
fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); | ||
return -1; | ||
} | ||
|
||
std::string path = android::base::GetExecutablePath(); | ||
|
||
// launch server in new thread | ||
std::thread adb_thread([]() { | ||
launch_server_main(pipe_server[1], thread_socket_spec); | ||
}); | ||
adb_thread.detach(); | ||
|
||
// parent side | ||
printf("launch_server pipe_write: %d\n", pipe_server[0]); | ||
printf("launch_server pipe_read: %d\n", pipe_server[1]); | ||
|
||
// wait for the "OK\n" message from the child | ||
char temp[3] = {}; | ||
int ret = adb_read(pipe_server[0], temp, 3); | ||
int saved_errno = errno; | ||
if (ret < 0) { | ||
fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); | ||
return -1; | ||
} | ||
if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { | ||
ReportServerStartupFailure(0); | ||
return -1; | ||
} | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/** | ||
* adb_client.cpp used to fix adb_set_socket_spec function | ||
*/ | ||
|
||
extern "C" { | ||
bool adb_kill_server_porting(void); | ||
} | ||
|
||
#define adb_set_socket_spec(...) adb_set_socket_spec_unused(__VA_ARGS__) | ||
#define adb_check_server_version(...) adb_check_server_version_unused(__VA_ARGS__) | ||
|
||
#include "adb/client/adb_client.cpp" | ||
|
||
#undef adb_set_socket_spec | ||
#undef adb_check_server_version | ||
|
||
bool adb_check_server_version(std::string* _Nonnull error) { | ||
// If this is first time be called, ignore, because __adb_server_socket_spec not ready | ||
static bool first_call = true; | ||
if (first_call) { | ||
first_call = false; | ||
return true; | ||
} | ||
|
||
// Make adb check server version can be called more than once | ||
static std::once_flag once; | ||
static bool result; | ||
static std::string* err; | ||
err = new std::string(); | ||
result = __adb_check_server_version(err); | ||
*error = *err; | ||
return result; | ||
} | ||
|
||
void adb_set_socket_spec(const char* socket_spec) { | ||
if (__adb_server_socket_spec) { | ||
// prevent fatal error here, just return | ||
return; | ||
} | ||
__adb_server_socket_spec = socket_spec; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/** | ||
* adb_io.cpp is used to handle ReadExactly with select which can be used to control thread exit | ||
*/ | ||
|
||
#define ReadFdExactly(...) ReadFdExactly_unused(__VA_ARGS__) | ||
|
||
#include "adb/adb_io.cpp" | ||
|
||
#undef ReadFdExactly | ||
#undef read | ||
|
||
// return bool to indicated whether continue to read | ||
bool read_select(borrowed_fd fd) { | ||
char name[10]; | ||
memset(name, 0, sizeof(name)); | ||
pthread_getname_np(pthread_self(), name, sizeof(name)); | ||
if (strlen(name) == 0) { | ||
return true; | ||
} | ||
|
||
std::string thread_name = name; | ||
// thread_name split by ':' | ||
size_t prefix_pos = thread_name.find("adb:"); | ||
if (prefix_pos == std::string::npos) { | ||
// not prefix with 'adb:', continue to read with adb_read | ||
return true; | ||
} | ||
|
||
// split fds | ||
thread_name.erase(0,4); | ||
std::string thread_fd_str = thread_name.substr(0, thread_name.find(":")); | ||
int thread_fd = atoi(thread_fd_str.c_str()); | ||
if (thread_fd <= 0) return true; | ||
|
||
// select read fds | ||
// fd_set with select | ||
fd_set fds; | ||
FD_ZERO(&fds); | ||
FD_SET(thread_fd, &fds); | ||
FD_SET(fd.get(), &fds); | ||
|
||
while (1) { | ||
int ret = select(FD_SETSIZE, &fds, NULL, NULL, NULL); | ||
if (ret == 0) { | ||
continue; | ||
} | ||
|
||
if (FD_ISSET(thread_fd, &fds)) { | ||
char thread_cmd; | ||
size_t n = read(thread_fd, &thread_cmd, 1); | ||
if (n > 0 && thread_cmd == 'Q') { | ||
pthread_exit((void *)0); | ||
return false; | ||
} | ||
printf("unknown thread command: %c\n", thread_cmd); | ||
} | ||
|
||
if (FD_ISSET(fd.get(), &fds)) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
bool ReadFdExactly(borrowed_fd fd, void* buf, size_t len) { | ||
char* p = reinterpret_cast<char*>(buf); | ||
|
||
size_t len0 = len; | ||
|
||
D("readx: fd=%d wanted=%zu", fd.get(), len); | ||
while (len > 0) { | ||
if (!read_select(fd)) { | ||
return false; | ||
} | ||
|
||
int r = adb_read(fd, p, len); | ||
if (r > 0) { | ||
len -= r; | ||
p += r; | ||
} else if (r == -1) { | ||
D("readx: fd=%d error %d: %s", fd.get(), errno, strerror(errno)); | ||
return false; | ||
} else { | ||
D("readx: fd=%d disconnected", fd.get()); | ||
errno = 0; | ||
return false; | ||
} | ||
} | ||
|
||
VLOG(RWX) << "readx: fd=" << fd.get() << " wanted=" << len0 << " got=" << (len0 - len) << " " | ||
<< dump_hex(reinterpret_cast<const unsigned char*>(buf), len0); | ||
|
||
return true; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* adb_listeners.cpp used to modify source code of adb_listeners.cpp in android_tools | ||
*/ | ||
|
||
#include "adb/adb_listeners.cpp" | ||
|
||
void clear_listener_list() { | ||
listener_list.clear(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* adb_porting.cpp used to define some functions to c | ||
*/ | ||
#include <stdio.h> | ||
#include <stdarg.h> | ||
#include "adb_trace.h" | ||
|
||
int porting_log_print(int p, const char *tag, const char *fmt, ...) { | ||
va_list args_list; | ||
va_start(args_list, fmt); | ||
int ret = vprintf(fmt, args_list); | ||
va_end(args_list); | ||
|
||
return ret; | ||
} | ||
|
||
int porting_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...) { | ||
va_list args_list; | ||
va_start(args_list, fmt); | ||
int ret = vprintf(fmt, args_list); | ||
va_end(args_list); | ||
|
||
return ret; | ||
} | ||
|
||
void usb_init() { | ||
return; | ||
} | ||
|
||
void usb_cleanup() { | ||
return; | ||
} | ||
|
||
void adb_trace_enable_porting(int trace_tag) { | ||
adb_trace_enable((AdbTrace)trace_tag); | ||
} | ||
|
||
void abort() { | ||
pthread_exit(NULL); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/** | ||
* commandline.cpp is use to handle command outputs | ||
*/ | ||
#include <stdio.h> | ||
#include <string.h> | ||
|
||
int printf_hijack(const char *format, ...); | ||
size_t fwrite_hijack(const void *__ptr, size_t __size, size_t __nitems, FILE *__stream); | ||
int fprintf_hijack(FILE *file, const char *format, ...); | ||
|
||
#define printf(...) printf_hijack(__VA_ARGS__) | ||
#define fwrite(...) fwrite_hijack(__VA_ARGS__) | ||
#define fprintf(...) fprintf_hijack(__VA_ARGS__) | ||
|
||
#include "adb/client/commandline.cpp" | ||
#include "adb/client/line_printer.cpp" | ||
|
||
#undef printf | ||
#undef fwrite | ||
|
||
// Declare global variable to catch outputs | ||
static std::string adb_commandline_stdout = ""; | ||
void append_commandline_stdout(char *text) { | ||
static pthread_mutex_t adb_append_stdout_lock = PTHREAD_MUTEX_INITIALIZER; | ||
pthread_mutex_lock(&adb_append_stdout_lock); | ||
adb_commandline_stdout.append(text); | ||
pthread_mutex_unlock(&adb_append_stdout_lock); | ||
} | ||
|
||
extern "C" { | ||
int adb_commandline_porting(int argc, const char** argv, char **message); | ||
} | ||
|
||
bool adb_check_server_version(std::string* _Nonnull error); | ||
int adb_commandline_porting(int argc, const char** argv, char **message) { | ||
// Empty stdout handler | ||
adb_commandline_stdout = ""; | ||
|
||
// Trigger adb_check_server_version once before adb_connect | ||
// Because adb_check_server_version only be called once, hacked here | ||
static std::string *error; | ||
error = new std::string(); | ||
if (!adb_check_server_version(error)) { | ||
*message = strdup(error->c_str()); | ||
return -1; | ||
} | ||
|
||
// Execute adb commandline | ||
int ret = adb_commandline(argc, argv); | ||
*message = strdup(adb_commandline_stdout.c_str()); | ||
if (ret != 0 && strlen(*message) == 0) { | ||
*message = strdup("adb_commandline failed"); | ||
} | ||
return ret; | ||
} | ||
|
||
int printf_hijack(const char *format, ...) { | ||
va_list args; | ||
va_start(args, format); | ||
int size = vsnprintf(NULL, 0, format, args); | ||
char text[size+1]; | ||
vsprintf(text, format, args); | ||
text[size] = '\0'; | ||
va_end(args); | ||
append_commandline_stdout(text); | ||
return 0; | ||
} | ||
|
||
size_t fwrite_hijack(const void *__ptr, size_t __size, size_t __nitems, FILE *__stream) { | ||
if (__ptr == NULL || strlen((char *)__ptr) == 0) { | ||
return 0; | ||
} | ||
char text[__nitems+1]; | ||
strncpy(text, (char *)__ptr, __nitems); | ||
text[__nitems] = '\0'; | ||
append_commandline_stdout(text); | ||
return 0; | ||
} | ||
|
||
int fprintf_hijack(FILE *file, const char *format, ...) { | ||
va_list args; | ||
va_start(args, format); | ||
int size = vsnprintf(NULL, 0, format, args); | ||
char text[size+1]; | ||
vsprintf(text, format, args); | ||
text[size] = '\0'; | ||
va_end(args); | ||
append_commandline_stdout(text); | ||
return 0; | ||
} |
Oops, something went wrong.