summaryrefslogtreecommitdiffstats
path: root/graphics/tests
diff options
context:
space:
mode:
authorDan Sandler <dsandler@android.com>2015-03-04 13:08:49 -0500
committerDan Sandler <dsandler@android.com>2015-05-01 13:44:42 -0400
commitb9f7aac3488873677377b36c57338d758098f78e (patch)
tree505fc8e2f81d70f0f9949ed490acb5854bf87c99 /graphics/tests
parent7dc7d09ba5abdc99eb5f106cf3ce545355d4c9be (diff)
downloadframeworks_base-b9f7aac3488873677377b36c57338d758098f78e.zip
frameworks_base-b9f7aac3488873677377b36c57338d758098f78e.tar.gz
frameworks_base-b9f7aac3488873677377b36c57338d758098f78e.tar.bz2
Icon: a clean, parcelable place for images.
Binder APIs which wish to consume Bitmaps *and* drawable resources can now do so by using Icon, a kind of union type that accommodates each of these. Icon also accepts byte arrays holding compressed Bitmaps (PNG, JPEG, etc), which saves clients the additional memory cost of decoding and sending full uncompressed bitmaps through Binder interfaces. Receiving clients can call loadDrawable{,Async} and then getDrawable to start immediately using the image in an ImageView or other Drawable-hosting container. Bug: 19609468 Change-Id: Ic1343711c2ac0b15876b46f0b6008b0108a49470
Diffstat (limited to 'graphics/tests')
-rw-r--r--graphics/tests/graphicstests/AndroidManifest.xml1
-rw-r--r--graphics/tests/graphicstests/res/drawable-nodpi/landscape.pngbin0 -> 24981 bytes
-rw-r--r--graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java345
3 files changed, 346 insertions, 0 deletions
diff --git a/graphics/tests/graphicstests/AndroidManifest.xml b/graphics/tests/graphicstests/AndroidManifest.xml
index 5fb5959..e019e28 100644
--- a/graphics/tests/graphicstests/AndroidManifest.xml
+++ b/graphics/tests/graphicstests/AndroidManifest.xml
@@ -24,6 +24,7 @@
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
<uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
diff --git a/graphics/tests/graphicstests/res/drawable-nodpi/landscape.png b/graphics/tests/graphicstests/res/drawable-nodpi/landscape.png
new file mode 100644
index 0000000..ddb3180
--- /dev/null
+++ b/graphics/tests/graphicstests/res/drawable-nodpi/landscape.png
Binary files differ
diff --git a/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java b/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
new file mode 100644
index 0000000..2b9bf50
--- /dev/null
+++ b/graphics/tests/graphicstests/src/android/graphics/drawable/IconTest.java
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.lang.Override;
+import java.util.Arrays;
+import java.util.ArrayList;
+
+import junit.framework.TestCase;
+
+import com.android.frameworks.graphicstests.R;
+
+public class IconTest extends AndroidTestCase {
+ public static final String TAG = IconTest.class.getSimpleName();
+ public static void L(String s, Object... parts) {
+ Log.d(TAG, (parts.length == 0) ? s : String.format(s, parts));
+ }
+
+ @SmallTest
+ public void testWithBitmap() throws Exception {
+ final Bitmap bm1 = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_8888);
+ final Bitmap bm2 = Bitmap.createBitmap(100, 200, Bitmap.Config.RGB_565);
+ final Bitmap bm3 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape))
+ .getBitmap();
+
+ final Canvas can1 = new Canvas(bm1);
+ can1.drawColor(0xFFFF0000);
+ final Canvas can2 = new Canvas(bm2);
+ can2.drawColor(0xFF00FF00);
+
+ final Icon im1 = Icon.createWithBitmap(bm1);
+ final Icon im2 = Icon.createWithBitmap(bm2);
+ final Icon im3 = Icon.createWithBitmap(bm3);
+
+ final Drawable draw1 = im1.loadDrawable(mContext);
+ final Drawable draw2 = im2.loadDrawable(mContext);
+ final Drawable draw3 = im3.loadDrawable(mContext);
+
+ final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(),
+ draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ final Bitmap test2 = Bitmap.createBitmap(draw2.getIntrinsicWidth(),
+ draw2.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ final Bitmap test3 = Bitmap.createBitmap(draw3.getIntrinsicWidth(),
+ draw3.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+
+ draw1.setBounds(0, 0, draw1.getIntrinsicWidth(), draw1.getIntrinsicHeight());
+ draw1.draw(new Canvas(test1));
+
+ draw2.setBounds(0, 0, draw2.getIntrinsicWidth(), draw2.getIntrinsicHeight());
+ draw2.draw(new Canvas(test2));
+
+ draw3.setBounds(0, 0, draw3.getIntrinsicWidth(), draw3.getIntrinsicHeight());
+ draw3.draw(new Canvas(test3));
+
+ final File dir = getContext().getExternalFilesDir(null);
+ L("writing temp bitmaps to %s...", dir);
+
+ bm1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "bitmap1-original.png")));
+ test1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "bitmap1-test.png")));
+ if (!equalBitmaps(bm1, test1)) {
+ findBitmapDifferences(bm1, test1);
+ fail("bitmap1 differs, check " + dir);
+ }
+
+ bm2.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "bitmap2-original.png")));
+ test2.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "bitmap2-test.png")));
+ if (!equalBitmaps(bm2, test2)) {
+ findBitmapDifferences(bm2, test2);
+ fail("bitmap2 differs, check " + dir);
+ }
+
+ bm3.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "bitmap3-original.png")));
+ test3.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "bitmap3-test.png")));
+ if (!equalBitmaps(bm3, test3)) {
+ findBitmapDifferences(bm3, test3);
+ fail("bitmap3 differs, check " + dir);
+ }
+ }
+
+ @SmallTest
+ public void testWithBitmapResource() throws Exception {
+ final Bitmap res1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape))
+ .getBitmap();
+
+ final Icon im1 = Icon.createWithResource(getContext().getResources(),
+ R.drawable.landscape);
+ final Drawable draw1 = im1.loadDrawable(mContext);
+ final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(),
+ draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight());
+ draw1.draw(new Canvas(test1));
+
+ final File dir = getContext().getExternalFilesDir(null);
+ res1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "res1-original.png")));
+ test1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "res1-test.png")));
+ if (!equalBitmaps(res1, test1)) {
+ findBitmapDifferences(res1, test1);
+ fail("res1 differs, check " + dir);
+ }
+ }
+
+ @SmallTest
+ public void testWithFile() throws Exception {
+ final Bitmap bit1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape))
+ .getBitmap();
+ final File dir = getContext().getExternalFilesDir(null);
+ final File file1 = new File(dir, "file1-original.png");
+ bit1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(file1));
+
+ final Icon im1 = Icon.createWithFilePath(file1.toString());
+ final Drawable draw1 = im1.loadDrawable(mContext);
+ final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(),
+ draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight());
+ draw1.draw(new Canvas(test1));
+
+ test1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "file1-test.png")));
+ if (!equalBitmaps(bit1, test1)) {
+ findBitmapDifferences(bit1, test1);
+ fail("testWithFile: file1 differs, check " + dir);
+ }
+ }
+
+ @SmallTest
+ public void testAsync() throws Exception {
+ final Bitmap bit1 = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape))
+ .getBitmap();
+ final File dir = getContext().getExternalFilesDir(null);
+ final File file1 = new File(dir, "async-original.png");
+ bit1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(file1));
+
+ final Icon im1 = Icon.createWithFilePath(file1.toString());
+ final HandlerThread thd = new HandlerThread("testAsync");
+ thd.start();
+ final Handler h = new Handler(thd.getLooper());
+ L(TAG, "asyncTest: dispatching load to thread: " + thd);
+ im1.loadDrawableAsync(mContext, h, new Icon.OnDrawableLoadedListener() {
+ @Override
+ public void onDrawableLoaded(Drawable draw1) {
+ L(TAG, "asyncTest: thread: loading drawable");
+ L(TAG, "asyncTest: thread: loaded: %dx%d", draw1.getIntrinsicWidth(),
+ draw1.getIntrinsicHeight());
+ final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(),
+ draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight());
+ draw1.draw(new Canvas(test1));
+
+ try {
+ test1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(new File(dir, "async-test.png")));
+ } catch (java.io.FileNotFoundException ex) {
+ fail("couldn't create test file: " + ex);
+ }
+ if (!equalBitmaps(bit1, test1)) {
+ findBitmapDifferences(bit1, test1);
+ fail("testAsync: file1 differs, check " + dir);
+ }
+ }
+ });
+ L(TAG, "asyncTest: awaiting result");
+ Thread.sleep(500); // ;_;
+ assertTrue("async-test.png does not exist!", new File(dir, "async-test.png").exists());
+ L(TAG, "asyncTest: done");
+ }
+
+ @SmallTest
+ public void testParcel() throws Exception {
+ final Bitmap originalbits = ((BitmapDrawable) getContext().getDrawable(R.drawable.landscape))
+ .getBitmap();
+
+ final ByteArrayOutputStream ostream = new ByteArrayOutputStream(
+ originalbits.getWidth() * originalbits.getHeight() * 2); // guess 50% compression
+ originalbits.compress(Bitmap.CompressFormat.PNG, 100, ostream);
+ final byte[] pngdata = ostream.toByteArray();
+
+ L("starting testParcel; bitmap: %d bytes, PNG: %d bytes",
+ originalbits.getByteCount(),
+ pngdata.length);
+
+ final File dir = getContext().getExternalFilesDir(null);
+ final File originalfile = new File(dir, "parcel-original.png");
+ new FileOutputStream(originalfile).write(pngdata);
+
+ ArrayList<Icon> imgs = new ArrayList<>();
+ final Icon file1 = Icon.createWithFilePath(originalfile.getAbsolutePath());
+ imgs.add(file1);
+ final Icon bit1 = Icon.createWithBitmap(originalbits);
+ imgs.add(bit1);
+ final Icon data1 = Icon.createWithData(pngdata, 0, pngdata.length);
+ imgs.add(data1);
+ final Icon res1 = Icon.createWithResource(getContext().getResources(), R.drawable.landscape);
+ imgs.add(res1);
+
+ ArrayList<Icon> test = new ArrayList<>();
+ final Parcel parcel = Parcel.obtain();
+ int pos = 0;
+ parcel.writeInt(imgs.size());
+ for (Icon img : imgs) {
+ img.writeToParcel(parcel, 0);
+ L("used %d bytes parceling: %s", parcel.dataPosition() - pos, img);
+ pos = parcel.dataPosition();
+ }
+
+ parcel.setDataPosition(0); // rewind
+ final int N = parcel.readInt();
+ for (int i=0; i<N; i++) {
+ Icon img = Icon.CREATOR.createFromParcel(parcel);
+ L("test %d: read from parcel: %s", i, img);
+ final File testfile = new File(dir,
+ String.format("parcel-test%02d.png", i));
+
+ final Drawable draw1 = img.loadDrawable(mContext);
+ if (draw1 == null) {
+ fail("null drawable from img: " + img);
+ }
+ final Bitmap test1 = Bitmap.createBitmap(draw1.getIntrinsicWidth(),
+ draw1.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
+ draw1.setBounds(0, 0, test1.getWidth(), test1.getHeight());
+ draw1.draw(new Canvas(test1));
+
+ try {
+ test1.compress(Bitmap.CompressFormat.PNG, 100,
+ new FileOutputStream(testfile));
+ } catch (java.io.FileNotFoundException ex) {
+ fail("couldn't create test file " + testfile + ": " + ex);
+ }
+ if (!equalBitmaps(originalbits, test1)) {
+ findBitmapDifferences(originalbits, test1);
+ fail(testfile + " differs from original: " + originalfile);
+ }
+
+ }
+ }
+
+
+ // ======== utils ========
+
+ static final char[] GRADIENT = " .:;+=xX$#".toCharArray();
+ static float[] hsv = new float[3];
+ static char colorToChar(int color) {
+ int sum = ((color >> 16) & 0xff)
+ + ((color >> 8) & 0xff)
+ + ((color) & 0xff);
+ return GRADIENT[sum * (GRADIENT.length-1) / (3*0xff)];
+ }
+ static void printBits(int[] a, int w, int h) {
+ final StringBuilder sb = new StringBuilder();
+ for (int i=0; i<w; i++) {
+ for (int j=0; j<h; j++) {
+ sb.append(colorToChar(a[i+w*j]));
+ }
+ sb.append('\n');
+ }
+ L(sb.toString());
+ }
+ static void printBits(Bitmap a) {
+ final int w = a.getWidth();
+ final int h = a.getHeight();
+ int[] aPix = new int[w * h];
+ printBits(aPix, w, h);
+ }
+ boolean equalBitmaps(Bitmap a, Bitmap b) {
+ if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) return false;
+
+ final int w = a.getWidth();
+ final int h = a.getHeight();
+ int[] aPix = new int[w * h];
+ int[] bPix = new int[w * h];
+
+ a.getPixels(aPix, 0, w, 0, 0, w, h);
+ b.getPixels(bPix, 0, w, 0, 0, w, h);
+
+ return Arrays.equals(aPix, bPix);
+ }
+
+ void findBitmapDifferences(Bitmap a, Bitmap b) {
+ if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) {
+ L("different sizes: %dx%d vs %dx%d",
+ a.getWidth(), a.getHeight(), b.getWidth(), b.getHeight());
+ return;
+ }
+
+ final int w = a.getWidth();
+ final int h = a.getHeight();
+ int[] aPix = new int[w * h];
+ int[] bPix = new int[w * h];
+
+ a.getPixels(aPix, 0, w, 0, 0, w, h);
+ b.getPixels(bPix, 0, w, 0, 0, w, h);
+
+ L("bitmap a (%dx%d)", w, h);
+ printBits(aPix, w, h);
+ L("bitmap b (%dx%d)", w, h);
+ printBits(bPix, w, h);
+
+ StringBuffer sb = new StringBuffer("Different pixels: ");
+ for (int i=0; i<w; i++) {
+ for (int j=0; j<h; j++) {
+ if (aPix[i+w*j] != bPix[i+w*j]) {
+ sb.append(" ").append(i).append(",").append(j);
+ }
+ }
+ }
+ L(sb.toString());
+ }
+}