Files
SoulStream/src-tauri/android/res/drawable/ic_launcher_ground.xml
T
KeelrLeek da4abeb8c9 android: the launcher's ground is the desktop's, not a flat colour under it
The icon round left the adaptive background as one `#FF05080B` and a note that
a gradient was being mocked. The mock settles it: the falcon covers about a
quarter of a circle-masked tile, so the ground is three quarters of what
anyone sees, and concept 04's glow survives every mask — the visible top-left
corner goes from `#05080B` to `#0E3543`. So `@color/ic_launcher_background`
becomes `@drawable/ic_launcher_ground`, a vector carrying the desktop icon's
own linear surface and the radial glow over it, every number
`src-tauri/icons/icon.svg`'s multiplied by 108/1024 and nothing else. The
colour resource stays where it is, unreferenced, because its filename is the
only thing stopping tauri's own `#fff` from colliding with it.

A vector and not five PNGs on evidence. The kit's glow has a uniform scale, so
the SVG ellipse is a circle and its rotation is a no-op, which is exactly what
`android:type="radial"` can carry; two numbers there and no vector could have
said it. The linear axis is 51.1° off horizontal, which rules out a
`<layer-list>` of shapes as well, whose angle must be a multiple of 45. It was
compiled and linked with the SDK's own aapt2 over the real merged res tree and
every stop read back out of the APK. The name is `ic_launcher_ground` and not
`ic_launcher_background` on purpose: the generated project still carries
Android Studio's template drawable of that name, so under the other name an
overlay copy that failed would silently link the green robot — under this one
it is a hard link error, which was tested too.

`verify-icon.sh` follows the layer. It does not ask whether the file is in the
APK; it asks what the adaptive icon's `<background>` resolves to, through the
resource table, in both build types, and then reads concept 04's six stops back
out of what it found — which catches a stale APK as well as a lost overlay.
Passing on a debug APK and on one put through `--shorten-resource-paths`,
failing on a stale one, and saying NOT CHECKED rather than guessing when aapt2
is absent. What none of it can see is a pixel: banding on the OLED, the glow's
weight under the Pixel's mask and how the falcon reads on a lit ground are a
launcher screenshot on the phone, and ANDROID.md says so instead of implying
the check covers it.

One slot the ground reaches is not the launcher at all. `MediaHub.appIcon()`
draws whatever `getApplicationIcon()` returns into a 512 px bitmap and hands
it to the lock-screen card as the large icon for any track whose cover has
not been decoded yet, so the card and the shade carry this ground as well —
the quickest place for Kyle to look at it, and the only reader of the
launcher icon inside the app. The walk reads that card's title and the
session's playback state and never its icon, so no step changes meaning. The
Android 12+ splash very likely changes as well, and the other way from what
the docs' one-line version of the rule suggests: the platform drops an
adaptive background only when it is a single colour close to
`windowSplashScreenBackground`, which round 44's flat `#05080B` was, so the
falcon has been drawing there alone and enlarged; a gradient is not one
colour, so it is kept and the whole icon is drawn. Likely, not proven — that
one is a screenshot too.
2026-09-15 07:22:02 -05:00

77 lines
3.6 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- The adaptive background: concept 04's ground, not a flat colour.
The desktop ships concept 04 "Deep navy glow" (src-tauri/icons/icon.svg,
byte-identical to the kit's soulstream-04-deep-navy-glow.svg) and the
phone shipped #05080B under the same falcon. The falcon covers about a
quarter of a circle-masked tile, so the ground is three quarters of what
anyone sees; the glow survives every mask, lifting the visible top-left
corner from #05080B to #0E3543; and a phone wearing a flatter icon than
the desktop is a divergence for no gain.
LAYER-FIT, not mask-fit: the 1024 artwork is mapped onto the whole 108
layer, not onto the 72 window inside it. Under a circle or a squircle the
two are indistinguishable, and this one never shows a flat edge when a
launcher parallaxes the layers apart.
Every number below is the kit's, multiplied by 108/1024 and nothing else:
surface <linearGradient x1=130 y1=50 x2=880 y2=980>
glow <radialGradient gradientTransform=
"translate(270 220) rotate(43) scale(660)">
108/1024 is 27/256, so each of those terminates inside eight decimals and
is an exact float — nothing here is a rounded coordinate.
The glow's transform has a UNIFORM scale, so the ellipse is a circle and
the rotate is a no-op — which is the whole reason a VectorDrawable can
carry this at all: android:type="radial" is centre plus radius, circular,
with no transform of its own. Had that scale been two numbers, no vector
could have expressed it and this would be five PNGs. stop-opacity folds
into the 8-bit alpha of android:color (0.18 -> 2E, 0.05 -> 0D, 0 -> 00);
the worst error that introduces, measured against the SVG's own float
composite at the layer corners, the visible corners, the circle's rim and
the centre, is one level of 255.
The rx="232" on the kit's two rects is deliberately NOT here. That is the
desktop window's corner; on the phone the launcher's mask does that job,
and an adaptive background must fill its layer.
Two full-bleed paths, surface then glow, because an adaptive background
must be opaque: the first is #FF everywhere and the second only lightens
it. -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M0,0h108v108h-108z">
<aapt:attr name="android:fillColor">
<gradient
android:type="linear"
android:startX="13.7109375"
android:startY="5.2734375"
android:endX="92.8125"
android:endY="103.359375">
<item android:offset="0" android:color="#FF0A2330" />
<item android:offset="0.52" android:color="#FF07141F" />
<item android:offset="1" android:color="#FF040A10" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M0,0h108v108h-108z">
<aapt:attr name="android:fillColor">
<gradient
android:type="radial"
android:centerX="28.4765625"
android:centerY="23.203125"
android:gradientRadius="69.609375">
<item android:offset="0" android:color="#2E31C0CB" />
<item android:offset="0.58" android:color="#0D1F8FC9" />
<item android:offset="1" android:color="#0007141F" />
</gradient>
</aapt:attr>
</path>
</vector>