Using public APIs for hardware bitmaps

Bug: 35428783
Change-Id: I4e7eeaa94e0cdfb1c76dce507a6f855e4eebbd6c
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 7f98935..352cd9c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -18,28 +18,22 @@
 
 import static com.android.launcher3.LauncherState.NORMAL;
 
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.PointF;
 import android.view.View.AccessibilityDelegate;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherStateManager.StateHandler;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.graphics.BitmapRenderer;
 import com.android.launcher3.util.TouchController;
 import com.android.quickstep.OverviewInteractionState;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.RecentsView;
-import com.android.systemui.shared.recents.view.RecentsTransition;
 
 public class UiFactory {
 
     private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
             "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
 
-    public static final boolean USE_HARDWARE_BITMAP = false; // FeatureFlags.IS_DOGFOOD_BUILD;
-
     public static TouchController[] createTouchControllers(Launcher launcher) {
         if (FeatureFlags.ENABLE_TWO_SWIPE_TARGETS) {
             return new TouchController[] {
@@ -72,17 +66,6 @@
                 || !launcher.isInState(NORMAL) || !launcher.hasWindowFocus());
     }
 
-    public static Bitmap createFromRenderer(int width, int height, boolean forceSoftwareRenderer,
-            BitmapRenderer renderer) {
-        if (USE_HARDWARE_BITMAP && !forceSoftwareRenderer) {
-            return RecentsTransition.createHardwareBitmap(width, height, renderer::render);
-        } else {
-            Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-            renderer.render(new Canvas(result));
-            return result;
-        }
-    }
-
     public static void resetOverview(Launcher launcher) {
         RecentsView recents = launcher.getOverviewPanel();
         recents.reset();
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index d0581a2..f4ae62a 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -45,12 +45,10 @@
 
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.graphics.BitmapInfo;
-import com.android.launcher3.graphics.ColorExtractor;
+import com.android.launcher3.graphics.BitmapRenderer;
 import com.android.launcher3.graphics.LauncherIcons;
 import com.android.launcher3.model.PackageItemInfo;
-import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.Preconditions;
@@ -126,7 +124,7 @@
         // automatically be loaded as ALPHA_8888.
         mLowResOptions.inPreferredConfig = Bitmap.Config.RGB_565;
 
-        if (UiFactory.USE_HARDWARE_BITMAP) {
+        if (BitmapRenderer.USE_HARDWARE_BITMAP) {
             mHighResOptions = new BitmapFactory.Options();
             mHighResOptions.inPreferredConfig = Bitmap.Config.HARDWARE;
         } else {
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index 1c6f77c..5576d91 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -36,7 +36,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.folder.PreviewBackground;
-import com.android.launcher3.uioverrides.UiFactory;
+import com.android.launcher3.graphics.BitmapRenderer;
 import com.android.launcher3.util.Preconditions;
 
 /**
@@ -113,7 +113,7 @@
         final float previewShiftX = shiftFactor * previewWidth;
         final float previewShiftY = shiftFactor * previewHeight;
 
-        Bitmap previewBitmap = UiFactory.createFromRenderer(previewWidth, previewHeight, false,
+        Bitmap previewBitmap = BitmapRenderer.createHardwareBitmap(previewWidth, previewHeight,
                 (canvas) -> {
                     int count = canvas.save();
                     canvas.translate(previewShiftX, previewShiftY);
diff --git a/src/com/android/launcher3/graphics/BitmapRenderer.java b/src/com/android/launcher3/graphics/BitmapRenderer.java
index 4652ded..f2a9f7c 100644
--- a/src/com/android/launcher3/graphics/BitmapRenderer.java
+++ b/src/com/android/launcher3/graphics/BitmapRenderer.java
@@ -15,9 +15,40 @@
  */
 package com.android.launcher3.graphics;
 
+import android.annotation.TargetApi;
+import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.Picture;
+import android.os.Build;
 
-public interface BitmapRenderer {
+import com.android.launcher3.Utilities;
 
-     void render(Canvas out);
+public class BitmapRenderer {
+
+     public static final boolean USE_HARDWARE_BITMAP = false && Utilities.ATLEAST_P;
+
+     public static Bitmap createSoftwareBitmap(int width, int height, Renderer renderer) {
+          Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+          renderer.draw(new Canvas(result));
+          return result;
+     }
+
+     @TargetApi(Build.VERSION_CODES.P)
+     public static Bitmap createHardwareBitmap(int width, int height, Renderer renderer) {
+          if (!USE_HARDWARE_BITMAP) {
+               return createSoftwareBitmap(width, height, renderer);
+          }
+
+          Picture picture = new Picture();
+          renderer.draw(picture.beginRecording(width, height));
+          picture.endRecording();
+          return Bitmap.createBitmap(picture);
+     }
+
+     /**
+      * Interface representing a bitmap draw operation.
+      */
+     public interface Renderer {
+          void draw(Canvas out);
+     }
 }
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index b770785..e60a2c7 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -24,19 +24,17 @@
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
-import android.graphics.Region.Op;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.view.View;
 
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.widget.LauncherAppWidgetHostView;
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.UiThreadHelper;
+import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
 import java.nio.ByteBuffer;
 
@@ -119,28 +117,26 @@
      * Responsibility for the bitmap is transferred to the caller.
      */
     public Bitmap createDragBitmap() {
-        float scale = 1f;
         int width = mView.getWidth();
         int height = mView.getHeight();
 
-        boolean forceSoftwareRenderer = false;
         if (mView instanceof BubbleTextView) {
             Drawable d = ((BubbleTextView) mView).getIcon();
             Rect bounds = getDrawableBounds(d);
             width = bounds.width();
             height = bounds.height();
         } else if (mView instanceof LauncherAppWidgetHostView) {
-            scale = ((LauncherAppWidgetHostView) mView).getScaleToFit();
+            float scale = ((LauncherAppWidgetHostView) mView).getScaleToFit();
             width = (int) (mView.getWidth() * scale);
             height = (int) (mView.getHeight() * scale);
 
             // Use software renderer for widgets as we know that they already work
-            forceSoftwareRenderer = true;
+            return BitmapRenderer.createSoftwareBitmap(width + blurSizeOutline,
+                    height + blurSizeOutline, (c) -> drawDragView(c, scale));
         }
 
-        final float scaleFinal = scale;
-        return UiFactory.createFromRenderer(width + blurSizeOutline, height + blurSizeOutline,
-                forceSoftwareRenderer, (c) -> drawDragView(c, scaleFinal));
+        return BitmapRenderer.createHardwareBitmap(width + blurSizeOutline,
+                height + blurSizeOutline, (c) -> drawDragView(c, 1));
     }
 
     public final void generateDragOutline(Bitmap preview) {
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 8abfdea..4a9cdd9 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -52,7 +52,6 @@
 import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.Themes;
 
@@ -349,7 +348,7 @@
         final ItemInfoWithIcon badge = getShortcutInfoBadge(shortcutInfo, cache);
 
         result.color = badge.iconColor;
-        result.icon = UiFactory.createFromRenderer(mIconBitmapSize, mIconBitmapSize, false, (c) -> {
+        result.icon = BitmapRenderer.createHardwareBitmap(mIconBitmapSize, mIconBitmapSize, (c) -> {
             getShadowGenerator().recreateIcon(unbadgedfinal, c);
             badgeWithDrawable(c, new FastBitmapDrawable(badge));
         });
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index a16ae48..de75ac9 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -16,25 +16,17 @@
 
 package com.android.launcher3.uioverrides;
 
-import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
 import android.graphics.PointF;
-import android.os.Bundle;
-import android.view.View;
 import android.view.View.AccessibilityDelegate;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherStateManager.StateHandler;
-import com.android.launcher3.graphics.BitmapRenderer;
 import com.android.launcher3.util.TouchController;
 
 public class UiFactory {
 
-    public static final boolean USE_HARDWARE_BITMAP = false;
-
     public static TouchController[] createTouchControllers(Launcher launcher) {
         return new TouchController[] {
                 new AllAppsSwipeController(launcher), new PinchToOverviewListener(launcher)};
@@ -54,13 +46,6 @@
         launcher.getStateManager().goToState(OVERVIEW);
     }
 
-    public static Bitmap createFromRenderer(int width, int height, boolean forceSoftwareRenderer,
-            BitmapRenderer renderer) {
-        Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-        renderer.render(new Canvas(result));
-        return result;
-    }
-
     public static void resetOverview(Launcher launcher) { }
 
     public static void onLauncherStateOrFocusChanged(Launcher launcher) { }