You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by GitBox <gi...@apache.org> on 2020/05/19 11:29:17 UTC

[GitHub] [incubator-weex] ikantech commented on issue #2706: [Android] Weex failed on Android Q failed with targetSdkVersion=29

ikantech commented on issue #2706:
URL: https://github.com/apache/incubator-weex/issues/2706#issuecomment-630758980


   基于 @nm-cmd 修改的代码,在Android Q上可以正常工作。我去掉了一些没有调用的函数。
   
   ```diff
   weex_core/Source/third_party/IPC/ashmem.h
   @@ -33,10 +33,7 @@ extern "C" {
    
    int ashmem_create_region(const char* name, size_t size);
    int ashmem_set_prot_region(int fd, int prot);
   -int ashmem_pin_region(int fd, size_t offset, size_t len);
   -int ashmem_unpin_region(int fd, size_t offset, size_t len);
    int ashmem_get_size_region(int fd);
   -int ashmem_purge_all(void);
    
    #ifdef __cplusplus
    }
   ```
   ```diff
   weex_core/Source/third_party/IPC/ashmem.c
   @@ -31,9 +31,44 @@
    
    #include "ashmem.h"
    #include <linux/ashmem.h>
   +#include <stdlib.h>
   +#include <sys/system_properties.h>
   +#include <dlfcn.h>
   +#include <pthread.h>
    
    #define ASHMEM_DEVICE "/dev/ashmem"
    
   +static int system_property_get_int(const char* name) {
   +    int result = 0;
   +    char value[PROP_VALUE_MAX] = {};
   +    if (__system_property_get(name, value) >= 1)
   +        result = atoi(value);
   +    return result;
   +}
   +
   +static int device_api_level() {
   +    static int s_api_level = -1;
   +    if (s_api_level < 0)
   +        s_api_level = system_property_get_int("ro.build.version.sdk");
   +    return s_api_level;
   +}
   +
   +typedef int(*ASharedMemory_createFunc)(const char *, size_t);
   +typedef size_t(*ASharedMemory_getSizeFunc)(int fd);
   +typedef int(*ASharedMemory_setProtFunc)(int fd, int prot);
   +
   +// Function pointers to shared memory functions.
   +typedef struct {
   +    ASharedMemory_createFunc create;
   +    ASharedMemory_getSizeFunc getSize;
   +    ASharedMemory_setProtFunc setProt;
   +} ASharedMemoryFuncs;
   +
   +static ASharedMemoryFuncs s_ashmem_funcs = {
   +        NULL, NULL, NULL
   +};
   +static pthread_once_t s_ashmem_funcs_once = PTHREAD_ONCE_INIT;
   +
    /*
     * ashmem_create_region - creates a new ashmem region and returns the file
     * descriptor, or <0 on error
   @@ -41,7 +76,7 @@
     * `name' is an optional label to give the region (visible in /proc/pid/maps)
     * `size' is the size of the region, in page-aligned bytes
     */
   -int ashmem_create_region(const char* name, size_t size)
   +static int ashmem_dev_create_region(const char* name, size_t size)
    {
        int fd, ret;
    
   @@ -69,34 +104,56 @@ error:
        return ret;
    }
    
   -int ashmem_set_prot_region(int fd, int prot)
   +static int ashmem_dev_set_prot_region(int fd, int prot)
    {
        return ioctl(fd, ASHMEM_SET_PROT_MASK, prot);
    }
    
   -int ashmem_pin_region(int fd, size_t offset, size_t len)
   +static size_t ashmem_dev_get_size_region(int fd)
    {
   -    struct ashmem_pin pin = { offset, len };
   -    return ioctl(fd, ASHMEM_PIN, &pin);
   +    return (size_t)ioctl(fd, ASHMEM_GET_SIZE, NULL);
    }
    
   -int ashmem_unpin_region(int fd, size_t offset, size_t len)
   -{
   -    struct ashmem_pin pin = { offset, len };
   -    return ioctl(fd, ASHMEM_UNPIN, &pin);
   +static void ashmem_init_funcs() {
   +    ASharedMemoryFuncs* funcs = &s_ashmem_funcs;
   +    // ANDROID_API_Q
   +    if (device_api_level() >= 29) {
   +        void * lib = dlopen("libandroid.so", RTLD_NOW);
   +        funcs->create =
   +                (ASharedMemory_createFunc)dlsym(lib, "ASharedMemory_create");
   +        funcs->getSize =
   +                (ASharedMemory_getSizeFunc)dlsym(lib, "ASharedMemory_getSize");
   +        funcs->setProt =
   +                (ASharedMemory_setProtFunc)dlsym(lib, "ASharedMemory_setProt");
   +    }
   +
   +    if(funcs->create == NULL) {
   +        funcs->create = &ashmem_dev_create_region;
   +    }
   +    if(funcs->getSize == NULL) {
   +        funcs->getSize = &ashmem_dev_get_size_region;
   +    }
   +    if(funcs->setProt == NULL) {
   +        funcs->setProt = &ashmem_dev_set_prot_region;
   +    }
    }
    
   -int ashmem_get_size_region(int fd)
   +static const ASharedMemoryFuncs* ashmem_get_funcs() {
   +    pthread_once(&s_ashmem_funcs_once, ashmem_init_funcs);
   +    return &s_ashmem_funcs;
   +}
   +
   +int ashmem_create_region(const char *name, size_t size)
    {
   -    return ioctl(fd, ASHMEM_GET_SIZE, NULL);
   +    return ashmem_get_funcs()->create(name, size);
    }
    
   -int ashmem_purge_all(void)
   +int ashmem_set_prot_region(int fd, int prot)
    {
   -    const int fd = open(ASHMEM_DEVICE, O_RDWR);
   -    if (fd < 0)
   -        return fd;
   -    const int ret = ioctl(fd, ASHMEM_PURGE_ALL_CACHES, 0);
   -    close(fd);
   -    return ret;
   +    return ashmem_get_funcs()->setProt(fd, prot);
    }
   +
   +int ashmem_get_size_region(int fd)
   +{
   +    return (int)ashmem_get_funcs()->getSize(fd);
   +}
   ```
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org