• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.quickstep;
17 
18 import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
19 import static com.android.launcher3.anim.Interpolators.ACCEL_2;
20 import static com.android.launcher3.anim.Interpolators.INSTANT;
21 import static com.android.launcher3.anim.Interpolators.LINEAR;
22 import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
23 import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
24 import static com.android.quickstep.SysUINavigationMode.getMode;
25 import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
26 import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
27 import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
28 import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
29 import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
30 import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
31 
32 import android.animation.Animator;
33 import android.animation.ObjectAnimator;
34 import android.annotation.TargetApi;
35 import android.content.Context;
36 import android.content.res.Resources;
37 import android.graphics.Color;
38 import android.graphics.PointF;
39 import android.graphics.Rect;
40 import android.os.Build;
41 import android.view.Gravity;
42 import android.view.MotionEvent;
43 
44 import androidx.annotation.Nullable;
45 import androidx.annotation.UiThread;
46 
47 import com.android.launcher3.DeviceProfile;
48 import com.android.launcher3.R;
49 import com.android.launcher3.anim.AnimatorPlaybackController;
50 import com.android.launcher3.anim.PendingAnimation;
51 import com.android.launcher3.config.FeatureFlags;
52 import com.android.launcher3.statehandlers.DepthController;
53 import com.android.launcher3.statemanager.BaseState;
54 import com.android.launcher3.statemanager.StatefulActivity;
55 import com.android.launcher3.touch.PagedOrientationHandler;
56 import com.android.launcher3.util.WindowBounds;
57 import com.android.launcher3.views.ScrimView;
58 import com.android.quickstep.SysUINavigationMode.Mode;
59 import com.android.quickstep.util.ActivityInitListener;
60 import com.android.quickstep.util.AnimatorControllerWithResistance;
61 import com.android.quickstep.util.SplitScreenBounds;
62 import com.android.quickstep.views.OverviewActionsView;
63 import com.android.quickstep.views.RecentsView;
64 import com.android.quickstep.views.TaskView;
65 import com.android.systemui.shared.recents.model.ThumbnailData;
66 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
67 
68 import java.util.function.Consumer;
69 import java.util.function.Predicate;
70 
71 /**
72  * Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
73  */
74 @TargetApi(Build.VERSION_CODES.P)
75 public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_TYPE>,
76         ACTIVITY_TYPE extends StatefulActivity<STATE_TYPE>> {
77 
78     public final boolean rotationSupportedByActivity;
79 
80     private final STATE_TYPE mBackgroundState;
81 
82     private STATE_TYPE mTargetState;
83 
BaseActivityInterface(boolean rotationSupportedByActivity, STATE_TYPE overviewState, STATE_TYPE backgroundState)84     protected BaseActivityInterface(boolean rotationSupportedByActivity,
85             STATE_TYPE overviewState, STATE_TYPE backgroundState) {
86         this.rotationSupportedByActivity = rotationSupportedByActivity;
87         mTargetState = overviewState;
88         mBackgroundState = backgroundState;
89     }
90 
91     /**
92      * Called when the current gesture transition is cancelled.
93      * @param activityVisible Whether the user can see the changes we make here, so try to animate.
94      * @param endTarget If the gesture ended before we got cancelled, where we were headed.
95      */
onTransitionCancelled(boolean activityVisible, @Nullable GestureState.GestureEndTarget endTarget)96     public void onTransitionCancelled(boolean activityVisible,
97             @Nullable GestureState.GestureEndTarget endTarget) {
98         ACTIVITY_TYPE activity = getCreatedActivity();
99         if (activity == null) {
100             return;
101         }
102         STATE_TYPE startState = activity.getStateManager().getRestState();
103         if (endTarget != null) {
104             // We were on our way to this state when we got canceled, end there instead.
105             startState = stateFromGestureEndTarget(endTarget);
106         }
107         activity.getStateManager().goToState(startState, activityVisible);
108     }
109 
getSwipeUpDestinationAndLength( DeviceProfile dp, Context context, Rect outRect, PagedOrientationHandler orientationHandler)110     public abstract int getSwipeUpDestinationAndLength(
111             DeviceProfile dp, Context context, Rect outRect,
112             PagedOrientationHandler orientationHandler);
113 
114     /** Called when the animation to home has fully settled. */
onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState)115     public void onSwipeUpToHomeComplete(RecentsAnimationDeviceState deviceState) {}
116 
onAssistantVisibilityChanged(float visibility)117     public abstract void onAssistantVisibilityChanged(float visibility);
118 
119     /** Called when one handed mode activated or deactivated. */
onOneHandedModeStateChanged(boolean activated)120     public abstract void onOneHandedModeStateChanged(boolean activated);
121 
prepareRecentsUI(RecentsAnimationDeviceState deviceState, boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback)122     public abstract AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState,
123             boolean activityVisible, Consumer<AnimatorControllerWithResistance> callback);
124 
createActivityInitListener( Predicate<Boolean> onInitListener)125     public abstract ActivityInitListener createActivityInitListener(
126             Predicate<Boolean> onInitListener);
127 
128     /**
129      * Sets a callback to be run when an activity launch happens while launcher is not yet resumed.
130      */
setOnDeferredActivityLaunchCallback(Runnable r)131     public void setOnDeferredActivityLaunchCallback(Runnable r) {}
132 
133     @Nullable
getCreatedActivity()134     public abstract ACTIVITY_TYPE getCreatedActivity();
135 
136     @Nullable
getDepthController()137     public DepthController getDepthController() {
138         return null;
139     }
140 
isResumed()141     public final boolean isResumed() {
142         ACTIVITY_TYPE activity = getCreatedActivity();
143         return activity != null && activity.hasBeenResumed();
144     }
145 
isStarted()146     public final boolean isStarted() {
147         ACTIVITY_TYPE activity = getCreatedActivity();
148         return activity != null && activity.isStarted();
149     }
150 
151     @UiThread
152     @Nullable
getVisibleRecentsView()153     public abstract <T extends RecentsView> T getVisibleRecentsView();
154 
155     @UiThread
switchToRecentsIfVisible(Runnable onCompleteCallback)156     public abstract boolean switchToRecentsIfVisible(Runnable onCompleteCallback);
157 
getOverviewWindowBounds( Rect homeBounds, RemoteAnimationTargetCompat target)158     public abstract Rect getOverviewWindowBounds(
159             Rect homeBounds, RemoteAnimationTargetCompat target);
160 
allowMinimizeSplitScreen()161     public abstract boolean allowMinimizeSplitScreen();
162 
deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev)163     public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
164         return deviceState.isInDeferredGestureRegion(ev);
165     }
166 
167     /**
168      * @return Whether the gesture in progress should be cancelled.
169      */
shouldCancelCurrentGesture()170     public boolean shouldCancelCurrentGesture() {
171         return false;
172     }
173 
onExitOverview(RotationTouchHelper deviceState, Runnable exitRunnable)174     public abstract void onExitOverview(RotationTouchHelper deviceState,
175             Runnable exitRunnable);
176 
isInLiveTileMode()177     public abstract boolean isInLiveTileMode();
178 
onLaunchTaskFailed()179     public abstract void onLaunchTaskFailed();
180 
onLaunchTaskSuccess()181     public void onLaunchTaskSuccess() {
182         ACTIVITY_TYPE activity = getCreatedActivity();
183         if (activity == null) {
184             return;
185         }
186         activity.getStateManager().moveToRestState();
187     }
188 
closeOverlay()189     public void closeOverlay() { }
190 
switchRunningTaskViewToScreenshot(ThumbnailData thumbnailData, Runnable runnable)191     public void switchRunningTaskViewToScreenshot(ThumbnailData thumbnailData, Runnable runnable) {
192         ACTIVITY_TYPE activity = getCreatedActivity();
193         if (activity == null) {
194             return;
195         }
196         RecentsView recentsView = activity.getOverviewPanel();
197         if (recentsView == null) {
198             if (runnable != null) {
199                 runnable.run();
200             }
201             return;
202         }
203         recentsView.switchToScreenshot(thumbnailData, runnable);
204     }
205 
206     /**
207      * Calculates the taskView size for the provided device configuration.
208      */
calculateTaskSize(Context context, DeviceProfile dp, Rect outRect, PagedOrientationHandler orientedState)209     public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
210             PagedOrientationHandler orientedState) {
211         Resources res = context.getResources();
212         if (dp.isTablet && FeatureFlags.ENABLE_OVERVIEW_GRID.get()) {
213             Rect gridRect = new Rect();
214             calculateGridSize(context, dp, gridRect);
215 
216             int verticalMargin = res.getDimensionPixelSize(
217                     R.dimen.overview_grid_focus_vertical_margin);
218             float taskHeight = gridRect.height() - verticalMargin * 2;
219 
220             PointF taskDimension = getTaskDimension(context, dp);
221             float scale = taskHeight / Math.max(taskDimension.x, taskDimension.y);
222             int outWidth = Math.round(scale * taskDimension.x);
223             int outHeight = Math.round(scale * taskDimension.y);
224 
225             int gravity = Gravity.CENTER_VERTICAL;
226             gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
227             Gravity.apply(gravity, outWidth, outHeight, gridRect, outRect);
228         } else {
229             int taskMargin = dp.overviewTaskMarginPx;
230             int proactiveRowAndMargin;
231             if (!TaskView.SHOW_PROACTIVE_ACTIONS || dp.isVerticalBarLayout()) {
232                 // In Vertical Bar Layout the proactive row doesn't have its own space, it's inside
233                 // the actions row.
234                 proactiveRowAndMargin = 0;
235             } else {
236                 proactiveRowAndMargin = res.getDimensionPixelSize(
237                         R.dimen.overview_proactive_row_height)
238                         + res.getDimensionPixelSize(R.dimen.overview_proactive_row_bottom_margin);
239             }
240             calculateTaskSizeInternal(context, dp,
241                     dp.overviewTaskThumbnailTopMarginPx,
242                     proactiveRowAndMargin + getOverviewActionsHeight(context, dp),
243                     res.getDimensionPixelSize(R.dimen.overview_minimum_next_prev_size) + taskMargin,
244                     outRect);
245         }
246     }
247 
calculateTaskSizeInternal(Context context, DeviceProfile dp, int claimedSpaceAbove, int claimedSpaceBelow, int minimumHorizontalPadding, Rect outRect)248     private void calculateTaskSizeInternal(Context context, DeviceProfile dp,
249             int claimedSpaceAbove, int claimedSpaceBelow, int minimumHorizontalPadding,
250             Rect outRect) {
251         PointF taskDimension = getTaskDimension(context, dp);
252         Rect insets = dp.getInsets();
253 
254         Rect potentialTaskRect = new Rect(0, 0, dp.widthPx, dp.heightPx);
255         potentialTaskRect.inset(insets.left, insets.top, insets.right, insets.bottom);
256         potentialTaskRect.inset(
257                 minimumHorizontalPadding,
258                 claimedSpaceAbove,
259                 minimumHorizontalPadding,
260                 claimedSpaceBelow);
261 
262         float scale = Math.min(
263                 potentialTaskRect.width() / taskDimension.x,
264                 potentialTaskRect.height() / taskDimension.y);
265         int outWidth = Math.round(scale * taskDimension.x);
266         int outHeight = Math.round(scale * taskDimension.y);
267 
268         Gravity.apply(Gravity.CENTER, outWidth, outHeight, potentialTaskRect, outRect);
269     }
270 
getTaskDimension(Context context, DeviceProfile dp)271     private static PointF getTaskDimension(Context context, DeviceProfile dp) {
272         PointF dimension = new PointF();
273         getTaskDimension(context, dp, dimension);
274         return dimension;
275     }
276 
277     /**
278      * Gets the dimension of the task in the current system state.
279      */
getTaskDimension(Context context, DeviceProfile dp, PointF out)280     public static void getTaskDimension(Context context, DeviceProfile dp, PointF out) {
281         if (dp.isMultiWindowMode) {
282             WindowBounds bounds = SplitScreenBounds.INSTANCE.getSecondaryWindowBounds(context);
283             if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
284                 out.x = bounds.availableSize.x;
285                 out.y = bounds.availableSize.y;
286             } else {
287                 out.x = bounds.availableSize.x + bounds.insets.left + bounds.insets.right;
288                 out.y = bounds.availableSize.y + bounds.insets.top + bounds.insets.bottom;
289             }
290         } else if (TaskView.CLIP_STATUS_AND_NAV_BARS) {
291             out.x = dp.availableWidthPx;
292             out.y = dp.availableHeightPx;
293         } else {
294             out.x = dp.widthPx;
295             out.y = dp.heightPx;
296         }
297     }
298 
299     /**
300      * Calculates the overview grid size for the provided device configuration.
301      */
calculateGridSize(Context context, DeviceProfile dp, Rect outRect)302     public final void calculateGridSize(Context context, DeviceProfile dp, Rect outRect) {
303         Resources res = context.getResources();
304         int topMargin = res.getDimensionPixelSize(R.dimen.overview_grid_top_margin);
305         int bottomMargin = res.getDimensionPixelSize(R.dimen.overview_grid_bottom_margin);
306         int sideMargin = res.getDimensionPixelSize(R.dimen.overview_grid_side_margin);
307 
308         Rect insets = dp.getInsets();
309         outRect.set(0, 0, dp.widthPx, dp.heightPx);
310         outRect.inset(Math.max(insets.left, sideMargin), Math.max(insets.top, topMargin),
311                 Math.max(insets.right, sideMargin), Math.max(insets.bottom, bottomMargin));
312     }
313 
314     /**
315      * Calculates the overview grid non-focused task size for the provided device configuration.
316      */
calculateGridTaskSize(Context context, DeviceProfile dp, Rect outRect, PagedOrientationHandler orientedState)317     public final void calculateGridTaskSize(Context context, DeviceProfile dp, Rect outRect,
318             PagedOrientationHandler orientedState) {
319         Resources res = context.getResources();
320         Rect gridRect = new Rect();
321         calculateGridSize(context, dp, gridRect);
322 
323         int rowSpacing = res.getDimensionPixelSize(R.dimen.overview_grid_row_spacing);
324         float rowHeight = (gridRect.height() - rowSpacing) / 2f;
325 
326         PointF taskDimension = getTaskDimension(context, dp);
327         float scale = (rowHeight - dp.overviewTaskThumbnailTopMarginPx) / Math.max(
328                 taskDimension.x, taskDimension.y);
329         int outWidth = Math.round(scale * taskDimension.x);
330         int outHeight = Math.round(scale * taskDimension.y);
331 
332         int gravity = Gravity.TOP;
333         gravity |= orientedState.getRecentsRtlSetting(res) ? Gravity.RIGHT : Gravity.LEFT;
334         gridRect.inset(0, dp.overviewTaskThumbnailTopMarginPx, 0, 0);
335         Gravity.apply(gravity, outWidth, outHeight, gridRect, outRect);
336     }
337 
338     /**
339      * Calculates the modal taskView size for the provided device configuration
340      */
calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect)341     public final void calculateModalTaskSize(Context context, DeviceProfile dp, Rect outRect) {
342         calculateTaskSizeInternal(
343                 context, dp,
344                 dp.overviewTaskMarginPx,
345                 getOverviewActionsHeight(context, dp),
346                 dp.overviewTaskMarginPx,
347                 outRect);
348     }
349 
350     /** Gets the space that the overview actions will take, including bottom margin. */
getOverviewActionsHeight(Context context, DeviceProfile dp)351     private int getOverviewActionsHeight(Context context, DeviceProfile dp) {
352         Resources res = context.getResources();
353         return OverviewActionsView.getOverviewActionsBottomMarginPx(getMode(context), dp)
354                 + OverviewActionsView.getOverviewActionsTopMarginPx(getMode(context), dp)
355                 + res.getDimensionPixelSize(R.dimen.overview_actions_height);
356     }
357 
358     /**
359      * Called when the gesture ends and the animation starts towards the given target. Used to add
360      * an optional additional animation with the same duration.
361      */
getParallelAnimationToLauncher( GestureState.GestureEndTarget endTarget, long duration)362     public @Nullable Animator getParallelAnimationToLauncher(
363             GestureState.GestureEndTarget endTarget, long duration) {
364         if (endTarget == RECENTS) {
365             ACTIVITY_TYPE activity = getCreatedActivity();
366             if (activity == null) {
367                 return null;
368             }
369             STATE_TYPE state = stateFromGestureEndTarget(endTarget);
370             ScrimView scrimView = activity.getScrimView();
371             ObjectAnimator anim = ObjectAnimator.ofArgb(scrimView, VIEW_BACKGROUND_COLOR,
372                     getOverviewScrimColorForState(activity, state));
373             anim.setDuration(duration);
374             return anim;
375         }
376         return null;
377     }
378 
379     /**
380      * Returns the color of the scrim behind overview when at rest in this state.
381      * Return {@link Color#TRANSPARENT} for no scrim.
382      */
getOverviewScrimColorForState(ACTIVITY_TYPE activity, STATE_TYPE state)383     protected abstract int getOverviewScrimColorForState(ACTIVITY_TYPE activity, STATE_TYPE state);
384 
385     /**
386      * Returns the expected STATE_TYPE from the provided GestureEndTarget.
387      */
stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget)388     public abstract STATE_TYPE stateFromGestureEndTarget(GestureState.GestureEndTarget endTarget);
389 
390     public interface AnimationFactory {
391 
createActivityInterface(long transitionLength)392         void createActivityInterface(long transitionLength);
393 
394         /**
395          * @param attached Whether to show RecentsView alongside the app window. If false, recents
396          *                 will be hidden by some property we can animate, e.g. alpha.
397          * @param animate Whether to animate recents to/from its new attached state.
398          */
setRecentsAttachedToAppWindow(boolean attached, boolean animate)399         default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
400 
isRecentsAttachedToAppWindow()401         default boolean isRecentsAttachedToAppWindow() {
402             return false;
403         }
404 
405         /** Called when the gesture ends and we know what state it is going towards */
setEndTarget(GestureState.GestureEndTarget endTarget)406         default void setEndTarget(GestureState.GestureEndTarget endTarget) { }
407     }
408 
409     class DefaultAnimationFactory implements AnimationFactory {
410 
411         protected final ACTIVITY_TYPE mActivity;
412         private final STATE_TYPE mStartState;
413         private final Consumer<AnimatorControllerWithResistance> mCallback;
414 
415         private boolean mIsAttachedToWindow;
416 
DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback)417         DefaultAnimationFactory(Consumer<AnimatorControllerWithResistance> callback) {
418             mCallback = callback;
419 
420             mActivity = getCreatedActivity();
421             mStartState = mActivity.getStateManager().getState();
422         }
423 
initUI()424         protected ACTIVITY_TYPE initUI() {
425             STATE_TYPE resetState = mStartState;
426             if (mStartState.shouldDisableRestore()) {
427                 resetState = mActivity.getStateManager().getRestState();
428             }
429             mActivity.getStateManager().setRestState(resetState);
430             mActivity.getStateManager().goToState(mBackgroundState, false);
431             return mActivity;
432         }
433 
434         @Override
createActivityInterface(long transitionLength)435         public void createActivityInterface(long transitionLength) {
436             PendingAnimation pa = new PendingAnimation(transitionLength * 2);
437             createBackgroundToOverviewAnim(mActivity, pa);
438             AnimatorPlaybackController controller = pa.createPlaybackController();
439             mActivity.getStateManager().setCurrentUserControlledAnimation(controller);
440 
441             // Since we are changing the start position of the UI, reapply the state, at the end
442             controller.setEndAction(() -> mActivity.getStateManager().goToState(
443                     controller.getInterpolatedProgress() > 0.5 ? mTargetState : mBackgroundState,
444                     false));
445 
446             RecentsView recentsView = mActivity.getOverviewPanel();
447             AnimatorControllerWithResistance controllerWithResistance =
448                     AnimatorControllerWithResistance.createForRecents(controller, mActivity,
449                             recentsView.getPagedViewOrientedState(), mActivity.getDeviceProfile(),
450                             recentsView, RECENTS_SCALE_PROPERTY, recentsView,
451                             TASK_SECONDARY_TRANSLATION);
452             mCallback.accept(controllerWithResistance);
453 
454             // Creating the activity controller animation sometimes reapplies the launcher state
455             // (because we set the animation as the current state animation), so we reapply the
456             // attached state here as well to ensure recents is shown/hidden appropriately.
457             if (SysUINavigationMode.getMode(mActivity) == Mode.NO_BUTTON) {
458                 setRecentsAttachedToAppWindow(mIsAttachedToWindow, false);
459             }
460         }
461 
462         @Override
setRecentsAttachedToAppWindow(boolean attached, boolean animate)463         public void setRecentsAttachedToAppWindow(boolean attached, boolean animate) {
464             if (mIsAttachedToWindow == attached && animate) {
465                 return;
466             }
467             mIsAttachedToWindow = attached;
468             RecentsView recentsView = mActivity.getOverviewPanel();
469             Animator fadeAnim = mActivity.getStateManager()
470                     .createStateElementAnimation(INDEX_RECENTS_FADE_ANIM, attached ? 1 : 0);
471 
472             float fromTranslation = attached ? 1 : 0;
473             float toTranslation = attached ? 0 : 1;
474             mActivity.getStateManager()
475                     .cancelStateElementAnimation(INDEX_RECENTS_TRANSLATE_X_ANIM);
476             if (!recentsView.isShown() && animate) {
477                 ADJACENT_PAGE_HORIZONTAL_OFFSET.set(recentsView, fromTranslation);
478             } else {
479                 fromTranslation = ADJACENT_PAGE_HORIZONTAL_OFFSET.get(recentsView);
480             }
481             if (!animate) {
482                 ADJACENT_PAGE_HORIZONTAL_OFFSET.set(recentsView, toTranslation);
483             } else {
484                 mActivity.getStateManager().createStateElementAnimation(
485                         INDEX_RECENTS_TRANSLATE_X_ANIM,
486                         fromTranslation, toTranslation).start();
487             }
488 
489             fadeAnim.setInterpolator(attached ? INSTANT : ACCEL_2);
490             fadeAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0).start();
491         }
492 
493         @Override
isRecentsAttachedToAppWindow()494         public boolean isRecentsAttachedToAppWindow() {
495             return mIsAttachedToWindow;
496         }
497 
498         @Override
setEndTarget(GestureState.GestureEndTarget endTarget)499         public void setEndTarget(GestureState.GestureEndTarget endTarget) {
500             mTargetState = stateFromGestureEndTarget(endTarget);
501         }
502 
createBackgroundToOverviewAnim(ACTIVITY_TYPE activity, PendingAnimation pa)503         protected void createBackgroundToOverviewAnim(ACTIVITY_TYPE activity, PendingAnimation pa) {
504             //  Scale down recents from being full screen to being in overview.
505             RecentsView recentsView = activity.getOverviewPanel();
506             pa.addFloat(recentsView, RECENTS_SCALE_PROPERTY,
507                     recentsView.getMaxScaleForFullScreen(), 1, LINEAR);
508             pa.addFloat(recentsView, FULLSCREEN_PROGRESS, 1, 0, LINEAR);
509         }
510     }
511 
512     /** Called when OverviewService is bound to this process */
onOverviewServiceBound()513     void onOverviewServiceBound() {
514         // Do nothing
515     }
516 }
517