Fix reconfigure & setPremult alpha handling

Bug: 20948129
Change-Id: Ifba35e5d87772a304fd3655e4a2363b293a6d8ac
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 04b9a95..832f92f 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -46,8 +46,8 @@
         SkSafeUnref(mColorTable);
     }
 
-    void reconfigure(const SkImageInfo& info, size_t rowBytes, SkColorTable* ctable) {
-        if (kIndex_8_SkColorType != info.colorType()) {
+    void reconfigure(const SkImageInfo& newInfo, size_t rowBytes, SkColorTable* ctable) {
+        if (kIndex_8_SkColorType != newInfo.colorType()) {
             ctable = nullptr;
         }
         mRowBytes = rowBytes;
@@ -56,13 +56,22 @@
             mColorTable = ctable;
             SkSafeRef(mColorTable);
         }
+
+        // Need to validate the alpha type to filter against the color type
+        // to prevent things like a non-opaque RGB565 bitmap
+        SkAlphaType alphaType;
+        LOG_ALWAYS_FATAL_IF(!SkColorTypeValidateAlphaType(
+                newInfo.colorType(), newInfo.alphaType(), &alphaType),
+                "Failed to validate alpha type!");
+
         // Dirty hack is dirty
         // TODO: Figure something out here, Skia's current design makes this
         // really hard to work with. Skia really, really wants immutable objects,
         // but with the nested-ref-count hackery going on that's just not
         // feasible without going insane trying to figure it out
         SkImageInfo* myInfo = const_cast<SkImageInfo*>(&this->info());
-        *myInfo = info;
+        *myInfo = newInfo;
+        changeAlphaType(alphaType);
 
         // Docs say to only call this in the ctor, but we're going to call
         // it anyway even if this isn't always the ctor.
@@ -254,6 +263,14 @@
     reconfigure(info, info.minRowBytes(), nullptr);
 }
 
+void Bitmap::setAlphaType(SkAlphaType alphaType) {
+    if (!SkColorTypeValidateAlphaType(info().colorType(), alphaType, &alphaType)) {
+        return;
+    }
+
+    mPixelRef->changeAlphaType(alphaType);
+}
+
 void Bitmap::detachFromJava() {
     bool disposeSelf;
     {
@@ -861,10 +878,10 @@
         jboolean hasAlpha, jboolean requestPremul) {
     LocalScopedBitmap bitmap(bitmapHandle);
     if (hasAlpha) {
-        bitmap->peekAtPixelRef()->changeAlphaType(
+        bitmap->setAlphaType(
                 requestPremul ? kPremul_SkAlphaType : kUnpremul_SkAlphaType);
     } else {
-        bitmap->peekAtPixelRef()->changeAlphaType(kOpaque_SkAlphaType);
+        bitmap->setAlphaType(kOpaque_SkAlphaType);
     }
 }
 
@@ -873,9 +890,9 @@
     LocalScopedBitmap bitmap(bitmapHandle);
     if (!bitmap->info().isOpaque()) {
         if (isPremul) {
-            bitmap->peekAtPixelRef()->changeAlphaType(kPremul_SkAlphaType);
+            bitmap->setAlphaType(kPremul_SkAlphaType);
         } else {
-            bitmap->peekAtPixelRef()->changeAlphaType(kUnpremul_SkAlphaType);
+            bitmap->setAlphaType(kUnpremul_SkAlphaType);
         }
     }
 }