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

Commit 2d3e8b8d authored by George Mount's avatar George Mount Committed by android-build-merger
Browse files

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

am: 230e0258

Change-Id: I8dbb21476f7d38a37c8e5b5732b51255b0bcba14
parents f5c9bd16 230e0258
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);
    }
}