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

Commit 7f58b95f authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix to custom scale animations.

These now do something reasonable when performing transitions
across two activities that are both on top of the wallpaper.

Fixed computation of the pivot point of the animations.

Fixed issue where the recents panel was considered a status
bar element for purposes of deciding if the animating elements
are obscured by the status bar, which would result in us not
running the animation correctly.

Change-Id: I4b9b588b80243463e6f087a9703ee886ee281630
parent f01d3dd7
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -306,7 +306,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    WindowState mStatusBar = null;
    boolean mHasSystemNavBar;
    int mStatusBarHeight;
    final ArrayList<WindowState> mStatusBarPanels = new ArrayList<WindowState>();
    final ArrayList<WindowState> mStatusBarSubPanels = new ArrayList<WindowState>();
    WindowState mNavigationBar = null;
    boolean mHasNavigationBar = false;
    boolean mCanHideNavigationBar = false;
@@ -1560,13 +1560,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.STATUS_BAR_SERVICE,
                        "PhoneWindowManager");
                mStatusBarPanels.add(win);
                break;
            case TYPE_STATUS_BAR_SUB_PANEL:
                mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.STATUS_BAR_SERVICE,
                        "PhoneWindowManager");
                mStatusBarPanels.add(win);
                mStatusBarSubPanels.add(win);
                break;
            case TYPE_KEYGUARD:
                if (mKeyguard != null) {
@@ -1587,7 +1586,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        } else if (mNavigationBar == win) {
            mNavigationBar = null;
        } else {
            mStatusBarPanels.remove(win);
            mStatusBarSubPanels.remove(win);
        }
    }

@@ -2760,8 +2759,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }
        if (mStatusBar != null && mStatusBar.isVisibleLw()) {
            RectF rect = new RectF(mStatusBar.getShownFrameLw());
            for (int i=mStatusBarPanels.size()-1; i>=0; i--) {
                WindowState w = mStatusBarPanels.get(i);
            for (int i=mStatusBarSubPanels.size()-1; i>=0; i--) {
                WindowState w = mStatusBarSubPanels.get(i);
                if (w.isVisibleLw()) {
                    rect.union(w.getShownFrameLw());
                }
+18 −11
Original line number Diff line number Diff line
@@ -3946,6 +3946,17 @@ final class ActivityStack {
        }
    }

    final void updateTransitLocked(int transit, Bundle options) {
        if (options != null) {
            ActivityRecord r = topRunningActivityLocked(null);
            if (r != null && r.state != ActivityState.RESUMED) {
                r.updateOptionsLocked(options);
            } else {
                ActivityOptions.abort(options);
            }
        }
        mService.mWindowManager.prepareAppTransition(transit, false);
    }

    final void moveTaskToFrontLocked(TaskRecord tr, ActivityRecord reason, Bundle options) {
        if (DEBUG_SWITCH) Slog.v(TAG, "moveTaskToFront: " + tr);
@@ -3955,7 +3966,12 @@ final class ActivityStack {

        if (top < 0 || (mHistory.get(top)).task.taskId == task) {
            // nothing to do!
            if (reason != null &&
                    (reason.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_ANIMATION) != 0) {
                ActivityOptions.abort(options);
            } else {
                updateTransitLocked(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, options);
            }
            return;
        }

@@ -3999,16 +4015,7 @@ final class ActivityStack {
            }
            ActivityOptions.abort(options);
        } else {
            if (options != null) {
                ActivityRecord r = topRunningActivityLocked(null);
                if (r != null && r.state != ActivityState.RESUMED) {
                    r.updateOptionsLocked(options);
                } else {
                    ActivityOptions.abort(options);
                }
            }
            mService.mWindowManager.prepareAppTransition(
                    WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, false);
            updateTransitLocked(WindowManagerPolicy.TRANSIT_TASK_TO_FRONT, options);
        }
        
        mService.mWindowManager.moveAppTokensToTop(moved);
+61 −25
Original line number Diff line number Diff line
@@ -3076,6 +3076,43 @@ public class WindowManagerService extends IWindowManager.Stub
        return null;
    }

    private Animation createExitAnimationLocked(int transit, int duration) {
        if (transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_OPEN ||
                transit == WindowManagerPolicy.TRANSIT_WALLPAPER_INTRA_CLOSE) {
            // If we are on top of the wallpaper, we need an animation that
            // correctly handles the wallpaper staying static behind all of
            // the animated elements.  To do this, will just have the existing
            // element fade out.
            Animation a = new AlphaAnimation(1, 0);
            a.setDetachWallpaper(true);
            a.setDuration(duration);
            return a;
        } else {
            // For normal animations, the exiting element just holds in place.
            Animation a = new AlphaAnimation(1, 1);
            a.setDuration(duration);
            return a;
        }
    }

    /**
     * Compute the pivot point for an animation that is scaling from a small
     * rect on screen to a larger rect.  The pivot point varies depending on
     * the distance between the inner and outer edges on both sides.  This
     * function computes the pivot point for one dimension.
     * @param startPos  Offset from left/top edge of outer rectangle to
     * left/top edge of inner rectangle.
     * @param finalScale The scaling factor between the size of the outer
     * and inner rectangles.
     */
    private static float computePivot(int startPos, float finalScale) {
        final float denom = finalScale-1;
        if (Math.abs(denom) < .0001f) {
            return startPos;
        }
        return -startPos / denom;
    }

    private Animation createScaleUpAnimationLocked(int transit, boolean enter) {
        Animation a;
        // Pick the desired duration.  If this is an inter-activity transition,
@@ -3094,11 +3131,12 @@ public class WindowManagerService extends IWindowManager.Stub
        }
        if (enter) {
            // Entering app zooms out from the center of the initial rect.
            Animation scale = new ScaleAnimation(
                    mNextAppTransitionStartWidth/mAppDisplayWidth, 1,
                    mNextAppTransitionStartHeight/mAppDisplayHeight, 1,
                    mNextAppTransitionStartX + mNextAppTransitionStartWidth/2,
                    mNextAppTransitionStartY + mNextAppTransitionStartHeight/2);
            float scaleW = mNextAppTransitionStartWidth/(float)mAppDisplayWidth;
            float scaleH = mNextAppTransitionStartHeight/(float)mAppDisplayHeight;
            Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
                    computePivot(mNextAppTransitionStartX, scaleW),
                    computePivot(mNextAppTransitionStartY, scaleH));
            scale.setDuration(duration);
            AnimationSet set = new AnimationSet(true);
            Animation alpha = new AlphaAnimation(0, 1);
            scale.setDuration(duration);
@@ -3107,13 +3145,11 @@ public class WindowManagerService extends IWindowManager.Stub
            set.addAnimation(alpha);
            a = set;
        } else {
            // Exiting app just holds in place.
            a = new AlphaAnimation(1, 1);
            a.setDuration(duration);
            a = createExitAnimationLocked(transit, duration);
        }
        a.setFillAfter(true);
        final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
                com.android.internal.R.interpolator.decelerate_quint);
                com.android.internal.R.interpolator.decelerate_quad);
        a.setInterpolator(interpolator);
        a.initialize(mAppDisplayWidth, mAppDisplayHeight,
                mAppDisplayWidth, mAppDisplayHeight);
