Skip to content

Daemon notifications never post on Android 15: Notification.<init> reads a DeviceConfig flag the daemon cannot reach #880

Description

@oneroomlife

Summary

On Android 15 (HyperOS 3.0), every Notification.Builder(...).build() inside the daemon throws
SecurityException, so no Vector notification is ever posted: no status notification, and no scope
request notification for modules that ask for scope from their own app. Hooking, Zygisk injection
and the daemon binder are unaffected.

Steps to reproduce

  1. Android 15 + HyperOS 3.0, Magisk with Zygisk (NeoZygisk 2.3 (286)).
  2. Install Vector 2.2 (3080) release, reboot.
  3. Open the Vector manager and turn status notification on.

Expected behaviour

The "Vector is running" notification appears, and tapping it opens the manager.

Actual behaviour

The toggle fails, nothing is posted, and the daemon logs a SecurityException.
/data/adb/lspd/cli status reports Status Notification: true while no notification exists.

Daemon log

[ 2026-08-06T17:27:52.110  0: 2509: 2509 E/VectorWorkarounds ] Failed to build dummy notification
java.lang.SecurityException: Unable to find app for caller android.app.IApplicationThread$Stub$Proxy@51545c9 (pid=2509) when getting content provider settings
    at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:6767)
    at android.app.ActivityThread.acquireProvider(ActivityThread.java:8777)
    at android.content.ContentResolver.acquireProvider(ContentResolver.java:2529)
    at android.provider.Settings$ContentProviderHolder.getProvider(Settings.java:3320)
    at android.provider.Settings$NameValueCache.getStringsForPrefixStripPrefix(Settings.java:3763)
    at android.provider.Settings$Config.getStrings(Settings.java:20457)
    at android.provider.SettingsConfigDataStore.getProperties(SettingsConfigDataStore.java:48)
    at android.provider.DeviceConfig.getPropertiesWithoutOverrides(DeviceConfig.java:1125)
    at android.provider.DeviceConfig.getProperties(DeviceConfig.java:1115)
    at android.app.FeatureFlagsImpl.load_overrides_systemui(FeatureFlagsImpl.java:145)
    at android.app.FeatureFlagsImpl.sortSectionByTime(FeatureFlagsImpl.java:536)
    at android.app.Flags.sortSectionByTime(Flags.java:298)
    at android.app.Notification.<init>(Notification.java:2628)
    at android.app.Notification$Builder.<init>(Notification.java:4447)
    at android.app.Notification$Builder.<init>(Notification.java:4419)
    at org.matrix.vector.daemon.VectorDaemon.main(...)
Caused by: android.os.RemoteException: Remote stack trace:
    at com.android.server.am.ContentProviderHelper.getContentProviderImpl(ContentProviderHelper.java:189)
    at com.android.server.am.ContentProviderHelper.getContentProvider(ContentProviderHelper.java:150)
    at com.android.server.am.ActivityManagerService.getContentProvider(ActivityManagerService.java:7873)

Manager log for the same toggle

08-06 17:48:30.964  5622  8903 W VectorManager: ipc: daemon transaction failed
08-06 17:48:30.964  5622  8903 W VectorManager: java.lang.SecurityException: Unable to find app for caller android.app.IApplicationThread$Stub$Proxy@26f2d99 (pid=2509) when getting content provider settings
    at org.matrix.vector.ipc.IManagerService$Stub$Proxy.setStatusNotificationEnabled(...)
08-06 17:48:30.965  5622  5622 E VectorManager: framework: setting the status notification to true failed

Process identities from the same session:

# daemon                          # parasitic manager
$ cat /proc/2509/status           $ cat /proc/5622/status
Name:   main                      Name:   .vector.manager
Uid:    0  1000  0  1000          Uid:    2000  2000  2000  2000
PPid:   1

verbose_2026-08-06T17_27_48.813714.log

Environment

Vector 2.2 (3080), release
Android 15, HyperOS 3.0 (Xiaomi)
Root Magisk, NeoZygisk 2.3 (286)
Xposed modules none required to reproduce

Maintainer notes

The daemon calls ActivityThread.systemMain() (daemon/src/main/kotlin/org/matrix/vector/daemon/VectorDaemon.kt:94),
so it owns an ActivityThread and an IApplicationThread, but AMS never started it and holds no
process record for it. Every content provider lookup from this process is therefore refused — the
same failure already described in daemon/src/main/kotlin/org/matrix/vector/daemon/ipc/ManagerService.kt:465.

What is new here is the caller. On this device Notification.<init> reads an aconfig flag, and the
first read of the systemui container goes out to content://settings/config:

Notification.<init> → Flags.sortSectionByTime → FeatureFlagsImpl.load_overrides_systemui
                    → DeviceConfig.getProperties → settings provider → SecurityException

That path uses Settings.Config's static cache and the process ActivityThread, not the Context
handed to the builder, so FakeContext has no say in it. load_overrides_systemui sets its
_is_cached guard only after the read returns, so the throw leaves the guard false and every later
build repeats the same failing lookup — which is why the boot probe fails and the toggle fails again
twenty minutes later.

applyNotificationWorkaround() (daemon/src/main/kotlin/org/matrix/vector/daemon/utils/Workarounds.kt:42)
is aimed at exactly this, and neither arm engages on this device:

  • Workarounds.kt:43 gates the systemui_is_cached bypass on SDK_INT == 36, so it is skipped on
    Android 15.
  • Workarounds.kt:57 only reacts to AbstractMethodError by flipping FakeContext.nullProvider.
    Here the resolver call reaches AMS and comes back as SecurityException, which is only logged.

Two consequences downstream:

  • notifyStatusNotification() builds outside its runCatching
    (daemon/src/main/kotlin/org/matrix/vector/daemon/system/NotificationManager.kt:129 vs :139), so
    the exception escapes through setStatusNotificationEnabled and fails the binder call.
  • The scope request notification is built the same way
    (daemon/src/main/kotlin/org/matrix/vector/daemon/system/NotificationManager.kt:431), which is the
    original report in this issue: a module cannot open Vector's scope UI from its own app.

Not yet established: whether stock Android 15 reads this flag in the Notification constructor, or
whether HyperOS backported it. That decides how many devices are affected.

Unrelated to #705, which is about a notification that is posted but not shown.

The first report in this issue came from Vector 2.0 (3021), whose manager was still named
org.lsposed.manager; it was renamed in #796. The log was Vector's, not LSPosed's.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions