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

Commit 1a7e3712 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactoring DigitalWellbeing Banner to not use footers." into ub-launcher3-master

parents 967551b0 6dcba895
Loading
Loading
Loading
Loading
+72 −10
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.quickstep.views;

import static android.provider.Settings.ACTION_APP_USAGE_SETTINGS;
import static android.view.Gravity.BOTTOM;
import static android.view.Gravity.CENTER_HORIZONTAL;

import static com.android.launcher3.Utilities.prefixTextWithIcon;
import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR;
@@ -27,6 +29,7 @@ import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.AppUsageLimit;
import android.graphics.Outline;
import android.icu.text.MeasureFormat;
import android.icu.text.MeasureFormat.FormatWidth;
import android.icu.util.Measure;
@@ -35,6 +38,9 @@ import android.os.Build;
import android.os.UserHandle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.StringRes;
@@ -61,6 +67,10 @@ public final class DigitalWellBeingToast {
    private Task mTask;
    private boolean mHasLimit;
    private long mAppRemainingTimeMs;
    private View mBanner;
    private ViewOutlineProvider mOldBannerOutlineProvider;
    private float mBannerOffsetPercentage;
    private float mBannerAlpha = 1f;

    public DigitalWellBeingToast(BaseDraggingActivity activity, TaskView taskView) {
        mActivity = activity;
@@ -68,18 +78,10 @@ public final class DigitalWellBeingToast {
        mLauncherApps = activity.getSystemService(LauncherApps.class);
    }

    private void setTaskFooter(View view) {
        View oldFooter = mTaskView.setFooter(TaskView.INDEX_DIGITAL_WELLBEING_TOAST, view);
        if (oldFooter != null) {
            oldFooter.setOnClickListener(null);
            mActivity.getViewCache().recycleView(R.layout.digital_wellbeing_toast, oldFooter);
        }
    }

    private void setNoLimit() {
        mHasLimit = false;
        mTaskView.setContentDescription(mTask.titleDescription);
        setTaskFooter(null);
        replaceBanner(null);
        mAppRemainingTimeMs = 0;
    }

@@ -90,7 +92,7 @@ public final class DigitalWellBeingToast {
                mActivity, mTaskView);
        toast.setText(prefixTextWithIcon(mActivity, R.drawable.ic_hourglass_top, getText()));
        toast.setOnClickListener(this::openAppUsageSettings);
        setTaskFooter(toast);
        replaceBanner(toast);

        mTaskView.setContentDescription(
                getContentDescriptionForTask(mTask, appUsageLimitTimeMs, appRemainingTimeMs));
@@ -233,4 +235,64 @@ public final class DigitalWellBeingToast {
                        getText(appRemainingTimeMs)) :
                task.titleDescription;
    }

    private void replaceBanner(View view) {
        resetOldBanner();
        setBanner(view);
    }

    private void resetOldBanner() {
        if (mBanner != null) {
            mBanner.setOutlineProvider(mOldBannerOutlineProvider);
            mTaskView.removeView(mBanner);
            mBanner.setOnClickListener(null);
            mActivity.getViewCache().recycleView(R.layout.digital_wellbeing_toast, mBanner);
        }
    }

    private void setBanner(View view) {
        mBanner = view;
        if (view != null) {
            setupAndAddBanner();
            setBannerOutline();
        }
    }

    private void setupAndAddBanner() {
        FrameLayout.LayoutParams layoutParams =
                (FrameLayout.LayoutParams) mBanner.getLayoutParams();
        layoutParams.gravity = BOTTOM | CENTER_HORIZONTAL;
        layoutParams.bottomMargin = ((ViewGroup.MarginLayoutParams)
                mTaskView.getThumbnail().getLayoutParams()).bottomMargin;
        mBanner.setTranslationY(mBannerOffsetPercentage * mBanner.getHeight());
        mBanner.setAlpha(mBannerAlpha);
        mTaskView.addView(mBanner);
    }

    private void setBannerOutline() {
        mOldBannerOutlineProvider = mBanner.getOutlineProvider();
        mBanner.setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                mOldBannerOutlineProvider.getOutline(view, outline);
                outline.offset(0, -Math.round(view.getTranslationY()));
            }
        });
        mBanner.setClipToOutline(true);
    }

    void updateBannerOffset(float offsetPercentage) {
        if (mBanner != null && mBannerOffsetPercentage != offsetPercentage) {
            mBannerOffsetPercentage = offsetPercentage;
            mBanner.setTranslationY(offsetPercentage * mBanner.getHeight());
            mBanner.invalidateOutline();
        }
    }

    void updateBannerAlpha(float alpha) {
        if (mBanner != null && mBannerAlpha != alpha) {
            mBannerAlpha = alpha;
            mBanner.setAlpha(alpha);
        }
    }
}
+5 −149
Original line number Diff line number Diff line
@@ -42,7 +42,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
@@ -193,12 +192,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {

    private boolean mEndQuickswitchCuj;

    // Order in which the footers appear. Lower order appear below higher order.
    public static final int INDEX_DIGITAL_WELLBEING_TOAST = 0;
    private final FooterWrapper[] mFooters = new FooterWrapper[2];
    private float mFooterVerticalOffset = 0;
    private float mFooterAlpha = 1;
    private int mStackHeight;
    private View mContextualChipWrapper;
    private View mContextualChip;
    private final float[] mIconCenterCoords = new float[2];
@@ -342,7 +335,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
        if (mContextualChipWrapper != null) {
            mContextualChipWrapper.setAlpha(comp(modalness));
        }
        updateFooterVerticalOffset(mFooterVerticalOffset);
        mDigitalWellBeingToast.updateBannerOffset(modalness);
    }

    public TaskMenuView getMenuView() {
@@ -564,7 +557,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
            mContextualChip.setScaleX(scale);
            mContextualChip.setScaleY(scale);
        }
        updateFooterVerticalOffset(1.0f - scale);
        mDigitalWellBeingToast.updateBannerOffset(1f - scale);
    }

    public void setIconScaleAnimStartProgress(float startProgress) {
@@ -636,12 +629,9 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
        mSnapshotView.setDimAlpha(curveInterpolation * MAX_PAGE_SCRIM_ALPHA);
        setCurveScale(curveScaleForCurveInterpolation);

        mFooterAlpha = Utilities.boundToRange(1.0f - 2 * scrollState.linearInterpolation, 0f, 1f);
        for (FooterWrapper footer : mFooters) {
            if (footer != null) {
                footer.mView.setAlpha(mFooterAlpha);
            }
        }
        float dwbBannerAlpha = Utilities.boundToRange(1.0f - 2 * scrollState.linearInterpolation,
                0f, 1f);
        mDigitalWellBeingToast.updateBannerAlpha(dwbBannerAlpha);

        if (mMenuView != null) {
            PagedOrientationHandler pagedOrientationHandler = getPagedOrientationHandler();
@@ -653,57 +643,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
        }
    }

    /**
     * Sets the footer at the specific index and returns the previously set footer.
     */
    public View setFooter(int index, View view) {
        View oldFooter = null;

        // If the footer are is already collapsed, do not animate entry
        boolean shouldAnimateEntry = mFooterVerticalOffset <= 0;

        if (mFooters[index] != null) {
            oldFooter = mFooters[index].mView;
            mFooters[index].release();
            removeView(oldFooter);

            // If we are replacing an existing footer, do not animate entry
            shouldAnimateEntry = false;
        }
        if (view != null) {
            int indexToAdd = getChildCount();
            for (int i = index - 1; i >= 0; i--) {
                if (mFooters[i] != null) {
                    indexToAdd = indexOfChild(mFooters[i].mView);
                    break;
                }
            }

            addView(view, indexToAdd);
            LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
            layoutParams.gravity = BOTTOM | CENTER_HORIZONTAL;
            layoutParams.bottomMargin =
                    ((MarginLayoutParams) mSnapshotView.getLayoutParams()).bottomMargin;
            view.setAlpha(mFooterAlpha);
            mFooters[index] = new FooterWrapper(view);
            if (shouldAnimateEntry) {
                mFooters[index].animateEntry();
            }
        } else {
            mFooters[index] = null;
        }

        mStackHeight = 0;
        for (FooterWrapper footer : mFooters) {
            if (footer != null) {
                footer.setVerticalShift(mStackHeight);
                mStackHeight += footer.mExpectedHeight;
            }
        }

        return oldFooter;
    }

    /**
     * Sets the contextual chip.
     *
@@ -777,24 +716,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
            SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(0, 0, getWidth(), getHeight());
            setSystemGestureExclusionRects(SYSTEM_GESTURE_EXCLUSION_RECT);
        }

        mStackHeight = 0;
        for (FooterWrapper footer : mFooters) {
            if (footer != null) {
                mStackHeight += footer.mView.getHeight();
            }
        }
        updateFooterVerticalOffset(0);
    }

    private void updateFooterVerticalOffset(float offset) {
        mFooterVerticalOffset = offset;

        for (FooterWrapper footer : mFooters) {
            if (footer != null) {
                footer.updateFooterOffset();
            }
        }
    }

    public static float getCurveScaleForInterpolation(float linearInterpolation) {
@@ -857,71 +778,6 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
        }
    }

    private class FooterWrapper extends ViewOutlineProvider {

        final View mView;
        final ViewOutlineProvider mOldOutlineProvider;
        final ViewOutlineProvider mDelegate;

        final int mExpectedHeight;
        final int mOldPaddingBottom;

        int mAnimationOffset = 0;
        int mEntryAnimationOffset = 0;

        public FooterWrapper(View view) {
            mView = view;
            mOldOutlineProvider = view.getOutlineProvider();
            mDelegate = mOldOutlineProvider == null
                    ? ViewOutlineProvider.BACKGROUND : mOldOutlineProvider;

            mExpectedHeight = getExpectedViewHeight(view);
            mOldPaddingBottom = view.getPaddingBottom();

            if (mOldOutlineProvider != null) {
                view.setOutlineProvider(this);
                view.setClipToOutline(true);
            }
        }

        public void setVerticalShift(int shift) {
            mView.setPadding(mView.getPaddingLeft(), mView.getPaddingTop(),
                    mView.getPaddingRight(), mOldPaddingBottom + shift);
        }

        @Override
        public void getOutline(View view, Outline outline) {
            mDelegate.getOutline(view, outline);
            outline.offset(0, -mAnimationOffset - mEntryAnimationOffset);
        }

        void updateFooterOffset() {
            float offset = Utilities.or(mFooterVerticalOffset, mModalness);
            mAnimationOffset = Math.round(mStackHeight * offset);
            mView.setTranslationY(mAnimationOffset + mEntryAnimationOffset
                    + mCurrentFullscreenParams.mCurrentDrawnInsets.bottom
                    + mCurrentFullscreenParams.mCurrentDrawnInsets.top);
            mView.invalidateOutline();
        }

        void release() {
            mView.setOutlineProvider(mOldOutlineProvider);
            setVerticalShift(0);
        }

        void animateEntry() {
            ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
            animator.addUpdateListener(anim -> {
               float factor = 1 - anim.getAnimatedFraction();
               int totalShift = mExpectedHeight + mView.getPaddingBottom() - mOldPaddingBottom;
                mEntryAnimationOffset = Math.round(factor * totalShift);
                updateFooterOffset();
            });
            animator.setDuration(100);
            animator.start();
        }
    }

    private int getExpectedViewHeight(View view) {
        int expectedHeight;
        int h = view.getLayoutParams().height;