From dde22baeb2356f604ca946f2ee99b37b7e256f97 Mon Sep 17 00:00:00 2001 From: Adonis Najimi Date: Tue, 1 May 2018 00:36:50 +0200 Subject: [PATCH] wip: add apk installer --- app/src/apkinstaller.c | 142 +++++++++++++++++++++++++++++++++++++++++ app/src/apkinstaller.h | 40 ++++++++++++ 2 files changed, 182 insertions(+) create mode 100644 app/src/apkinstaller.c create mode 100644 app/src/apkinstaller.h diff --git a/app/src/apkinstaller.c b/app/src/apkinstaller.c new file mode 100644 index 00000000..aa5359af --- /dev/null +++ b/app/src/apkinstaller.c @@ -0,0 +1,142 @@ +#include "apkinstaller.h" + +#include "server.h" // contains server path + +#include "lockutil.h" +#include "log.h" +#include "command.h" +#include "string.h" + +// apk queue +SDL_bool apk_queue_is_empty(const struct apk_queue *queue) { + return queue->head == queue->tail; +} + +SDL_bool apk_queue_is_full(const struct apk_queue *queue) { + return (queue->head + 1) % APK_QUEUE_SIZE == queue->tail; +} + +SDL_bool apk_queue_init(struct apk_queue *queue) { + queue->head = 0; + queue->tail = 0; + return SDL_TRUE; +} + +void apk_queue_destroy(struct apk_queue *queue) { + int i = queue->tail; + while (i != queue->head) { + SDL_free(&queue->data[i]); + i = (i + 1) % APK_QUEUE_SIZE; + } +} + +SDL_bool apk_queue_push(struct apk_queue *queue, const char *apk) { + if (apk_queue_is_full(queue)) { + return SDL_FALSE; + } + strcpy(queue->data[queue->head],apk); + queue->head = (queue->head + 1) % APK_QUEUE_SIZE; + return SDL_TRUE; +} + +SDL_bool apk_queue_take(struct apk_queue *queue, char* apk) { + if (apk_queue_is_empty(queue)) { + return SDL_FALSE; + } + strcpy(apk,queue->data[queue->tail]); + queue->tail = (queue->tail + 1) % APK_QUEUE_SIZE; + return SDL_TRUE; +} + +SDL_bool installer_init(struct installer *installer, const char* serial) { + if (!apk_queue_init(&installer->queue)) { + return SDL_FALSE; + } + + if (!(installer->mutex = SDL_CreateMutex())) { + return SDL_FALSE; + } + + if (!(installer->event_cond = SDL_CreateCond())) { + SDL_DestroyMutex(installer->mutex); + return SDL_FALSE; + } + + installer->stopped = SDL_FALSE; + + return SDL_TRUE; +} + +void installer_destroy(struct installer *installer) { + SDL_DestroyCond(installer->event_cond); + SDL_DestroyMutex(installer->mutex); + apk_queue_destroy(&installer->queue); +} + +SDL_bool installer_push_apk(struct installer *installer, const char* apk) { + SDL_bool res; + mutex_lock(installer->mutex); + SDL_bool was_empty = apk_queue_is_empty(&installer->queue); + res = apk_queue_push(&installer->queue, apk); + if (was_empty) { + cond_signal(installer->event_cond); + } + mutex_unlock(installer->mutex); + return res; +} + +static SDL_bool process_install(struct installer *installer, const char* filename) { + process_t process = adb_install(installer->serial, filename); + return process_check_success(process, "adb install"); +} + +static int run_installer(void *data) { + struct installer *installer = data; + + mutex_lock(installer->mutex); + for (;;) { + while (!installer->stopped && apk_queue_is_empty(&installer->queue)) { + cond_wait(installer->event_cond, installer->mutex); + } + if (installer->stopped) { + // stop immediately, do not process further events + break; + } + char* apk = ""; + while (apk_queue_take(&installer->queue, apk)) { + SDL_bool ok = process_install(installer,apk); + free(apk); + apk = NULL; + if (!ok) { + LOGD("Cannot write event to socket"); + goto end; + } + } + } +end: + mutex_unlock(installer->mutex); + return 0; +} + +SDL_bool installer_start(struct installer *installer) { + LOGD("Starting installer thread"); + + installer->thread = SDL_CreateThread(run_installer, "installer", installer); + if (!installer->thread) { + LOGC("Could not start installer thread"); + return SDL_FALSE; + } + + return SDL_TRUE; +} + +void installer_stop(struct installer *installer) { + mutex_lock(installer->mutex); + installer->stopped = SDL_TRUE; + cond_signal(installer->event_cond); + mutex_unlock(installer->mutex); +} + +void installer_join(struct installer *installer) { + SDL_WaitThread(installer->thread, NULL); +} diff --git a/app/src/apkinstaller.h b/app/src/apkinstaller.h new file mode 100644 index 00000000..e3ab104a --- /dev/null +++ b/app/src/apkinstaller.h @@ -0,0 +1,40 @@ +#ifndef APK_INSTALLER_H +#define APK_INSTALLER_H + +#define APK_QUEUE_SIZE 16 + +#include "apkinstaller.h" + +#include +#include +#include + +// NOTE(AdoPi) apk_queue and control_event can use a generic queue + +struct apk_queue { + char* data[APK_QUEUE_SIZE]; + int tail; + int head; +}; + + +struct installer { + char* serial; + SDL_Thread *thread; + SDL_mutex *mutex; + SDL_cond *event_cond; + SDL_bool stopped; + struct apk_queue queue; +}; + +SDL_bool installer_init(struct installer *installer, const char* serial); +void installer_destroy(struct installer *installer); + +SDL_bool installer_start(struct installer *installer); +void installer_stop(struct installer *installer); +void installer_join(struct installer *installer); + +// install an apk +SDL_bool installer_push_apk(struct installer *installer, const char* filename); + +#endif