18ae4198a448ab308aed95756e82da82ce42735a7Winson Chung/* 28ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * Copyright (C) 2017 The Android Open Source Project 38ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * 48ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 58ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * you may not use this file except in compliance with the License. 68ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * You may obtain a copy of the License at 78ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * 88ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 98ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * 108ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * Unless required by applicable law or agreed to in writing, software 118ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 128ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * See the License for the specific language governing permissions and 148ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * limitations under the License. 158ae4198a448ab308aed95756e82da82ce42735a7Winson Chung */ 168ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 17f633ef5f4310b6f79087797a2dc215812f841b70Sunny Goyalpackage com.android.quickstep.views; 188ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 196dceb7755a40de149ee1548d1ebf728ab4ea8318Winson Chungimport static android.widget.Toast.LENGTH_SHORT; 20783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev 21d58c2d5a48f163d7f6837cef3415562a81582df9Tony Wickhamimport static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA_MULTIPLIER; 22c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham 23c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickhamimport android.animation.Animator; 24c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickhamimport android.animation.AnimatorListenerAdapter; 25c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickhamimport android.animation.ObjectAnimator; 26e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyalimport android.animation.TimeInterpolator; 27b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chungimport android.app.ActivityOptions; 288ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport android.content.Context; 29bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyalimport android.content.res.Resources; 30bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyalimport android.graphics.Outline; 31ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshevimport android.os.Bundle; 329c70e7e220b8ffebc15d3cc1fed89163d4724abfTonyimport android.os.Handler; 338ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport android.util.AttributeSet; 34b271ad89728d9af582022a07fd190c3f3d685b97Tonyimport android.util.FloatProperty; 3580602a94ec225e26e39c4054d71da711bf17a531Winson Chungimport android.util.Log; 36b271ad89728d9af582022a07fd190c3f3d685b97Tonyimport android.util.Property; 37bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyalimport android.view.View; 38bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyalimport android.view.ViewOutlineProvider; 39ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshevimport android.view.accessibility.AccessibilityNodeInfo; 408ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport android.widget.FrameLayout; 416dceb7755a40de149ee1548d1ebf728ab4ea8318Winson Chungimport android.widget.Toast; 42b271ad89728d9af582022a07fd190c3f3d685b97Tony 439bd862e588aad4971f0f4383412b20ddeb0ff4b4Tony Wickhamimport com.android.launcher3.BaseActivity; 440b0847b272a37ed115504956be5ce44a96b5784cSunny Goyalimport com.android.launcher3.BaseDraggingActivity; 458ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport com.android.launcher3.R; 469bd862e588aad4971f0f4383412b20ddeb0ff4b4Tony Wickhamimport com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; 479bd862e588aad4971f0f4383412b20ddeb0ff4b4Tony Wickhamimport com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch; 48ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshevimport com.android.quickstep.TaskSystemShortcut; 499bd862e588aad4971f0f4383412b20ddeb0ff4b4Tony Wickhamimport com.android.quickstep.TaskUtils; 50f633ef5f4310b6f79087797a2dc215812f841b70Sunny Goyalimport com.android.quickstep.views.RecentsView.PageCallbacks; 51f633ef5f4310b6f79087797a2dc215812f841b70Sunny Goyalimport com.android.quickstep.views.RecentsView.ScrollState; 528ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport com.android.systemui.shared.recents.model.Task; 538ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport com.android.systemui.shared.recents.model.Task.TaskCallbacks; 548ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport com.android.systemui.shared.recents.model.ThumbnailData; 558ae4198a448ab308aed95756e82da82ce42735a7Winson Chungimport com.android.systemui.shared.system.ActivityManagerWrapper; 568ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 579c70e7e220b8ffebc15d3cc1fed89163d4724abfTonyimport java.util.function.Consumer; 58b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung 598ae4198a448ab308aed95756e82da82ce42735a7Winson Chung/** 608ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * A task in the Recents view. 618ae4198a448ab308aed95756e82da82ce42735a7Winson Chung */ 6205a3bbdef8c328370a51e045db12d67e62956b3fSunny Goyalpublic class TaskView extends FrameLayout implements TaskCallbacks, PageCallbacks { 63e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal 6480602a94ec225e26e39c4054d71da711bf17a531Winson Chung private static final String TAG = TaskView.class.getSimpleName(); 6580602a94ec225e26e39c4054d71da711bf17a531Winson Chung 6659a38e67885cceae10649f19f822bfde84c5ed57Tony Wickham /** A curve of x from 0 to 1, where 0 is the center of the screen and 1 is the edge. */ 675cd8ab938c7439c3cfabee5293be35c35d121f2fTony private static final TimeInterpolator CURVE_INTERPOLATOR 6859a38e67885cceae10649f19f822bfde84c5ed57Tony Wickham = x -> (float) -Math.cos(x * Math.PI) / 2f + .5f; 69e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal 70e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal /** 71e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal * The alpha of a black scrim on a page in the carousel as it leaves the screen. 72e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal * In the resting position of the carousel, the adjacent pages have about half this scrim. 73e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal */ 7459a38e67885cceae10649f19f822bfde84c5ed57Tony Wickham private static final float MAX_PAGE_SCRIM_ALPHA = 0.4f; 758643cd4ef492ba5257eb5cebc4aaef8333275a21Tony Wickham 765eb4a1e90d9eb168f4d31a58b43130aff5afeb28Tony Wickham /** 775eb4a1e90d9eb168f4d31a58b43130aff5afeb28Tony Wickham * How much to scale down pages near the edge of the screen. 785eb4a1e90d9eb168f4d31a58b43130aff5afeb28Tony Wickham */ 795eb4a1e90d9eb168f4d31a58b43130aff5afeb28Tony Wickham private static final float EDGE_SCALE_DOWN_FACTOR = 0.03f; 805eb4a1e90d9eb168f4d31a58b43130aff5afeb28Tony Wickham 81b271ad89728d9af582022a07fd190c3f3d685b97Tony public static final long SCALE_ICON_DURATION = 120; 82d58c2d5a48f163d7f6837cef3415562a81582df9Tony Wickham private static final long DIM_ANIM_DURATION = 700; 83b271ad89728d9af582022a07fd190c3f3d685b97Tony 84b271ad89728d9af582022a07fd190c3f3d685b97Tony public static final Property<TaskView, Float> ZOOM_SCALE = 85b271ad89728d9af582022a07fd190c3f3d685b97Tony new FloatProperty<TaskView>("zoomScale") { 86b271ad89728d9af582022a07fd190c3f3d685b97Tony @Override 87b271ad89728d9af582022a07fd190c3f3d685b97Tony public void setValue(TaskView taskView, float v) { 88b271ad89728d9af582022a07fd190c3f3d685b97Tony taskView.setZoomScale(v); 89b271ad89728d9af582022a07fd190c3f3d685b97Tony } 90b271ad89728d9af582022a07fd190c3f3d685b97Tony 91b271ad89728d9af582022a07fd190c3f3d685b97Tony @Override 92b271ad89728d9af582022a07fd190c3f3d685b97Tony public Float get(TaskView taskView) { 93b271ad89728d9af582022a07fd190c3f3d685b97Tony return taskView.mZoomScale; 94b271ad89728d9af582022a07fd190c3f3d685b97Tony } 95b271ad89728d9af582022a07fd190c3f3d685b97Tony }; 960349b6c01c360c77a475a309b7c946ba2c779170Tony Wickham 978ae4198a448ab308aed95756e82da82ce42735a7Winson Chung private Task mTask; 988ae4198a448ab308aed95756e82da82ce42735a7Winson Chung private TaskThumbnailView mSnapshotView; 9985c53f2af562f0b4a2ec50d1bf83bbaf64fd57ebSunny Goyal private IconView mIconView; 1000c95559cbc65dee86feba07261b24f4541a05066Tony private float mCurveScale; 101b271ad89728d9af582022a07fd190c3f3d685b97Tony private float mZoomScale; 102c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham private Animator mDimAlphaAnim; 1038ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 1048ae4198a448ab308aed95756e82da82ce42735a7Winson Chung public TaskView(Context context) { 1058ae4198a448ab308aed95756e82da82ce42735a7Winson Chung this(context, null); 1068ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 1078ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 1088ae4198a448ab308aed95756e82da82ce42735a7Winson Chung public TaskView(Context context, AttributeSet attrs) { 1098ae4198a448ab308aed95756e82da82ce42735a7Winson Chung this(context, attrs, 0); 1108ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 1118ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 1128ae4198a448ab308aed95756e82da82ce42735a7Winson Chung public TaskView(Context context, AttributeSet attrs, int defStyleAttr) { 1138ae4198a448ab308aed95756e82da82ce42735a7Winson Chung super(context, attrs, defStyleAttr); 11427289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song setOnClickListener((view) -> { 11527289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song if (getTask() == null) { 11627289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song return; 11727289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song } 11827289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song launchTask(true /* animate */); 11927289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song BaseActivity.fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss( 120783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this), 12127289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song TaskUtils.getComponentKeyForTask(getTask().key)); 12227289bbe409643a0e673350304a28da20f0e1644Hyunyoung Song }); 123bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal setOutlineProvider(new TaskOutlineProvider(getResources())); 1248ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 1258ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 1268ae4198a448ab308aed95756e82da82ce42735a7Winson Chung @Override 1278ae4198a448ab308aed95756e82da82ce42735a7Winson Chung protected void onFinishInflate() { 1280607cf03eae90e22fb05d8938b597c72d356c395Sunny Goyal super.onFinishInflate(); 1298ae4198a448ab308aed95756e82da82ce42735a7Winson Chung mSnapshotView = findViewById(R.id.snapshot); 1308ae4198a448ab308aed95756e82da82ce42735a7Winson Chung mIconView = findViewById(R.id.icon); 1318ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 1328ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 1338ae4198a448ab308aed95756e82da82ce42735a7Winson Chung /** 1348ae4198a448ab308aed95756e82da82ce42735a7Winson Chung * Updates this task view to the given {@param task}. 1358ae4198a448ab308aed95756e82da82ce42735a7Winson Chung */ 1368ae4198a448ab308aed95756e82da82ce42735a7Winson Chung public void bind(Task task) { 137b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung if (mTask != null) { 138b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung mTask.removeCallback(this); 139b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung } 1408ae4198a448ab308aed95756e82da82ce42735a7Winson Chung mTask = task; 1410ea5006cbaa9a15ae333cc3e09b4e68ebbdc8dd2Sunny Goyal mSnapshotView.bind(); 1428ae4198a448ab308aed95756e82da82ce42735a7Winson Chung task.addCallback(this); 1434ba5e6046fea22699f9608c6fc644dcec477dcbeVadim Tryshev setContentDescription(task.titleDescription); 1448ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 1458ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 146b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung public Task getTask() { 147b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung return mTask; 148b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung } 149b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung 150b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung public TaskThumbnailView getThumbnail() { 151b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung return mSnapshotView; 152b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung } 153b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung 15485c53f2af562f0b4a2ec50d1bf83bbaf64fd57ebSunny Goyal public IconView getIconView() { 1557d2e40912eb7007e8378f106556b4cbcbc24d661Sunny Goyal return mIconView; 1567d2e40912eb7007e8378f106556b4cbcbc24d661Sunny Goyal } 1577d2e40912eb7007e8378f106556b4cbcbc24d661Sunny Goyal 158b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung public void launchTask(boolean animate) { 15980602a94ec225e26e39c4054d71da711bf17a531Winson Chung launchTask(animate, (result) -> { 16080602a94ec225e26e39c4054d71da711bf17a531Winson Chung if (!result) { 1616dceb7755a40de149ee1548d1ebf728ab4ea8318Winson Chung notifyTaskLaunchFailed(TAG); 16280602a94ec225e26e39c4054d71da711bf17a531Winson Chung } 16380602a94ec225e26e39c4054d71da711bf17a531Winson Chung }, getHandler()); 1649c70e7e220b8ffebc15d3cc1fed89163d4724abfTony } 1659c70e7e220b8ffebc15d3cc1fed89163d4724abfTony 1669c70e7e220b8ffebc15d3cc1fed89163d4724abfTony public void launchTask(boolean animate, Consumer<Boolean> resultCallback, 1679c70e7e220b8ffebc15d3cc1fed89163d4724abfTony Handler resultCallbackHandler) { 168b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung if (mTask != null) { 169b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung final ActivityOptions opts; 170b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung if (animate) { 1710b0847b272a37ed115504956be5ce44a96b5784cSunny Goyal opts = BaseDraggingActivity.fromContext(getContext()) 17273c27ec176270cb2dff8f0c974a64eddb383b377Jon Miranda .getActivityLaunchOptions(this); 173b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung } else { 174b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung opts = ActivityOptions.makeCustomAnimation(getContext(), 0, 0); 175b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung } 176b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(mTask.key, 1779c70e7e220b8ffebc15d3cc1fed89163d4724abfTony opts, resultCallback, resultCallbackHandler); 178b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung } 179b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung } 180b63b44c3d55cc49423b9c70d37f2e1d9a0799ea4Winson Chung 1818ae4198a448ab308aed95756e82da82ce42735a7Winson Chung @Override 1828ae4198a448ab308aed95756e82da82ce42735a7Winson Chung public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData) { 183bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal mSnapshotView.setThumbnail(task, thumbnailData); 18485c53f2af562f0b4a2ec50d1bf83bbaf64fd57ebSunny Goyal mIconView.setDrawable(task.icon); 1859c70e7e220b8ffebc15d3cc1fed89163d4724abfTony mIconView.setOnClickListener(icon -> TaskMenuView.showForTask(this)); 186f3c10bf15f18d20657e980ba801268238aea8298Tony Wickham mIconView.setOnLongClickListener(icon -> { 187f3c10bf15f18d20657e980ba801268238aea8298Tony Wickham requestDisallowInterceptTouchEvent(true); 188f3c10bf15f18d20657e980ba801268238aea8298Tony Wickham return TaskMenuView.showForTask(this); 189f3c10bf15f18d20657e980ba801268238aea8298Tony Wickham }); 1908ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 1918ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 1928ae4198a448ab308aed95756e82da82ce42735a7Winson Chung @Override 1938ae4198a448ab308aed95756e82da82ce42735a7Winson Chung public void onTaskDataUnloaded() { 194bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal mSnapshotView.setThumbnail(null, null); 19585c53f2af562f0b4a2ec50d1bf83bbaf64fd57ebSunny Goyal mIconView.setDrawable(null); 1962fae2a0e9c337d217a63980f19eaae198720f86aTony Wickham mIconView.setOnLongClickListener(null); 1978ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 1988ae4198a448ab308aed95756e82da82ce42735a7Winson Chung 1998ae4198a448ab308aed95756e82da82ce42735a7Winson Chung @Override 2008ae4198a448ab308aed95756e82da82ce42735a7Winson Chung public void onTaskWindowingModeChanged() { 2018ae4198a448ab308aed95756e82da82ce42735a7Winson Chung // Do nothing 2028ae4198a448ab308aed95756e82da82ce42735a7Winson Chung } 2038643cd4ef492ba5257eb5cebc4aaef8333275a21Tony Wickham 204c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham public void animateIconToScaleAndDim(float scale) { 20560876ac0d77cbf3abda9eb609f6cd49ea3081cfaSunny Goyal mIconView.animate().scaleX(scale).scaleY(scale).setDuration(SCALE_ICON_DURATION).start(); 206d58c2d5a48f163d7f6837cef3415562a81582df9Tony Wickham mDimAlphaAnim = ObjectAnimator.ofFloat(mSnapshotView, DIM_ALPHA_MULTIPLIER, 1 - scale, 207d58c2d5a48f163d7f6837cef3415562a81582df9Tony Wickham scale); 208d58c2d5a48f163d7f6837cef3415562a81582df9Tony Wickham mDimAlphaAnim.setDuration(DIM_ANIM_DURATION); 209c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham mDimAlphaAnim.addListener(new AnimatorListenerAdapter() { 210c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham @Override 211c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham public void onAnimationEnd(Animator animation) { 212c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham mDimAlphaAnim = null; 213c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham } 214c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham }); 215c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham mDimAlphaAnim.start(); 2160349b6c01c360c77a475a309b7c946ba2c779170Tony Wickham } 2170349b6c01c360c77a475a309b7c946ba2c779170Tony Wickham 218c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham protected void setIconScaleAndDim(float iconScale) { 21960876ac0d77cbf3abda9eb609f6cd49ea3081cfaSunny Goyal mIconView.animate().cancel(); 22060876ac0d77cbf3abda9eb609f6cd49ea3081cfaSunny Goyal mIconView.setScaleX(iconScale); 22160876ac0d77cbf3abda9eb609f6cd49ea3081cfaSunny Goyal mIconView.setScaleY(iconScale); 222c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham if (mDimAlphaAnim != null) { 223c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham mDimAlphaAnim.cancel(); 224c879dbf7646b244c32df99ad0f04c0e4e67af2baTony Wickham } 225d58c2d5a48f163d7f6837cef3415562a81582df9Tony Wickham mSnapshotView.setDimAlphaMultipler(iconScale); 2260349b6c01c360c77a475a309b7c946ba2c779170Tony Wickham } 227e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal 228005df0ba69e38aa94a9f55eb43819a426c0cd3ccTony Wickham public void resetVisualProperties() { 229b271ad89728d9af582022a07fd190c3f3d685b97Tony setZoomScale(1); 230005df0ba69e38aa94a9f55eb43819a426c0cd3ccTony Wickham setTranslationX(0f); 231005df0ba69e38aa94a9f55eb43819a426c0cd3ccTony Wickham setTranslationY(0f); 23220a13ff54e5579a5d4efcdcb822df7a39f05de4aSunny Goyal setTranslationZ(0); 233005df0ba69e38aa94a9f55eb43819a426c0cd3ccTony Wickham setAlpha(1f); 23428254eec60526f27768a928c142f584b78965970Sunny Goyal setIconScaleAndDim(1); 235005df0ba69e38aa94a9f55eb43819a426c0cd3ccTony Wickham } 236005df0ba69e38aa94a9f55eb43819a426c0cd3ccTony Wickham 237e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal @Override 2385cd8ab938c7439c3cfabee5293be35c35d121f2fTony public void onPageScroll(ScrollState scrollState) { 239e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal float curveInterpolation = 240e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal CURVE_INTERPOLATOR.getInterpolation(scrollState.linearInterpolation); 241e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal 242d58c2d5a48f163d7f6837cef3415562a81582df9Tony Wickham mSnapshotView.setDimAlpha(curveInterpolation * MAX_PAGE_SCRIM_ALPHA); 243b271ad89728d9af582022a07fd190c3f3d685b97Tony setCurveScale(getCurveScaleForCurveInterpolation(curveInterpolation)); 2440c95559cbc65dee86feba07261b24f4541a05066Tony } 2450c95559cbc65dee86feba07261b24f4541a05066Tony 2465fdd300e8a6481502bb3728fea500270d6d4722aSunny Goyal @Override 2475fdd300e8a6481502bb3728fea500270d6d4722aSunny Goyal protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 2485fdd300e8a6481502bb3728fea500270d6d4722aSunny Goyal super.onLayout(changed, left, top, right, bottom); 2495fdd300e8a6481502bb3728fea500270d6d4722aSunny Goyal setPivotX((right - left) * 0.5f); 2505fdd300e8a6481502bb3728fea500270d6d4722aSunny Goyal setPivotY(mSnapshotView.getTop() + mSnapshotView.getHeight() * 0.5f); 2515fdd300e8a6481502bb3728fea500270d6d4722aSunny Goyal } 2525fdd300e8a6481502bb3728fea500270d6d4722aSunny Goyal 2539bb8ffb5e303597bd65ee4cae957c64c1f532d10Sunny Goyal public static float getCurveScaleForInterpolation(float linearInterpolation) { 25478595cd7dea011bcfc9b40791a5f85bdaa122c23Tony Wickham float curveInterpolation = CURVE_INTERPOLATOR.getInterpolation(linearInterpolation); 25578595cd7dea011bcfc9b40791a5f85bdaa122c23Tony Wickham return getCurveScaleForCurveInterpolation(curveInterpolation); 25678595cd7dea011bcfc9b40791a5f85bdaa122c23Tony Wickham } 25778595cd7dea011bcfc9b40791a5f85bdaa122c23Tony Wickham 2589bb8ffb5e303597bd65ee4cae957c64c1f532d10Sunny Goyal private static float getCurveScaleForCurveInterpolation(float curveInterpolation) { 25978595cd7dea011bcfc9b40791a5f85bdaa122c23Tony Wickham return 1 - curveInterpolation * EDGE_SCALE_DOWN_FACTOR; 26078595cd7dea011bcfc9b40791a5f85bdaa122c23Tony Wickham } 26178595cd7dea011bcfc9b40791a5f85bdaa122c23Tony Wickham 262b271ad89728d9af582022a07fd190c3f3d685b97Tony private void setCurveScale(float curveScale) { 263b271ad89728d9af582022a07fd190c3f3d685b97Tony mCurveScale = curveScale; 264b271ad89728d9af582022a07fd190c3f3d685b97Tony onScaleChanged(); 265b271ad89728d9af582022a07fd190c3f3d685b97Tony } 266b271ad89728d9af582022a07fd190c3f3d685b97Tony 2670c95559cbc65dee86feba07261b24f4541a05066Tony public float getCurveScale() { 2680c95559cbc65dee86feba07261b24f4541a05066Tony return mCurveScale; 269e15e2a8267c677a41bd91eac4d79ee36d467d8d4Sunny Goyal } 270bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal 271b271ad89728d9af582022a07fd190c3f3d685b97Tony public void setZoomScale(float adjacentScale) { 272b271ad89728d9af582022a07fd190c3f3d685b97Tony mZoomScale = adjacentScale; 273b271ad89728d9af582022a07fd190c3f3d685b97Tony onScaleChanged(); 274b271ad89728d9af582022a07fd190c3f3d685b97Tony } 275b271ad89728d9af582022a07fd190c3f3d685b97Tony 276b271ad89728d9af582022a07fd190c3f3d685b97Tony private void onScaleChanged() { 277b271ad89728d9af582022a07fd190c3f3d685b97Tony float scale = mCurveScale * mZoomScale; 278b271ad89728d9af582022a07fd190c3f3d685b97Tony setScaleX(scale); 279b271ad89728d9af582022a07fd190c3f3d685b97Tony setScaleY(scale); 280b271ad89728d9af582022a07fd190c3f3d685b97Tony } 281b271ad89728d9af582022a07fd190c3f3d685b97Tony 282a9f554681d13bcc88eacea73f715e1c608fdb527Sunny Goyal @Override 283a9f554681d13bcc88eacea73f715e1c608fdb527Sunny Goyal public boolean hasOverlappingRendering() { 284a9f554681d13bcc88eacea73f715e1c608fdb527Sunny Goyal // TODO: Clip-out the icon region from the thumbnail, since they are overlapping. 285a9f554681d13bcc88eacea73f715e1c608fdb527Sunny Goyal return false; 286a9f554681d13bcc88eacea73f715e1c608fdb527Sunny Goyal } 287a9f554681d13bcc88eacea73f715e1c608fdb527Sunny Goyal 288bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal private static final class TaskOutlineProvider extends ViewOutlineProvider { 289bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal 290bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal private final int mMarginTop; 291bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal private final float mRadius; 292bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal 293bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal TaskOutlineProvider(Resources res) { 294bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal mMarginTop = res.getDimensionPixelSize(R.dimen.task_thumbnail_top_margin); 295bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal mRadius = res.getDimension(R.dimen.task_corner_radius); 296bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal } 297bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal 298bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal @Override 299bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal public void getOutline(View view, Outline outline) { 300bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal outline.setRoundRect(0, mMarginTop, view.getWidth(), 301bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal view.getHeight(), mRadius); 302bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal } 303bac7f64fccb8856e7f4a45cf78c811743a3def26Sunny Goyal } 304ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev 305ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev @Override 306ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { 307ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev super.onInitializeAccessibilityNodeInfo(info); 308ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev 309ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev info.addAction( 310ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev new AccessibilityNodeInfo.AccessibilityAction(R.string.accessibility_close_task, 311ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev getContext().getText(R.string.accessibility_close_task))); 312ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev 313ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev final Context context = getContext(); 314ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev final BaseDraggingActivity activity = BaseDraggingActivity.fromContext(context); 315ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) { 316ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev OnClickListener onClickListener = menuOption.getOnClickListener(activity, this); 317ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev if (onClickListener != null) { 318ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev info.addAction(new AccessibilityNodeInfo.AccessibilityAction(menuOption.labelResId, 319ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev context.getText(menuOption.labelResId))); 320ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 321ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 322783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev 32379141a1236ebf9d540b72cd1bf1bc56d4b5fe954Hyunyoung Song final RecentsView recentsView = getRecentsView(); 32479141a1236ebf9d540b72cd1bf1bc56d4b5fe954Hyunyoung Song final AccessibilityNodeInfo.CollectionItemInfo itemInfo = 32579141a1236ebf9d540b72cd1bf1bc56d4b5fe954Hyunyoung Song AccessibilityNodeInfo.CollectionItemInfo.obtain( 326d5ccb6978dbf458280bbea17af4df655510f68d0Vadim Tryshev 0, 1, recentsView.getChildCount() - recentsView.indexOfChild(this) - 1, 1, 327d5ccb6978dbf458280bbea17af4df655510f68d0Vadim Tryshev false); 32879141a1236ebf9d540b72cd1bf1bc56d4b5fe954Hyunyoung Song info.setCollectionItemInfo(itemInfo); 329ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 330ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev 331ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev @Override 332ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev public boolean performAccessibilityAction(int action, Bundle arguments) { 333ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev if (action == R.string.accessibility_close_task) { 334783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev getRecentsView().dismissTask(this, true /*animateTaskView*/, 335ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev true /*removeTask*/); 336ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev return true; 337ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 338ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev 339ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev for (TaskSystemShortcut menuOption : TaskMenuView.MENU_OPTIONS) { 340ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev if (action == menuOption.labelResId) { 341ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev OnClickListener onClickListener = menuOption.getOnClickListener( 342ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev BaseDraggingActivity.fromContext(getContext()), this); 343ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev if (onClickListener != null) { 344ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev onClickListener.onClick(this); 345ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 346ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev return true; 347ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 348ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 349ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev 350783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev if (getRecentsView().performTaskAccessibilityActionExtra(action)) return true; 351783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev 352ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev return super.performAccessibilityAction(action, arguments); 353ac2042a40a42fcdc483cad512c40291d7f41070aVadim Tryshev } 35480602a94ec225e26e39c4054d71da711bf17a531Winson Chung 355783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev private RecentsView getRecentsView() { 356783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev return (RecentsView) getParent(); 357783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev } 358783cd3cf213ddb37920d1e88ddb9ce83352e8754Vadim Tryshev 3596dceb7755a40de149ee1548d1ebf728ab4ea8318Winson Chung public void notifyTaskLaunchFailed(String tag) { 36080602a94ec225e26e39c4054d71da711bf17a531Winson Chung String msg = "Failed to launch task"; 36180602a94ec225e26e39c4054d71da711bf17a531Winson Chung if (mTask != null) { 36280602a94ec225e26e39c4054d71da711bf17a531Winson Chung msg += " (task=" + mTask.key.baseIntent + " userId=" + mTask.key.userId + ")"; 36380602a94ec225e26e39c4054d71da711bf17a531Winson Chung } 3646dceb7755a40de149ee1548d1ebf728ab4ea8318Winson Chung Log.w(tag, msg); 3656dceb7755a40de149ee1548d1ebf728ab4ea8318Winson Chung Toast.makeText(getContext(), R.string.activity_not_available, LENGTH_SHORT).show(); 36680602a94ec225e26e39c4054d71da711bf17a531Winson Chung } 3678ae4198a448ab308aed95756e82da82ce42735a7Winson Chung} 368