Merge "Revert "fix broken build on erorrprone"" into tm-dev
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 3b02599..eda0823 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -53,6 +53,7 @@
 public class DepthController implements StateHandler<LauncherState>,
         BaseActivity.MultiWindowModeChangedListener {
 
+    private static final boolean OVERLAY_SCROLL_ENABLED = false;
     public static final FloatProperty<DepthController> DEPTH =
             new FloatProperty<DepthController>("depth") {
                 @Override
@@ -294,6 +295,9 @@
     }
 
     public void onOverlayScrollChanged(float progress) {
+        if (!OVERLAY_SCROLL_ENABLED) {
+            return;
+        }
         // Add some padding to the progress, such we don't change the depth on the last frames of
         // the animation. It's possible that a user flinging the feed quickly would scroll
         // horizontally by accident, causing the device to enter client composition unnecessarily.
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index ed00b8e..e5cbbee 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -106,6 +106,7 @@
 import android.widget.ListView;
 import android.widget.OverScroller;
 import android.widget.Toast;
+import android.window.PictureInPictureSurfaceTransaction;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
@@ -161,6 +162,7 @@
 import com.android.quickstep.TaskViewUtils;
 import com.android.quickstep.ViewUtils;
 import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.LauncherSplitScreenListener;
 import com.android.quickstep.util.LayoutUtils;
 import com.android.quickstep.util.RecentsOrientedState;
 import com.android.quickstep.util.SplitScreenBounds;
@@ -4507,6 +4509,18 @@
             final SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(getContext());
             systemUiProxy.notifySwipeToHomeFinished();
             systemUiProxy.setShelfHeight(true, mActivity.getDeviceProfile().hotseatBarSizePx);
+            // Transaction to hide the task to avoid flicker for entering PiP from split-screen.
+            // See also {@link AbsSwipeUpHandler#maybeFinishSwipeToHome}.
+            PictureInPictureSurfaceTransaction tx =
+                    new PictureInPictureSurfaceTransaction.Builder()
+                            .setAlpha(0f)
+                            .build();
+            int[] taskIds =
+                    LauncherSplitScreenListener.INSTANCE.getNoCreate().getRunningSplitTaskIds();
+            for (int taskId : taskIds) {
+                mRecentsAnimationController.setFinishTaskTransaction(taskId,
+                        tx, null /* overlay */);
+            }
         }
         mRecentsAnimationController.finish(toRecents, () -> {
             if (onFinishComplete != null) {
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index 74d9a22..6f295e6 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -20,9 +20,13 @@
 
 import android.annotation.TargetApi;
 import android.graphics.Bitmap;
-import android.graphics.Matrix;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.Path.Direction;
+import android.graphics.Picture;
+import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.AdaptiveIconDrawable;
@@ -31,10 +35,11 @@
 import android.util.Log;
 
 import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
 
+import com.android.launcher3.Utilities;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.folder.PreviewBackground;
-import com.android.launcher3.graphics.ShiftedBitmapDrawable;
 import com.android.launcher3.icons.BitmapRenderer;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.views.ActivityContext;
@@ -69,79 +74,104 @@
         return mBadge;
     }
 
+    @TargetApi(Build.VERSION_CODES.P)
     public static @Nullable FolderAdaptiveIcon createFolderAdaptiveIcon(
-            ActivityContext activity, int folderId, Point dragViewSize) {
+            ActivityContext activity, int folderId, Point size) {
         Preconditions.assertNonUiThread();
+        if (!Utilities.ATLEAST_P) {
+            return null;
+        }
 
-        // Create the actual drawable on the UI thread to avoid race conditions with
+        // assume square
+        if (size.x != size.y) {
+            return null;
+        }
+        int requestedSize = size.x;
+
+        // Only use the size actually needed for drawing the folder icon
+        int drawingSize = activity.getDeviceProfile().folderIconSizePx;
+        int foregroundSize = Math.max(requestedSize, drawingSize);
+        float shift = foregroundSize - requestedSize;
+
+        Picture background = new Picture();
+        Picture foreground = new Picture();
+        Picture badge = new Picture();
+
+        Canvas bgCanvas = background.beginRecording(requestedSize, requestedSize);
+        Canvas badgeCanvas = badge.beginRecording(requestedSize, requestedSize);
+
+        Canvas fgCanvas = foreground.beginRecording(foregroundSize, foregroundSize);
+        fgCanvas.translate(shift, shift);
+
+        // Do not clip the folder drawing since the icon previews extend outside the background.
+        Path mask = new Path();
+        mask.addRect(-shift, -shift, requestedSize + shift, requestedSize + shift,
+                Direction.CCW);
+
+        // Initialize the actual draw commands on the UI thread to avoid race conditions with
         // FolderIcon draw pass
         try {
-            return MAIN_EXECUTOR.submit(() -> {
+            MAIN_EXECUTOR.submit(() -> {
                 FolderIcon icon = activity.findFolderIcon(folderId);
-                return icon == null ? null : createDrawableOnUiThread(icon, dragViewSize);
-
+                if (icon == null) {
+                    throw new IllegalArgumentException("Folder not found with id: " + folderId);
+                }
+                initLayersOnUiThread(icon, requestedSize, bgCanvas, fgCanvas, badgeCanvas);
             }).get();
         } catch (Exception e) {
             Log.e(TAG, "Unable to create folder icon", e);
             return null;
+        } finally {
+            background.endRecording();
+            foreground.endRecording();
+            badge.endRecording();
         }
+
+        // Only convert foreground to a bitmap as it can contain multiple draw commands. Other
+        // layers either draw a nothing or a single draw call.
+        Bitmap fgBitmap = Bitmap.createBitmap(foreground);
+        Paint foregroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+
+        // Do not use PictureDrawable as it moves the picture to the canvas bounds, whereas we want
+        // to draw it at (0,0)
+        return new FolderAdaptiveIcon(
+                new BitmapRendererDrawable(c -> c.drawPicture(background)),
+                new BitmapRendererDrawable(
+                        c -> c.drawBitmap(fgBitmap, -shift, -shift, foregroundPaint)),
+                new BitmapRendererDrawable(c -> c.drawPicture(badge)),
+                mask);
     }
 
-    private static FolderAdaptiveIcon createDrawableOnUiThread(FolderIcon icon,
-                                                               Point dragViewSize) {
-        Preconditions.assertUIThread();
-
+    @UiThread
+    private static void initLayersOnUiThread(FolderIcon icon, int size,
+            Canvas backgroundCanvas, Canvas foregroundCanvas, Canvas badgeCanvas) {
         icon.getPreviewBounds(sTmpRect);
-
-        PreviewBackground bg = icon.getFolderBackground();
-
-        // assume square
-        assert (dragViewSize.x == dragViewSize.y);
         final int previewSize = sTmpRect.width();
 
-        final int margin = (dragViewSize.x - previewSize) / 2;
+        PreviewBackground bg = icon.getFolderBackground();
+        final int margin = (size - previewSize) / 2;
         final float previewShiftX = -sTmpRect.left + margin;
         final float previewShiftY = -sTmpRect.top + margin;
 
         // Initialize badge, which consists of the outline stroke, shadow and dot; these
         // must be rendered above the foreground
-        Bitmap badgeBmp = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
-                (canvas) -> {
-                    canvas.save();
-                    canvas.translate(previewShiftX, previewShiftY);
-                    bg.drawShadow(canvas);
-                    bg.drawBackgroundStroke(canvas);
-                    icon.drawDot(canvas);
-                    canvas.restore();
-                });
+        badgeCanvas.save();
+        badgeCanvas.translate(previewShiftX, previewShiftY);
+        icon.drawDot(badgeCanvas);
+        badgeCanvas.restore();
 
-        // Initialize mask
-        Path mask = new Path();
-        Matrix m = new Matrix();
-        m.setTranslate(previewShiftX, previewShiftY);
-        bg.getClipPath().transform(m, mask);
+        // Draw foreground
+        foregroundCanvas.save();
+        foregroundCanvas.translate(previewShiftX, previewShiftY);
+        icon.getPreviewItemManager().draw(foregroundCanvas);
+        foregroundCanvas.restore();
 
-        Bitmap previewBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
-                (canvas) -> {
-                    canvas.save();
-                    canvas.translate(previewShiftX, previewShiftY);
-                    icon.getPreviewItemManager().draw(canvas);
-                    canvas.restore();
-                });
-
-        Bitmap bgBitmap = BitmapRenderer.createHardwareBitmap(dragViewSize.x, dragViewSize.y,
-                (canvas) -> {
-                    Paint p = new Paint();
-                    p.setColor(bg.getBgColor());
-
-                    canvas.drawCircle(dragViewSize.x / 2f, dragViewSize.y / 2f, bg.getRadius(), p);
-                });
-
-        ShiftedBitmapDrawable badge = new ShiftedBitmapDrawable(badgeBmp, 0, 0);
-        ShiftedBitmapDrawable foreground = new ShiftedBitmapDrawable(previewBitmap, 0, 0);
-        ShiftedBitmapDrawable background = new ShiftedBitmapDrawable(bgBitmap, 0, 0);
-
-        return new FolderAdaptiveIcon(background, foreground, badge, mask);
+        // Draw background
+        Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+        backgroundPaint.setColor(bg.getBgColor());
+        bg.drawShadow(backgroundCanvas);
+        backgroundCanvas.drawCircle(size / 2f, size / 2f, bg.getRadius(), backgroundPaint);
+        bg.drawBackgroundStroke(backgroundCanvas);
     }
 
     @Override
@@ -174,4 +204,52 @@
                     & mBadge.getChangingConfigurations();
         }
     }
+
+    private static class BitmapRendererDrawable extends Drawable {
+
+        private final BitmapRenderer mRenderer;
+
+        BitmapRendererDrawable(BitmapRenderer renderer) {
+            mRenderer = renderer;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            mRenderer.draw(canvas);
+        }
+
+        @Override
+        public void setAlpha(int i) { }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {  }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+
+        @Override
+        public ConstantState getConstantState() {
+            return new MyConstantState(mRenderer);
+        }
+
+        private static class MyConstantState extends ConstantState {
+            private final BitmapRenderer mRenderer;
+
+            MyConstantState(BitmapRenderer renderer) {
+                mRenderer = renderer;
+            }
+
+            @Override
+            public Drawable newDrawable() {
+                return new BitmapRendererDrawable(mRenderer);
+            }
+
+            @Override
+            public int getChangingConfigurations() {
+                return 0;
+            }
+        }
+    }
 }
diff --git a/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java b/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java
deleted file mode 100644
index f8583b8..0000000
--- a/src/com/android/launcher3/graphics/ShiftedBitmapDrawable.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2019 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.graphics;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.ColorFilter;
-import android.graphics.Paint;
-import android.graphics.PixelFormat;
-import android.graphics.drawable.Drawable;
-
-/**
- * A simple drawable which draws a bitmap at a fixed position irrespective of the bounds
- */
-public class ShiftedBitmapDrawable extends Drawable {
-
-    private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
-    private final Bitmap mBitmap;
-    private float mShiftX;
-    private float mShiftY;
-
-    private final ConstantState mConstantState;
-
-    public ShiftedBitmapDrawable(Bitmap bitmap, float shiftX, float shiftY) {
-        mBitmap = bitmap;
-        mShiftX = shiftX;
-        mShiftY = shiftY;
-
-        mConstantState = new MyConstantState(mBitmap, mShiftX, mShiftY);
-    }
-
-    public float getShiftX() {
-        return mShiftX;
-    }
-
-    public float getShiftY() {
-        return mShiftY;
-    }
-
-    public void setShiftX(float shiftX) {
-        mShiftX = shiftX;
-    }
-
-    public void setShiftY(float shiftY) {
-        mShiftY = shiftY;
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        canvas.drawBitmap(mBitmap, mShiftX, mShiftY, mPaint);
-    }
-
-    @Override
-    public void setAlpha(int i) { }
-
-    @Override
-    public void setColorFilter(ColorFilter colorFilter) {
-        mPaint.setColorFilter(colorFilter);
-    }
-
-    @Override
-    public int getOpacity() {
-        return PixelFormat.TRANSLUCENT;
-    }
-
-    @Override
-    public ConstantState getConstantState() {
-        return mConstantState;
-    }
-
-    private static class MyConstantState extends ConstantState {
-        private final Bitmap mBitmap;
-        private float mShiftX;
-        private float mShiftY;
-
-        MyConstantState(Bitmap bitmap, float shiftX, float shiftY) {
-            mBitmap = bitmap;
-            mShiftX = shiftX;
-            mShiftY = shiftY;
-        }
-
-        @Override
-        public Drawable newDrawable() {
-            return new ShiftedBitmapDrawable(mBitmap, mShiftX, mShiftY);
-        }
-
-        @Override
-        public int getChangingConfigurations() {
-            return 0;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 56a1d37..babe607 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -49,7 +49,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.dragndrop.DragLayer;
-import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.graphics.PreloadIconDrawable;
 import com.android.launcher3.icons.FastBitmapDrawable;
@@ -413,8 +412,7 @@
     @WorkerThread
     @SuppressWarnings("WrongThread")
     private static int getOffsetForIconBounds(Launcher l, Drawable drawable, RectF position) {
-        if (!(drawable instanceof AdaptiveIconDrawable)
-                || (drawable instanceof FolderAdaptiveIcon)) {
+        if (!(drawable instanceof AdaptiveIconDrawable)) {
             return 0;
         }
         int blurSizeOutline =