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

Commit b5e65c8b authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Calling buildLayer only on views which are actually visible

> Creating a common listener for handling buildLayer logic

Bug: 30138067
Change-Id: I803ef78b48e07e5ae5922e0392d390f274a87d75
parent 9ccafbff
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.DefaultAppSearchController;
import com.android.launcher3.anim.AnimationLayerSet;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherActivityInfoCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
@@ -2954,7 +2955,7 @@ public class Launcher extends Activity
     * new state.
     */
    public Animator startWorkspaceStateChangeAnimation(Workspace.State toState,
            boolean animated, HashMap<View, Integer> layerViews) {
            boolean animated, AnimationLayerSet layerViews) {
        Workspace.State fromState = mWorkspace.getState();
        Animator anim = mWorkspace.setStateWithAnimation(toState, animated, layerViews);
        updateInteraction(fromState, toState);
+17 −103
Original line number Diff line number Diff line
@@ -34,13 +34,12 @@ import android.view.animation.DecelerateInterpolator;

import com.android.launcher3.allapps.AllAppsContainerView;
import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimationLayerSet;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.CircleRevealOutlineProvider;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.widget.WidgetsContainerView;

import java.util.HashMap;

/**
 * TODO: figure out what kind of tests we can write for this
 *
@@ -119,9 +118,6 @@ public class LauncherStateTransitionAnimation {

    public static final String TAG = "LSTAnimation";

    // Flags to determine how to set the layers on views before the transition animation
    public static final int BUILD_LAYER = 0;
    public static final int BUILD_AND_SET_LAYER = 1;
    public static final int SINGLE_FRAME_DELAY = 16;

    @Thunk Launcher mLauncher;
@@ -243,7 +239,7 @@ public class LauncherStateTransitionAnimation {

        final View fromView = mLauncher.getWorkspace();

        final HashMap<View, Integer> layerViews = new HashMap<>();
        final AnimationLayerSet layerViews = new AnimationLayerSet();

        // If for some reason our views aren't initialized, don't animate
        boolean initialized = buttonView != null;
@@ -319,14 +315,14 @@ public class LauncherStateTransitionAnimation {
            panelAlphaAndDrift.setInterpolator(new LogDecelerateInterpolator(100, 0));

            // Play the animation
            layerViews.put(revealView, BUILD_AND_SET_LAYER);
            layerViews.addView(revealView);
            animation.play(panelAlphaAndDrift);

            // Setup the animation for the content view
            contentView.setVisibility(View.VISIBLE);
            contentView.setAlpha(0f);
            contentView.setTranslationY(revealViewToYDrift);
            layerViews.put(contentView, BUILD_AND_SET_LAYER);
            layerViews.addView(contentView);

            // Create the individual animators
            ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
@@ -365,13 +361,6 @@ public class LauncherStateTransitionAnimation {
                    // Hide the reveal view
                    revealView.setVisibility(View.INVISIBLE);

                    // Disable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_NONE, null);
                        }
                    }

                    // This can hold unnecessary references to views.
                    cleanupAnimation();
                    pCb.onTransitionComplete();
@@ -393,16 +382,6 @@ public class LauncherStateTransitionAnimation {
                    dispatchOnLauncherTransitionStart(fromView, animated, false);
                    dispatchOnLauncherTransitionStart(toView, animated, false);

                    // Enable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                        }
                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
                            v.buildLayer();
                        }
                    }

                    // Focus the new view
                    toView.requestFocus();

@@ -411,25 +390,19 @@ public class LauncherStateTransitionAnimation {
            };
            toView.bringToFront();
            toView.setVisibility(View.VISIBLE);

            animation.addListener(layerViews);
            toView.post(startAnimRunnable);
            mCurrentAnimation = animation;
        } else if (animType == PULLUP) {
            // We are animating the content view alpha, so ensure we have a layer for it
            layerViews.put(contentView, BUILD_AND_SET_LAYER);
            layerViews.addView(contentView);

            animation.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    dispatchOnLauncherTransitionEnd(fromView, animated, false);
                    dispatchOnLauncherTransitionEnd(toView, animated, false);

                    // Disable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_NONE, null);
                        }
                    }

                    cleanupAnimation();
                    pCb.onTransitionComplete();
                }
@@ -450,21 +423,12 @@ public class LauncherStateTransitionAnimation {
                    dispatchOnLauncherTransitionStart(fromView, animated, false);
                    dispatchOnLauncherTransitionStart(toView, animated, false);

                    // Enable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                        }
                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
                            v.buildLayer();
                        }
                    }

                    toView.requestFocus();
                    stateAnimation.start();
                }
            };
            mCurrentAnimation = animation;
            mCurrentAnimation.addListener(layerViews);
            if (shouldPost) {
                toView.post(startAnimRunnable);
            } else {
@@ -479,7 +443,7 @@ public class LauncherStateTransitionAnimation {
    private void playCommonTransitionAnimations(
            Workspace.State toWorkspaceState, View fromView, View toView,
            boolean animated, boolean initialized, AnimatorSet animation,
            HashMap<View, Integer> layerViews) {
            AnimationLayerSet layerViews) {
        // Create the workspace animation.
        // NOTE: this call apparently also sets the state for the workspace if !animated
        Animator workspaceAnim = mLauncher.startWorkspaceStateChangeAnimation(toWorkspaceState,
@@ -594,10 +558,8 @@ public class LauncherStateTransitionAnimation {
            final Workspace.State toWorkspaceState, final boolean animated,
            final Runnable onCompleteRunnable) {
        final View fromWorkspace = mLauncher.getWorkspace();
        final HashMap<View, Integer> layerViews = new HashMap<>();
        final AnimationLayerSet layerViews = new AnimationLayerSet();
        final AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
        final int revealDuration = mLauncher.getResources()
                .getInteger(R.integer.config_overlayRevealTime);

        // Cancel the current animation
        cancelAnimation();
@@ -622,16 +584,6 @@ public class LauncherStateTransitionAnimation {
                        return;

                    dispatchOnLauncherTransitionStart(fromWorkspace, animated, true);

                    // Enable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                        }
                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
                            v.buildLayer();
                        }
                    }
                    stateAnimation.start();
                }
            };
@@ -645,17 +597,11 @@ public class LauncherStateTransitionAnimation {
                        onCompleteRunnable.run();
                    }

                    // Disable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_NONE, null);
                        }
                    }

                    // This can hold unnecessary references to views.
                    cleanupAnimation();
                }
            });
            stateAnimation.addListener(layerViews);
            fromWorkspace.post(startAnimRunnable);
            mCurrentAnimation = animation;
        } else /* if (!animated) */ {
@@ -692,7 +638,7 @@ public class LauncherStateTransitionAnimation {
        final View revealView = fromView.getRevealView();
        final View contentView = fromView.getContentView();

        final HashMap<View, Integer> layerViews = new HashMap<>();
        final AnimationLayerSet layerViews = new AnimationLayerSet();

        // If for some reason our views aren't initialized, don't animate
        boolean initialized = buttonView != null;
@@ -735,7 +681,7 @@ public class LauncherStateTransitionAnimation {
                revealView.setVisibility(View.VISIBLE);
                revealView.setAlpha(1f);
                revealView.setTranslationY(0);
                layerViews.put(revealView, BUILD_AND_SET_LAYER);
                layerViews.addView(revealView);

                // Calculate the final animation values
                final float revealViewToXDrift;
@@ -783,7 +729,7 @@ public class LauncherStateTransitionAnimation {
                }

                // Setup the animation for the content view
                layerViews.put(contentView, BUILD_AND_SET_LAYER);
                layerViews.addView(contentView);

                // Create the individual animators
                ObjectAnimator pageDrift = ObjectAnimator.ofFloat(contentView, "translationY",
@@ -843,13 +789,6 @@ public class LauncherStateTransitionAnimation {
                        onCompleteRunnable.run();
                    }

                    // Disable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_NONE, null);
                        }
                    }

                    // Reset page transforms
                    if (contentView != null) {
                        contentView.setTranslationX(0);
@@ -874,24 +813,15 @@ public class LauncherStateTransitionAnimation {

                    dispatchOnLauncherTransitionStart(fromView, animated, false);
                    dispatchOnLauncherTransitionStart(toView, animated, false);

                    // Enable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                        }
                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
                            v.buildLayer();
                        }
                    }
                    stateAnimation.start();
                }
            };
            mCurrentAnimation = animation;
            mCurrentAnimation.addListener(layerViews);
            fromView.post(startAnimRunnable);
        } else if (animType == PULLUP) {
            // We are animating the content view alpha, so ensure we have a layer for it
            layerViews.put(contentView, BUILD_AND_SET_LAYER);
            layerViews.addView(contentView);

            animation.addListener(new AnimatorListenerAdapter() {
                boolean canceled = false;
@@ -910,13 +840,6 @@ public class LauncherStateTransitionAnimation {
                        onCompleteRunnable.run();
                    }

                    // Disable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_NONE, null);
                        }
                    }

                    cleanupAnimation();
                    pCb.onTransitionComplete();
                }
