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

Commit 96e3bc1f authored by Winson Chung's avatar Winson Chung
Browse files

Fixing issue with animation not running after SystemUI crashes (Bug 14453240)

- Falling back to default transition if we don't have a thumbnail (Bug 14589475)
- Tweaking over scroll to prevent scrolling past a certain point (Bug 14582630)
- Fixing issue with missing top padding in the stack view
- Adding some shadowing to distinguish similar cards from each other
parent 3aeaebb6
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -227,6 +227,12 @@
    <!-- The radius of the rounded corners on a task view. -->
    <dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>

    <!-- The min translation in the Z index for the last task. -->
    <dimen name="recents_task_view_z_min">3dp</dimen>

    <!-- The translation in the Z index for each task above the last task. -->
    <dimen name="recents_task_view_z_increment">5dp</dimen>

    <!-- The amount of space a user has to scroll to dismiss any info panes. -->
    <dimen name="recents_task_stack_scroll_dismiss_info_pane_distance">50dp</dimen>

+101 −49
Original line number Diff line number Diff line
@@ -64,6 +64,17 @@ public class AlternateRecentsComponent {
                mSingleCountFirstTaskRect.offset(0, (int) statusBarHeight);
                mMultipleCountFirstTaskRect = replyData.getParcelable(KEY_MULTIPLE_TASK_STACK_RECT);
                mMultipleCountFirstTaskRect.offset(0, (int) statusBarHeight);
                Console.log(Constants.DebugFlags.App.RecentsComponent,
                        "[RecentsComponent|RecentsMessageHandler|handleMessage]",
                        "singleTaskRect: " + mSingleCountFirstTaskRect +
                        " multipleTaskRect: " + mMultipleCountFirstTaskRect);

                // If we had the update the animation rects as a result of onServiceConnected, then
                // we check for whether we need to toggle the recents here.
                if (mToggleRecentsUponServiceBound) {
                    startAlternateRecentsActivity();
                    mToggleRecentsUponServiceBound = false;
                }
            }
        }
    }
