diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java index 3c654d6dec485..e60506ff88efd 100644 --- a/graphics/java/android/graphics/Bitmap.java +++ b/graphics/java/android/graphics/Bitmap.java @@ -26,7 +26,9 @@ import android.compat.annotation.UnsupportedAppUsage; import android.hardware.HardwareBuffer; import android.os.Build; import android.os.Parcel; +import android.os.ParcelFileDescriptor; import android.os.Parcelable; +import android.os.SharedMemory; import android.os.StrictMode; import android.os.Trace; import android.util.DisplayMetrics; @@ -38,6 +40,7 @@ import dalvik.annotation.optimization.CriticalNative; import libcore.util.NativeAllocationRegistry; +import java.io.IOException; import java.io.OutputStream; import java.lang.ref.WeakReference; import java.nio.Buffer; @@ -737,6 +740,26 @@ public final class Bitmap implements Parcelable { return shared; } + /** + * Returns the shared memory handle to the pixel storage if the bitmap is already using + * shared memory and null if it is not. The SharedMemory object is then useful to then pass + * through HIDL APIs (e.g. WearOS's DisplayOffload service). + * + * @hide + */ + public SharedMemory getSharedMemory() { + checkRecycled("Cannot access shared memory of a recycled bitmap"); + if (nativeIsBackedByAshmem(mNativePtr)) { + try { + int fd = nativeGetAshmemFD(mNativePtr); + return SharedMemory.fromFileDescriptor(ParcelFileDescriptor.fromFd(fd)); + } catch (IOException e) { + Log.e(TAG, "Unable to create dup'd file descriptor for shared bitmap memory"); + } + } + return null; + } + /** * Create a hardware bitmap backed by a {@link HardwareBuffer}. * @@ -2294,6 +2317,7 @@ public final class Bitmap implements Parcelable { boolean isMutable); private static native Bitmap nativeCopyAshmem(long nativeSrcBitmap); private static native Bitmap nativeCopyAshmemConfig(long nativeSrcBitmap, int nativeConfig); + private static native int nativeGetAshmemFD(long nativeBitmap); private static native long nativeGetNativeFinalizer(); private static native void nativeRecycle(long nativeBitmap); @UnsupportedAppUsage diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp index 540abec38ebc3..c68a6b9962c2d 100755 --- a/libs/hwui/jni/Bitmap.cpp +++ b/libs/hwui/jni/Bitmap.cpp @@ -422,6 +422,11 @@ static jobject Bitmap_copyAshmemConfig(JNIEnv* env, jobject, jlong srcHandle, ji return ret; } +static jint Bitmap_getAshmemFd(JNIEnv* env, jobject, jlong bitmapHandle) { + LocalScopedBitmap bitmap(bitmapHandle); + return (bitmap.valid()) ? bitmap->bitmap().getAshmemFd() : -1; +} + static void Bitmap_destruct(BitmapWrapper* bitmap) { delete bitmap; } @@ -1257,6 +1262,7 @@ static const JNINativeMethod gBitmapMethods[] = { (void*)Bitmap_copyAshmem }, { "nativeCopyAshmemConfig", "(JI)Landroid/graphics/Bitmap;", (void*)Bitmap_copyAshmemConfig }, + { "nativeGetAshmemFD", "(J)I", (void*)Bitmap_getAshmemFd }, { "nativeGetNativeFinalizer", "()J", (void*)Bitmap_getNativeFinalizer }, { "nativeRecycle", "(J)V", (void*)Bitmap_recycle }, { "nativeReconfigure", "(JIIIZ)V", (void*)Bitmap_reconfigure },