Redraw the monochrome icon and the header ambiences, and compare the installed manager - #849
Merged
Conversation
The themed launcher icon and the daemon's status notification both drew a flat blob traced from the outline of ic_winged_victory, which told you nothing about what the statue is. Take the silhouette of the two-tone drawing instead and punch the statue's own modelling out of it with evenOdd, so the wing feathers and the drapery folds read at launcher size while the shape stays solid in the status bar. The line work is curated down to twenty-five strokes: the contour-hugging ones are dropped, the rest are thinned by spacing rather than by length so the wing keeps its feathers, and each is widened to survive 24dp. The whole path has to stay under 32767 bytes, which is where the resource string pool gives up and writes STRING_TOO_LARGE instead. Geometry is fitted to ic_winged_victory's bounding box, so the themed layer still registers with the coloured one under the shared 25% inset.
Every trace used to start at a random height and wander rightwards in steps of a random size, blind to the others. Traces landed on top of one another, doubled up along the same line, crowded one half of the header and left the other empty, and a trace that met one already drawn simply stopped where it stood, hanging in the middle of the picture. Route them on a lattice instead. Lanes are evenly spaced, traces run along them and step between neighbours at the columns, and every run a trace occupies is claimed, so no two are ever drawn along the same line. A trace that meets copper already laid steps aside — one lane out, then two, then three — and carries on to the right-hand side, crossing what is in its way: a board has layers, a crossing reads as one of them, and without them the lattice reads as a set of ruled lines. A trace that has drifted a couple of lanes from where it started prefers the step back, which keeps the horizontal grain a board has, and three in ten stop on a land short of the edge rather than running off it, so both kinds of ending are visible. Corners are mitred into the two 45° elbows a real router leaves behind, and the vias move onto those elbows, where a board actually puts them. The signal is a swell of current rather than a dot: a tapering ribbon filled with a gradient, widest and brightest under the head and drawn down to nothing behind, breathing a tenth of its width as it travels. A chain of segments would have done, but it beads visibly once the stroke is wider than the step between samples, and the ribbon costs nothing per frame — the path and its far edge are kept between them. The head is the rounded end of that body, not a ball towing it. Signals also run a third slower at rest, and a vertical drag now sets their speed, the same gesture the code rain and the snow already use, with a sideways one still re-routing the board.
The glyph was a fraction of the header's height multiplied by a zoom with bounds of its own, and the column count was a fixed fifty-two regardless. So the rain drew fifty-two streams at a size that fit thirty across, which is thirty columns of overlapping glyphs however many are in the list, and the pinch went on resizing after the field had stopped answering it. Turn it round: the pinch sets how many columns fit over the width, and the glyph size is worked back from that — a monospace glyph advances about six tenths of its font size, and the font is drawn at four fifths of the cell. Thirty across is now as large as a glyph may be and a hundred and twenty as small, with eighty at rest, which is a limit that means the same thing on a phone and on a tablet where a size in pixels would not. One column to each lane that fits, so the field is exactly as dense as it says it is, and the zoom bounds fall out of the counts instead of being chosen beside them. Lanes are taken in golden-ratio steps rather than at random. Eighty random numbers do not cover a width evenly — the widest bare gap is around a fourteenth of the header, with doubled-up streams somewhere else to pay for it — and at the far end of a zoom in, where thirty large glyphs carry the whole field, that gap is most of what you see. Columns are added and taken away between frames instead of the field being rebuilt, so a pinch never blanks a stretch of the header: new streams arrive from above the top edge, and the ones taken away are those that have already fallen furthest. A tapped-in column is counted, so the next frame does not quietly take it back off again.
Parasitically the manager is not a package: it runs inside the host, loaded from the daemon's own APK. "Install as an app" puts a second copy of that code on the device, and nothing keeps the two in step afterwards — the module behind it is reflashed on every framework update, while the install stays whatever it was. The row was a boolean and collapsed to a green check the moment the package existed, so a copy from a build two months old looked exactly like a copy of the build that is running. The version code cannot separate them. It is `git rev-list --count origin/master`, so a branch build and the official build at the same depth wear the same number. Compare the bytes instead: the version code first because it is free and a disagreement there is already the answer, and when the numbers agree, SHA-256 the installed copy's own APK against the one the daemon would install. Both are streamed a chunk at a time — the heap that would otherwise hold twenty megabytes belongs to com.android.shell — and the verdict is remembered against the installed copy's lastUpdateTime, so it expires exactly when that copy is replaced and not before. A comparison that could not be made is not a mismatch. A dead daemon, a refused APK, an unreadable install: each leaves the card reading as it did before there was anything to compare, because sending somebody to replace a working copy on the strength of a check that never ran is the one outcome worse than saying nothing. Only a completed comparison is remembered, so a daemon that comes back is asked again. Nothing new is needed to act on it: install() has always set INSTALL_REPLACE_EXISTING, because a SHELL_UID session is not given it for free. The row simply stays a button, labelled Reinstall — in every language, since check_translations.py holds each locale to the English key set.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four changes, three of them cosmetic.
The monochrome icon was a flat blob traced round the winged victory, so neither the themed launcher icon nor the status notification said what the statue is. It now carries the statue's own line work, punched out of the silhouette so it stays solid at 24dp.
The circuit ambience routes its board on a lattice rather than scribbling it: no two traces share a line, a blocked one steps aside and carries on rather than stopping mid-header, corners are mitred, and the signal is a swell of current with a proper head. A vertical drag sets its speed, as with the rain and the snow.
The code rain takes its glyph size from how many columns fit across the header — thirty to a hundred and twenty, eighty at rest — rather than a fraction of its height, and lanes are spread by golden ratio so the field stops clumping.
Last, parasitically the "Install as an app" row went green as soon as the package existed, even when that copy was a different build. Version codes cannot tell those apart, so it now compares the two APKs by digest and offers a reinstall.