Work-around paletted image decoding bug in SDK_JELLYBEAN

Because there is a bug decoding paletted images in SDK_JELLYBEAN,
we need to avoid encoding paletted images for apps that support
SDK_JELLYBEAN and earlier.

BUG=27643907

Change-Id: Ib7d51ed87435cd36507915d62b0057c06f18b2b6
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index c449550..ca06ac4 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -249,7 +249,7 @@
      * above. SDK levels that have a non-numeric identifier are assumed
      * to be newer than any SDK level that has a number designated.
      */
-    bool isMinSdkAtLeast(int desired) {
+    bool isMinSdkAtLeast(int desired) const {
         /* If the application specifies a minSdkVersion in the manifest
          * then use that. Otherwise, check what the user specified on
          * the command line. If neither, it's not available since
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index 40466bd..9939c18 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -1134,10 +1134,9 @@
     }
 }
 
-
 static void write_png(const char* imageName,
                       png_structp write_ptr, png_infop write_info,
-                      image_info& imageInfo, int grayscaleTolerance)
+                      image_info& imageInfo, const Bundle* bundle)
 {
     png_uint_32 width, height;
     int color_type;
@@ -1174,9 +1173,26 @@
     bool hasTransparency;
     int paletteEntries, alphaPaletteEntries;
 
+    int grayscaleTolerance = bundle->getGrayscaleTolerance();
     analyze_image(imageName, imageInfo, grayscaleTolerance, rgbPalette, alphaPalette,
                   &paletteEntries, &alphaPaletteEntries, &hasTransparency, &color_type, outRows);
 
+    // Legacy versions of aapt would always encode 9patch PNGs as RGBA.  This had the unintended
+    // benefit of working around a bug decoding paletted images in Android 4.1.
+    // https://code.google.com/p/android/issues/detail?id=34619
+    //
+    // If SDK_JELLY_BEAN is supported, we need to avoid a paletted encoding in order to not expose
+    // this bug.
+    if (!bundle->isMinSdkAtLeast(SDK_JELLY_BEAN_MR1)) {
+        if (imageInfo.is9Patch && PNG_COLOR_TYPE_PALETTE == color_type) {
+            if (hasTransparency) {
+                color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+            } else {
+                color_type = PNG_COLOR_TYPE_RGB;
+            }
+        }
+    }
+
     if (kIsDebug) {
         switch (color_type) {
         case PNG_COLOR_TYPE_PALETTE:
@@ -1332,8 +1348,7 @@
         return false;
     }
 
-    write_png(printableName.string(), write_ptr, write_info, *imageInfo,
-              bundle->getGrayscaleTolerance());
+    write_png(printableName.string(), write_ptr, write_info, *imageInfo, bundle);
 
     return true;
 }
@@ -1543,8 +1558,7 @@
     }
 
     // Actually write out to the new png
-    write_png(dest.string(), write_ptr, write_info, imageInfo,
-              bundle->getGrayscaleTolerance());
+    write_png(dest.string(), write_ptr, write_info, imageInfo, bundle);
 
     if (bundle->getVerbose()) {
         // Find the size of our new file