ecere/drivers/Android: Tweaks to run with latest Android SDK/NDK on Nexus 9
authorJerome St-Louis <jerome@ecere.com>
Thu, 10 Dec 2015 04:43:31 +0000 (23:43 -0500)
committerJerome St-Louis <jerome@ecere.com>
Thu, 28 Jul 2016 22:23:15 +0000 (18:23 -0400)
- Improved resolving library path to work on newer Android, ARM64/Nexus 9
- Working around ntohs() macros breaking

ecere/src/com/instance.c
ecere/src/com/instance.ec
ecere/src/gui/drivers/AndroidInterface.ec
ecere/src/net/Service.ec
ecere/src/net/Socket.ec

index 7ae555d..59304a8 100644 (file)
@@ -494,7 +494,10 @@ void * Instance_Module_Load(const char * libLocation, const char * name, void **
 #endif
 
 #if !defined(__EMSCRIPTEN__)
+   // dlerror();
    library = dlopen(fileName, RTLD_LAZY);
+   // if(!library)
+      // printf("Error opening %s: %s", fileName, dlerror());
 #endif
    while(!library && attempts < sizeof(paths)/sizeof(paths[0]))
    {
index 5b9388d..d90d650 100644 (file)
@@ -110,7 +110,7 @@ private:
 
 #if defined(__ANDROID__)
 
-default const char * AndroidInterface_GetLibLocation();
+default const char * AndroidInterface_GetLibLocation(Module m);
 
 #include <android/log.h>
 #include <android/native_activity.h>
@@ -5577,7 +5577,7 @@ static Module Module_Load(Module fromModule, const char * name, AccessMode impor
       {
          const char * libLocation = null;
 #if defined(__ANDROID__)
-         libLocation = AndroidInterface_GetLibLocation();
+         libLocation = AndroidInterface_GetLibLocation(fromModule.application);
 #endif
          library = Instance_Module_Load(libLocation, name, &Load, &Unload);
       }
index c3af1dd..a79b8a3 100644 (file)
@@ -12,6 +12,7 @@ import "Condition"
 #include <locale.h>
 #include <pthread.h>
 #include <unistd.h>
+#include <sys/prctl.h>
 
 #include <android/configuration.h>
 #include <android/looper.h>
@@ -24,6 +25,8 @@ import "Condition"
 #undef set
 #undef uint
 
+#define printf(...) ((void)__android_log_print(ANDROID_LOG_INFO, "ecere-app", __VA_ARGS__))
+
 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "ecere-app", __VA_ARGS__))
 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "ecere-app", __VA_ARGS__))
 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "ecere-app", __VA_ARGS__))
@@ -50,6 +53,8 @@ public:
    virtual void any_object::process();
 };
 
