diff --git a/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_drawer.png b/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_drawer.png index a20e7280b4..be47302cb0 100644 Binary files a/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_drawer.png and b/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_drawer.png differ diff --git a/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_open.png b/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_open.png index a7896adb5c..78f13a1e93 100644 Binary files a/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_open.png and b/screenshots/gplay/debug/com.nextcloud.client.FileDisplayActivityScreenshotIT_open.png differ diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png b/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png index 793fc3768b..bab3c63e9e 100644 Binary files a/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png and b/screenshots/gplay/debug/com.owncloud.android.ui.activity.ManageAccountsActivityIT_open.png differ diff --git a/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png b/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png index 69d4abdb45..5f0ec53953 100644 Binary files a/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png and b/screenshots/gplay/debug/com.owncloud.android.ui.dialog.DialogFragmentIT_testAccountChooserDialog.png differ diff --git a/scripts/analysis/findbugs-results.txt b/scripts/analysis/findbugs-results.txt index 9573848579..18eed1357e 100644 --- a/scripts/analysis/findbugs-results.txt +++ b/scripts/analysis/findbugs-results.txt @@ -1 +1 @@ -326 \ No newline at end of file +320 diff --git a/src/androidTest/java/com/owncloud/android/utils/BitmapUtilsIT.kt b/src/androidTest/java/com/owncloud/android/utils/BitmapUtilsIT.kt new file mode 100644 index 0000000000..abe4c722e6 --- /dev/null +++ b/src/androidTest/java/com/owncloud/android/utils/BitmapUtilsIT.kt @@ -0,0 +1,79 @@ +/* + * + * Nextcloud Android client application + * + * @author Tobias Kaminsky + * Copyright (C) 2020 Tobias Kaminsky + * Copyright (C) 2020 Nextcloud GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +package com.owncloud.android.utils + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotEquals +import org.junit.Test + +class BitmapUtilsIT { + @Test + @Suppress("MagicNumber") + fun usernameToColor() { + assertEquals(BitmapUtils.Color(0, 0, 0), BitmapUtils.Color(0, 0, 0)) + assertEquals(BitmapUtils.Color(221, 203, 85), BitmapUtils.usernameToColor("User")) + assertEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.usernameToColor("Admin")) + assertEquals(BitmapUtils.Color(0, 130, 201), BitmapUtils.usernameToColor("")) + assertEquals(BitmapUtils.Color(201, 136, 121), BitmapUtils.usernameToColor("68b329da9893e34099c7d8ad5cb9c940")) + + // tests from server + assertEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.usernameToColor("Alishia Ann Lowry")) + assertEquals(BitmapUtils.Color(0, 130, 201), BitmapUtils.usernameToColor("Arham Johnson")) + assertEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.usernameToColor("Brayden Truong")) + assertEquals(BitmapUtils.Color(151, 80, 164), BitmapUtils.usernameToColor("Daphne Roy")) + assertEquals(BitmapUtils.Color(195, 114, 133), BitmapUtils.usernameToColor("Ellena Wright Frederic Conway")) + assertEquals(BitmapUtils.Color(214, 180, 97), BitmapUtils.usernameToColor("Gianluca Hills")) + assertEquals(BitmapUtils.Color(214, 180, 97), BitmapUtils.usernameToColor("Haseeb Stephens")) + assertEquals(BitmapUtils.Color(151, 80, 164), BitmapUtils.usernameToColor("Idris Mac")) + assertEquals(BitmapUtils.Color(0, 130, 201), BitmapUtils.usernameToColor("Kristi Fisher")) + assertEquals(BitmapUtils.Color(188, 92, 145), BitmapUtils.usernameToColor("Lillian Wall")) + assertEquals(BitmapUtils.Color(221, 203, 85), BitmapUtils.usernameToColor("Lorelai Taylor")) + assertEquals(BitmapUtils.Color(151, 80, 164), BitmapUtils.usernameToColor("Madina Knight")) + assertEquals(BitmapUtils.Color(121, 90, 171), BitmapUtils.usernameToColor("Rae Hope")) + assertEquals(BitmapUtils.Color(188, 92, 145), BitmapUtils.usernameToColor("Santiago Singleton")) + assertEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.usernameToColor("Sid Combs")) + assertEquals(BitmapUtils.Color(30, 120, 193), BitmapUtils.usernameToColor("Vivienne Jacobs")) + assertEquals(BitmapUtils.Color(110, 166, 143), BitmapUtils.usernameToColor("Zaki Cortes")) + assertEquals(BitmapUtils.Color(91, 100, 179), BitmapUtils.usernameToColor("a user")) + assertEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.usernameToColor("admin")) + assertEquals(BitmapUtils.Color(151, 80, 164), BitmapUtils.usernameToColor("admin@cloud.example.com")) + assertEquals(BitmapUtils.Color(221, 203, 85), BitmapUtils.usernameToColor("another user")) + assertEquals(BitmapUtils.Color(36, 142, 181), BitmapUtils.usernameToColor("asd")) + assertEquals(BitmapUtils.Color(0, 130, 201), BitmapUtils.usernameToColor("bar")) + assertEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.usernameToColor("foo")) + assertEquals(BitmapUtils.Color(182, 70, 157), BitmapUtils.usernameToColor("wasd")) + } + + @Test + @Suppress("MagicNumber") + fun checkEqual() { + assertEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.Color(208, 158, 109)) + assertNotEquals(BitmapUtils.Color(208, 158, 109), BitmapUtils.Color(208, 158, 100)) + } + + @Test + @Suppress("MagicNumber") + fun checkHashCode() { + assertEquals(BitmapUtils.Color(208, 158, 109).hashCode(), BitmapUtils.Color(208, 158, 109).hashCode()) + assertNotEquals(BitmapUtils.Color(208, 158, 109).hashCode(), BitmapUtils.Color(208, 158, 100).hashCode()) + } +} diff --git a/src/main/java/com/nextcloud/client/account/UserAccountManager.java b/src/main/java/com/nextcloud/client/account/UserAccountManager.java index 5d864f0a66..8eca155bf4 100644 --- a/src/main/java/com/nextcloud/client/account/UserAccountManager.java +++ b/src/main/java/com/nextcloud/client/account/UserAccountManager.java @@ -20,12 +20,15 @@ package com.nextcloud.client.account; import android.accounts.Account; +import android.accounts.AccountManager; import android.app.Activity; import android.content.Intent; import com.nextcloud.java.util.Optional; +import com.owncloud.android.MainApp; import com.owncloud.android.datamodel.OCFile; import com.owncloud.android.lib.common.OwnCloudAccount; +import com.owncloud.android.lib.common.accounts.AccountUtils; import com.owncloud.android.lib.resources.status.OwnCloudVersion; import java.util.List; @@ -154,13 +157,14 @@ public interface UserAccountManager extends CurrentAccountProvider { /** * Extract username from account. - * + *

* Full account name is in form of "username@nextcloud.domain". * * @param account Account instance * @return User name (without domain) or null, if name cannot be extracted. */ - static String getUsername(Account account) { + static @Nullable + String getUsername(Account account) { if (account != null && account.name != null) { return account.name.substring(0, account.name.lastIndexOf('@')); } else { @@ -168,9 +172,15 @@ public interface UserAccountManager extends CurrentAccountProvider { } } + static @Nullable + String getDisplayName(Account account) { + return AccountManager.get(MainApp.getAppContext()).getUserData(account, + AccountUtils.Constants.KEY_DISPLAY_NAME); + } + /** * Launch account registration activity. - * + *

* This method returns immediately. Authenticator activity will be launched asynchronously. * * @param activity Activity used to launch authenticator flow via {@link Activity#startActivity(Intent)} diff --git a/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java b/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java index 02641a98ba..6b527d2a78 100644 --- a/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java +++ b/src/main/java/com/owncloud/android/datamodel/ThumbnailsCacheManager.java @@ -1136,13 +1136,10 @@ public final class ThumbnailsCacheManager { } public static class AsyncMediaThumbnailDrawable extends BitmapDrawable { - private final WeakReference bitmapWorkerTaskReference; - public AsyncMediaThumbnailDrawable(Resources res, Bitmap bitmap, - MediaThumbnailGenerationTask bitmapWorkerTask) { + public AsyncMediaThumbnailDrawable(Resources res, Bitmap bitmap) { super(res, bitmap); - bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask); } } diff --git a/src/main/java/com/owncloud/android/ui/TextDrawable.java b/src/main/java/com/owncloud/android/ui/TextDrawable.java index 3e5f45e715..f2106f1b5f 100644 --- a/src/main/java/com/owncloud/android/ui/TextDrawable.java +++ b/src/main/java/com/owncloud/android/ui/TextDrawable.java @@ -69,19 +69,17 @@ public class TextDrawable extends Drawable { * Create a TextDrawable with the given radius. * * @param text the text to be rendered - * @param r rgb red value - * @param g rgb green value - * @param b rgb blue value + * @param color color * @param radius circle radius */ - public TextDrawable(String text, int r, int g, int b, float radius) { + public TextDrawable(String text, BitmapUtils.Color color, float radius) { mRadius = radius; mText = text; mBackground = new Paint(); mBackground.setStyle(Paint.Style.FILL); mBackground.setAntiAlias(true); - mBackground.setColor(Color.rgb(r, g, b)); + mBackground.setColor(Color.rgb(color.r, color.g, color.b)); mTextPaint = new Paint(); mTextPaint.setColor(Color.WHITE); @@ -101,8 +99,9 @@ public class TextDrawable extends Drawable { */ @NonNull @NextcloudServer(max = 12) - public static TextDrawable createAvatar(Account account, float radiusInDp) throws NoSuchAlgorithmException { - String username = UserAccountManager.getUsername(account); + public static TextDrawable createAvatar(Account account, float radiusInDp) throws + NoSuchAlgorithmException { + String username = UserAccountManager.getDisplayName(account); return createNamedAvatar(username, radiusInDp); } @@ -132,11 +131,8 @@ public class TextDrawable extends Drawable { */ @NonNull public static TextDrawable createNamedAvatar(String name, float radiusInDp) throws NoSuchAlgorithmException { - int[] hsl = BitmapUtils.calculateHSL(name); - int[] rgb = BitmapUtils.HSLtoRGB(hsl[0], hsl[1], hsl[2], 1); - - return new TextDrawable(extractCharsFromDisplayName(name), rgb[0], rgb[1], rgb[2], - radiusInDp); + BitmapUtils.Color color = BitmapUtils.usernameToColor(name); + return new TextDrawable(extractCharsFromDisplayName(name), color, radiusInDp); } @VisibleForTesting diff --git a/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java b/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java index 7720eb7f11..89bbff62d2 100644 --- a/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java +++ b/src/main/java/com/owncloud/android/ui/adapter/SyncedFolderAdapter.java @@ -337,8 +337,7 @@ public class SyncedFolderAdapter extends SectionedRecyclerViewAdapter private constructor } /** - * Decodes a bitmap from a file containing it minimizing the memory use, known that the bitmap - * will be drawn in a surface of reqWidth x reqHeight + * Decodes a bitmap from a file containing it minimizing the memory use, known that the bitmap will be drawn in a + * surface of reqWidth x reqHeight * - * @param srcPath Absolute path to the file containing the image. - * @param reqWidth Width of the surface where the Bitmap will be drawn on, in pixels. - * @param reqHeight Height of the surface where the Bitmap will be drawn on, in pixels. + * @param srcPath Absolute path to the file containing the image. + * @param reqWidth Width of the surface where the Bitmap will be drawn on, in pixels. + * @param reqHeight Height of the surface where the Bitmap will be drawn on, in pixels. * @return decoded bitmap */ public static Bitmap decodeSampledBitmapFromFile(String srcPath, int reqWidth, int reqHeight) { @@ -93,16 +88,14 @@ public final class BitmapUtils { /** - * Calculates a proper value for options.inSampleSize in order to decode a Bitmap minimizing - * the memory overload and covering a target surface of reqWidth x reqHeight if the original - * image is big enough. + * Calculates a proper value for options.inSampleSize in order to decode a Bitmap minimizing the memory overload and + * covering a target surface of reqWidth x reqHeight if the original image is big enough. * - * @param options Bitmap decoding options; options.outHeight and options.inHeight should - * be set. - * @param reqWidth Width of the surface where the Bitmap will be drawn on, in pixels. - * @param reqHeight Height of the surface where the Bitmap will be drawn on, in pixels. - * @return The largest inSampleSize value that is a power of 2 and keeps both - * height and width larger than reqWidth and reqHeight. + * @param options Bitmap decoding options; options.outHeight and options.inHeight should be set. + * @param reqWidth Width of the surface where the Bitmap will be drawn on, in pixels. + * @param reqHeight Height of the surface where the Bitmap will be drawn on, in pixels. + * @return The largest inSampleSize value that is a power of 2 and keeps both height and width larger than reqWidth + * and reqHeight. */ public static int calculateSampleFactor(Options options, int reqWidth, int reqHeight) { @@ -142,9 +135,9 @@ public final class BitmapUtils { } /** - * Rotate bitmap according to EXIF orientation. - * Cf. http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/ - * @param bitmap Bitmap to be rotated + * Rotate bitmap according to EXIF orientation. Cf. http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/ + * + * @param bitmap Bitmap to be rotated * @param storagePath Path to source file of bitmap. Needed for EXIF information. * @return correctly EXIF-rotated bitmap */ @@ -201,167 +194,115 @@ public final class BitmapUtils { return resultBitmap; } - /** - * Convert HSL values to a RGB Color. - * - * @param h Hue is specified as degrees in the range 0 - 360. - * @param s Saturation is specified as a percentage in the range 1 - 100. - * @param l Luminance is specified as a percentage in the range 1 - 100. - * @param alpha the alpha value between 0 - 1 - * adapted from https://svn.codehaus.org/griffon/builders/gfxbuilder/tags/GFXBUILDER_0.2/ - * gfxbuilder-core/src/main/com/camick/awt/HSLColor.java - */ - @SuppressWarnings("PMD.MethodNamingConventions") - public static int[] HSLtoRGB(float h, float s, float l, float alpha) { - if (s < 0.0f || s > 100.0f) { - String message = "Color parameter outside of expected range - Saturation"; - throw new IllegalArgumentException(message); - } + public static Color usernameToColor(String name) throws NoSuchAlgorithmException { + String hash = name.toLowerCase(Locale.ROOT); - if (l < 0.0f || l > 100.0f) { - String message = "Color parameter outside of expected range - Luminance"; - throw new IllegalArgumentException(message); - } - - if (alpha < 0.0f || alpha > 1.0f) { - String message = "Color parameter outside of expected range - Alpha"; - throw new IllegalArgumentException(message); - } - - // Formula needs all values between 0 - 1. - - h = h % 360.0f; - h /= 360f; - s /= 100f; - l /= 100f; - - float q; - - if (l < 0.5) { - q = l * (1 + s); - } else { - q = (l + s) - (s * l); - } - - float p = 2 * l - q; - - int r = Math.round(Math.max(0, HueToRGB(p, q, h + (1.0f / 3.0f)) * 256)); - int g = Math.round(Math.max(0, HueToRGB(p, q, h) * 256)); - int b = Math.round(Math.max(0, HueToRGB(p, q, h - (1.0f / 3.0f)) * 256)); - - return new int[]{r, g, b}; - } - - @SuppressWarnings("PMD.MethodNamingConventions") - private static float HueToRGB(float p, float q, float h) { - if (h < 0) { - h += 1; - } - - if (h > 1) { - h -= 1; - } - - if (6 * h < 1) { - return p + ((q - p) * 6 * h); - } - - if (2 * h < 1) { - return q; - } - - if (3 * h < 2) { - return p + ((q - p) * 6 * (2.0f / 3.0f - h)); - } - - return p; - } - - /** - * calculates the RGB value based on a given account name. - * - * @param name The name - * @return corresponding RGB color - * @throws NoSuchAlgorithmException if the specified algorithm is not available - */ - public static int[] calculateHSL(String name) throws NoSuchAlgorithmException { - // using adapted algorithm from https://github.com/nextcloud/server/blob/master/core/js/placeholder.js#L126 - - String[] result = new String[]{"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"}; - double[] rgb = new double[]{0, 0, 0}; - int sat = 70; - int lum = 68; - int modulo = 16; - - String hash = name.toLowerCase(Locale.ROOT).replaceAll("[^0-9a-f]", ""); - - if (!hash.matches("^[0-9a-f]{32}")) { + // already a md5 hash? + if (!hash.matches("([0-9a-f]{4}-?){8}$")) { hash = md5(hash); } - // Splitting evenly the string - for (int i = 0; i < hash.length(); i++) { - result[i % modulo] = result[i % modulo] + Integer.parseInt(hash.substring(i, i + 1), 16); - } + hash = hash.replaceAll("[^0-9a-f]", ""); + int steps = 6; - // Converting our data into a usable rgb format - // Start at 1 because 16%3=1 but 15%3=0 and makes the repartition even - for (int count = 1; count < modulo; count++) { - rgb[count % 3] += Integer.parseInt(result[count]); - } + Color[] finalPalette = generateColors(steps); - // Reduce values bigger than rgb requirements - rgb[INDEX_RED] = rgb[INDEX_RED] % 255; - rgb[INDEX_GREEN] = rgb[INDEX_GREEN] % 255; - rgb[INDEX_BLUE] = rgb[INDEX_BLUE] % 255; - - double[] hsl = rgbToHsl(rgb[INDEX_RED], rgb[INDEX_GREEN], rgb[INDEX_BLUE]); - - // Classic formula to check the brightness for our eye - // If too bright, lower the sat - double bright = Math.sqrt(0.299 * Math.pow(rgb[INDEX_RED], 2) + 0.587 * Math.pow(rgb[INDEX_GREEN], 2) + 0.114 - * Math.pow(rgb[INDEX_BLUE], 2)); - - if (bright >= 200) { - sat = 60; - } - - return new int[]{(int) (hsl[INDEX_HUE] * 360), sat, lum}; + return finalPalette[hashToInt(hash, steps * 3)]; } - private static double[] rgbToHsl(double rUntrimmed, double gUntrimmed, double bUntrimmed) { - double r = rUntrimmed / 255; - double g = gUntrimmed / 255; - double b = bUntrimmed / 255; + private static int hashToInt(String hash, int maximum) { + int finalInt = 0; + int[] result = new int[hash.length()]; - double max = Math.max(r, Math.max(g, b)); - double min = Math.min(r, Math.min(g, b)); - double h = (max + min) / 2; - double s; - double l = (max + min) / 2; - - if (max == min) { - h = s = 0; // achromatic - } else { - double d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - if (max == r) { - h = (g - b) / d + (g < b ? 6 : 0); - } else if (max == g) { - h = (b - r) / d + 2; - } else if (max == b) { - h = (r - g) / d + 4; - } - h /= 6; + // splitting evenly the string + for (int i = 0; i < hash.length(); i++) { + // chars in md5 goes up to f, hex: 16 + result[i] = Integer.parseInt(String.valueOf(hash.charAt(i)), 16) % 16; } - double[] hsl = new double[]{0.0, 0.0, 0.0}; - hsl[INDEX_HUE] = h; - hsl[INDEX_SATURATION] = s; - hsl[INDEX_LUMINATION] = l; + // adds up all results + for (int value : result) { + finalInt += value; + } - return hsl; + // chars in md5 goes up to f, hex:16 + // make sure we're always using int in our operation + return Integer.parseInt(String.valueOf(Integer.parseInt(String.valueOf(finalInt), 10) % maximum), 10); + } + + private static Color[] generateColors(int steps) { + Color red = new Color(182, 70, 157); + Color yellow = new Color(221, 203, 85); + Color blue = new Color(0, 130, 201); // Nextcloud blue + + Color[] palette1 = mixPalette(steps, red, yellow); + Color[] palette2 = mixPalette(steps, yellow, blue); + Color[] palette3 = mixPalette(steps, blue, red); + + Color[] resultPalette = new Color[palette1.length + palette2.length + palette3.length]; + System.arraycopy(palette1, 0, resultPalette, 0, palette1.length); + System.arraycopy(palette2, 0, resultPalette, palette1.length, palette2.length); + System.arraycopy(palette3, + 0, + resultPalette, + palette1.length + palette2.length, + palette1.length); + + return resultPalette; + } + + @SuppressFBWarnings("CLI_CONSTANT_LIST_INDEX") + private static Color[] mixPalette(int steps, Color color1, Color color2) { + Color[] palette = new Color[steps]; + palette[0] = color1; + + float[] step = stepCalc(steps, color1, color2); + for (int i = 1; i < steps; i++) { + int r = (int) (color1.r + step[0] * i); + int g = (int) (color1.g + step[1] * i); + int b = (int) (color1.b + step[2] * i); + + palette[i] = new Color(r, g, b); + } + + return palette; + } + + private static float[] stepCalc(int steps, Color color1, Color color2) { + float[] step = new float[3]; + + step[0] = (color2.r - color1.r) / (float) steps; + step[1] = (color2.g - color1.g) / (float) steps; + step[2] = (color2.b - color1.b) / (float) steps; + + return step; + } + + public static class Color { + public int r; + public int g; + public int b; + + public Color(int r, int g, int b) { + this.r = r; + this.g = g; + this.b = b; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (!(obj instanceof Color)) { + return false; + } + + Color other = (Color) obj; + return this.r == other.r && this.g == other.g && this.b == other.b; + } + + @Override + public int hashCode() { + return r * 10000 + g * 1000 + b; + } } public static String md5(String string) throws NoSuchAlgorithmException { @@ -372,11 +313,11 @@ public final class BitmapUtils { } /** - * Returns a new circular bitmap drawable by creating it from a bitmap, setting initial target density based on - * the display metrics of the resources. + * Returns a new circular bitmap drawable by creating it from a bitmap, setting initial target density based on the + * display metrics of the resources. * * @param resources the resources for initial target density - * @param bitmap the original bitmap + * @param bitmap the original bitmap * @return the circular bitmap */ public static RoundedBitmapDrawable bitmapToCircularBitmapDrawable(Resources resources, @@ -420,7 +361,7 @@ public final class BitmapUtils { bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); } else { bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), - Bitmap.Config.ARGB_8888); + Bitmap.Config.ARGB_8888); } Canvas canvas = new Canvas(bitmap); @@ -436,14 +377,14 @@ public final class BitmapUtils { imageView); } - public static void setRoundedBitmapForGridMode(Bitmap thumbnail, ImageView imageView){ + public static void setRoundedBitmapForGridMode(Bitmap thumbnail, ImageView imageView) { BitmapUtils.setRoundedBitmap(getResources(), thumbnail, getResources().getDimension(R.dimen.file_icon_rounded_corner_radius_for_grid_mode), imageView); } - private static Resources getResources(){ + private static Resources getResources() { return MainApp.getAppContext().getResources(); } }