Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1596ec2 authored by Orion Hodson's avatar Orion Hodson Committed by android-build-merger
Browse files

Merge "Ensure all fields of AutoBufferPointer are initialized" into qt-dev

am: 0fd71745

Change-Id: Ia1697f22e3b55f325f0d74ab9c501bfa9dccf7b0
parents 7f7388b2 0fd71745
Loading
Loading
Loading
Loading
+23 −14
Original line number Diff line number Diff line
@@ -18,42 +18,51 @@

#include "core_jni_helpers.h"

void* android::nio_getPointer(JNIEnv *_env, jobject buffer, jarray *array) {
    assert(array);
namespace {

void* getPointer(JNIEnv *_env, jobject buffer, jarray *array, void** elements) {
    assert(array);
    jint position;
    jint limit;
    jint elementSizeShift;
    jlong pointer = jniGetNioBufferFields(_env, buffer, &position, &limit, &elementSizeShift);
    if (pointer != 0L) {
        *array = nullptr;
        *elements = nullptr;
        pointer += position << elementSizeShift;
        return reinterpret_cast<void*>(pointer);
    }

    jint offset = jniGetNioBufferBaseArrayOffset(_env, buffer);
    *array = jniGetNioBufferBaseArray(_env, buffer);
    void * data = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
    return reinterpret_cast<void*>(reinterpret_cast<char*>(data) + offset);
    *elements = _env->GetPrimitiveArrayCritical(*array, (jboolean *) 0);
    return reinterpret_cast<void*>(reinterpret_cast<char*>(*elements) + offset);
}

void releasePointer(JNIEnv *_env, jarray array, void *elements, jboolean commit) {
    _env->ReleasePrimitiveArrayCritical(array, elements, commit ? 0 : JNI_ABORT);
}

}  // namespace

void* android::nio_getPointer(JNIEnv *_env, jobject buffer, jarray *array) {
    void* elements;
    return getPointer(_env, buffer, array, &elements);
}

void android::nio_releasePointer(JNIEnv *_env, jarray array, void *data,
                                jboolean commit) {
    _env->ReleasePrimitiveArrayCritical(array, data,
                                        commit ? 0 : JNI_ABORT);
void android::nio_releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit) {
    releasePointer(_env, array, data, commit);
}

///////////////////////////////////////////////////////////////////////////////

android::AutoBufferPointer::AutoBufferPointer(JNIEnv* env, jobject nioBuffer,
                                              jboolean commit) {
android::AutoBufferPointer::AutoBufferPointer(JNIEnv* env, jobject nioBuffer, jboolean commit) {
    fEnv = env;
    fCommit = commit;
    fPointer = android::nio_getPointer(env, nioBuffer, &fArray);
    fPointer = getPointer(env, nioBuffer, &fArray, &fElements);
}

android::AutoBufferPointer::~AutoBufferPointer() {
    if (NULL != fArray) {
        android::nio_releasePointer(fEnv, fArray, fPointer, fCommit);
    if (nullptr != fArray) {
        releasePointer(fEnv, fArray, fElements, fCommit);
    }
}
+5 −4
Original line number Diff line number Diff line
@@ -63,9 +63,10 @@ public:

private:
    JNIEnv* fEnv;
    void*   fPointer;
    jarray  fArray;
    jboolean fCommit;
    void*   fPointer;   // pointer to current buffer position.
    void*   fElements;  // pointer to array element 0 (may be directly in fArray or a copy).
    jarray  fArray;     // pointer to array on managed heap.
    jboolean fCommit;   // commit data to source if required (when fElements is a copy of fArray).
};

}   /* namespace android */
+72 −0
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import androidx.test.filters.SmallTest;

import junit.framework.TestCase;

import java.nio.ByteBuffer;

public class BitmapTest extends TestCase {

    @SmallTest
@@ -262,4 +264,74 @@ public class BitmapTest extends TestCase {
        assertFalse(hardwareBitmap.isMutable());
        assertEquals(ColorSpace.get(ColorSpace.Named.DISPLAY_P3), hardwareBitmap.getColorSpace());
    }

    @SmallTest
    public void testCopyWithDirectBuffer() {
        // Initialize Bitmap
        final int width = 2;
        final int height = 2;
        Bitmap bm1 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        bm1.setPixels(new int[] { 0xff, 0xeeee, 0xdddddd, 0xcccccccc }, 0, 2, 0, 0, 2, 2);

        // Copy bytes to direct buffer, buffer is padded by fixed amount (pad bytes) either side
        // of bitmap.
        final int pad = 1;
        final byte padValue = 0x5a;
        final int bufferSize = pad + width * height * 2 + pad;
        ByteBuffer directBuffer = ByteBuffer.allocateDirect(bufferSize);

        // Write padding
        directBuffer.put(0, padValue);
        directBuffer.put(directBuffer.limit() - 1, padValue);

        // Copy bitmap
        directBuffer.position(pad);
        bm1.copyPixelsToBuffer(directBuffer);
        assertEquals(directBuffer.position(), pad + width * height * 2);

        // Check padding
        assertEquals(directBuffer.get(0), padValue);
        assertEquals(directBuffer.get(directBuffer.limit() - 1), padValue);

        // Create bitmap from direct buffer and check match.
        directBuffer.position(pad);
        Bitmap bm2 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        bm2.copyPixelsFromBuffer(directBuffer);
        assertTrue(bm2.sameAs(bm1));
    }

    @SmallTest
    public void testCopyWithHeapBuffer() {
        // Initialize Bitmap
        final int width = 2;
        final int height = 2;
        Bitmap bm1 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        bm1.setPixels(new int[] { 0xff, 0xeeee, 0xdddddd, 0xcccccccc }, 0, 2, 0, 0, 2, 2);

        // Copy bytes to heap buffer, buffer is padded by fixed amount (pad bytes) either side
        // of bitmap.
        final int pad = 1;
        final byte padValue = 0x5a;
        final int bufferSize = pad + width * height * 2 + pad;
        ByteBuffer heapBuffer = ByteBuffer.allocate(bufferSize);

        // Write padding
        heapBuffer.put(0, padValue);
        heapBuffer.put(heapBuffer.limit() - 1, padValue);

        // Copy bitmap
        heapBuffer.position(pad);
        bm1.copyPixelsToBuffer(heapBuffer);
        assertEquals(heapBuffer.position(), pad + width * height * 2);

        // Check padding
        assertEquals(heapBuffer.get(0), padValue);
        assertEquals(heapBuffer.get(heapBuffer.limit() - 1), padValue);

        // Create bitmap from heap buffer and check match.
        heapBuffer.position(pad);
        Bitmap bm2 = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        bm2.copyPixelsFromBuffer(heapBuffer);
        assertTrue(bm2.sameAs(bm1));
    }
}