[Feature][T8TSK-250][ADBD]add adb debug patch
Only Configure: No
Affected branch: GSW3.0-No-Connman
Affected module: adbd
Is it addected on both ZXIC and MTK: only MTK
Self-test: Yes
Doc Update: No
Change-Id: Id158d099ac8b9661a4fa1b51e731be951da56ed8
diff --git a/src/devtools/adb/usb_linux_client.c b/src/devtools/adb/usb_linux_client.c
index 2466275..da39951 100644
--- a/src/devtools/adb/usb_linux_client.c
+++ b/src/devtools/adb/usb_linux_client.c
@@ -58,6 +58,15 @@
#define FFS_CONTOL_MAX_EPOLL_EVENT 50
#define DEBUG 0
+#define USB_FFS_WAKE_LOCK_ID "usb_adbd_wakelock"
+#define USB_FFS_WAKE_LOCK_TIMEOUT (2 * 1000)
+
+static const char* sTag = "adbd_usb";
+adb_mutex_t g_wake_lock;
+timer_t g_wake_unlock_timer;
+bool g_wake_lock_acquired;
+typedef void (*timer_routine) (int id);
+
struct usb_handle
{
adb_cond_t notify;
@@ -75,6 +84,7 @@
int bulk_out; /* "out" from the host's perspective => source for adbd */
int bulk_in; /* "in" from the host's perspective => sink for adbd */
bool ffs_control_thread_created;
+ bool ffs_control_suspend_mode;
};
static const struct {
@@ -312,10 +322,12 @@
h->bulk_out = -1;
h->control = -1;
h->ffs_control_thread_created = false;
+ h->ffs_control_suspend_mode = false;
h->fd = -1;
adb_cond_init(&h->notify, 0);
adb_mutex_init(&h->lock, 0);
+ adb_mutex_init(&g_wake_lock, 0);
// Open the file /dev/android_adb_enable to trigger
// the enabling of the adb USB function in the kernel.
@@ -335,6 +347,94 @@
}
}
+////////////////////// wake lock ///////////////////////////////
+timer_t timer_init(timer_routine cb, int id) {
+ struct sigevent sevp;
+ timer_t timerid;
+
+ memset(&sevp, 0, sizeof(sevp));
+ sevp.sigev_value.sival_int = id;
+ sevp.sigev_notify = SIGEV_THREAD;
+ sevp.sigev_notify_function = (void*)cb;
+
+ if(timer_create(CLOCK_BOOTTIME, &sevp, &timerid) == -1) {
+ D("timer_init() timer_create() failed, reason=[%s]%d",
+ strerror(errno), errno);
+ return NULL;
+ }
+ return timerid;
+}
+
+bool timer_start(timer_t timerid, int milliseconds) {
+ struct itimerspec expire;
+ expire.it_interval.tv_sec = 0;
+ expire.it_interval.tv_nsec = 0;
+ expire.it_value.tv_sec = milliseconds/1000;
+ expire.it_value.tv_nsec = (milliseconds%1000)*1000000;
+ if(timer_settime(timerid, 0, &expire, NULL) == -1) {
+ D("timer_start() timer_settime() failed, reason=[%s]%d", strerror(errno), errno);
+ return false;
+ }
+ return true;
+}
+
+bool timer_stop(timer_t timerid) {
+ return timer_start(timerid, 0);
+}
+
+bool usb_ffs_wake_lock() {
+#if !defined(__LBS_OS_LINUX__) //no permission to open wake_lock on Linux
+ int fd = adb_open("/sys/power/wake_lock", O_RDWR | O_NONBLOCK);
+ if(fd == -1) {
+ D("[%s] open() failed, reason=[%s]%d", sTag, strerror(errno), errno);
+ return false;
+ }
+
+ int ret = adb_write(fd, USB_FFS_WAKE_LOCK_ID, strlen(USB_FFS_WAKE_LOCK_ID));
+ if(ret == -1) {
+ D("[%s] write() failed id=[%s], reason=[%s]%d", sTag, USB_FFS_WAKE_LOCK_ID, strerror(errno), errno);
+ adb_close(fd);
+ return false;
+ }
+
+ adb_close(fd);
+#endif
+ return true;
+}
+
+bool usb_ffs_wake_unlock() {
+#if !defined(__LBS_OS_LINUX__) //no permission to open wake_lock on Linux
+ int fd = adb_open("/sys/power/wake_unlock", O_RDWR | O_NONBLOCK);
+ if(fd == -1) {
+ D("[%s] open() failed, reason=[%s]%d", sTag, strerror(errno), errno);
+ return false;
+ }
+
+ int ret = adb_write(fd, USB_FFS_WAKE_LOCK_ID, strlen(USB_FFS_WAKE_LOCK_ID));
+ if(ret == -1) {
+ D("[%s] write() failed id=[%s], reason=[%s]%d", sTag,
+ USB_FFS_WAKE_LOCK_ID, strerror(errno), errno);
+ adb_close(fd);
+ return false;
+ }
+
+ adb_close(fd);
+#endif
+ return true;
+}
+
+static void usb_ffs_timer_wake_unlock_routine(int id) {
+ //do not use the internal msg or it will cause infinite loop in epoll_wait
+ adb_mutex_lock(&g_wake_lock);
+ if(g_wake_lock_acquired) {
+ if(usb_ffs_wake_unlock()) {
+ g_wake_lock_acquired = false;
+ }
+ }
+ if (DEBUG) D("[%s] unlock wake_lock_acquired=[%d]", sTag, g_wake_lock_acquired);
+ adb_mutex_unlock(&g_wake_lock);
+}
+
static void *ffs_control_read_msg_thread(void *_h)
{
usb_handle *h = _h;
@@ -404,6 +504,13 @@
D("event.type: %s\n", ffs_get_event_type_code(event.type));
switch (event.type) {
+ case FUNCTIONFS_SUSPEND:
+ D("received FUNCTIONFS_SUSPEND set suspend mode 1");
+ h->ffs_control_suspend_mode = true;
+ break;
+ case FUNCTIONFS_RESUME:
+ D("received FUNCTIONFS_RESUME");
+ break;
case FUNCTIONFS_SETUP: {
D("received FUNCTIONFS_SETUP");
D("bRequestType = %d",(int)(event.u.setup.bRequestType));
@@ -460,6 +567,7 @@
int control_fd = h->control;
struct epoll_event events[FFS_CONTOL_MAX_EPOLL_EVENT];
+ g_wake_unlock_timer = timer_init(usb_ffs_timer_wake_unlock_routine, 0);
int epfd = epoll_create(FFS_CONTOL_MAX_EPOLL_EVENT);
if(epfd == -1) {
D("ERR: epoll_create() fail reason=[%s]", strerror(errno));
@@ -475,6 +583,14 @@
D("Before ffs control thread epoll_wait");
n = epoll_wait(epfd, events, FFS_CONTOL_MAX_EPOLL_EVENT , -1);
+ adb_mutex_lock(&g_wake_lock);
+ timer_stop(g_wake_unlock_timer);
+ if (!g_wake_lock_acquired) {
+ g_wake_lock_acquired = usb_ffs_wake_lock();
+ if (DEBUG) D("[%s] wake_lock_acquired=[%d]", sTag, g_wake_lock_acquired);
+ }
+ adb_mutex_unlock(&g_wake_lock);
+
for(i = 0; i < n; i++) {
if(events[i].data.fd == control_fd) {
if(events[i].events & EPOLLIN) {
@@ -483,6 +599,8 @@
}
}
}
+
+ timer_start(g_wake_unlock_timer, USB_FFS_WAKE_LOCK_TIMEOUT);
}
}
@@ -646,11 +764,22 @@
D("about to read (fd=%d, len=%d)\n", h->bulk_out, len);
n = bulk_read(h->bulk_out, data, len);
- if (n != len) {
+ if (h->ffs_control_suspend_mode) {
+ if (n < 0) {
+ int ret_err = -1 * errno;
+ D("Suspended bulk_read() ERROR: fd = %d, n = %d, errno = %d (%s) ret_err=%d\n",
+ h->bulk_out, n, errno, strerror(errno), ret_err);
+ return ret_err;
+ } else {
+ D("Suspended bulk_read: fd = %d, n = %d, errno = %d (%s) len:%d data:%s\n",
+ h->bulk_out, n, errno, strerror(errno), len, data);
+ }
+ } else if (n != len) {
D("ERROR: fd = %d, n = %d, errno = %d (%s)\n",
h->bulk_out, n, errno, strerror(errno));
return -1;
}
+ h->ffs_control_suspend_mode = false;
D("[ done fd=%d ]\n", h->bulk_out);
return 0;
}
@@ -705,6 +834,7 @@
adb_cond_init(&h->notify, 0);
adb_mutex_init(&h->lock, 0);
+ adb_mutex_init(&g_wake_lock, 0);
D("[ usb_init - starting thread ]\n");
if (adb_thread_create(&tid, usb_ffs_open_thread, h)){