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

Commit 2276ceac authored by Makoto Onuki's avatar Makoto Onuki
Browse files

Improve CursorWindow failure message

Bug: 129139241
Bug: 129721058
Test: atest CursorWindowTest
Change-Id: Iac1c5ec6f999dadd638fc5ab47c69d13f60ea467
parent 1c721134
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -61,7 +61,10 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {

    private final CloseGuard mCloseGuard = CloseGuard.get();

    // May throw CursorWindowAllocationException
    private static native long nativeCreate(String name, int cursorWindowSize);

    // May throw CursorWindowAllocationException
    private static native long nativeCreateFromParcel(Parcel parcel);
    private static native void nativeDispose(long windowPtr);
    private static native void nativeWriteToParcel(long windowPtr, Parcel parcel);
@@ -135,8 +138,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
        mName = name != null && name.length() != 0 ? name : "<unnamed>";
        mWindowPtr = nativeCreate(mName, (int) windowSizeBytes);
        if (mWindowPtr == 0) {
            throw new CursorWindowAllocationException("Cursor window allocation of " +
                    windowSizeBytes + " bytes failed. " + printStats());
            throw new IllegalStateException(); // Shouldn't happen.
        }
        mCloseGuard.open("close");
        recordNewWindow(Binder.getCallingPid(), mWindowPtr);
@@ -164,8 +166,7 @@ public class CursorWindow extends SQLiteClosable implements Parcelable {
        mStartPos = source.readInt();
        mWindowPtr = nativeCreateFromParcel(source);
        if (mWindowPtr == 0) {
            throw new CursorWindowAllocationException("Cursor window could not be "
                    + "created from binder.");
            throw new IllegalStateException(); // Shouldn't happen.
        }
        mName = nativeGetName(mWindowPtr);
        mCloseGuard.open("close");
+6 −2
Original line number Diff line number Diff line
@@ -92,7 +92,9 @@ static jlong nativeCreate(JNIEnv* env, jclass clazz, jstring nameObj, jint curso
    CursorWindow* window;
    status_t status = CursorWindow::create(name, cursorWindowSize, &window);
    if (status || !window) {
        ALOGE("Could not allocate CursorWindow '%s' of size %d due to error %d.",
        jniThrowExceptionFmt(env,
                "android/database/CursorWindowAllocationException",
                "Could not allocate CursorWindow '%s' of size %d due to error %d.",
                name.string(), cursorWindowSize, status);
        return 0;
    }
@@ -107,7 +109,9 @@ static jlong nativeCreateFromParcel(JNIEnv* env, jclass clazz, jobject parcelObj
    CursorWindow* window;
    status_t status = CursorWindow::createFromParcel(parcel, &window);
    if (status || !window) {
        ALOGE("Could not create CursorWindow from Parcel due to error %d, process fd count=%d",
        jniThrowExceptionFmt(env,
                "android/database/CursorWindowAllocationException",
                "Could not create CursorWindow from Parcel due to error %d, process fd count=%d",
                status, getFdCount());
        return 0;
    }
+17 −3
Original line number Diff line number Diff line
@@ -49,15 +49,21 @@ status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** o
    int ashmemFd = ashmem_create_region(ashmemName.string(), size);
    if (ashmemFd < 0) {
        result = -errno;
        ALOGE("CursorWindow: ashmem_create_region() failed: errno=%d.", errno);
    } else {
        result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);
        if (result >= 0) {
        if (result < 0) {
            ALOGE("CursorWindow: ashmem_set_prot_region() failed: errno=%d",errno);
        } else {
            void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);
            if (data == MAP_FAILED) {
                result = -errno;
                ALOGE("CursorWindow: mmap() failed: errno=%d.", errno);
            } else {
                result = ashmem_set_prot_region(ashmemFd, PROT_READ);
                if (result >= 0) {
                if (result < 0) {
                    ALOGE("CursorWindow: ashmem_set_prot_region() failed: errno=%d.", errno);
                } else {
                    CursorWindow* window = new CursorWindow(name, ashmemFd,
                            data, size, false /*readOnly*/);
                    result = window->clear();
@@ -86,26 +92,34 @@ status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursor
    String8 name = parcel->readString8();

    status_t result;
    int actualSize;
    int ashmemFd = parcel->readFileDescriptor();
    if (ashmemFd == int(BAD_TYPE)) {
        result = BAD_TYPE;
        ALOGE("CursorWindow: readFileDescriptor() failed");
    } else {
        ssize_t size = ashmem_get_size_region(ashmemFd);
        if (size < 0) {
            result = UNKNOWN_ERROR;
            ALOGE("CursorWindow: ashmem_get_size_region() failed: errno=%d.", errno);
        } else {
            int dupAshmemFd = ::fcntl(ashmemFd, F_DUPFD_CLOEXEC, 0);
            if (dupAshmemFd < 0) {
                result = -errno;
                ALOGE("CursorWindow: fcntl() failed: errno=%d.", errno);
            } else {
                // the size of the ashmem descriptor can be modified between ashmem_get_size_region
                // call and mmap, so we'll check again immediately after memory is mapped
                void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);
                if (data == MAP_FAILED) {
                    result = -errno;
                } else if (ashmem_get_size_region(dupAshmemFd) != size) {
                    ALOGE("CursorWindow: mmap() failed: errno=%d.", errno);
                } else if ((actualSize = ashmem_get_size_region(dupAshmemFd)) != size) {
                    ::munmap(data, size);
                    result = BAD_VALUE;
                    ALOGE("CursorWindow: ashmem_get_size_region() returned %d, expected %d"
                            " errno=%d",
                            actualSize, (int) size, errno);
                } else {
                    CursorWindow* window = new CursorWindow(name, dupAshmemFd,
                            data, size, true /*readOnly*/);