Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 230e0258 authored by George Mount's avatar George Mount Committed by Android (Google) Code Review
Browse files

Merge "Use hardware bitmap for shared element snapshots." into oc-mr1-dev

parents e45c956f 3f81c33a
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
@@ -44,6 +45,8 @@ import java.util.Map;
public abstract class SharedElementCallback {
    private Matrix mTempMatrix;
    private static final String BUNDLE_SNAPSHOT_BITMAP = "sharedElement:snapshot:bitmap";
    private static final String BUNDLE_SNAPSHOT_GRAPHIC_BUFFER =
            "sharedElement:snapshot:graphicBuffer";
    private static final String BUNDLE_SNAPSHOT_IMAGE_SCALETYPE = "sharedElement:snapshot:imageScaleType";
    private static final String BUNDLE_SNAPSHOT_IMAGE_MATRIX = "sharedElement:snapshot:imageMatrix";

@@ -176,7 +179,12 @@ public abstract class SharedElementCallback {
                Bitmap bitmap = TransitionUtils.createDrawableBitmap(d);
                if (bitmap != null) {
                    Bundle bundle = new Bundle();
                    if (bitmap.getConfig() != Bitmap.Config.HARDWARE) {
                        bundle.putParcelable(BUNDLE_SNAPSHOT_BITMAP, bitmap);
                    } else {
                        GraphicBuffer graphicBuffer = bitmap.createGraphicBufferHandle();
                        bundle.putParcelable(BUNDLE_SNAPSHOT_GRAPHIC_BUFFER, graphicBuffer);
                    }
                    bundle.putString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE,
                            imageView.getScaleType().toString());
                    if (imageView.getScaleType() == ScaleType.MATRIX) {
@@ -218,10 +226,14 @@ public abstract class SharedElementCallback {
        View view = null;
        if (snapshot instanceof Bundle) {
            Bundle bundle = (Bundle) snapshot;
            Bitmap bitmap = (Bitmap) bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP);
            if (bitmap == null) {
            GraphicBuffer buffer = bundle.getParcelable(BUNDLE_SNAPSHOT_GRAPHIC_BUFFER);
            Bitmap bitmap = bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP);
            if (buffer == null && bitmap == null) {
                return null;
            }
            if (bitmap == null) {
                bitmap = Bitmap.createHardwareBitmap(buffer);
            }
            ImageView imageView = new ImageView(context);
            view = imageView;
            imageView.setImageBitmap(bitmap);
+17 −6
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.TypeEvaluator;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.DisplayListCanvas;
import android.view.RenderNode;
import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
@@ -126,8 +128,11 @@ public class TransitionUtils {
        }
        int bitmapWidth = (int) (width * scale);
        int bitmapHeight = (int) (height * scale);
        Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        final RenderNode node = RenderNode.create("TransitionUtils", null);
        node.setLeftTopRightBottom(0, 0, width, height);
        node.setClipToBounds(false);
        final DisplayListCanvas canvas = node.start(width, height);
        // Do stuff with the canvas
        Rect existingBounds = drawable.getBounds();
        int left = existingBounds.left;
        int top = existingBounds.top;
@@ -136,7 +141,8 @@ public class TransitionUtils {
        drawable.setBounds(0, 0, bitmapWidth, bitmapHeight);
        drawable.draw(canvas);
        drawable.setBounds(left, top, right, bottom);
        return bitmap;
        node.end(canvas);
        return ThreadedRenderer.createHardwareBitmap(node, width, height);
    }

    /**
@@ -162,10 +168,15 @@ public class TransitionUtils {
            bitmapHeight *= scale;
            matrix.postTranslate(-bounds.left, -bounds.top);
            matrix.postScale(scale, scale);
            bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);

            final RenderNode node = RenderNode.create("TransitionUtils", null);
            node.setLeftTopRightBottom(0, 0, bitmapWidth, bitmapHeight);
            node.setClipToBounds(false);
            final DisplayListCanvas canvas = node.start(bitmapWidth, bitmapHeight);
            canvas.concat(matrix);
            view.draw(canvas);
            node.end(canvas);
            bitmap = ThreadedRenderer.createHardwareBitmap(node, bitmapWidth, bitmapHeight);
        }
        return bitmap;
    }
+42 −3
Original line number Diff line number Diff line
@@ -16,22 +16,24 @@

package android.transition;

import android.animation.Animator;
import android.animation.AnimatorSetActivity;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.SmallTest;
import android.transition.Transition.TransitionListener;
import android.transition.TransitionListenerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;

import com.android.frameworks.coretests.R;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import static android.support.test.espresso.Espresso.onView;

public class FadeTransitionTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
    Activity mActivity;
    public FadeTransitionTest() {
@@ -129,6 +131,43 @@ public class FadeTransitionTest extends ActivityInstrumentationTestCase2<Animato
        assertEquals(View.INVISIBLE, square1.getVisibility());
    }

    @SmallTest
    public void testSnapshotView() throws Throwable {
        final View square1 = mActivity.findViewById(R.id.square1);

        final CountDownLatch disappearCalled = new CountDownLatch(1);
        final Fade fadeOut = new Fade(Fade.MODE_OUT) {
            @Override
            public Animator onDisappear(ViewGroup sceneRoot, View view,
                    TransitionValues startValues,
                    TransitionValues endValues) {
                assertNotSame(square1, view);
                assertTrue(view instanceof ImageView);
                ImageView imageView = (ImageView) view;
                BitmapDrawable background = (BitmapDrawable) imageView.getDrawable();
                Bitmap bitmap = background.getBitmap();
                assertEquals(Bitmap.Config.HARDWARE, bitmap.getConfig());
                Bitmap copy = bitmap.copy(Bitmap.Config.ARGB_8888, false);
                assertEquals(0xFFFF0000, copy.getPixel(1, 1));
                disappearCalled.countDown();
                return super.onDisappear(sceneRoot, view, startValues, endValues);
            }
        };

        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                ViewGroup container = mActivity.findViewById(R.id.container);
                TransitionManager.beginDelayedTransition(container, fadeOut);
                container.removeView(square1);
                FrameLayout parent = new FrameLayout(mActivity);
                parent.addView(square1);
            }
        });

        assertTrue(disappearCalled.await(1, TimeUnit.SECONDS));
    }

    public TransitionLatch setVisibilityInTransition(final Transition transition, int viewId,
            final int visibility) throws Throwable {
        final ViewGroup sceneRoot = (ViewGroup) mActivity.findViewById(R.id.container);
+38 −16
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import android.widget.TextView;

import com.android.frameworks.coretests.R;

import java.lang.reflect.Field;

public class TransitionTest extends ActivityInstrumentationTestCase2<AnimatorSetActivity> {
    Activity mActivity;
    public TransitionTest() {
@@ -77,27 +79,47 @@ public class TransitionTest extends ActivityInstrumentationTestCase2<AnimatorSet
        fade.setEpicenterCallback(epicenterCallback);

        Fade clone = (Fade) fade.clone();
        assertEquals(fade.mStartDelay, clone.mStartDelay);
        assertEquals(fade.mDuration, clone.mDuration);
        assertEquals(fade.mInterpolator, clone.mInterpolator);
        assertEquals(fade.mPropagation, clone.mPropagation);
        assertFieldEquals(fade, clone, "mStartDelay");
        assertFieldEquals(fade, clone, "mDuration");
        assertFieldEquals(fade, clone, "mInterpolator");
        assertFieldEquals(fade, clone, "mPropagation");
        assertEquals(fade.getPathMotion(), clone.getPathMotion());
        assertEquals(fade.getEpicenterCallback(), clone.getEpicenterCallback());
        assertEquals(fade.mNameOverrides, clone.mNameOverrides);
        assertEquals(fade.mMatchOrder, clone.mMatchOrder);
        assertFieldEquals(fade, clone, "mNameOverrides");
        assertFieldEquals(fade, clone, "mMatchOrder");

        assertFieldEquals(fade, clone, "mTargets");
        assertFieldEquals(fade, clone, "mTargetExcludes");
        assertFieldEquals(fade, clone, "mTargetChildExcludes");

        assertEquals(fade.mTargets, clone.mTargets);
        assertEquals(fade.mTargetExcludes, clone.mTargetExcludes);
        assertEquals(fade.mTargetChildExcludes, clone.mTargetChildExcludes);
        assertFieldEquals(fade, clone, "mTargetIds");
        assertFieldEquals(fade, clone, "mTargetIdExcludes");
        assertFieldEquals(fade, clone, "mTargetIdChildExcludes");

        assertEquals(fade.mTargetIds, clone.mTargetIds);
        assertEquals(fade.mTargetIdExcludes, clone.mTargetIdExcludes);
        assertEquals(fade.mTargetIdChildExcludes, clone.mTargetIdChildExcludes);
        assertFieldEquals(fade, clone, "mTargetNames");
        assertFieldEquals(fade, clone, "mTargetNameExcludes");

        assertEquals(fade.mTargetNames, clone.mTargetNames);
        assertEquals(fade.mTargetNameExcludes, clone.mTargetNameExcludes);
        assertFieldEquals(fade, clone, "mTargetTypes");
        assertFieldEquals(fade, clone, "mTargetTypeExcludes");
    }

        assertEquals(fade.mTargetTypes, clone.mTargetTypes);
        assertEquals(fade.mTargetTypeExcludes, clone.mTargetTypeExcludes);
    private static void assertFieldEquals(Fade fade1, Fade fade2, String fieldName)
            throws NoSuchFieldException, IllegalAccessException {
        Field field = findField(Fade.class, fieldName);
        field.setAccessible(true);
        assertEquals("Field '" + fieldName + "' value mismatch", field.get(fade1),
                field.get(fade2));
    }

    private static Field findField(Class<?> type, String fieldName) throws NoSuchFieldException {
        while (type != null) {
            try {
                return type.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                // try the parent
                type = type.getSuperclass();
            }
        }
        throw new NoSuchFieldException(fieldName);
    }
}