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, 452cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung final Runnable 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) { 592cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung animationStartCallback.run(); 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, 742cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung final Runnable animationStartCallback) { 752cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung if (animationStartCallback == 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 { 812cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung handler.post(animationStartCallback); 82a6ea18334bb12f1940c23611bde669881000add2Winson Chung } 83a6ea18334bb12f1940c23611bde669881000add2Winson Chung }; 84a6ea18334bb12f1940c23611bde669881000add2Winson Chung } 85a6ea18334bb12f1940c23611bde669881000add2Winson Chung 86a6ea18334bb12f1940c23611bde669881000add2Winson Chung /** 87a6ea18334bb12f1940c23611bde669881000add2Winson Chung * @return a {@link GraphicBuffer} with the {@param view} drawn into it. Result can be null if 88a6ea18334bb12f1940c23611bde669881000add2Winson Chung * we were unable to allocate a hardware bitmap. 89a6ea18334bb12f1940c23611bde669881000add2Winson Chung */ 902cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung public static Bitmap drawViewIntoHardwareBitmap(int width, int height, final View view, 91bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal final float scale, final int eraseColor) { 922cf6ad832d7be4e86765a2326498b50560af07dfWinson Chung return createHardwareBitmap(width, height, new Consumer<Canvas>() { 93bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal @Override 94bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal public void accept(Canvas c) { 95bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal c.scale(scale, scale); 96bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal if (eraseColor != 0) { 97bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal c.drawColor(eraseColor); 98bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal } 99bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal if (view != null) { 100bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal view.draw(c); 101bbc9b6fb5046588828daea5e2c81b4a1ceeb464fSunny Goyal } 102a6ea18334bb12f1940c23611bde669881000add2Winson Chung } 103a6ea18334bb12f1940c23611bde669881000add2Winson Chung }); 104a6ea18334bb12f1940c23611bde669881000add2Winson Chung } 105a6ea18334bb12f1940c23611bde669881000add2Winson Chung 106a6ea18334bb12f1940c23611bde669881000add2Winson Chung /** 107a6ea18334bb12f1940c23611bde669881000add2Winson Chung * @return a hardware {@link Bitmap} after being drawn with the {@param consumer}. Result can be 108a6ea18334bb12f1940c23611bde669881000add2Winson Chung * null if we were unable to allocate a hardware bitmap. 109a6ea18334bb12f1940c23611bde669881000add2Winson Chung */ 110a6ea18334bb12f1940c23611bde669881000add2Winson Chung public static Bitmap createHardwareBitmap(int width, int height, Consumer<Canvas> consumer) { 111a6ea18334bb12f1940c23611bde669881000add2Winson Chung RenderNode node = RenderNode.create("RecentsTransition", null); 112a6ea18334bb12f1940c23611bde669881000add2Winson Chung node.setLeftTopRightBottom(0, 0, width, height); 113a6ea18334bb12f1940c23611bde669881000add2Winson Chung node.setClipToBounds(false); 114a6ea18334bb12f1940c23611bde669881000add2Winson Chung DisplayListCanvas c = node.start(width, height); 115a6ea18334bb12f1940c23611bde669881000add2Winson Chung consumer.accept(c); 116a6ea18334bb12f1940c23611bde669881000add2Winson Chung node.end(c); 117a6ea18334bb12f1940c23611bde669881000add2Winson Chung return ThreadedRenderer.createHardwareBitmap(node, width, height); 118a6ea18334bb12f1940c23611bde669881000add2Winson Chung } 119a6ea18334bb12f1940c23611bde669881000add2Winson Chung} 120