@@ -3123,8 +3159,10 @@ public class WindowManagerService extends IWindowManager.Stub
    private Animation createThumbnailAnimationLocked(int transit,
            boolean enter, boolean thumb) {
        Animation a;
        final float thumbWidth = mNextAppTransitionThumbnail.getWidth();
        final float thumbHeight = mNextAppTransitionThumbnail.getHeight();
        final int thumbWidthI = mNextAppTransitionThumbnail.getWidth();
        final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1;
        final int thumbHeightI = mNextAppTransitionThumbnail.getHeight();
        final float thumbHeight = thumbHeightI > 0 ? thumbHeightI : 1;
        // Pick the desired duration.  If this is an inter-activity transition,
        // it  is the standard duration for that.  Otherwise we use the longer
        // task transition duration.
@@ -3142,11 +3180,11 @@ public class WindowManagerService extends IWindowManager.Stub
        if (thumb) {
            // Animation for zooming thumbnail from its initial size to
            // filling the screen.
            Animation scale = new ScaleAnimation(
                    1, mAppDisplayWidth/thumbWidth,
                    1, mAppDisplayHeight/thumbHeight,
                    mNextAppTransitionStartX + thumbWidth/2,
                    mNextAppTransitionStartY + thumbHeight/2);
            float scaleW = mAppDisplayWidth/thumbWidth;
            float scaleH = mAppDisplayHeight/thumbHeight;
            Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
                    computePivot(mNextAppTransitionStartX, 1/scaleW),
                    computePivot(mNextAppTransitionStartY, 1/scaleH));
            AnimationSet set = new AnimationSet(true);
            Animation alpha = new AlphaAnimation(1, 0);
            scale.setDuration(duration);
@@ -3156,20 +3194,18 @@ public class WindowManagerService extends IWindowManager.Stub
            a = set;
        } else if (enter) {
            // Entering app zooms out from the center of the thumbnail.
            a = new ScaleAnimation(
                    thumbWidth/mAppDisplayWidth, 1,
                    thumbHeight/mAppDisplayHeight, 1,
                    mNextAppTransitionStartX + thumbWidth/2,
                    mNextAppTransitionStartY + thumbHeight/2);
            float scaleW = thumbWidth/mAppDisplayWidth;
            float scaleH = thumbHeight/mAppDisplayHeight;
            a = new ScaleAnimation(scaleW, 1, scaleH, 1,
                    computePivot(mNextAppTransitionStartX, scaleW),
                    computePivot(mNextAppTransitionStartY, scaleH));
            a.setDuration(duration);
        } else {
            // Exiting app just holds in place.
            a = new AlphaAnimation(1, 1);
            a.setDuration(duration);
            a = createExitAnimationLocked(transit, duration);
        }
        a.setFillAfter(true);
        final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
                com.android.internal.R.interpolator.decelerate_quint);
                com.android.internal.R.interpolator.decelerate_quad);
        a.setInterpolator(interpolator);
        a.initialize(mAppDisplayWidth, mAppDisplayHeight,
                mAppDisplayWidth, mAppDisplayHeight);