Improve CursorWindow failure message

Bug: 129139241
Bug: 129721058
Test: atest CursorWindowTest
Change-Id: Iac1c5ec6f999dadd638fc5ab47c69d13f60ea467
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index 44bd883..647448c 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -61,7 +61,10 @@
 
     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 @@
         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 @@
         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 86cda44..5e4d6e3 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -92,7 +92,9 @@
     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 @@
     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 a99e77f..e1067fc 100644
--- a/libs/androidfw/CursorWindow.cpp
+++ b/libs/androidfw/CursorWindow.cpp
@@ -49,15 +49,21 @@
     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 @@
     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*/);