This is an automated email from the ASF dual-hosted git repository.

kyork pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-weex.git


The following commit(s) were added to refs/heads/master by this push:
     new fd558c0  [Feature] Support Android R (#3284)
fd558c0 is described below

commit fd558c049494f84457d996aa8217896bcba48651
Author: katherine95s <[email protected]>
AuthorDate: Tue Oct 20 14:40:45 2020 +0800

    [Feature] Support Android R (#3284)
    
    * FIx jsc Crash on Android R arm64 devices
    * Update create fd method
    * Remove JavaScript Log
    
    Co-authored-by: 东煜 <[email protected]>
    Co-authored-by: xumin.mxm <[email protected]>
---
 .../main/java/org/apache/weex/WXEnvironment.java   | 27 ++++++-
 weex_core/Source/CMakeLists.txt                    |  3 +-
 weex_core/Source/android/jsengine/CMakeLists.txt   |  5 +-
 .../android/multiprocess/weex_js_connection.cpp    | 92 ++++++++++++++++++----
 .../android/multiprocess/weex_js_connection.h      | 11 ++-
 weex_core/Source/android/utils/params_utils.cpp    |  9 +++
 weex_core/Source/android/utils/so_utils.cpp        |  1 +
 weex_core/Source/android/utils/so_utils.h          |  6 ++
 weex_core/Source/js_runtime/CMakeLists.txt         |  2 +-
 9 files changed, 137 insertions(+), 19 deletions(-)

diff --git a/android/sdk/src/main/java/org/apache/weex/WXEnvironment.java 
b/android/sdk/src/main/java/org/apache/weex/WXEnvironment.java
index 7fc01e6..0f8ba4c 100644
--- a/android/sdk/src/main/java/org/apache/weex/WXEnvironment.java
+++ b/android/sdk/src/main/java/org/apache/weex/WXEnvironment.java
@@ -28,23 +28,26 @@ import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.graphics.Typeface;
+import android.os.Build;
 import android.os.Environment;
 import android.support.annotation.RestrictTo;
 import android.support.annotation.RestrictTo.Scope;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
+import android.system.Os;
 import dalvik.system.PathClassLoader;
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.FileReader;
 import java.io.IOException;
+import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import org.apache.weex.R;
 import org.apache.weex.common.WXConfig;
 import org.apache.weex.utils.FontDO;
 import org.apache.weex.utils.LogLevel;
@@ -561,6 +564,28 @@ public class WXEnvironment {
     return null;
   }
 
+  public static int memfd_create(String name, int size) {
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
+      return 0;
+    }
+
+    int fd = 0;
+    try {
+      Method memfd_create = Os.class.getMethod("memfd_create", String.class, 
int.class);
+      Object fd_object = memfd_create.invoke(null, name, 0);
+      if (fd_object instanceof FileDescriptor) {
+        Field descriptor = FileDescriptor.class.getDeclaredField("descriptor");
+        descriptor.setAccessible(true);
+        Object fd_int_object = descriptor.get(fd_object);
+        fd = Integer.parseInt(String.valueOf(fd_int_object));
+        descriptor.setAccessible(false);
+        Os.ftruncate((FileDescriptor) fd_object, size);
+      }
+    } catch (Throwable e) {
+      // do Nothing
+    }
+    return fd;
+  }
 
   public static String findSoPath(String libName) {
     String soPath = ((PathClassLoader) 
(WXEnvironment.class.getClassLoader())).findLibrary(libName);
diff --git a/weex_core/Source/CMakeLists.txt b/weex_core/Source/CMakeLists.txt
index 2b7a392..c05254e 100755
--- a/weex_core/Source/CMakeLists.txt
+++ b/weex_core/Source/CMakeLists.txt
@@ -39,7 +39,8 @@ add_definitions(-DPERFORMANCE_LOG=0)
 add_definitions(-DLAYOUT_LOG=0)
 add_definitions(-DJSAPI_LOG=0)
 add_definitions(-DDOM_PARSER_LOG=0)
-add_definitions(-DDEBUG=1)
+#add_definitions(-DDEBUG=1)
+add_definitions(-DNDEBUG=1)
 
 message("ANDROID_PROJECT_DIR:"${ANDROID_PROJECT_DIR})
 set(LOCAL_LIBRARIES_DIR ${ANDROID_PROJECT_DIR}/src/main/jniLibs/${ANDROID_ABI})
diff --git a/weex_core/Source/android/jsengine/CMakeLists.txt 
b/weex_core/Source/android/jsengine/CMakeLists.txt
index 4c0a691..809a53e 100644
--- a/weex_core/Source/android/jsengine/CMakeLists.txt
+++ b/weex_core/Source/android/jsengine/CMakeLists.txt
@@ -26,7 +26,10 @@ set(PORT JSCOnly)
 add_definitions(-DPRINT_LOG_CACHEFILE=0)
 add_definitions(-DOS_ANDROID)
 #add_definitions(-DNDEBUG)
-add_definitions(-DUSE_SYSTEM_MALLOC=1)
+add_definitions(-DNDEBUG=1)
+add_definitions(-DUSE_SYSTEM_MALLOC=0)
+add_definitions(-DWTF_OS_ANDROID=1)
+add_definitions(-DUSE_EXPORT_MACROS=1)
 if (${ANDROID_PLATFORM} STREQUAL "android-21")
 else ()
     add_definitions(-D_POSIX_THREAD_KEYS_MAX=128)                              
diff --git a/weex_core/Source/android/multiprocess/weex_js_connection.cpp 
b/weex_core/Source/android/multiprocess/weex_js_connection.cpp
index 51d25d9..555324d 100644
--- a/weex_core/Source/android/multiprocess/weex_js_connection.cpp
+++ b/weex_core/Source/android/multiprocess/weex_js_connection.cpp
@@ -31,6 +31,7 @@
 #include <iostream>
 #include <fstream>
 #include <unistd.h>
+#include <dlfcn.h>
 #include "android/weex_extend_js_api.h"
 #include "android/utils/so_utils.h"
 #include "android/bridge/platform/android_bridge_in_multi_process.h"
@@ -156,7 +157,7 @@ static volatile int newThreadStatus = UNFINISH;
 
 static void *newIPCServer(void *_td) {
     WeexConnInfo  *server = static_cast<WeexConnInfo *>(_td);
-    void *base = server->mmap_for_ipc();
+    void *base = server->base_mem_;
 
     if (base == MAP_FAILED) {
         LOGE("newIPCServer start map filed errno %d ", errno);
@@ -204,7 +205,7 @@ IPCSender *WeexJSConnection::start(bool reinit) {
     return nullptr;
   }
 
-  void *base = client_->mmap_for_ipc();
+  void *base = client_->base_mem_;
   if (base == MAP_FAILED) {
     int _errno = errno;
     throw IPCException("failed to map ashmem region: %s", strerror(_errno));
@@ -256,7 +257,7 @@ IPCSender *WeexJSConnection::start(bool reinit) {
 
 //  static bool startupPie = s_start_pie;
   static bool startupPie = SoUtils::pie_support();
-  LOGE("startupPie :%d", startupPie);
+  __android_log_print(ANDROID_LOG_ERROR,"weex","startupPie :%d", startupPie);
 
   pid_t child;
   if (reinit) {
@@ -277,13 +278,13 @@ IPCSender *WeexJSConnection::start(bool reinit) {
     munmap(base, IPCFutexPageQueue::ipc_size);
     throw IPCException("failed to fork: %s", strerror(myerrno));
   } else if (child == 0) {
-    LOGE("weexcore fork child success\n");
+    __android_log_print(ANDROID_LOG_ERROR,"weex","weexcore fork child 
success\n");
     // the child
     closeAllButThis(client_->ipcFd, server_->ipcFd);
     // implements close all but handles[1]
     // do exec
     doExec(client_->ipcFd, server_->ipcFd, true, startupPie);
-    LOGE("exec Failed completely.");
+    __android_log_print(ANDROID_LOG_ERROR,"weex","exec Failed completely.");
     // failed to exec
     _exit(1);
   } else {
@@ -413,7 +414,7 @@ void doExec(int fdClient, int fdServer, bool traceEnable, 
bool startupPie) {
   std::string executablePath;
   std::string icuDataPath;
   if(SoUtils::jss_icu_path() != nullptr) {
-    LOGD("jss_icu_path not null %s",SoUtils::jss_icu_path());
+    __android_log_print(ANDROID_LOG_ERROR,"weex", "jss_icu_path not null 
%s",SoUtils::jss_icu_path());
     icuDataPath = SoUtils::jss_icu_path();
   } else {
     s_in_find_icu = true;
@@ -440,8 +441,7 @@ void doExec(int fdClient, int fdServer, bool traceEnable, 
bool startupPie) {
     executablePath.replace(pos, libName.length(), "");
 
   if (executablePath.empty()) {
-    LOGE("executablePath is empty");
-
+    __android_log_print(ANDROID_LOG_ERROR,"weex","executablePath is empty");
 #if PRINT_LOG_CACHEFILE
     mcfile << "jsengine WeexJSConnection::doExec executablePath is empty and 
return" << std::endl;
     mcfile.close();
@@ -449,10 +449,10 @@ void doExec(int fdClient, int fdServer, bool traceEnable, 
bool startupPie) {
 
     return;
   } else {
-    LOGE("executablePath is %s", executablePath.c_str());
+    __android_log_print(ANDROID_LOG_ERROR,"weex","executablePath is %s", 
executablePath.c_str());
   }}
   if (icuDataPath.empty()) {
-    LOGE("icuDataPath is empty");
+    __android_log_print(ANDROID_LOG_ERROR,"weex","icuDataPath is empty");
 #if PRINT_LOG_CACHEFILE
     mcfile << "jsengine WeexJSConnection::doExec icuDataPath is empty and 
return" << std::endl;
     mcfile.close();
@@ -502,7 +502,7 @@ void doExec(int fdClient, int fdServer, bool traceEnable, 
bool startupPie) {
     chmod(executableName.c_str(), 0755);
     int result = access(executableName.c_str(), 01);
 
-    LOGE("doExec access result %d executableName %s \n", result, 
executableName.c_str());
+    __android_log_print(ANDROID_LOG_ERROR,"weex", "doExec access result %d 
executableName %s \n", result, executableName.c_str());
 #if PRINT_LOG_CACHEFILE
     mcfile << "jsengine WeexJSConnection::doExec file exist result:"
            << result << " startupPie:" << startupPie << std::endl;
@@ -526,7 +526,7 @@ void doExec(int fdClient, int fdServer, bool traceEnable, 
bool startupPie) {
       const char *argv[] = {executableName.c_str(), fdStr, fdServerStr, 
traceEnable ? "1" : "0", g_crashFileName.c_str(), nullptr};
       if (-1 == execve(argv[0], const_cast<char *const *>(&argv[0]),
                        const_cast<char *const *>(envp.get()))) {
-          LOGE("execve failed errno %s \n", strerror(errno));
+        __android_log_print(ANDROID_LOG_ERROR,"weex","execve failed errno %s 
\n", strerror(errno));
 #if PRINT_LOG_CACHEFILE
         mcfile << "execve failed11:" << strerror(errno) << std::endl;
 #endif
@@ -541,7 +541,7 @@ void doExec(int fdClient, int fdServer, bool traceEnable, 
bool startupPie) {
       const char *argv[] = {executableName.c_str(), fdStr, fdServerStr, 
traceEnable ? "1" : "0", g_crashFileName.c_str(), nullptr};
       if (-1 == execve(argv[0], const_cast<char *const *>(&argv[0]),
                        const_cast<char *const *>(envp.get()))) {
-          LOGE("execve failed errno %s \n", strerror(errno));
+        __android_log_print(ANDROID_LOG_ERROR,"weex","execve failed errno %s 
\n", strerror(errno));
 #if PRINT_LOG_CACHEFILE
         mcfile << "execve failed:" << strerror(errno) << std::endl;
 #endif
@@ -616,7 +616,7 @@ void *WeexConnInfo::mmap_for_ipc() {
   int initTimes = 1;
   void *base = MAP_FAILED;
   do {
-    fd = ashmem_create_region(fileName.c_str(), IPCFutexPageQueue::ipc_size);
+    fd = memfd_create(fileName.c_str(), IPCFutexPageQueue::ipc_size);
     if (-1 == fd) {
       if (this->is_client) {
         throw IPCException("failed to create ashmem region: %s", 
strerror(errno));
@@ -648,3 +648,67 @@ void *WeexConnInfo::mmap_for_ipc() {
   this->ipcFd = fd;
   return base;
 }
+
+int WeexConnInfo::memfd_create(const char *name, size_t size) {
+  if (SoUtils::android_api() <= __ANDROID_API_P__) {
+    return ashmem_create_region(name, size);
+  }
+
+
+  int fd = 0;
+  if (SoUtils::android_api() >= 29) {
+    fd = memfd_create_androidR(name, size);
+    if (fd != 0) {
+      return fd;
+    }
+  }
+  return memfd_create_below_androidR(name, size);
+}
+typedef int (*ASharedMemory_create_func_ptr)(const char *name, size_t size);
+typedef int (*ASharedMemory_setProt_func_ptr)(int fd, int prot);
+int WeexConnInfo::memfd_create_below_androidR(const char *name, size_t size) {
+  static auto handle = dlopen("libandroid.so", RTLD_LAZY | RTLD_LOCAL);
+  if (handle == RTLD_DEFAULT) {
+    return -1;
+  }
+  int fd;
+  static ASharedMemory_create_func_ptr funcPtr =
+      (handle != nullptr) ? 
reinterpret_cast<ASharedMemory_create_func_ptr>(dlsym(handle,
+                                                                               
   "ASharedMemory_create"))
+                          : nullptr;
+  if (funcPtr) {
+    fd = funcPtr(name, size);
+    if (fd < 0)
+      return fd;
+    static auto funcSetProt =
+        reinterpret_cast<ASharedMemory_setProt_func_ptr>(dlsym(handle, 
"ASharedMemory_setProt"));
+    if (!funcSetProt) {
+      return -1;
+    }
+    funcSetProt(fd, PROT_READ | PROT_WRITE | PROT_EXEC);
+    return fd;
+  }
+  return -1;
+}
+
+int WeexConnInfo::memfd_create_androidR(const char *name, size_t size) {
+  JNIEnv *env = base::android::AttachCurrentThread();
+  jclass wx_env = env->FindClass("com/taobao/weex/WXEnvironment");
+  if (wx_env) {
+    jmethodID m_memfd_create_id =
+        env->GetStaticMethodID(wx_env, "memfd_create", 
"(Ljava/lang/String;I)I");
+
+    if (m_memfd_create_id) {
+      jint i =
+          env->CallStaticIntMethod(wx_env, m_memfd_create_id, 
env->NewStringUTF(name), (jint) size);
+      __android_log_print(ANDROID_LOG_ERROR,
+                          "dyy",
+                          "memfd_create_androidR %d  %s  %d",
+                          i,
+                          name,
+                          size);
+      return i;
+    }
+  }
+  return -1;
+}
diff --git a/weex_core/Source/android/multiprocess/weex_js_connection.h 
b/weex_core/Source/android/multiprocess/weex_js_connection.h
index 23a032f..95cba1f 100644
--- a/weex_core/Source/android/multiprocess/weex_js_connection.h
+++ b/weex_core/Source/android/multiprocess/weex_js_connection.h
@@ -36,13 +36,17 @@ class WeexConnInfo {
     this->handler = std::move(handler);
     ipcFd = -1;
     is_client = isClient;
+    base_mem_ = mmap_for_ipc();
   }
 
   ~WeexConnInfo() {
     closeFd();
   }
 
-  void *mmap_for_ipc();
+
+  static int memfd_create_below_androidR(const char *name, size_t size);
+  static int memfd_create_androidR(const char *name, size_t size);
+  static int memfd_create(const char *name, size_t size);
 
   void closeFd() {
     if(ipcFd == -1) {
@@ -55,6 +59,11 @@ class WeexConnInfo {
     close(ipcFd);
   }
 
+  void* base_mem_;
+
+ private:
+  void *mmap_for_ipc();
+
  private:
   bool hasBeenClosed = false;
   bool is_client = false;
diff --git a/weex_core/Source/android/utils/params_utils.cpp 
b/weex_core/Source/android/utils/params_utils.cpp
index abeaa86..c87a956 100644
--- a/weex_core/Source/android/utils/params_utils.cpp
+++ b/weex_core/Source/android/utils/params_utils.cpp
@@ -143,6 +143,15 @@ std::vector<INIT_FRAMEWORK_PARAMS*> initFromParam(
     }                                                                       \
   }
 
+  jclass versionClass = env->FindClass("android/os/Build$VERSION");
+  if (versionClass) {
+    jfieldID sdk_init_filed_id = env->GetStaticFieldID(versionClass, 
"SDK_INT", "I");
+    if (sdk_init_filed_id) {
+      SoUtils::set_android_api(env->GetStaticIntField(versionClass, 
sdk_init_filed_id));
+    } else {
+    }
+  }
+
   jclass c_params = env->GetObjectClass(params);
   if (c_params == nullptr) {
     ADDSTRING(nullptr);
diff --git a/weex_core/Source/android/utils/so_utils.cpp 
b/weex_core/Source/android/utils/so_utils.cpp
index d7d8439..c8bceb3 100644
--- a/weex_core/Source/android/utils/so_utils.cpp
+++ b/weex_core/Source/android/utils/so_utils.cpp
@@ -35,6 +35,7 @@ namespace WeexCore {
     char * SoUtils::g_lib_ld_path = nullptr;
     char * SoUtils::g_jss_so_name = const_cast<char *>("libweexjss.so");
     bool SoUtils::g_pie_support = false;
+    int SoUtils::g_android_api = 0;
     std::function<void(const char*, const char*)> SoUtils::g_exception_handler 
= nullptr;
 
     const char *SoUtils::GetDefaultCacheDir(JNIEnv *env) {
diff --git a/weex_core/Source/android/utils/so_utils.h 
b/weex_core/Source/android/utils/so_utils.h
index 8924778..42bc328 100644
--- a/weex_core/Source/android/utils/so_utils.h
+++ b/weex_core/Source/android/utils/so_utils.h
@@ -81,6 +81,11 @@ class SoUtils {
 
   inline static const char* lib_ld_path() { return g_lib_ld_path; }
 
+  inline static const int android_api() {return g_android_api;}
+  inline static void set_android_api(int android_api) {
+    g_android_api = android_api;
+  }
+
   static void updateSoLinkPath(const char *lib_ld_path);
 
  private:
@@ -94,6 +99,7 @@ class SoUtils {
   static char* g_jsc_so_path;
   static char* g_lib_ld_path;
   static bool g_pie_support;
+  static int g_android_api;
   static std::function<void(const char*, const char*)> g_exception_handler;
 };
 }  // namespace WeexCore
diff --git a/weex_core/Source/js_runtime/CMakeLists.txt 
b/weex_core/Source/js_runtime/CMakeLists.txt
index feed09e..7956b33 100644
--- a/weex_core/Source/js_runtime/CMakeLists.txt
+++ b/weex_core/Source/js_runtime/CMakeLists.txt
@@ -53,7 +53,7 @@ add_definitions(-DLOG_JS_DEBUG=0)
 add_definitions(-DUSE_JS_RUNTIME=1)
 
 
-add_definitions(-DUSE_SYSTEM_MALLOC=1)
+add_definitions(-DUSE_SYSTEM_MALLOC=0)
 if (${ANDROID_PLATFORM} STREQUAL "android-21")
 else ()
     add_definitions(-D_POSIX_THREAD_KEYS_MAX=128)                              

Reply via email to