diff options
-rw-r--r-- | api/current.txt | 3 | ||||
-rw-r--r-- | api/system-current.txt | 3 | ||||
-rw-r--r-- | api/test-current.txt | 3 | ||||
-rw-r--r-- | core/java/android/os/MemoryFile.java | 2 | ||||
-rw-r--r-- | core/java/android/os/SharedMemory.java | 7 | ||||
-rw-r--r-- | native/android/libandroid.map.txt | 1 | ||||
-rw-r--r-- | native/android/sharedmem.cpp | 43 |
7 files changed, 52 insertions, 10 deletions
diff --git a/api/current.txt b/api/current.txt index 8d2e9c8b9a54..c5fe76b30eac 100644 --- a/api/current.txt +++ b/api/current.txt @@ -31066,7 +31066,6 @@ package android.os { ctor public MemoryFile(java.lang.String, int) throws java.io.IOException; method public deprecated synchronized boolean allowPurging(boolean) throws java.io.IOException; method public void close(); - method public java.io.FileDescriptor getFileDescriptor() throws java.io.IOException; method public java.io.InputStream getInputStream(); method public java.io.OutputStream getOutputStream(); method public deprecated boolean isPurgingAllowed(); @@ -31498,8 +31497,6 @@ package android.os { method public void close(); method public static android.os.SharedMemory create(java.lang.String, int) throws android.system.ErrnoException; method public int describeContents(); - method public int getFd(); - method public java.io.FileDescriptor getFileDescriptor(); method public int getSize(); method public java.nio.ByteBuffer map(int, int, int) throws android.system.ErrnoException; method public java.nio.ByteBuffer mapReadOnly() throws android.system.ErrnoException; diff --git a/api/system-current.txt b/api/system-current.txt index e2754fdd9cd5..60e4960d2b65 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -33911,7 +33911,6 @@ package android.os { ctor public MemoryFile(java.lang.String, int) throws java.io.IOException; method public deprecated synchronized boolean allowPurging(boolean) throws java.io.IOException; method public void close(); - method public java.io.FileDescriptor getFileDescriptor() throws java.io.IOException; method public java.io.InputStream getInputStream(); method public java.io.OutputStream getOutputStream(); method public deprecated boolean isPurgingAllowed(); @@ -34372,8 +34371,6 @@ package android.os { method public void close(); method public static android.os.SharedMemory create(java.lang.String, int) throws android.system.ErrnoException; method public int describeContents(); - method public int getFd(); - method public java.io.FileDescriptor getFileDescriptor(); method public int getSize(); method public java.nio.ByteBuffer map(int, int, int) throws android.system.ErrnoException; method public java.nio.ByteBuffer mapReadOnly() throws android.system.ErrnoException; diff --git a/api/test-current.txt b/api/test-current.txt index fcb404edff99..70addad3c38d 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -31223,7 +31223,6 @@ package android.os { ctor public MemoryFile(java.lang.String, int) throws java.io.IOException; method public deprecated synchronized boolean allowPurging(boolean) throws java.io.IOException; method public void close(); - method public java.io.FileDescriptor getFileDescriptor() throws java.io.IOException; method public java.io.InputStream getInputStream(); method public java.io.OutputStream getOutputStream(); method public deprecated boolean isPurgingAllowed(); @@ -31656,8 +31655,6 @@ package android.os { method public void close(); method public static android.os.SharedMemory create(java.lang.String, int) throws android.system.ErrnoException; method public int describeContents(); - method public int getFd(); - method public java.io.FileDescriptor getFileDescriptor(); method public int getSize(); method public java.nio.ByteBuffer map(int, int, int) throws android.system.ErrnoException; method public java.nio.ByteBuffer mapReadOnly() throws android.system.ErrnoException; diff --git a/core/java/android/os/MemoryFile.java b/core/java/android/os/MemoryFile.java index 9294c449e4d6..ff3258f806c9 100644 --- a/core/java/android/os/MemoryFile.java +++ b/core/java/android/os/MemoryFile.java @@ -219,6 +219,8 @@ public class MemoryFile { * The returned file descriptor is not duplicated. * * @throws IOException If the memory file has been closed. + * + * @hide */ public FileDescriptor getFileDescriptor() throws IOException { return mSharedMemory.getFileDescriptor(); diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java index 459aeb087c2f..e6c7a1716941 100644 --- a/core/java/android/os/SharedMemory.java +++ b/core/java/android/os/SharedMemory.java @@ -60,7 +60,8 @@ public final class SharedMemory implements Parcelable, Closeable { } mMemoryRegistration = new MemoryRegistration(mSize); - mCleaner = Cleaner.create(this, new Closer(mFileDescriptor, mMemoryRegistration)); + mCleaner = Cleaner.create(mFileDescriptor, + new Closer(mFileDescriptor, mMemoryRegistration)); } /** @@ -138,6 +139,8 @@ public final class SharedMemory implements Parcelable, Closeable { * This FileDescriptor is interoperable with the ASharedMemory NDK APIs. * * @return Returns the FileDescriptor associated with this object. + * + * @hide Exists only for MemoryFile interop */ public @NonNull FileDescriptor getFileDescriptor() { return mFileDescriptor; @@ -150,6 +153,8 @@ public final class SharedMemory implements Parcelable, Closeable { * This fd is interoperable with the ASharedMemory NDK APIs. * * @return Returns the native fd associated with this object, or -1 if it is already closed. + * + * @hide Exposed for native ASharedMemory_dupFromJava() */ public int getFd() { return mFileDescriptor.getInt$(); diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index c82a1f6a646a..bbd27839d551 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -198,6 +198,7 @@ LIBANDROID { ASharedMemory_create; # introduced=26 ASharedMemory_getSize; # introduced=26 ASharedMemory_setProt; # introduced=26 + ASharedMemory_dupFromJava; # introduced=27 AStorageManager_delete; AStorageManager_getMountedObbPath; AStorageManager_isObbMounted; diff --git a/native/android/sharedmem.cpp b/native/android/sharedmem.cpp index 9d029dfad41a..757aaecab40d 100644 --- a/native/android/sharedmem.cpp +++ b/native/android/sharedmem.cpp @@ -14,10 +14,36 @@ * limitations under the License. */ +#include <jni.h> + #include <android/sharedmem.h> +#include <android/sharedmem_jni.h> #include <cutils/ashmem.h> +#include <log/log.h> #include <utils/Errors.h> +#include <mutex> +#include <unistd.h> + +static struct { + jclass clazz; + jmethodID getFd; +} sSharedMemory; + +static void jniInit(JNIEnv* env) { + static std::once_flag sJniInitialized; + std::call_once(sJniInitialized, [](JNIEnv* env) { + jclass clazz = env->FindClass("android/os/SharedMemory"); + LOG_ALWAYS_FATAL_IF(clazz == nullptr, "Failed to find android.os.SharedMemory"); + sSharedMemory.clazz = (jclass) env->NewGlobalRef(clazz); + LOG_ALWAYS_FATAL_IF(sSharedMemory.clazz == nullptr, + "Failed to create global ref of android.os.SharedMemory"); + sSharedMemory.getFd = env->GetMethodID(sSharedMemory.clazz, "getFd", "()I"); + LOG_ALWAYS_FATAL_IF(sSharedMemory.getFd == nullptr, + "Failed to find method SharedMemory#getFd()"); + }, env); +} + int ASharedMemory_create(const char *name, size_t size) { if (size == 0) { return android::BAD_VALUE; @@ -32,3 +58,20 @@ size_t ASharedMemory_getSize(int fd) { int ASharedMemory_setProt(int fd, int prot) { return ashmem_set_prot_region(fd, prot); } + +int ASharedMemory_dupFromJava(JNIEnv* env, jobject javaSharedMemory) { + if (env == nullptr || javaSharedMemory == nullptr) { + return -1; + } + jniInit(env); + if (!env->IsInstanceOf(javaSharedMemory, sSharedMemory.clazz)) { + ALOGW("ASharedMemory_dupFromJava called with object " + "that's not an instanceof android.os.SharedMemory"); + return -1; + } + int fd = env->CallIntMethod(javaSharedMemory, sSharedMemory.getFd); + if (fd != -1) { + fd = dup(fd); + } + return fd; +} |