Workaround for crash in GradientDrawable

When cornerRadii is null, GradientDrawable#getCornerRadii() throws NPE
instead of returning null.

Fixes: 156035955
Change-Id: Id606fc8e46b4c44d4dbff3ec28680d7a5b8f5cb9
diff --git a/src/com/android/wallpaper/picker/CategoryFragment.java b/src/com/android/wallpaper/picker/CategoryFragment.java
index 2bab863..396d3ed 100755
--- a/src/com/android/wallpaper/picker/CategoryFragment.java
+++ b/src/com/android/wallpaper/picker/CategoryFragment.java
@@ -89,8 +89,8 @@
 import com.android.wallpaper.util.DisplayMetricsRetriever;
 import com.android.wallpaper.util.PreviewUtils;
 import com.android.wallpaper.util.ScreenSizeCalculator;
+import com.android.wallpaper.util.SizeCalculator;
 import com.android.wallpaper.util.SurfaceViewUtils;
-import com.android.wallpaper.util.TileSizeCalculator;
 import com.android.wallpaper.util.WallpaperConnection;
 import com.android.wallpaper.util.WallpaperConnection.WallpaperConnectionListener;
 import com.android.wallpaper.widget.LiveTileOverlay;
@@ -270,11 +270,11 @@
                 mBottomSheetBehavior.setPeekHeight(minimumHeight);
                 containerView.setMinimumHeight(minimumHeight);
                 ((CardView) mHomePreview.getParent())
