Merge "Include more error logging for widget restore" into ub-launcher3-master
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
index 95bde80..6630aed 100644
--- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -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.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.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 @@
     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 @@
         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 @@
                 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 @@
                         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);
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 1b85b2e..3230348 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -42,7 +42,6 @@
 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 @@
 
     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 @@
         if (mContextualChipWrapper != null) {
             mContextualChipWrapper.setAlpha(comp(modalness));
         }
-        updateFooterVerticalOffset(mFooterVerticalOffset);
+        mDigitalWellBeingToast.updateBannerOffset(modalness);
     }
 
     public TaskMenuView getMenuView() {
@@ -564,7 +557,7 @@
             mContextualChip.setScaleX(scale);
             mContextualChip.setScaleY(scale);
         }
-        updateFooterVerticalOffset(1.0f - scale);
+        mDigitalWellBeingToast.updateBannerOffset(1f - scale);
     }
 
     public void setIconScaleAnimStartProgress(float startProgress) {
@@ -636,12 +629,9 @@
         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();
@@ -654,57 +644,6 @@
     }
 
     /**
-     * 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.
      *
      * @param view Wrapper view containing contextual chip.
@@ -777,24 +716,6 @@
             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 @@
         }
     }
 
-    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;