Skip to content

Fix manager crash (AbstractMethodError) on HyperOS3(Android 17) due to IServiceConnection signature change#784

Merged
JingMatrix merged 4 commits into
JingMatrix:masterfrom
Leaf-lsgtky:fix/android17-iserviceconnection
Jul 25, 2026
Merged

Fix manager crash (AbstractMethodError) on HyperOS3(Android 17) due to IServiceConnection signature change#784
JingMatrix merged 4 commits into
JingMatrix:masterfrom
Leaf-lsgtky:fix/android17-iserviceconnection

Conversation

@Leaf-lsgtky

Copy link
Copy Markdown
Contributor

Problem

On Android 17 (API 36), opening the manager triggers an AbstractMethodError that kills the parasitic manager process, followed by a DeadObjectException in system_server (dispatching a broadcast to the dead process), which causes a framework restart (SYSTEM_RESTART) every time the manager is launched.

The debug crash log shows:
java.lang.AbstractMethodError: abstract method "void android.app.IServiceConnection.connected(android.content.ComponentName, android.os.IBinder, android.app.IBinderSession, boolean)" on receiver org.matrix.vector.daemon.ipc.ManagerServiceManagerGuardconnection$1

Root cause

Android 17 replaced the old IServiceConnection.connected(ComponentName, IBinder, boolean) overload with a new 4-argument signature that adds an IBinderSession parameter, and removed the old overload entirely from the framework interface.

Vector's IServiceConnection stub and the ManagerService connection implementation only declared/overrode the old 3-argument signature. When system_server dispatched the new 4-argument connected() to the parasitic manager process, the Stub lacked the new abstract method → AbstractMethodError → process death → DeadObjectException → framework restart.

Fix

Commit 1 — Android 17 compatibility (core fix)

  • Add IBinderSession stub (android.app.IBinderSession extends IInterface) with binderTransactionCompleted(long) and binderTransactionStarting(String):long, matching the Android 17 framework interface.
  • Declare both connected() overloads in the IServiceConnection stub so it compiles against Android 8.1–17. The old overload is simply never invoked on Android 17+.
  • Override the new 4-argument connected() in ManagerService's connection Stub (no-op, same as the existing 3-argument override).

Commit 2 — Windows build fix (prerequisite for local testing)

Passing string macros wrapped in single quotes (-DVERSION_NAME='"2.0"') breaks on Windows because single quotes are not shell quoting characters there. The compiler receives -DVERSION_NAME='2.0' (a multi-character constant) and fails. Fixed by passing bare tokens and stringizing them at the C++ side via a STRINGIZE macro, which is robust across Windows and Unix toolchains.

Testing

  • Device: Xiaomi (HyperOS 3, Android 17 / API 36)
  • Reproduced the crash with the unpatched debug build (manager launch → AbstractMethodError → framework restart).
  • Applied the fix, rebuilt the debug zip, flashed via KSU and rebooted.
  • Manager opens successfully without crash; framework remains stable.
  • Verified no regression on framework startup (VectorDaemon / VectorSystemServer logs normal).

The change is backward-compatible: on Android 8.1–16 the new overload exists only in the stub (never invoked at runtime), and the old overload is preserved unchanged.

Android 17 (API 36) replaced the old 3-argument
IServiceConnection.connected(ComponentName, IBinder, boolean) with a
new 4-argument overload that adds an IBinderSession parameter, and
removed the old overload entirely from the framework interface.

Vector's IServiceConnection stub and the ManagerService connection
implementation only declared/overrode the old 3-argument signature.
When system_server dispatched the new 4-argument connected() to the
parasitic manager process on Android 17, the Stub lacked the new
abstract method and threw AbstractMethodError, killing the manager
process. system_server then hit DeadObjectException while dispatching
a broadcast to the dead process, triggering a framework restart
(SYSTEM_RESTART) every time the manager was opened.

Fix:
- Add an IBinderSession stub (android.app.IBinderSession extends
  IInterface) with binderTransactionCompleted(long) and
  binderTransactionStarting(String):long, matching the Android 17
  framework interface.
- Declare both connected() overloads in the IServiceConnection stub so
  it compiles against Android 8.1~17 (the old overload is simply never
  invoked on Android 17+).
- Override the new 4-argument connected() in ManagerService's
  connection Stub (no-op, same as the existing 3-argument override).
The build system passed string macros to the C/C++ compiler wrapped in
single quotes, e.g.  -DVERSION_NAME='2.0'  and
-DINJECTED_PACKAGE_NAME='com.android.shell'. On Linux/macOS the shell
strips the single quotes and the compiler sees a quoted string literal,
but on Windows single quotes are not shell quoting characters, so the
compiler receives -DVERSION_NAME='2.0' (a multi-character constant) or
-DINJECTED_PACKAGE_NAME='com.android.shell', causing compilation
failures:
  - narrowing conversion from 'int' to 'const char*'
  - expected unqualified-id / multi-character constant

Fix by passing the values as bare tokens
(-DVERSION_NAME=2.0, -DINJECTED_PACKAGE_NAME=com.android.shell) and
stringizing them at the C++ side via a STRINGIZE macro, which is robust
across Windows and Unix toolchains. Also move the stringize helper
macros out of a namespace (macros are not namespace members and cannot
be invoked with a qualified name).
@h3nnes

h3nnes commented Jul 15, 2026

Copy link
Copy Markdown

Confirmed working on Xiaomi 17 Ultra EEA (OS3.0.332.0.XPAEUXM) Android 17 API 37

@HSSkyBoy

Copy link
Copy Markdown

Upload the device's art file, I can't figure out what the problem is otherwise

This reverts commit 73f7b33.

The quoting problem is unrelated to the Android 17 crash and only affects
local builds on Windows; CI builds on ubuntu-latest, where the shell strips
the quotes as intended. It is handled separately so that this pull request
carries a single change.
Android 17 (API 37) reshaped the IServiceConnection callback and dropped the
old overload instead of keeping both:

    void connected(in ComponentName name, IBinder service,
                   in @nullable IBinderSession session, boolean dead);

ManagerGuard overrode only the three-argument form, so as soon as system_server
dispatched the new transaction the Stub landed on an abstract method and the
daemon died with AbstractMethodError, taking the manager session down with it.
Only the Xiaomi XSpace workaround binds this connection, which is why the crash
was reported on HyperOS first; the interface change itself ships in stock
Android 17 and is not vendor specific.

Declare both overloads in the IServiceConnection stub and override both in
ManagerGuard, so every supported release finds the method system_server
dispatches. IBinderSession is stubbed as an empty interface, since the type is
only referenced by the descriptor of the new overload.

Verified on a Pixel 6 running Android 17 (SDK 37.1), whose framework declares
the four-argument overload alone: a Stub subclass overriding only the
three-argument form throws AbstractMethodError on an Android 17 shaped
transaction, while overriding both dispatches the four-argument method with a
null session and no crash.
@JingMatrix

JingMatrix commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Verified on a Pixel 6 running Android 17 (SDK 37.1), whose framework declares the four-argument overload alone: a Stub subclass overriding only the three-argument form throws AbstractMethodError on an Android 17 shaped
transaction, while overriding both dispatches the four-argument method with a null session and no crash.

@JingMatrix
JingMatrix merged commit 73571c7 into JingMatrix:master Jul 25, 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.

4 participants