Change how Java Bitmaps are accessed in a few places

Stop assuming that a Java Bitmap has a SkBitmap* that
has some externally managed lifecycle, and instead switch
a bunch of users to accessing the bitmap by providing
their own SkBitmap* on which to set the (ref counted!)
SkPixelRef* instead

Attempt #2 to land this, original issue was in getSkBitmap
and should be fixed

Change-Id: I0fd9e193968b41e5597784140d56b4885906864a
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 4c4a39d..d4069a1 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -261,7 +261,7 @@
     SkBitmap* outputBitmap = NULL;
     unsigned int existingBufferSize = 0;
     if (javaBitmap != NULL) {
-        outputBitmap = GraphicsJNI::getSkBitmap(env, javaBitmap);
+        outputBitmap = GraphicsJNI::getSkBitmapDeprecated(env, javaBitmap);
         if (outputBitmap->isImmutable()) {
             ALOGW("Unable to reuse an immutable bitmap as an image decoder target.");
             javaBitmap = NULL;
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index 3525d07..aeea808 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -217,7 +217,7 @@
 
     if (tileBitmap != NULL) {
         // Re-use bitmap.
-        bitmap = GraphicsJNI::getSkBitmap(env, tileBitmap);
+        bitmap = GraphicsJNI::getSkBitmapDeprecated(env, tileBitmap);
     }
     if (bitmap == NULL) {
         bitmap = new SkBitmap;
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 44037dd..f793df1 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -338,7 +338,7 @@
     return static_cast<SkColorType>(gConfig2ColorType[legacyConfig]);
 }
 
-SkBitmap* GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap) {
+SkBitmap* GraphicsJNI::getSkBitmapDeprecated(JNIEnv* env, jobject bitmap) {
     SkASSERT(env);
     SkASSERT(bitmap);
     SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
@@ -348,6 +348,19 @@
     return b;
 }
 
+void GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap, SkBitmap* outBitmap) {
+    // TODO: We have to copy from the existing bitmap due to rowBytes not
+    // being updated on the SkPixelRef at reconfigure time. This is a short term
+    // problem that will be fixed with the specialized wrapper
+    *outBitmap = *getSkBitmapDeprecated(env, bitmap);
+}
+
+SkPixelRef* GraphicsJNI::getSkPixelRef(JNIEnv* env, jobject bitmap) {
+    jlong bitmapHandle = env->GetLongField(bitmap, gBitmap_skBitmapPtr);
+    SkBitmap* b = reinterpret_cast<SkBitmap*>(bitmapHandle);
+    return b->pixelRef();
+}
+
 SkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) {
     SkASSERT(env);
     if (NULL == jconfig) {
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index d73507e..8eb43f8 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -49,7 +49,9 @@
     static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
 
     static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
-    static SkBitmap* getSkBitmap(JNIEnv*, jobject bitmap);
+    static SkBitmap* getSkBitmapDeprecated(JNIEnv*, jobject bitmap);
+    static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
+    static SkPixelRef* getSkPixelRef(JNIEnv*, jobject bitmap);
     static SkRegion* getNativeRegion(JNIEnv*, jobject region);
 
     // Given the 'native' long held by the Rasterizer.java object, return a
diff --git a/core/jni/android/graphics/pdf/PdfRenderer.cpp b/core/jni/android/graphics/pdf/PdfRenderer.cpp
index fc98cf9..876bea4 100644
--- a/core/jni/android/graphics/pdf/PdfRenderer.cpp
+++ b/core/jni/android/graphics/pdf/PdfRenderer.cpp
@@ -243,19 +243,21 @@
 }
 
 static void nativeRenderPage(JNIEnv* env, jclass thiz, jlong documentPtr, jlong pagePtr,
-        jlong bitmapPtr, jint destLeft, jint destTop, jint destRight, jint destBottom,
+        jobject jbitmap, jint destLeft, jint destTop, jint destRight, jint destBottom,
         jlong matrixPtr, jint renderMode) {
 
     FPDF_PAGE page = reinterpret_cast<FPDF_PAGE>(pagePtr);
-    SkBitmap* skBitmap = reinterpret_cast<SkBitmap*>(bitmapPtr);
     SkMatrix* skMatrix = reinterpret_cast<SkMatrix*>(matrixPtr);
 
-    skBitmap->lockPixels();
+    SkBitmap skBitmap;
+    GraphicsJNI::getSkBitmap(env, jbitmap, &skBitmap);
 
-    const int stride = skBitmap->width() * 4;
+    SkAutoLockPixels alp(skBitmap);
 
-    FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap->width(), skBitmap->height(),
-            FPDFBitmap_BGRA, skBitmap->getPixels(), stride);
+    const int stride = skBitmap.width() * 4;
+
+    FPDF_BITMAP bitmap = FPDFBitmap_CreateEx(skBitmap.width(), skBitmap.height(),
+            FPDFBitmap_BGRA, skBitmap.getPixels(), stride);
 
     if (!bitmap) {
         ALOGE("Erorr creating bitmap");
@@ -278,8 +280,7 @@
     renderPageBitmap(bitmap, page, destLeft, destTop, destRight,
             destBottom, skMatrix, renderFlags);
 
-    skBitmap->notifyPixelsChanged();
-    skBitmap->unlockPixels();
+    skBitmap.notifyPixelsChanged();
 }
 
 static JNINativeMethod gPdfRenderer_Methods[] = {
@@ -287,7 +288,7 @@
     {"nativeClose", "(J)V", (void*) nativeClose},
     {"nativeGetPageCount", "(J)I", (void*) nativeGetPageCount},
     {"nativeScaleForPrinting", "(J)Z", (void*) nativeScaleForPrinting},
-    {"nativeRenderPage", "(JJJIIIIJI)V", (void*) nativeRenderPage},
+    {"nativeRenderPage", "(JJLandroid/graphics/Bitmap;IIIIJI)V", (void*) nativeRenderPage},
     {"nativeOpenPageAndGetSize", "(JILandroid/graphics/Point;)J", (void*) nativeOpenPageAndGetSize},
     {"nativeClosePage", "(J)V", (void*) nativeClosePage}
 };
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 5c2d0d0..bce2b33 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -618,23 +618,25 @@
 static jint util_getInternalFormat(JNIEnv *env, jclass clazz,
         jobject jbitmap)
 {
-    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
-    return getInternalFormat(nativeBitmap->colorType());
+    SkBitmap nativeBitmap;
+    GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap);
+    return getInternalFormat(nativeBitmap.colorType());
 }
 
 static jint util_getType(JNIEnv *env, jclass clazz,
         jobject jbitmap)
 {
-    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
-    return getType(nativeBitmap->colorType());
+    SkBitmap nativeBitmap;
+    GraphicsJNI::getSkBitmap(env, jbitmap, &nativeBitmap);
+    return getType(nativeBitmap.colorType());
 }
 
 static jint util_texImage2D(JNIEnv *env, jclass clazz,
         jint target, jint level, jint internalformat,
         jobject jbitmap, jint type, jint border)
 {
-    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
-    const SkBitmap& bitmap(*nativeBitmap);
+    SkBitmap bitmap;
+    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
     SkColorType colorType = bitmap.colorType();
     if (internalformat < 0) {
         internalformat = getInternalFormat(colorType);
@@ -680,8 +682,8 @@
         jint target, jint level, jint xoffset, jint yoffset,
         jobject jbitmap, jint format, jint type)
 {
-    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
-    const SkBitmap& bitmap(*nativeBitmap);
+    SkBitmap bitmap;
+    GraphicsJNI::getSkBitmap(env, jbitmap, &bitmap);
     SkColorType colorType = bitmap.colorType();
     if (format < 0) {
         format = getInternalFormat(colorType);
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 3ae829b..5d08532 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -42,7 +42,7 @@
 static jlong initRaster(JNIEnv* env, jobject, jobject jbitmap) {
     SkBitmap* bitmap = nullptr;
     if (jbitmap != NULL) {
-        bitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
+        bitmap = GraphicsJNI::getSkBitmapDeprecated(env, jbitmap);
     }
     return reinterpret_cast<jlong>(Canvas::create_canvas(
             bitmap ? *bitmap : SkBitmap()));
@@ -53,7 +53,7 @@
 static void setBitmap(JNIEnv* env, jobject, jlong canvasHandle, jobject jbitmap) {
     SkBitmap* bitmap = nullptr;
     if (jbitmap != NULL) {
-        bitmap = GraphicsJNI::getSkBitmap(env, jbitmap);
+        bitmap = GraphicsJNI::getSkBitmapDeprecated(env, jbitmap);
     }
     get_canvas(canvasHandle)->setBitmap(bitmap ? *bitmap : SkBitmap());
 }
diff --git a/core/jni/android_view_PointerIcon.cpp b/core/jni/android_view_PointerIcon.cpp
index f6d9a1a..d04adbf 100644
--- a/core/jni/android_view_PointerIcon.cpp
+++ b/core/jni/android_view_PointerIcon.cpp
@@ -80,10 +80,7 @@
 
     jobject bitmapObj = env->GetObjectField(loadedPointerIconObj, gPointerIconClassInfo.mBitmap);
     if (bitmapObj) {
-        SkBitmap* bitmap = GraphicsJNI::getSkBitmap(env, bitmapObj);
-        if (bitmap) {
-            outPointerIcon->bitmap = *bitmap; // use a shared pixel ref
-        }
+        GraphicsJNI::getSkBitmap(env, bitmapObj, &(outPointerIcon->bitmap));
         env->DeleteLocalRef(bitmapObj);
     }
 
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 7080e2a..baeb7dd 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -277,8 +277,9 @@
     EGLConfig  cnf = getConfig(_env, config);
     jint* base = 0;
 
-    SkBitmap const * nativeBitmap = GraphicsJNI::getSkBitmap(_env, native_pixmap);
-    SkPixelRef* ref = nativeBitmap ? nativeBitmap->pixelRef() : 0;
+    SkBitmap nativeBitmap;
+    GraphicsJNI::getSkBitmap(_env, native_pixmap, &nativeBitmap);
+    SkPixelRef* ref = nativeBitmap.pixelRef();
     if (ref == NULL) {
         jniThrowException(_env, "java/lang/IllegalArgumentException", "Bitmap has no PixelRef");
         return;
@@ -289,10 +290,10 @@
 
     egl_native_pixmap_t pixmap;
     pixmap.version = sizeof(pixmap);
-    pixmap.width  = nativeBitmap->width();
-    pixmap.height = nativeBitmap->height();
-    pixmap.stride = nativeBitmap->rowBytes() / nativeBitmap->bytesPerPixel();
-    pixmap.format = convertPixelFormat(nativeBitmap->colorType());
+    pixmap.width  = nativeBitmap.width();
+    pixmap.height = nativeBitmap.height();
+    pixmap.stride = nativeBitmap.rowBytes() / nativeBitmap.bytesPerPixel();
+    pixmap.format = convertPixelFormat(nativeBitmap.colorType());
     pixmap.data   = (uint8_t*)ref->pixels();
 
     base = beginNativeAttribList(_env, attrib_list);