7 Commits
Author SHA1 Message Date
bdeshiandagent a24ff6a804 Replace the launcher icon with a crescent moon and add a themed layer
The new icon is a pearl crescent on deep indigo, with the rest of the
moon still faintly visible behind it: hidden, not removed.

- ic_launcher_background: radial indigo gradient, replacing the flat
  colour resource (values/colors.xml, now unused, is removed)
- ic_launcher_foreground: faint full disc plus a gradient crescent,
  scaled to sit inside the 66 dp safe zone
- ic_launcher_monochrome: new; solid crescent over the disc at 30%
  alpha, used for Android 13+ themed icons

Both adaptive icons (regular and round) reference all three layers.
All shapes are plain paths and gradients, no masks. Built with
assembleDebug and checked in the APK with aapt2; not yet seen on a
device.

Co-Authored-By: agent <agent@bdeshi.space>
2026-11-05 15:13:32 +06:00
bdeshiandagent 62549d7741 Hide a fixed set of well-known root and hook packages
With per-app configuration gone, the hidden list is the same for every app
and can't be edited at runtime, so it carries the well-known names instead
of only KernelSU, Magisk and Veil. 28 packages plus Veil, grouped in
Features.kt:

- root managers: Magisk, Magisk Delta, Magisk Alpha, KernelSU, KernelSU
  Next, SukiSU Ultra, APatch
- module managers and helpers: MMRL (both variants), Magisk Module
  Manager, KsuWebUI
- hook frameworks and managers: Vector, LSPosed, LSPatch, EdXposed,
  Xposed installer, Taichi, VirtualXposed, Substrate
- older su apps and one-click root tools

Packages that aren't installed match nothing, so a name that's wrong or
absent is harmless. Most names were not checked against an install; only
KernelSU and MMRL were present on the test device. Xposed modules in
general have no common package name, so they stay uncovered by name.

The settings screen shows the count and puts the list behind a toggle.
Verified on device with Veil Probe: the installed ones (KernelSU and both
MMRL packages) report HIDDEN across all ten lookups, no LEAK/FAIL/ERROR,
and a scoped app still starts.

Co-Authored-By: agent <agent@bdeshi.space>
2026-11-03 20:37:23 +06:00
bdeshiandagent cfed7989f2 Mask direct settings-provider reads (ContentResolver.call and query)
An app could skip Settings.Secure/Global and read the settings provider
straight through ContentResolver, getting the real accessibility, ADB and
developer-options state. Two routes, both now masked for the same keys the
Settings hooks cover:

- ContentResolver.call(content://settings/<table>, "GET_<table>", key):
  the returned Bundle's "value" is rewritten to null / "0".
- ContentResolver.query on settings/secure and settings/global: the
  cursor is replaced with a MatrixCursor with the value masked. The key is
  read from the "name" column, or, when a caller projects only "value",
  from the URI path or a single selection arg. Cursors that touch no
  masked key are left as they were.

Verified on device with Veil Probe: call(), query() with name=?, and the
settings/global/<key> path form all report HIDDEN for accessibility,
adb_enabled and development_settings_enabled, and a scoped app still starts.

Co-Authored-By: agent <agent@bdeshi.space>
2026-11-03 20:27:07 +06:00
bdeshiandagent 32c926841b Hide hidden packages from four more PackageManager lookups
Veil Probe showed KernelSU and Veil still resolvable through lookups the
hooks didn't cover, so an app could find either by skipping getPackageInfo:

- getPackageUid(name, flags)             -> NameNotFoundException
- getPackageInfo(VersionedPackage, flags) -> NameNotFoundException
- getApplicationEnabledSetting(name)     -> IllegalArgumentException,
  which is what the real call throws for an unknown package
- getLaunchIntentForPackage(name)        -> null

Same pattern as the existing hooks: set the result or throwable before the
original runs, so errors for packages that really don't exist still come
from the platform unwrapped.

Verified on device with Veil Probe: all eight rows (four lookups x KernelSU
and Veil) now report HIDDEN, no LEAK/FAIL/ERROR, and a scoped app still starts.

Co-Authored-By: agent <agent@bdeshi.space>
2026-11-03 20:19:02 +06:00
bdeshiandagent eebba2f9f1 Apply one fixed baseline to every scoped app; drop all settings
Per-app settings never worked: a hooked app reads Veil's config through
XSharedPreferences, which for a legacy module points at Veil's private
data dir (/data/data/space.bdeshi.veil/shared_prefs). Hooked apps can't
read it, so every app silently fell back to "hide everything" and every
toggle, hidden-package edit and picker entry was ignored. Confirmed on
device with Veil Probe: unticking a feature changed nothing.

The framework's fix for this (xposedsharedprefs, redirecting the module's
prefs dir to one hooked apps can read) needs the framework to hook Veil's
own process. On Vector v2.2 here it never does, even with Veil in its own
scope and after a reboot, so there's no reliable channel from Veil's app
to a hooked app.

