RecentsTransition.java revision bbc9b6fb5046588828daea5e2c81b4a1ceeb464f
1a6ea18334bb12f1940c23611bde669881000add2Winson Chung/*
2a6ea18334bb12f1940c23611bde669881000add2Winson Chung * Copyright (C) 2017 The Android Open Source Project
3a6ea18334bb12f1940c23611bde669881000add2Winson Chung *
4a6ea18334bb12f1940c23611bde669881000add2Winson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5a6ea18334bb12f1940c23611bde669881000add2Winson Chung * you may not use this file except in compliance with the License.
6a6ea18334bb12f1940c23611bde669881000add2Winson Chung * You may obtain a copy of the License at
7a6ea18334bb12f1940c23611bde669881000add2Winson Chung *
8a6ea18334bb12f1940c23611bde669881000add2Winson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9a6ea18334bb12f1940c23611bde669881000add2Winson Chung *
10a6ea18334bb12f1940c23611bde669881000add2Winson Chung * Unless required by applicable law or agreed to in writing, software
11a6ea18334bb12f1940c23611bde669881000add2Winson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12a6ea18334bb12f1940c23611bde669881000add2Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a6ea18334bb12f1940c23611bde669881000add2Winson Chung * See the License for the specific language governing permissions and
14a6ea18334bb12f1940c23611bde669881000add2Winson Chung * limitations under the License.
15a6ea18334bb12f1940c23611bde669881000add2Winson Chung */
16a6ea18334bb12f1940c23611bde669881000add2Winson Chungpackage com.android.systemui.shared.recents.view;
17a6ea18334bb12f1940c23611bde669881000add2Winson Chung
18a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.app.ActivityOptions;
19a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.app.ActivityOptions.OnAnimationStartedListener;
20a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.content.Context;
21a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.graphics.Bitmap;
22a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.graphics.Canvas;
23a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.graphics.GraphicBuffer;
24a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.os.Bundle;
25a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.os.Handler;
26a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.os.IRemoteCallback;
27a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.os.RemoteException;
28a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.view.DisplayListCanvas;
29a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.view.RenderNode;
30a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.view.ThreadedRenderer;
31a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport android.view.View;
32a6ea18334bb12f1940c23611bde669881000add2Winson Chung
33a6ea18334bb12f1940c23611bde669881000add2Winson Chungimport java.util.function.Consumer;
34a6ea18334bb12f1940c23611bde669881000add2Winson Chung
35a6ea18334bb12f1940c23611bde669881000add2Winson Chung/**
36a6ea18334bb12f1940c23611bde669881000add2Winson Chung * A helper class to create transitions to/from an App to Recents.
37a6ea18334bb12f1940c23611bde669881000add2Winson Chung */
38a6ea18334bb12f1940c23611bde669881000add2Winson Chungpublic class RecentsTransition {
39a6ea18334bb12f1940c23611bde669881000add2Winson Chung
40a6ea18334bb12f1940c23611bde669881000add2Winson Chung    /**
41a6ea18334bb12f1940c23611bde669881000add2Winson Chung     * Creates a new transition aspect scaled transition activity options.
42a6ea18334bb12f1940c23611bde669881000add2Winson Chung     */
43a6ea18334bb12f1940c23611bde669881000add2Winson Chung    public static ActivityOptions createAspectScaleAnimation(Context context, Handler handler,
44a6ea18334bb12f1940c23611bde669881000add2Winson Chung            boolean scaleUp, AppTransitionAnimationSpecsFuture animationSpecsFuture,
45bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal            final OnAnimationStartedListener animationStartCallback) {
46a6ea18334bb12f1940c23611bde669881000add2Winson Chung        final OnAnimationStartedListener animStartedListener = new OnAnimationStartedListener() {
47a6ea18334bb12f1940c23611bde669881000add2Winson Chung            private boolean mHandled;
48a6ea18334bb12f1940c23611bde669881000add2Winson Chung
49a6ea18334bb12f1940c23611bde669881000add2Winson Chung            @Override
50a6ea18334bb12f1940c23611bde669881000add2Winson Chung            public void onAnimationStarted() {
51a6ea18334bb12f1940c23611bde669881000add2Winson Chung                // OnAnimationStartedListener can be called numerous times, so debounce here to
52a6ea18334bb12f1940c23611bde669881000add2Winson Chung                // prevent multiple callbacks
53a6ea18334bb12f1940c23611bde669881000add2Winson Chung                if (mHandled) {
54a6ea18334bb12f1940c23611bde669881000add2Winson Chung                    return;
55a6ea18334bb12f1940c23611bde669881000add2Winson Chung                }
56a6ea18334bb12f1940c23611bde669881000add2Winson Chung                mHandled = true;
57a6ea18334bb12f1940c23611bde669881000add2Winson Chung
58a6ea18334bb12f1940c23611bde669881000add2Winson Chung                if (animationStartCallback != null) {
59a6ea18334bb12f1940c23611bde669881000add2Winson Chung                    animationStartCallback.onAnimationStarted();
60a6ea18334bb12f1940c23611bde669881000add2Winson Chung                }
61a6ea18334bb12f1940c23611bde669881000add2Winson Chung            }
62a6ea18334bb12f1940c23611bde669881000add2Winson Chung        };
63a6ea18334bb12f1940c23611bde669881000add2Winson Chung        final ActivityOptions opts = ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(
64a6ea18334bb12f1940c23611bde669881000add2Winson Chung                context, handler,
65a6ea18334bb12f1940c23611bde669881000add2Winson Chung                animationSpecsFuture != null ? animationSpecsFuture.getFuture() : null,
66a6ea18334bb12f1940c23611bde669881000add2Winson Chung                animStartedListener, scaleUp);
67a6ea18334bb12f1940c23611bde669881000add2Winson Chung        return opts;
68a6ea18334bb12f1940c23611bde669881000add2Winson Chung    }
69a6ea18334bb12f1940c23611bde669881000add2Winson Chung
70a6ea18334bb12f1940c23611bde669881000add2Winson Chung    /**
71a6ea18334bb12f1940c23611bde669881000add2Winson Chung     * Wraps a animation-start callback in a binder that can be called from window manager.
72a6ea18334bb12f1940c23611bde669881000add2Winson Chung     */
73bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal    public static IRemoteCallback wrapStartedListener(final Handler handler,
74bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal            final OnAnimationStartedListener listener) {
75a6ea18334bb12f1940c23611bde669881000add2Winson Chung        if (listener == null) {
76a6ea18334bb12f1940c23611bde669881000add2Winson Chung            return null;
77a6ea18334bb12f1940c23611bde669881000add2Winson Chung        }
78a6ea18334bb12f1940c23611bde669881000add2Winson Chung        return new IRemoteCallback.Stub() {
79a6ea18334bb12f1940c23611bde669881000add2Winson Chung            @Override
80a6ea18334bb12f1940c23611bde669881000add2Winson Chung            public void sendResult(Bundle data) throws RemoteException {
81bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                handler.post(new Runnable() {
82bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                                 @Override
83bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                                 public void run() {
84bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                                     listener.onAnimationStarted();
85bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                                 }
86bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                             });
87a6ea18334bb12f1940c23611bde669881000add2Winson Chung            }
88a6ea18334bb12f1940c23611bde669881000add2Winson Chung        };
89a6ea18334bb12f1940c23611bde669881000add2Winson Chung    }
90a6ea18334bb12f1940c23611bde669881000add2Winson Chung
91a6ea18334bb12f1940c23611bde669881000add2Winson Chung    /**
92a6ea18334bb12f1940c23611bde669881000add2Winson Chung     * @return a {@link GraphicBuffer} with the {@param view} drawn into it. Result can be null if
93a6ea18334bb12f1940c23611bde669881000add2Winson Chung     *         we were unable to allocate a hardware bitmap.
94a6ea18334bb12f1940c23611bde669881000add2Winson Chung     */
95bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal    public static GraphicBuffer drawViewIntoGraphicBuffer(int width, int height, final View view,
96bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal            final float scale, final int eraseColor) {
97bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal        final Bitmap hwBitmap = createHardwareBitmap(width, height, new Consumer<Canvas>() {
98bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal            @Override
99bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal            public void accept(Canvas c) {
100bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                c.scale(scale, scale);
101bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                if (eraseColor != 0) {
102bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                    c.drawColor(eraseColor);
103bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                }
104bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                if (view != null) {
105bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                    view.draw(c);
106bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal                }
107a6ea18334bb12f1940c23611bde669881000add2Winson Chung            }
108a6ea18334bb12f1940c23611bde669881000add2Winson Chung        });
109a6ea18334bb12f1940c23611bde669881000add2Winson Chung        return hwBitmap != null ? hwBitmap.createGraphicBufferHandle() : null;
110a6ea18334bb12f1940c23611bde669881000add2Winson Chung    }
111a6ea18334bb12f1940c23611bde669881000add2Winson Chung
112a6ea18334bb12f1940c23611bde669881000add2Winson Chung    /**
113a6ea18334bb12f1940c23611bde669881000add2Winson Chung     * @return a hardware {@link Bitmap} after being drawn with the {@param consumer}. Result can be
114a6ea18334bb12f1940c23611bde669881000add2Winson Chung     *         null if we were unable to allocate a hardware bitmap.
115a6ea18334bb12f1940c23611bde669881000add2Winson Chung     */
116a6ea18334bb12f1940c23611bde669881000add2Winson Chung    public static Bitmap createHardwareBitmap(int width, int height, Consumer<Canvas> consumer) {
117a6ea18334bb12f1940c23611bde669881000add2Winson Chung        RenderNode node = RenderNode.create("RecentsTransition", null);
118a6ea18334bb12f1940c23611bde669881000add2Winson Chung        node.setLeftTopRightBottom(0, 0, width, height);
119a6ea18334bb12f1940c23611bde669881000add2Winson Chung        node.setClipToBounds(false);
120a6ea18334bb12f1940c23611bde669881000add2Winson Chung        DisplayListCanvas c = node.start(width, height);
121a6ea18334bb12f1940c23611bde669881000add2Winson Chung        consumer.accept(c);
122a6ea18334bb12f1940c23611bde669881000add2Winson Chung        node.end(c);
123a6ea18334bb12f1940c23611bde669881000add2Winson Chung        return ThreadedRenderer.createHardwareBitmap(node, width, height);
124a6ea18334bb12f1940c23611bde669881000add2Winson Chung    }
125a6ea18334bb12f1940c23611bde669881000add2Winson Chung}
126