From 71cf764907df2869a2ac33cbf19aff5710760e23 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 25 Dec 2021 10:55:43 +0200 Subject: [PATCH] apk build (not done) --- .gitignore | 2 + Makefile.android | 28 ++++- src/android/android_native_app_glue.c | 41 +++---- src/android/main.c | 203 ++++++++++++++++++++++++++++++++- 4 files changed, 248 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 9194d39..3730bf2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ *.swp demo *.so +*.apk* +keystore.jks diff --git a/Makefile.android b/Makefile.android index 0df3c95..904df4b 100644 --- a/Makefile.android +++ b/Makefile.android @@ -1,19 +1,41 @@ +SDK ?= /usr/lib/android-sdk NDK ?= /usr/lib/android-ndk CCSYSROOT = $(NDK)/sysroot ISYS = $(CCSYSROOT)/usr/include/aarch64-linux-android -LDSYSROOT = $(NDK)/platforms/anrdoid-21/arch-arm64 +LDSYSROOT = $(NDK)/platforms/android-23/arch-arm64 +PLATFORM_JAR = $(SDK)/platforms/android-23/android.jar TCPATH = $(NDK)/toolchains/llvm/prebuilt/linux-$(shell uname -m)/bin -TC = $(TCPATH)/aarch64-linux-android21- +TC = $(TCPATH)/aarch64-linux-android23- src = $(wildcard src/*.c) $(wildcard src/android/*.c) obj = $(src:.c=.arm64.o) dep = $(src:.c=.d) -lib_so = libandemo.so +name = andemo +lib_so = lib$(name).so + +warn = -pedantic -Wall +dbg = -g +opt = -O3 -ffast-math -fno-strict-aliasing +incdir = -Isrc CC = $(TC)clang CFLAGS = --sysroot=$(CCSYSROOT) -isystem=$(ISYS) $(warn) $(dbg) $(opt) $(def) $(incdir) -fPIC -fcommon -MMD LDFLAGS = --sysroot=$(LDSYSROOT) -lEGL -lGLESv2 +$(name).apk: $(name).aligned.apk keystore.jks + apksigner sign --ks keystore.jks --ks-key-alias androidkey --ks-pass pass:android --key-pass pass:android --out $@ $< + +keystore.jks: + keytool -genkeypair -keystore $@ -alias androidkey -validity 10000 -keyalg RSA -keysize 2048 -storepass android -keypass android + +$(name).aligned.apk: $(name).unsigned.apk + zipalign -f -p 4 $< $@ + +$(name).unsigned.apk: $(lib_so) AndroidManifest.xml + mkdir -p apkbuild/lib/aarch64 + cp $(lib_so) apkbuild/lib/aarch64 + aapt package -f -v -F $@ -I $(PLATFORM_JAR) -M AndroidManifest.xml apkbuild + $(lib_so): $(obj) $(CC) -o $@ -shared $(obj) $(LDFLAGS) diff --git a/src/android/android_native_app_glue.c b/src/android/android_native_app_glue.c index 7eada08..0e34391 100644 --- a/src/android/android_native_app_glue.c +++ b/src/android/android_native_app_glue.c @@ -182,7 +182,7 @@ static void android_app_destroy(struct android_app* android_app) { android_app->destroyed = 1; pthread_cond_broadcast(&android_app->cond); pthread_mutex_unlock(&android_app->mutex); - // Can't touch android_app object after this. + /* Can't touch android_app object after this. */ } static void process_input(struct android_app* app, struct android_poll_source* source) { @@ -236,9 +236,10 @@ static void* android_app_entry(void* param) { return NULL; } -// -------------------------------------------------------------------- -// Native activity interaction (called from main thread) -// -------------------------------------------------------------------- +/* -------------------------------------------------------------------- + * Native activity interaction (called from main thread) + * -------------------------------------------------------------------- +*/ static struct android_app* android_app_create(ANativeActivity* activity, void* savedState, size_t savedStateSize) { @@ -263,12 +264,12 @@ static struct android_app* android_app_create(ANativeActivity* activity, android_app->msgread = msgpipe[0]; android_app->msgwrite = msgpipe[1]; - pthread_attr_t attr; + pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&android_app->thread, &attr, android_app_entry, android_app); - // Wait for thread to start. + /* Wait for thread to start. */ pthread_mutex_lock(&android_app->mutex); while (!android_app->running) { pthread_cond_wait(&android_app->cond, &android_app->mutex); @@ -334,17 +335,17 @@ static void android_app_free(struct android_app* android_app) { } static void onDestroy(ANativeActivity* activity) { - LOGV("Destroy: %p\n", activity); + LOGV("Destroy: %p\n", (void*)activity); android_app_free((struct android_app*)activity->instance); } static void onStart(ANativeActivity* activity) { - LOGV("Start: %p\n", activity); + LOGV("Start: %p\n", (void*)activity); android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); } static void onResume(ANativeActivity* activity) { - LOGV("Resume: %p\n", activity); + LOGV("Resume: %p\n", (void*)activity); android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); } @@ -352,7 +353,7 @@ static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { struct android_app* android_app = (struct android_app*)activity->instance; void* savedState = NULL; - LOGV("SaveInstanceState: %p\n", activity); + LOGV("SaveInstanceState: %p\n", (void*)activity); pthread_mutex_lock(&android_app->mutex); android_app->stateSaved = 0; android_app_write_cmd(android_app, APP_CMD_SAVE_STATE); @@ -373,57 +374,57 @@ static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { } static void onPause(ANativeActivity* activity) { - LOGV("Pause: %p\n", activity); + LOGV("Pause: %p\n", (void*)activity); android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); } static void onStop(ANativeActivity* activity) { - LOGV("Stop: %p\n", activity); + LOGV("Stop: %p\n", (void*)activity); android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); } static void onConfigurationChanged(ANativeActivity* activity) { struct android_app* android_app = (struct android_app*)activity->instance; - LOGV("ConfigurationChanged: %p\n", activity); + LOGV("ConfigurationChanged: %p\n", (void*)activity); android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED); } static void onLowMemory(ANativeActivity* activity) { struct android_app* android_app = (struct android_app*)activity->instance; - LOGV("LowMemory: %p\n", activity); + LOGV("LowMemory: %p\n", (void*)activity); android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY); } static void onWindowFocusChanged(ANativeActivity* activity, int focused) { - LOGV("WindowFocusChanged: %p -- %d\n", activity, focused); + LOGV("WindowFocusChanged: %p -- %d\n", (void*)activity, focused); android_app_write_cmd((struct android_app*)activity->instance, focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); } static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { - LOGV("NativeWindowCreated: %p -- %p\n", activity, window); + LOGV("NativeWindowCreated: %p -- %p\n", (void*)activity, (void*)window); android_app_set_window((struct android_app*)activity->instance, window); } static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { - LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window); + LOGV("NativeWindowDestroyed: %p -- %p\n", (void*)activity, (void*)window); android_app_set_window((struct android_app*)activity->instance, NULL); } static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { - LOGV("InputQueueCreated: %p -- %p\n", activity, queue); + LOGV("InputQueueCreated: %p -- %p\n", (void*)activity, (void*)queue); android_app_set_input((struct android_app*)activity->instance, queue); } static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { - LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue); + LOGV("InputQueueDestroyed: %p -- %p\n", (void*)activity, (void*)queue); android_app_set_input((struct android_app*)activity->instance, NULL); } JNIEXPORT void ANativeActivity_onCreate(ANativeActivity* activity, void* savedState, size_t savedStateSize) { - LOGV("Creating: %p\n", activity); + LOGV("Creating: %p\n", (void*)activity); activity->callbacks->onDestroy = onDestroy; activity->callbacks->onStart = onStart; activity->callbacks->onResume = onResume; diff --git a/src/android/main.c b/src/android/main.c index 7b971d5..2ec85b6 100644 --- a/src/android/main.c +++ b/src/android/main.c @@ -1,17 +1,28 @@ +#include +#include #include #include #include "demo.h" #include "android_native_app_glue.h" +static void handle_command(struct android_app *app, int32_t cmd); +static int handle_input(struct android_app *app, AInputEvent *ev); +static int handle_touch_input(struct android_app *app, AInputEvent *ev); +static int init_gl(void); +static void destroy_gl(void); + static struct android_app *app; static EGLDisplay dpy; static EGLSurface surf; static EGLContext ctx; +static int running; + +static int width, height; + void android_main(struct android_app *app_ptr) { - app_dummy(); app = app_ptr; app->onAppCmd = handle_command; @@ -23,16 +34,202 @@ void android_main(struct android_app *app_ptr) while(ALooper_pollAll(0, 0, &num_events, (void**)&pollsrc) >= 0) { if(pollsrc) { - pollsrc->process(ap, pollsrc); + pollsrc->process(app, pollsrc); } } if(app->destroyRequested) { return; } - if(!paused) { + if(running) { demo_display(); eglSwapBuffers(dpy, surf); } } } + +static void handle_command(struct android_app *app, int32_t cmd) +{ + int xsz, ysz; + + switch(cmd) { + case APP_CMD_PAUSE: + running = 0; /* TODO: handle timers */ + break; + case APP_CMD_RESUME: + running = 1; + break; + + case APP_CMD_INIT_WINDOW: + if(init_gl() == -1) { + exit(1); + } + if(demo_init() == -1) { + exit(1); + } + demo_reshape(width, height); + running = 1; + break; + + case APP_CMD_TERM_WINDOW: + running = 0; + demo_cleanup(); + destroy_gl(); + break; + + case APP_CMD_WINDOW_RESIZED: + case APP_CMD_CONFIG_CHANGED: + xsz = ANativeWindow_getWidth(app->window); + ysz = ANativeWindow_getHeight(app->window); + if(xsz != width || ysz != height) { + printf("reshape(%d, %d)\n", xsz, ysz); + demo_reshape(xsz, ysz); + width = xsz; + height = ysz; + } + break; + + /* + case APP_CMD_SAVE_STATE: + case APP_CMD_GAINED_FOCUS: + case APP_CMD_LOST_FOCUS: + */ + default: + break; + } +} + +static int handle_input(struct android_app *app, AInputEvent *ev) +{ + int evtype = AInputEvent_getType(ev); + + switch(evtype) { + case AINPUT_EVENT_TYPE_MOTION: + return handle_touch_input(app, ev); + + default: + break; + } + return 0; +} + +static int handle_touch_input(struct android_app *app, AInputEvent *ev) +{ + int i, pcount, x, y, idx; + unsigned int action; + static int prev_pos[2]; + + action = AMotionEvent_getAction(ev); + + idx = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> + AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; + + x = AMotionEvent_getX(ev, idx); + y = AMotionEvent_getY(ev, idx); + + switch(action & AMOTION_EVENT_ACTION_MASK) { + case AMOTION_EVENT_ACTION_DOWN: + case AMOTION_EVENT_ACTION_POINTER_DOWN: + demo_mouse(0, 1, x, y); + + prev_pos[0] = x; + prev_pos[1] = y; + break; + + case AMOTION_EVENT_ACTION_UP: + case AMOTION_EVENT_ACTION_POINTER_UP: + demo_mouse(0, 0, x, y); + + prev_pos[0] = x; + prev_pos[1] = y; + break; + + case AMOTION_EVENT_ACTION_MOVE: + pcount = AMotionEvent_getPointerCount(ev); + for(i=0; iwindow, 0, 0, vis); + + if(!(surf = eglCreateWindowSurface(dpy, eglcfg, app->window, 0))) { + fprintf(stderr, "failed to create window\n"); + destroy_gl(); + return -1; + } + + if(!(ctx = eglCreateContext(dpy, eglcfg, EGL_NO_CONTEXT, ctxattr))) { + fprintf(stderr, "failed to create OpenGL ES context\n"); + destroy_gl(); + return -1; + } + eglMakeCurrent(dpy, surf, surf, ctx); + + eglQuerySurface(dpy, surf, EGL_WIDTH, &width); + eglQuerySurface(dpy, surf, EGL_HEIGHT, &height); + return 0; +} + +static void destroy_gl(void) +{ + if(!dpy) return; + + eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + + if(ctx) { + eglDestroyContext(dpy, ctx); + ctx = 0; + } + if(surf) { + eglDestroySurface(dpy, surf); + surf = 0; + } + + eglTerminate(dpy); + dpy = 0; +} -- 1.7.10.4