@@ -939,22 +862,13 @@ public class LauncherStateTransitionAnimation {
                    dispatchOnLauncherTransitionStart(fromView, animated, false);
                    dispatchOnLauncherTransitionStart(toView, animated, false);

                    // Enable all necessary layers
                    for (View v : layerViews.keySet()) {
                        if (layerViews.get(v) == BUILD_AND_SET_LAYER) {
                            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                        }
                        if (Utilities.ATLEAST_LOLLIPOP && v.isAttachedToWindow()) {
                            v.buildLayer();
                        }
                    }

                    // Focus the new view
                    toView.requestFocus();
                    stateAnimation.start();
                }
            };
            mCurrentAnimation = animation;
            mCurrentAnimation.addListener(layerViews);
            if (shouldPost) {
                fromView.post(startAnimRunnable);
            } else {
+2 −2
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
import com.android.launcher3.accessibility.OverviewAccessibilityDelegate;
import com.android.launcher3.accessibility.OverviewScreenAccessibilityDelegate;
import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
import com.android.launcher3.anim.AnimationLayerSet;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.UserHandleCompat;
import com.android.launcher3.config.FeatureFlags;
@@ -86,7 +87,6 @@ import com.android.launcher3.widget.PendingAddShortcutInfo;
import com.android.launcher3.widget.PendingAddWidgetInfo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

/**
@@ -2029,7 +2029,7 @@ public class Workspace extends PagedView
     * to that new state.
     */
    public Animator setStateWithAnimation(State toState, boolean animated,
            HashMap<View, Integer> layerViews) {
            AnimationLayerSet layerViews) {
        // Create the animation to the new state
        AnimatorSet workspaceAnim =  mStateTransitionAnimation.getAnimationToState(mState,
                toState, animated, layerViews);
+7 −11
Original line number Diff line number Diff line
@@ -30,12 +30,11 @@ import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.DecelerateInterpolator;

import com.android.launcher3.anim.AnimationLayerSet;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.util.Thunk;

import java.util.HashMap;

/**
 * A convenience class to update a view's visibility state after an alpha animation.
 */
@@ -226,7 +225,7 @@ public class WorkspaceStateTransitionAnimation {
    }

    public AnimatorSet getAnimationToState(Workspace.State fromState, Workspace.State toState,
            boolean animated, HashMap<View, Integer> layerViews) {
            boolean animated, AnimationLayerSet layerViews) {
        AccessibilityManager am = (AccessibilityManager)
                mLauncher.getSystemService(Context.ACCESSIBILITY_SERVICE);
        final boolean accessibilityEnabled = am.isEnabled();
@@ -262,8 +261,7 @@ public class WorkspaceStateTransitionAnimation {
     * Starts a transition animation for the workspace.
     */
    private void animateWorkspace(final TransitionStates states, final boolean animated,
                                  final int duration, final HashMap<View, Integer> layerViews,
                                  final boolean accessibilityEnabled) {
            final int duration, AnimationLayerSet layerViews, final boolean accessibilityEnabled) {
        // Cancel existing workspace animations and create a new animator set if requested
        cancelAnimation();
        if (animated) {
@@ -396,12 +394,10 @@ public class WorkspaceStateTransitionAnimation {

            // For animation optimization, we may need to provide the Launcher transition
            // with a set of views on which to force build and manage layers in certain scenarios.
            layerViews.put(overviewPanel, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
            layerViews.put(qsbContainer, LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
            layerViews.put(mLauncher.getHotseat(),
                    LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
            layerViews.put(mWorkspace.getPageIndicator(),
                    LauncherStateTransitionAnimation.BUILD_AND_SET_LAYER);
            layerViews.addView(overviewPanel);
            layerViews.addView(qsbContainer);
            layerViews.addView(mLauncher.getHotseat());
            layerViews.addView(mWorkspace.getPageIndicator());

            if (states.workspaceToOverview) {
                hotseatAlpha.setInterpolator(new DecelerateInterpolator(2));
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.launcher3.anim;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;

import java.util.HashSet;

/**
 * Helper class to automatically build view hardware layers for the duration of an animation.
 */
public class AnimationLayerSet extends AnimatorListenerAdapter {

    private final HashSet<View> mViews = new HashSet<>();

    public void addView(View v) {
        mViews.add(v);
    }

    @Override
    public void onAnimationStart(Animator animation) {
        // Enable all necessary layers
        for (View v : mViews) {
            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
            if (v.isAttachedToWindow() && v.getVisibility() == View.VISIBLE) {
                v.buildLayer();
            }
        }
    }

    @Override
    public void onAnimationEnd(Animator animation) {
        for (View v : mViews) {
            v.setLayerType(View.LAYER_TYPE_NONE, null);
        }
    }
}