Skip to content

Refuse a scope target that reaches nothing, and name the framework - #1062

Closed
JingMatrix wants to merge 1 commit into
masterfrom
fix/cli-scope-targets
Closed

JingMatrix wants to merge 1 commit into
masterfrom
fix/cli-scope-targets

Conversation

@JingMatrix

@JingMatrix JingMatrix commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

A module scoped to the system framework through the CLI is never loaded into it, and says nothing anywhere. #1061 is that, configured entirely through vector-cli on a device with no manager: cli scope ls answers android, com.google.android.gms and the module's own package, the framework bootstraps completely inside system_server — injection, PreloadedDex, full LSPlant init, every framework hook, the daemon channel — and then module loading for the system package never starts. No error, no exception, no skip entry.

getModulesForSystemServer is the whole of where that process's module set comes from, by way of getAllModules sending uid 1000 and process system there rather than to the scope map, and it reads systemServerModuleRows — app_pkg_name = 'system', and nothing else, because it answers before any package manager exists to expand a package name with. A row spelled android is therefore invisible to it, and the reporter's correct observation that nothing was skipped is for a different reason than they took it for: SystemServerService.attachProcess does not consult the scope at all, so Process channel attached for system and no Skipped system/1000 is what both a working and an unconfigured system server look like.

Two things let the row be written and then kept quiet about it.

The CLI wrote whatever it was handed. handleScope split a target on / and passed the halves to setModuleScope, which normalises the user id for system and has never had an opinion about the name. A typo, a package that was uninstalled, a package name from another device: all accepted, all listed back by scope ls, all reaching nothing. add and set now refuse a target the daemon can see is not there, by name, through the predicate getInstalledPackagesFromAllUsers filters the manager's own list by — so what the editor offers and what a write may name are one thing, hidden packages included. The predicate has a third answer for having no package manager to ask, since this socket is listening before main has waited for one and a question that cannot be asked is not a no. rm deliberately still takes anything, because the rows already written this way have to stay removable.

The rebuild built an entry for it that nothing queries. android resolves, so the row went down the ordinary path, and fetchProcesses answers system for that package among others — the expansion added a system/1000 entry, which no reader ever looks up, since getAllModules sends that process to the database instead. The module held the framework in the configuration and was never in it. That entry goes, and the rebuild logs the package the row named and the word that would have worked. com.android.providers.settings is the same shape and gets the same line, correctly: its provider does run in the system server, and system is how a module reaches it.

Which leaves the vocabulary, which is the actual trap. system is the system server and android is the ordinary framework package — ScopeViewModel synthesises the first and shows it as system_server, swapLegacyFrameworkNames turns a legacy module's reversed spelling around, and the CLI said neither. It cannot refuse android: that is a legitimate row, reaching android:ui. So scope --help and the three target-taking commands spell out which word means which.

Also here: the scope request path had its own inline copy of the "is this target there" test, which is now the one predicate beside the rebuild that depends on it; and the three commands share one target parse instead of spelling pkg/user_id out apiece.

Left alone: that system/1000 can be in the scope map at all. Nothing reads it, so the entry is dead rather than wrong, and removing the special case in getAllModules would mean teaching the system-server path to answer from a cache that does not exist when it is asked.

Not tested on a device. The refusal and the help text are straightforward; the rebuild's warning is on a path I can only reach by configuring a module the way #1061 did.

The scope table takes any string, and nothing on the way in asked
whether that string named anything. `handleScope` parsed a target and
wrote it: a name that resolves for nobody was accepted, listed back by
`scope ls`, and expanded to no process at all — a module that is
configured and never loads, with nothing anywhere to say why. `scope
add` and `scope set` now refuse such a target by name, through the same
predicate the manager's own installed list is filtered by, so what the
editor offers and what a write may name mean one thing. The predicate
has a third answer for having no package manager to ask, which this
socket can reach before `main` has waited for one and which must not be
read as a refusal, and `scope rm` still takes anything, because a row
already written this way has to stay removable.

`system` is the system server and `android` is the ordinary framework
package, and the CLI spelled out neither. A row naming `android` is a
legitimate row — that package's injectable process is android:ui — but
it cannot reach the system server: `getModulesForSystemServer` asks the
scope table for the rows spelled `system` alone, because it answers
before any package manager exists to expand a package name with. The
rebuild nevertheless expanded such a row into a `system`/1000 entry,
which nothing ever queries, so the module held the framework in the
configuration and was never loaded into it. That entry goes, and the
rebuild now names the package it came from. The three target-taking
commands and `scope --help` say which word means which.

Also here: the scope request path kept its own copy of the "is this
target there" test, which is now the one predicate beside the rebuild
that depends on it, and the three commands share one target parse
rather than spelling `pkg/user_id` out apiece.

Fixes #1061
@JingMatrix

Copy link
Copy Markdown
Owner Author

Basically, AI generated PRs are of low quality.

Sometimes I wish AI could replace me, sigh...

@JingMatrix JingMatrix closed this Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Modules never load into system_server on Android 15: framework bootstraps fully, then silence — same module loads fine in regular apps

1 participant