diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index 44bd88376c4fd..647448caee826 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -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 : ""; 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"); diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp index 86cda44557343..5e4d6e38569b9 100644 --- a/core/jni/android_database_CursorWindow.cpp +++ b/core/jni/android_database_CursorWindow.cpp @@ -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; } diff --git a/libs/androidfw/CursorWindow.cpp b/libs/androidfw/CursorWindow.cpp index a99e77f8dbb93..e1067fcd4d3db 100644 --- a/libs/androidfw/CursorWindow.cpp +++ b/libs/androidfw/CursorWindow.cpp @@ -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*/);