@@ -78,12 +89,17 @@ public class AlternateRecentsComponent {
            mService = new Messenger(service);
            mServiceIsBound = true;

            // Toggle recents if this service connection was triggered by hitting the recents button
            if (hasValidTaskRects()) {
                // Toggle recents if this new service connection was triggered by hitting recents
                if (mToggleRecentsUponServiceBound) {
                    startAlternateRecentsActivity();
            }
                    mToggleRecentsUponServiceBound = false;
                }
            } else {
                // Otherwise, update the animation rects before starting the recents if requested
                updateAnimationRects();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName className) {
@@ -191,6 +207,26 @@ public class AlternateRecentsComponent {
    }

    public void onConfigurationChanged(Configuration newConfig) {
        updateAnimationRects();
    }

    /** Binds to the recents implementation */
    private void bindToRecentsService(boolean toggleRecentsUponConnection) {
        mToggleRecentsUponServiceBound = toggleRecentsUponConnection;
        Intent intent = new Intent();
        intent.setClassName(sRecentsPackage, sRecentsService);
        mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    /** Returns whether we have valid task rects to animate to. */
    boolean hasValidTaskRects() {
        return mSingleCountFirstTaskRect != null && mSingleCountFirstTaskRect.width() > 0 &&
                mSingleCountFirstTaskRect.height() > 0 && mMultipleCountFirstTaskRect != null &&
                mMultipleCountFirstTaskRect.width() > 0 && mMultipleCountFirstTaskRect.height() > 0;
    }

    /** Updates each of the task animation rects. */
    void updateAnimationRects() {
        if (mServiceIsBound) {
            Resources res = mContext.getResources();
            int statusBarHeight = res.getDimensionPixelSize(
@@ -216,14 +252,6 @@ public class AlternateRecentsComponent {
        }
    }

    /** Binds to the recents implementation */
    private void bindToRecentsService(boolean toggleRecentsUponConnection) {
        mToggleRecentsUponServiceBound = toggleRecentsUponConnection;
        Intent intent = new Intent();
        intent.setClassName(sRecentsPackage, sRecentsService);
        mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
    }

    /** Loads the first task thumbnail */
    Bitmap loadFirstTaskThumbnail() {
        SystemServicesProxy ssp = mSystemServicesProxy;
@@ -300,6 +328,49 @@ public class AlternateRecentsComponent {
        return SurfaceControl.screenshot((int) dims[0], (int) dims[1]);
    }

    /** Creates the activity options for a thumbnail transition. */
    ActivityOptions getThumbnailTransitionActivityOptions(Rect taskRect) {
        // Loading from thumbnail
        Bitmap thumbnail;
        Bitmap firstThumbnail = loadFirstTaskThumbnail();
        if (firstThumbnail != null) {
            // Create the thumbnail
            thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
                    Bitmap.Config.ARGB_8888);
            int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight());
            Canvas c = new Canvas(thumbnail);
            c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size),
                    new Rect(0, 0, taskRect.width(), taskRect.height()), null);
            c.setBitmap(null);
            // Recycle the old thumbnail
            firstThumbnail.recycle();
        } else {
            // Load the thumbnail from the screenshot if can't get one from the system
            WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            Bitmap screenshot = takeScreenshot(display);
            if (screenshot != null) {
                Resources res = mContext.getResources();
                int size = Math.min(screenshot.getWidth(), screenshot.getHeight());
                int statusBarHeight = res.getDimensionPixelSize(
                        com.android.internal.R.dimen.status_bar_height);
                thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
                        Bitmap.Config.ARGB_8888);
                Canvas c = new Canvas(thumbnail);
                c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight +
                        size), new Rect(0, 0, taskRect.width(), taskRect.height()), null);
                c.setBitmap(null);
                // Recycle the temporary screenshot
                screenshot.recycle();
            } else {
                return null;
            }
        }

        return ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView, thumbnail,
                taskRect.left, taskRect.top, null);
    }

    /** Starts the recents activity */
    void startAlternateRecentsActivity() {
        // If the user has toggled it too quickly, then just eat up the event here (it's better than
@@ -351,47 +422,28 @@ public class AlternateRecentsComponent {
        // number of items in the list.
        List<ActivityManager.RecentTaskInfo> recentTasks =
                ssp.getRecentTasks(4, UserHandle.CURRENT.getIdentifier());
        boolean hasMultipleTasks = hasMultipleRecentsTask(recentTasks);
        Rect taskRect = hasMultipleRecentsTask(recentTasks) ? mMultipleCountFirstTaskRect :
                mSingleCountFirstTaskRect;
        boolean isTaskExcludedFromRecents = isTopTaskExcludeFromRecents(recentTasks);
        Rect taskRect = hasMultipleTasks ? mMultipleCountFirstTaskRect : mSingleCountFirstTaskRect;
        if (!isTopTaskHome && !isTaskExcludedFromRecents &&
                (taskRect != null) && (taskRect.width() > 0) && (taskRect.height() > 0)) {
            // Loading from thumbnail
            Bitmap thumbnail;
            Bitmap firstThumbnail = loadFirstTaskThumbnail();
            if (firstThumbnail != null) {// Create the thumbnail
                thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
                        Bitmap.Config.ARGB_8888);
                int size = Math.min(firstThumbnail.getWidth(), firstThumbnail.getHeight());
                Canvas c = new Canvas(thumbnail);
                c.drawBitmap(firstThumbnail, new Rect(0, 0, size, size),
                        new Rect(0, 0, taskRect.width(), taskRect.height()), null);
                c.setBitmap(null);
                // Recycle the old thumbnail
                firstThumbnail.recycle();
            } else {
                // Load the thumbnail from the screenshot if can't get one from the system
                WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
                Display display = wm.getDefaultDisplay();
                Bitmap screenshot = takeScreenshot(display);
                Resources res = mContext.getResources();
                int size = Math.min(screenshot.getWidth(), screenshot.getHeight());
                int statusBarHeight = res.getDimensionPixelSize(
                        com.android.internal.R.dimen.status_bar_height);
                thumbnail = Bitmap.createBitmap(taskRect.width(), taskRect.height(),
                        Bitmap.Config.ARGB_8888);
                Canvas c = new Canvas(thumbnail);
                c.drawBitmap(screenshot, new Rect(0, statusBarHeight, size, statusBarHeight + size),
                        new Rect(0, 0, taskRect.width(), taskRect.height()), null);
                c.setBitmap(null);
                // Recycle the temporary screenshot
                screenshot.recycle();
            }
        boolean useThumbnailTransition = !isTopTaskHome && !isTaskExcludedFromRecents &&
                hasValidTaskRects();

            ActivityOptions opts = ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView,
                    thumbnail, taskRect.left, taskRect.top, null);
        if (useThumbnailTransition) {
            // Try starting with a thumbnail transition
            ActivityOptions opts = getThumbnailTransitionActivityOptions(taskRect);
            if (opts != null) {
                startAlternateRecentsActivity(opts, true);
            } else {
                // Fall through below to the non-thumbnail transition
                useThumbnailTransition = false;
            }
        }

        // If there is no thumbnail transition, then just use a generic transition
        // XXX: This should be different between home and from a recents-excluded app, perhaps the
        //      recents-excluded app should still show up in recents, when the app is in the
        //      foreground
        if (!useThumbnailTransition) {
            ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
                    R.anim.recents_from_launcher_enter,
                    R.anim.recents_from_launcher_exit);
+1 −4
Original line number Diff line number Diff line
@@ -91,11 +91,8 @@ public class Constants {
            public static final int TaskStackOverscrollRange = 150;
            public static final int FilterStartDelay = 25;

            // The amount to inverse scale the movement if we are overscrolling
            public static final float TouchOverscrollScaleFactor = 3f;

            // The padding will be applied to the smallest dimension, and then applied to all sides
            public static final float StackPaddingPct = 0.15f;
            public static final float StackPaddingPct = 0.1f;
            // The overlap height relative to the task height
            public static final float StackOverlapPct = 0.65f;
            // The height of the peek space relative to the stack height
+5 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ public class RecentsConfiguration {
    public int taskStackScrollDismissInfoPaneDistance;
    public int taskStackMaxDim;
    public int taskViewInfoPaneAnimDuration;
    public int taskViewTranslationZMinPx;
    public int taskViewTranslationZIncrementPx;
    public int taskViewRoundedCornerRadiusPx;
    public int searchBarSpaceHeightPx;

@@ -105,6 +107,9 @@ public class RecentsConfiguration {
                res.getInteger(R.integer.recents_animate_task_view_info_pane_duration);
        taskViewRoundedCornerRadiusPx =
                res.getDimensionPixelSize(R.dimen.recents_task_view_rounded_corners_radius);
        taskViewTranslationZMinPx = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
        taskViewTranslationZIncrementPx =
                res.getDimensionPixelSize(R.dimen.recents_task_view_z_increment);
        searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height);


+11 −0
Original line number Diff line number Diff line
@@ -20,10 +20,12 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.TouchFeedbackDrawable;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.FrameLayout;
@@ -151,6 +153,15 @@ class TaskInfoView extends FrameLayout {
        RecentsConfiguration configuration = RecentsConfiguration.getInstance();
        if (Constants.DebugFlags.App.EnableTaskBarThemeColors && t.colorPrimary != 0) {
            setBackgroundColor(t.colorPrimary);
            // Workaround: The button currently doesn't support setting a custom background tint
            // not defined in the theme.  Just lower the alpha on the button to make it blend more
            // into the background.
            if (mAppInfoButton.getBackground() instanceof TouchFeedbackDrawable) {
                TouchFeedbackDrawable d = (TouchFeedbackDrawable) mAppInfoButton.getBackground();
                if (d != null) {
                    d.setAlpha(96);
                }
            }
        } else {
            setBackgroundColor(configuration.taskBarViewDefaultBackgroundColor);
        }
Loading