Tencent/matrix · error · ClassNotFoundException

WindowManagerGlobal_mRoots not found

Error message

WindowManagerGlobal_mRoots not found

What it means

OverlayWindowLifecycleOwner monitors windows by reflectively reading WindowManagerGlobal.mRoots. prepareWindowGlobal() caches the reflected field once; if the reflection failed previously (fallbacked == true) and WindowManagerGlobal_mRoots is still null, it throws ClassNotFoundException('WindowManagerGlobal_mRoots not found').

Solutions

  1. Check the device's hidden-API policy / targetSdkVersion; reflection on mRoots is restricted on newer Android (9+ hidden API limits).
  2. Wrap callers of hasVisibleWindow/hasOverlayWindow/getAllViews in try-catch for ClassNotFoundException and fall back to non-reflective logic.
  3. Update Matrix to a version with updated reflection paths for the target Android version.

Example fix

// before
val has = OverlayWindowLifecycleOwner.hasVisibleWindow()
// after
val has = try {
    OverlayWindowLifecycleOwner.hasVisibleWindow()
} catch (e: ClassNotFoundException) {
    MatrixLog.w(TAG, "overlay check unsupported", e)
    false
}
Defensive patterns

Strategy: fallback

Validate before calling

null

Type guard

null

Try / catch

val has = try {
    OverlayWindowLifecycleOwner.hasVisibleWindow()
} catch (e: ClassNotFoundException) {
    MatrixLog.w(TAG, "overlay monitor unsupported on this ROM", e)
    false
}

Prevention

When it happens

Trigger: Calling hasVisibleWindow(), hasOverlayWindow(), or getAllViews() on a ROM/Android version where reflective access to android.view.WindowManagerGlobal.mRoots fails twice — first attempt silently nulls via safeLetOrNull, second call hits the fallbacked guard and throws.

Common situations: Running on restricted OEM ROMs or newer Android versions where hidden-API restrictions block reflection into WindowManagerGlobal; calling overlay detection APIs on unsupported devices.

Related errors


AI-assisted analysis of Tencent/matrix@3b8293bd65 (2026-09-08). Data as JSON: /api/errors/725e7dc9d86c95aa. Report an issue: GitHub.

Appendix: source

Thrown at matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/owners/OverlayWindowLifecycleOwner.kt:115

            val proxy = ArrayListProxy(origin, onViewRootChangedListener)
            ReflectUtils.set(
                Clazz_WindowManagerGlobal,
                "mRoots",
                WindowManagerGlobal_instance,
                proxy
            )
            WindowManagerGlobal_mRoots = proxy
        }
        injected = true
    }

    @Volatile
    private var fallbacked = false

    private fun prepareWindowGlobal() {
        if (WindowManagerGlobal_mRoots == null) {
            if (fallbacked) {
                throw ClassNotFoundException("WindowManagerGlobal_mRoots not found")
            }
            MatrixLog.i(TAG, "monitor disabled, fallback init")
            fallbacked = true
            WindowManagerGlobal_mRoots = safeLetOrNull(TAG) {
                Class.forName("android.view.WindowManagerGlobal").let {
                    val instance = ReflectUtils.invoke<Any>(it, "getInstance", null)
                    ReflectUtils.get(it, "mRoots", instance)
                }
            }
        }
        if (WindowManagerGlobal_mRoots == null) {
            throw ClassNotFoundException("WindowManagerGlobal_mRoots not found")
        }
        if (Field_ViewRootImpl_mView == null) {
            throw ClassNotFoundException("Field_ViewRootImpl_mView not found")
        }
    }

View on GitHub (pinned to 3b8293bd65)