1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <jni.h> 18 19 #include <android/sharedmem.h> 20 #include <android/sharedmem_jni.h> 21 #include <cutils/ashmem.h> 22 #include <log/log.h> 23 #include <utils/Errors.h> 24 25 #include <mutex> 26 #include <unistd.h> 27 28 static struct { 29 jclass clazz; 30 jmethodID getFd; 31 } sSharedMemory; 32 33 static void jniInit(JNIEnv* env) { 34 static std::once_flag sJniInitialized; 35 std::call_once(sJniInitialized, [](JNIEnv* env) { 36 jclass clazz = env->FindClass("android/os/SharedMemory"); 37 LOG_ALWAYS_FATAL_IF(clazz == nullptr, "Failed to find android.os.SharedMemory"); 38 sSharedMemory.clazz = (jclass) env->NewGlobalRef(clazz); 39 LOG_ALWAYS_FATAL_IF(sSharedMemory.clazz == nullptr, 40 "Failed to create global ref of android.os.SharedMemory"); 41 sSharedMemory.getFd = env->GetMethodID(sSharedMemory.clazz, "getFd", "()I"); 42 LOG_ALWAYS_FATAL_IF(sSharedMemory.getFd == nullptr, 43 "Failed to find method SharedMemory#getFd()"); 44 }, env); 45 } 46 47 int ASharedMemory_create(const char *name, size_t size) { 48 if (size == 0) { 49 return android::BAD_VALUE; 50 } 51 return ashmem_create_region(name, size); 52 } 53 54 size_t ASharedMemory_getSize(int fd) { 55 return ashmem_valid(fd) ? ashmem_get_size_region(fd) : 0; 56 } 57 58 int ASharedMemory_setProt(int fd, int prot) { 59 return ashmem_set_prot_region(fd, prot); 60 } 61 62 int ASharedMemory_dupFromJava(JNIEnv* env, jobject javaSharedMemory) { 63 if (env == nullptr || javaSharedMemory == nullptr) { 64 return -1; 65 } 66 jniInit(env); 67 if (!env->IsInstanceOf(javaSharedMemory, sSharedMemory.clazz)) { 68 ALOGW("ASharedMemory_dupFromJava called with object " 69 "that's not an instanceof android.os.SharedMemory"); 70 return -1; 71 } 72 int fd = env->CallIntMethod(javaSharedMemory, sSharedMemory.getFd); 73 if (fd != -1) { 74 fd = dup(fd); 75 } 76 return fd; 77 } 78