Add internal bitmap api for creating immutable ashmem backed bitmaps.

Bug 21037890
Change-Id: I827e83dd75e301e7d93ead5efdd744f0d8435ae5
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 7bd5af1..04b9a95 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -719,6 +719,21 @@
             getPremulBitmapCreateFlags(isMutable));
 }
 
+static jobject Bitmap_copyAshmem(JNIEnv* env, jobject, jlong srcHandle) {
+    SkBitmap src;
+    reinterpret_cast<Bitmap*>(srcHandle)->getSkBitmap(&src);
+    SkBitmap result;
+
+    AshmemPixelAllocator allocator(env);
+    if (!src.copyTo(&result, &allocator)) {
+        return NULL;
+    }
+    Bitmap* bitmap = allocator.getStorageObjAndReset();
+    bitmap->peekAtPixelRef()->setImmutable();
+    jobject ret = GraphicsJNI::createBitmap(env, bitmap, getPremulBitmapCreateFlags(false));
+    return ret;
+}
+
 static void Bitmap_destructor(JNIEnv* env, jobject, jlong bitmapHandle) {
     LocalScopedBitmap bitmap(bitmapHandle);
     bitmap->detachFromJava();
@@ -1267,6 +1282,8 @@
         (void*)Bitmap_creator },
     {   "nativeCopy",               "(JIZ)Landroid/graphics/Bitmap;",
         (void*)Bitmap_copy },
+    {   "nativeCopyAshmem",         "(J)Landroid/graphics/Bitmap;",
+        (void*)Bitmap_copyAshmem },
     {   "nativeDestructor",         "(J)V", (void*)Bitmap_destructor },
     {   "nativeRecycle",            "(J)Z", (void*)Bitmap_recycle },
     {   "nativeReconfigure",        "(JIIIIZ)V", (void*)Bitmap_reconfigure },
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 028a385..ff22ef3 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -674,6 +674,25 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
+AshmemPixelAllocator::AshmemPixelAllocator(JNIEnv *env) {
+    LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJavaVM) != JNI_OK,
+            "env->GetJavaVM failed");
+}
+
+AshmemPixelAllocator::~AshmemPixelAllocator() {
+    if (mStorage) {
+        mStorage->detachFromJava();
+    }
+}
+
+bool AshmemPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
+    JNIEnv* env = vm2env(mJavaVM);
+    mStorage = GraphicsJNI::allocateAshmemPixelRef(env, bitmap, ctable);
+    return mStorage != nullptr;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
 static jclass make_globalref(JNIEnv* env, const char classname[])
 {
     jclass c = env->FindClass(classname);
diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h
index 4f72118..1938e85 100644
--- a/core/jni/android/graphics/GraphicsJNI.h
+++ b/core/jni/android/graphics/GraphicsJNI.h
@@ -144,6 +144,23 @@
     android::Bitmap* mStorage = nullptr;
 };
 
+class AshmemPixelAllocator : public SkBitmap::Allocator {
+public:
+    AshmemPixelAllocator(JNIEnv* env);
+    ~AshmemPixelAllocator();
+    virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
+    android::Bitmap* getStorageObjAndReset() {
+        android::Bitmap* result = mStorage;
+        mStorage = NULL;
+        return result;
+    };
+
+private:
+    JavaVM* mJavaVM;
+    android::Bitmap* mStorage = nullptr;
+};
+
+
 enum JNIAccess {
     kRO_JNIAccess,
     kRW_JNIAccess