So stop pretending there is one:
- VeilHook applies all six features with the fixed Features.HIDDEN_PACKAGES
  (KernelSU, Magisk, Veil) to every app in scope, with no prefs read.
- Remove discovery: the Application#attach hook, the exported provider
  (one less way for an app to spot Veil) and the launcher <queries>.
- The settings screen becomes a read-only summary plus the help panel;
  help tips cover leaving an app out of scope, changing the list by
  rebuilding, and turning verbose logging off afterwards, since it
  names Veil in each hooked app's own logcat.

Verified on device: all 24 testable hooked paths in Veil Probe stay
hidden, Veil's provider no longer resolves, a scoped app still loads Veil.

Co-Authored-By: agent <agent@bdeshi.space>
2026-11-03 19:51:52 +06:00
bdeshiandagent af97a85c54 Add an app picker for targets that can't report themselves
Auto-discovery only works for apps that can see Veil: on Android 11+ an
app without QUERY_ALL_PACKAGES (or a matching <queries>) can't resolve
Veil's provider, so its first-launch check-in silently fails. A real app hit this: scoped and hooked, but never listed. That made 615f000's premise,
that auto-detection covers every target, wrong.

- "Add app" opens a searchable list of launchable apps; picking one saves
  its default feature set, which is what gives an app a card. A
  launcher-intent <queries> is enough for this and narrower than
  QUERY_ALL_PACKAGES; it widens what Veil sees, not who sees Veil.
- App cards show the app's label above the package name.
- reportScoped checks resolveContentProvider first and skips the call
  when Veil isn't visible. That also drops the framework's
  "Failed to find provider info for space.bdeshi.veil.provider" line,
  which named Veil in the target's own, app-readable logcat.
- New help tip explains why a scoped app may not show up.

Verified on device (Android 16, Vector): a scoped app no longer logs the
provider failure, and adding it through the picker saves its feature set.

Co-Authored-By: agent <agent@bdeshi.space>
2026-11-03 18:54:13 +06:00
bdeshiandagent 6dfb0d5779 Hide Veil itself from target apps by default
An installed hooking module is as much a tell as a root manager, but
Veil's own package wasn't in the hidden list, so any scoped app could
find it with getPackageInfo or the installed-package lists. It's now a
default alongside KernelSU and Magisk.

DEFAULT_HIDDEN_PACKAGES only applies while no list has been saved, so a
one-time migration adds Veil to an existing list the first time the
settings screen opens; a flag stops it from re-adding Veil after a
manual removal.

Discovery is unaffected: the hooked process resolves Veil's provider
through ActivityManager, not the hooked ApplicationPackageManager.
Verified on device (Android 16, Vector) with Veil Probe: getPackageInfo
for Veil now throws NameNotFoundException, the probe still registers,
and every other hooked path stays hidden.

Co-Authored-By: agent <agent@bdeshi.space>
2026-11-03 18:26:38 +06:00