From c11e03b451d6e23d03d53716c6c54c737f59e060 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Wed, 7 Aug 2024 17:38:51 -0600 Subject: [PATCH] widget: use system display size for widget bitmap size May have introduced some variation by accident by using the smaller limit. --- .../oxycblt/auxio/widgets/WidgetComponent.kt | 4 ++-- .../org/oxycblt/auxio/widgets/WidgetUtil.kt | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt index 8179e2ab8..0866c07dc 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt @@ -99,7 +99,7 @@ constructor( return if (cornerRadius > 0) { // If rounded, reduce the bitmap size further to obtain more pronounced // rounded corners. - builder.size(getSafeRemoteViewsImageSize(context, 10f)) + builder.size(getSafeRemoteViewsImageSize(10f)) val cornersTransformation = RoundedRectTransformation(cornerRadius.toFloat()) if (imageSettings.forceSquareCovers) { @@ -112,7 +112,7 @@ constructor( if (imageSettings.forceSquareCovers) { builder.transformations(SquareCropTransformation.INSTANCE) } - builder.size(getSafeRemoteViewsImageSize(context)) + builder.size(getSafeRemoteViewsImageSize()) } } diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetUtil.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetUtil.kt index 799aa8a67..2722dd8bd 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetUtil.kt @@ -21,6 +21,7 @@ package org.oxycblt.auxio.widgets import android.appwidget.AppWidgetManager import android.content.ComponentName import android.content.Context +import android.content.res.Resources import android.os.Build import android.util.SizeF import android.widget.RemoteViews @@ -31,6 +32,7 @@ import kotlin.math.sqrt import org.oxycblt.auxio.util.isLandscape import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.newMainPendingIntent +import kotlin.math.min /** * Create a [RemoteViews] instance with the specified layout and an automatic click handler to open @@ -46,6 +48,8 @@ fun newRemoteViews(context: Context, @LayoutRes layoutRes: Int): RemoteViews { return views } +const val MINIMUM_OBSERVED_MAX_SAFE_BITMAP_SIZE = 6912000 * 0.95f // 95% slack + /** * Get an image size guaranteed to not exceed the [RemoteViews] bitmap memory limit, assuming that * there is only one image. @@ -55,13 +59,18 @@ fun newRemoteViews(context: Context, @LayoutRes layoutRes: Int): RemoteViews { * device-specific variations in memory limit. * @return The dimension of a bitmap that can be safely used in [RemoteViews]. */ -fun getSafeRemoteViewsImageSize(context: Context, reduce: Float = 2f): Int { - val metrics = context.resources.displayMetrics +fun getSafeRemoteViewsImageSize(reduce: Float = 2f): Int { + val metrics = Resources.getSystem().displayMetrics val sw = metrics.widthPixels val sh = metrics.heightPixels - // Maximum size is 1/3 total screen area * 4 bytes per pixel. Reverse - // that to obtain the image size. - return sqrt((6f / 4f / reduce) * sw * sh).toInt() + + // Cap memory usage at 1.5 times the size of the display + // 1.5 * 4 bytes/pixel * w * h ==> 6 * w * h + // https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java + val maxWidgetBitmapMemory = 6 * sw * sh + val maxBitmapArea = (maxWidgetBitmapMemory / 4) / reduce + val maxBitmapSize = sqrt(maxBitmapArea).toInt() + return maxBitmapSize; } /**