+static const char * packagePath;
+
 class AndroidAppGlue : Thread
 {
    void* userData;
@@ -201,7 +206,7 @@ private:
 
    void pre_exec_cmd(AppCommand cmd)
    {
-      PrintLn("pre_exec_cmd: ", cmd);
+      //PrintLn("pre_exec_cmd: ", cmd);
       switch(cmd)
       {
          case inputChanged:
@@ -244,7 +249,7 @@ private:
 
    void post_exec_cmd(AppCommand cmd)
    {
-      PrintLn("post_exec_cmd: ", cmd);
+      //PrintLn("post_exec_cmd: ", cmd);
       switch(cmd)
       {
          case termWindow:
@@ -480,6 +485,8 @@ default dllexport void ANativeActivity_onCreate(ANativeActivity* activity, void*
    __thisModule = null;
    __androidCurrentModule = null;
 
+   prctl(PR_SET_DUMPABLE, 1);
+
    LOGI("Creating: %p\n", activity);
 
    //(*activity->vm)->AttachCurrentThread(activity->vm, &env, 0);
@@ -487,26 +494,35 @@ default dllexport void ANativeActivity_onCreate(ANativeActivity* activity, void*
    methodID = (*env)->GetMethodID(env, clazz, "getPackageName", "()Ljava/lang/String;");
    result = (*env)->CallObjectMethod(env, activity->clazz, methodID);
    str = (*env)->GetStringUTFChars(env, (jstring)result, &isCopy);
-   // (*activity->vm)->DetachCurrentThread(activity->vm);
+
    moduleName = strstr(str, "com.ecere.");
    if(moduleName) moduleName += 10;
    androidArgv[0] = moduleName;
 
+   methodID = (*env)->GetMethodID(env, clazz, "getPackageCodePath", "()Ljava/lang/String;");
+   result = (*env)->CallObjectMethod(env, activity->clazz, methodID);
+   str = (*env)->GetStringUTFChars(env, (jstring)result, &isCopy);
+   packagePath = str;
+   // (*activity->vm)->DetachCurrentThread(activity->vm);
+   LOGI("packagePath: %s\n", packagePath);
+
    // Create a base Application class
    __androidCurrentModule = __ecere_COM_Initialize(true, 1, androidArgv);
    // Load up Ecere
    eModule_Load(__androidCurrentModule, "ecere", publicAccess);
 
-
+   /*
    if(activity->internalDataPath) PrintLn("internalDataPath is ", activity->internalDataPath);
    if(activity->externalDataPath) PrintLn("externalDataPath is ", activity->externalDataPath);
    {
       char tmp[256];
       PrintLn("cwd is ", GetWorkingDir(tmp, sizeof(tmp)));
    }
+   */
 
    ANativeActivity_setWindowFlags(activity, AWINDOW_FLAG_FULLSCREEN|AWINDOW_FLAG_KEEP_SCREEN_ON, 0 );
    app = AndroidActivity { activity = activity, moduleName = moduleName };
+
    incref app;
    app.setSavedState(savedState, (uint)savedStateSize);
    activity->callbacks->onDestroy = onDestroy;
@@ -906,15 +922,50 @@ struct SavedState
 
 static AndroidActivity androidActivity;
 
-default const char * AndroidInterface_GetLibLocation()
+default const char * AndroidInterface_GetLibLocation(Application a)
 {
-   if(androidActivity)
+   static char loc[MAX_LOCATION] = "", mod[MAX_LOCATION];
+   bool found = false;
+#if defined(__LP64__)
+   static const char * arch = "arm64";
+#else
+   static const char * arch = "armeabi";
+#endif
+   int i;
+   bool useArch = true;
+
+   while(!found)
    {
-      static char loc[MAX_LOCATION];
-      sprintf(loc, "/data/data/com.ecere.%s/lib/lib", androidActivity.moduleName);
-      return loc;
+      StripLastDirectory(packagePath, loc);
+      strcatf(loc, "/lib/%s/lib", useArch ? arch : "");
+      sprintf(mod, "%s%s.so", loc, a.argv[0]);
+      found = FileExists(mod).isFile;
+      if(!found)
+      {
+         bool useApp = true;
+         while(!found)
+         {
+            for(i = 0; !found && i < 10; i++)
+            {
+               if(i)
+                  sprintf(loc, "/data/%s/com.ecere.%s-%d/lib/%s/lib", useApp ? "app" : "data", a.argv[0], i, useArch ? arch : "");
+               else
+                  sprintf(loc, "/data/%s/com.ecere.%s/lib/%s/lib",    useApp ? "app" : "data", a.argv[0], useArch ? arch : "");
+               sprintf(mod, "%s%s.so", loc, a.argv[0]);
+               found = FileExists(mod).isFile;
+            }
+            if(useApp)
+               useApp = false;
+            else
+               break;
+         }
+      }
+      if(useArch)
+         useArch = false;
+      else
+         break;
    }
-   return null;
+   return loc;
 }
 
 static bool gotInit;
index 686fb68..2728439 100644 (file)
@@ -46,6 +46,24 @@ typedef struct in_addr IN_ADDR;
 
 import "network"
 
+#ifdef __ANDROID__
+#include <endian.h>
+#undef ntohs
+#undef htons
+
+#define SWAP_WORD(word) (((uint16)(word) & 0x00ff) << 8) \
+                      | (((uint16)(word) & 0xff00) >> 8)
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define ntohs(x)(x)
+#define htons(x)(x)
+#else
+#define ntohs(x) SWAP_WORD(x)
+#define htons(x) SWAP_WORD(x)
+#endif
+
+#endif
+
 public class Service
 {
 public:
index 96b25cf..b462f7a 100644 (file)
@@ -43,6 +43,25 @@ typedef struct in_addr IN_ADDR;
 
 import "network"
 
+
+#ifdef __ANDROID__
+#include <endian.h>
+#undef ntohs
+#undef htons
+
+#define SWAP_WORD(word) (((uint16)(word) & 0x00ff) << 8) \
+                      | (((uint16)(word) & 0xff00) >> 8)
+
+#if _BYTE_ORDER == _BIG_ENDIAN
+#define ntohs(x)(x)
+#define htons(x)(x)
+#else
+#define ntohs(x) SWAP_WORD(x)
+#define htons(x) SWAP_WORD(x)
+#endif
+
+#endif
+
 #define GETLEDWORD(b) (uint32)(((b)[3] << 24) | ((b)[2] << 16) | ((b)[1] << 8) | (b)[0])
 
 #define PUTLEDWORD(b, d) \