-                        .setRadius(TileSizeCalculator.getPreviewCornerRadius(
+                        .setRadius(SizeCalculator.getPreviewCornerRadius(
                                 getActivity(), homePreviewCard.getMeasuredWidth()));
                 if (mLockscreenPreview != null) {
                     ((CardView) mLockscreenPreview.getParent())
-                            .setRadius(TileSizeCalculator.getPreviewCornerRadius(
+                            .setRadius(SizeCalculator.getPreviewCornerRadius(
                                     getActivity(), mLockscreenPreview.getMeasuredWidth()));
                 }
                 fragmentContainer.removeOnLayoutChangeListener(this);
diff --git a/src/com/android/wallpaper/picker/CategorySelectorFragment.java b/src/com/android/wallpaper/picker/CategorySelectorFragment.java
index 4094cda..733aeb1 100644
--- a/src/com/android/wallpaper/picker/CategorySelectorFragment.java
+++ b/src/com/android/wallpaper/picker/CategorySelectorFragment.java
@@ -46,7 +46,7 @@
 import com.android.wallpaper.module.InjectorProvider;
 import com.android.wallpaper.module.UserEventLogger;
 import com.android.wallpaper.util.DisplayMetricsRetriever;
-import com.android.wallpaper.util.TileSizeCalculator;
+import com.android.wallpaper.util.SizeCalculator;
 
 import com.bumptech.glide.Glide;
 
@@ -104,7 +104,7 @@
         mImageGrid.addItemDecoration(new GridPaddingDecoration(
                 getResources().getDimensionPixelSize(R.dimen.grid_padding)));
 
-        mTileSizePx = TileSizeCalculator.getCategoryTileSize(getActivity());
+        mTileSizePx = SizeCalculator.getCategoryTileSize(getActivity());
 
         mImageGrid.setAdapter(mAdapter);
 
@@ -184,7 +184,7 @@
 
     private int getNumColumns() {
         Activity activity = getActivity();
-        return activity == null ? 0 : TileSizeCalculator.getNumCategoryColumns(activity);
+        return activity == null ? 0 : SizeCalculator.getNumCategoryColumns(activity);
     }
 
 
diff --git a/src/com/android/wallpaper/picker/ImagePreviewFragment.java b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
index dda50a5..62578b1 100755
--- a/src/com/android/wallpaper/picker/ImagePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/ImagePreviewFragment.java
@@ -59,8 +59,8 @@
 import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
 import com.android.wallpaper.util.PreviewUtils;
 import com.android.wallpaper.util.ScreenSizeCalculator;
+import com.android.wallpaper.util.SizeCalculator;
 import com.android.wallpaper.util.SurfaceViewUtils;
-import com.android.wallpaper.util.TileSizeCalculator;
 import com.android.wallpaper.util.WallpaperCropUtils;
 import com.android.wallpaper.widget.BottomActionBar;
 import com.android.wallpaper.widget.WallpaperInfoView;
@@ -515,7 +515,7 @@
             int rightPadding = (int) horizontalPadding - leftPadding;
             mWorkspaceContainer.setPadding(leftPadding, topPadding, rightPadding, bottomPadding);
             ((CardView) mWorkspaceSurface.getParent())
-                    .setRadius(TileSizeCalculator.getPreviewCornerRadius(
+                    .setRadius(SizeCalculator.getPreviewCornerRadius(
                             getActivity(),
                             (int) (mWorkspaceContainer.getMeasuredWidth() - horizontalPadding)));
         }
diff --git a/src/com/android/wallpaper/picker/LivePreviewFragment.java b/src/com/android/wallpaper/picker/LivePreviewFragment.java
index 6cf08c4..07d09ee 100644
--- a/src/com/android/wallpaper/picker/LivePreviewFragment.java
+++ b/src/com/android/wallpaper/picker/LivePreviewFragment.java
@@ -67,7 +67,7 @@
 import com.android.wallpaper.compat.BuildCompat;
 import com.android.wallpaper.model.LiveWallpaperInfo;
 import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback;
-import com.android.wallpaper.util.TileSizeCalculator;
+import com.android.wallpaper.util.SizeCalculator;
 import com.android.wallpaper.util.WallpaperConnection;
 import com.android.wallpaper.widget.BottomActionBar;
 import com.android.wallpaper.widget.LiveTileOverlay;
@@ -183,7 +183,7 @@
             view.addOnLayoutChangeListener((thisView, left, top, right, bottom,
                     oldLeft, oldTop, oldRight, oldBottom) ->
                     ((CardView) mHomePreview.getParent())
-                            .setRadius(TileSizeCalculator.getPreviewCornerRadius(
+                            .setRadius(SizeCalculator.getPreviewCornerRadius(
                                     getActivity(), homePreviewCard.getMeasuredWidth()))
             );
             // TODO(chriscsli): Integrate SurfaceView utilities of home screen
diff --git a/src/com/android/wallpaper/picker/PreviewFragment.java b/src/com/android/wallpaper/picker/PreviewFragment.java
index 3daf7b9..8497524 100755
--- a/src/com/android/wallpaper/picker/PreviewFragment.java
+++ b/src/com/android/wallpaper/picker/PreviewFragment.java
@@ -25,7 +25,6 @@
 import android.content.res.Resources.NotFoundException;
 import android.content.res.TypedArray;
 import android.graphics.Insets;
-import android.graphics.drawable.GradientDrawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.util.Log;
@@ -65,6 +64,7 @@
 import com.android.wallpaper.module.WallpaperPersister.Destination;
 import com.android.wallpaper.module.WallpaperPreferences;
 import com.android.wallpaper.module.WallpaperSetter;
+import com.android.wallpaper.util.SizeCalculator;
 
 import com.google.android.material.bottomsheet.BottomSheetBehavior;
 import com.google.android.material.bottomsheet.BottomSheetBehavior.State;
@@ -234,16 +234,7 @@
         mBottomSheet = view.findViewById(getBottomSheetResId());
         setUpBottomSheetView(mBottomSheet);
 
-        // Workaround as we don't have access to bottomDialogCornerRadius, mBottomSheet radii are
-        // set to dialogCornerRadius by default.
-        GradientDrawable bottomSheetBackground = (GradientDrawable) mBottomSheet.getBackground();
-        float[] radii = bottomSheetBackground.getCornerRadii();
-        for (int i = 0; i < radii.length; i++) {
-            radii[i]*=2f;
-        }
-        bottomSheetBackground = ((GradientDrawable)bottomSheetBackground.mutate());
-        bottomSheetBackground.setCornerRadii(radii);
-        mBottomSheet.setBackground(bottomSheetBackground);
+        SizeCalculator.adjustBackgroundCornerRadius(mBottomSheet);
 
         mBottomSheetInitialState = (savedInstanceState == null) ? STATE_EXPANDED
                 : savedInstanceState.getInt(KEY_BOTTOM_SHEET_STATE, STATE_EXPANDED);
diff --git a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
index c87c4cd..bc27e49 100755
--- a/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
+++ b/src/com/android/wallpaper/picker/individual/IndividualPickerFragment.java
@@ -90,7 +90,7 @@
 import com.android.wallpaper.picker.WallpapersUiContainer;
 import com.android.wallpaper.picker.individual.SetIndividualHolder.OnSetListener;
 import com.android.wallpaper.util.DiskBasedLogger;
-import com.android.wallpaper.util.TileSizeCalculator;
+import com.android.wallpaper.util.SizeCalculator;
 import com.android.wallpaper.widget.BottomActionBar;
 import com.android.wallpaper.widget.WallpaperInfoView;
 
@@ -443,7 +443,7 @@
                              Bundle savedInstanceState) {
         View view = inflater.inflate(R.layout.fragment_individual_picker, container, false);
 
-        mTileSizePx = TileSizeCalculator.getIndividualTileSize(getActivity());
+        mTileSizePx = SizeCalculator.getIndividualTileSize(getActivity());
 
         mImageGrid = (RecyclerView) view.findViewById(R.id.wallpaper_grid);
         if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
@@ -832,7 +832,7 @@
 
     int getNumColumns() {
         Activity activity = getActivity();
-        return activity == null ? 0 : TileSizeCalculator.getNumIndividualColumns(activity);
+        return activity == null ? 0 : SizeCalculator.getNumIndividualColumns(activity);
     }
 
     /**
diff --git a/src/com/android/wallpaper/util/TileSizeCalculator.java b/src/com/android/wallpaper/util/SizeCalculator.java
similarity index 83%
rename from src/com/android/wallpaper/util/TileSizeCalculator.java
rename to src/com/android/wallpaper/util/SizeCalculator.java
index ffc799e..89f4318 100755
--- a/src/com/android/wallpaper/util/TileSizeCalculator.java
+++ b/src/com/android/wallpaper/util/SizeCalculator.java
@@ -19,8 +19,10 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Point;
+import android.graphics.drawable.GradientDrawable;
 import android.util.DisplayMetrics;
 import android.view.Display;
+import android.view.View;
 import android.view.WindowManager;
 
 import androidx.annotation.NonNull;
@@ -33,9 +35,10 @@
 
 
 /**
- * Simple utility class that calculates tile sizes relative to the size of the display.
+ * Simple utility class that calculates various sizes relative to the display or current
+ * configuration.
  */
-public class TileSizeCalculator {
+public class SizeCalculator {
     private static final int COLUMN_COUNT_THRESHOLD_DP = 732;
 
     /**
@@ -61,13 +64,13 @@
     private static final int INDIVIDUAL_MORE_COLUMNS = 4;
 
     // Suppress default constructor for noninstantiability.
-    private TileSizeCalculator() {
-        throw new AssertionError("Can't initialize a TileSizeCalculator.");
+    private SizeCalculator() {
+        throw new AssertionError("Can't initialize a SizeCalculator.");
     }
 
     /**
-     * Returns the number of columns for a grid of category tiles. Selects from fewer and more columns
-     * based on the width of the activity.
+     * Returns the number of columns for a grid of category tiles. Selects from fewer and more
+     * columns based on the width of the activity.
      */
     public static int getNumCategoryColumns(@NonNull Activity activity) {
         int windowWidthPx = getActivityWindowWidthPx(activity);
@@ -84,7 +87,8 @@
     }
 
     private static int getNumCategoryColumns(Activity activity, int windowWidthPx) {
-        return getNumColumns(activity, windowWidthPx, CATEGORY_FEWER_COLUMNS, CATEGORY_MORE_COLUMNS);
+        return getNumColumns(activity, windowWidthPx, CATEGORY_FEWER_COLUMNS,
+                CATEGORY_MORE_COLUMNS);
     }
 
     private static int getNumIndividualColumns(Activity activity, int windowWidthPx) {
@@ -94,7 +98,8 @@
 
     private static int getNumColumns(
             Context context, int windowWidthPx, int fewerCount, int moreCount) {
-        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        WindowManager windowManager = (WindowManager)
+                context.getSystemService(Context.WINDOW_SERVICE);
         Display display = windowManager.getDefaultDisplay();
 
         DisplayMetrics metrics = DisplayMetricsRetriever.getInstance()
@@ -138,8 +143,9 @@
      * individual tile size when an activity takes up the entire screen's width.
      */
     public static Point getSuggestedThumbnailSize(@NonNull Context appContext) {
-        // Category tiles are larger than individual tiles, so get the number of columns for categories
-        // and then calculate a tile size for when the app window takes up the entire display.
+        // Category tiles are larger than individual tiles, so get the number of columns for
+        // categories and then calculate a tile size for when the app window takes up the entire
+        // display.
         int windowWidthPx = getDeviceDisplayWidthPx(appContext);
         int columnCount = getNumColumns(
                 appContext, windowWidthPx, INDIVIDUAL_FEWER_COLUMNS, INDIVIDUAL_MORE_COLUMNS);
@@ -178,8 +184,8 @@
             gridPaddingPx = res.getDimensionPixelSize(R.dimen.grid_padding_desktop);
         }
 
-        // Note: don't need to multiply by density because getting the dimension from resources already
-        // does that.
+        // Note: don't need to multiply by density because getting the dimension from resources
+        // already does that.
         int guttersWidthPx = (columnCount + 1) * gridPaddingPx;
         int availableWidthPx = windowWidthPx - guttersWidthPx;
 
@@ -234,4 +240,29 @@
 
         return outPoint.x;
     }
+
+    /**
+     * Adjusts the corner radius of the given view by doubling their current values
+     *
+     * @param view whose background is set to a GradientDrawable
+     */
+    public static void adjustBackgroundCornerRadius(View view) {
+        GradientDrawable background = (GradientDrawable) view.getBackground();
+        // Using try/catch because currently GradientDrawable has a bug where when the radii array
+        // is null, instead of getCornerRadii returning null, it throws NPE.
+        try {
+            float[] radii = background.getCornerRadii();
+            if (radii == null) {
+                return;
+            }
+            for (int i = 0; i < radii.length; i++) {
+                radii[i] *= 2f;
+            }
+            background = ((GradientDrawable) background.mutate());
+            background.setCornerRadii(radii);
+            view.setBackground(background);
+        } catch (NullPointerException e) {
+            //Ignore in this case, since it means the radius was 0.
+        }
+    }
 }
diff --git a/src/com/android/wallpaper/widget/BottomActionBar.java b/src/com/android/wallpaper/widget/BottomActionBar.java
index 69b73ba..b87e8ea 100644
--- a/src/com/android/wallpaper/widget/BottomActionBar.java
+++ b/src/com/android/wallpaper/widget/BottomActionBar.java
@@ -20,7 +20,6 @@
 
 import android.app.Activity;
 import android.content.Context;
-import android.graphics.drawable.GradientDrawable;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -33,6 +32,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.wallpaper.R;
+import com.android.wallpaper.util.SizeCalculator;
 
 import com.google.android.material.bottomsheet.BottomSheetBehavior;
 import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback;
@@ -86,16 +86,7 @@
         mActionMap.put(BottomAction.APPLY, findViewById(R.id.action_apply));
 
         mBottomSheetView = findViewById(R.id.action_bottom_sheet);
-        // Workaround as we don't have access to bottomDialogCornerRadius, mBottomSheet radii are
-        // set to dialogCornerRadius by default.
-        GradientDrawable background = (GradientDrawable) mBottomSheetView.getBackground();
-        float[] radii = background.getCornerRadii();
-        for (int i = 0; i < radii.length; i++) {
-            radii[i] *= 2f;
-        }
-        background = ((GradientDrawable) background.mutate());
-        background.setCornerRadii(radii);
-        mBottomSheetView.setBackground(background);
+        SizeCalculator.adjustBackgroundCornerRadius(mBottomSheetView);
 
         mBottomSheetBehavior = BottomSheetBehavior.from(mBottomSheetView);
         mBottomSheetBehavior.setState(STATE_COLLAPSED);