widgets: fix insanity

Fix two issues where Auxio's widget could not be resized to a single
cell, and another where covers would not load into the widget.

The first is caused by a random, subtle change that completely changed
up the minHeight size calculation regarding widgets. Thus, we need to
lower it for android to recognize it still as 1 cell. I cannot believe
we can't just specify the specific minimum grid size that our widget
takes up, like you know, iOS did, nearly a decade after widgets were
first added in Android.

The second is an absurd race condition stemming from me hitting the
RemoteViews memory limit. Turns out my cover bitmaps were simply too
big. Getting them below the limit requires me to resize them to a puny
~500 pixels. Why can't we just render our own views into our widget?
You know, like iOS did, nearly a decade after widgets were first added
to Android.

Nah, screw modernizing the broken widget API. Let's just vaguely copy
iOS widgets because we have to while not fixing a single issue plaguing
widget development on this OS. That way some google engineer can get
promoted faster.
This commit is contained in:
OxygenCobalt 2022-07-30 20:35:46 -06:00
parent c3d8509069
commit 170cdf80ef
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
5 changed files with 19 additions and 20 deletions

View file

@ -11,7 +11,7 @@ android {
defaultConfig { defaultConfig {
applicationId namespace applicationId namespace
versionName "2.6.0-beta" versionName "2.5.0"
versionCode 19 versionCode 19
// API 33 is still busted, waiting until the XML element issue is fixed // API 33 is still busted, waiting until the XML element issue is fixed

View file

@ -22,6 +22,7 @@ import android.graphics.Bitmap
import android.os.Build import android.os.Build
import coil.request.ImageRequest import coil.request.ImageRequest
import coil.transform.RoundedCornersTransformation import coil.transform.RoundedCornersTransformation
import kotlin.math.sqrt
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.image.BitmapProvider import org.oxycblt.auxio.image.BitmapProvider
import org.oxycblt.auxio.image.SquareFrameTransform import org.oxycblt.auxio.image.SquareFrameTransform
@ -93,23 +94,27 @@ class WidgetComponent(private val context: Context) :
0 0
} }
// Resize the image in a such a way that we don't hit the RemoteView size
// limit. The limit is technically the byte-size of an RGB_8888 bitmap 1.5x
// the screen size, but the size of a RemoteView can for some reason be 10x
// the size of the binded bitmaps, which means we need to heavily reduce
// our image size as to make sure we stay around an order of magnitude below
// the memory limit. This fixed size is also needed to ensure consistent
// outlines on rounded images.
val metrics = context.resources.displayMetrics
val sw = metrics.widthPixels
val sh = metrics.heightPixels
builder.size((sqrt((6f * sw * sh)) / 8f).toInt())
return if (cornerRadius > 0) { return if (cornerRadius > 0) {
this@WidgetComponent.logD("Loading round covers: $cornerRadius") this@WidgetComponent.logD("Loading round covers: $cornerRadius")
val metrics = context.resources.displayMetrics
// Use RoundedCornersTransformation. This is because our hack to get a 1:1 // Use RoundedCornersTransformation. This is because our hack to get a 1:1
// aspect ratio on widget ImageViews doesn't actually result in a square // aspect ratio on widget ImageViews doesn't actually result in a square
// ImageView, so clipToOutline won't work. // ImageView, so clipToOutline won't work.
builder builder.transformations(
.transformations(
SquareFrameTransform.INSTANCE, SquareFrameTransform.INSTANCE,
RoundedCornersTransformation(cornerRadius.toFloat())) RoundedCornersTransformation(cornerRadius.toFloat()))
// The output of RoundedCornersTransformation is dimension-dependent,
// so scale up the image to the screen size to ensure consistent radii.
// Make sure we stop at 1024, so we don't accidentally make a massive
// bitmap on very large screens.
.size(minOf(metrics.widthPixels, metrics.heightPixels, 1024))
} else { } else {
builder builder
} }

View file

@ -53,8 +53,6 @@
<dimen name="recycler_fab_space_normal">88dp</dimen> <dimen name="recycler_fab_space_normal">88dp</dimen>
<dimen name="recycler_fab_space_large">128dp</dimen> <dimen name="recycler_fab_space_large">128dp</dimen>
<dimen name="widget_width_min">176dp</dimen> <dimen name="widget_width_def">176dp</dimen>
<dimen name="widget_height_min">110dp</dimen> <dimen name="widget_height_def">100dp</dimen>
<dimen name="widget_width_def">@dimen/widget_width_min</dimen>
<dimen name="widget_height_def">@dimen/widget_height_min</dimen>
</resources> </resources>

View file

@ -4,8 +4,6 @@
android:initialLayout="@layout/widget_default" android:initialLayout="@layout/widget_default"
android:minWidth="@dimen/widget_width_def" android:minWidth="@dimen/widget_width_def"
android:minHeight="@dimen/widget_height_def" android:minHeight="@dimen/widget_height_def"
android:minResizeWidth="@dimen/widget_width_min"
android:minResizeHeight="@dimen/widget_height_min"
android:previewImage="@drawable/ui_widget_preview" android:previewImage="@drawable/ui_widget_preview"
android:previewLayout="@layout/widget_small" android:previewLayout="@layout/widget_small"
android:resizeMode="horizontal|vertical" android:resizeMode="horizontal|vertical"

View file

@ -3,8 +3,6 @@
android:initialLayout="@layout/widget_default" android:initialLayout="@layout/widget_default"
android:minWidth="@dimen/widget_width_def" android:minWidth="@dimen/widget_width_def"
android:minHeight="@dimen/widget_height_def" android:minHeight="@dimen/widget_height_def"
android:minResizeWidth="@dimen/widget_width_min"
android:minResizeHeight="@dimen/widget_height_min"
android:previewImage="@drawable/ui_widget_preview" android:previewImage="@drawable/ui_widget_preview"
android:resizeMode="horizontal|vertical" android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="0" android:updatePeriodMillis="0"