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