{"record":{"id":"725e7dc9d86c95aa","repo":"Tencent/matrix","slug":"windowmanagerglobal-mroots-not-found","errorCode":null,"errorMessage":"WindowManagerGlobal_mRoots not found","messagePattern":"WindowManagerGlobal_mRoots not found","errorType":"exception","errorClass":"ClassNotFoundException","httpStatus":null,"severity":"error","filePath":"matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/owners/OverlayWindowLifecycleOwner.kt","lineNumber":115,"sourceCode":"            val proxy = ArrayListProxy(origin, onViewRootChangedListener)\n            ReflectUtils.set(\n                Clazz_WindowManagerGlobal,\n                \"mRoots\",\n                WindowManagerGlobal_instance,\n                proxy\n            )\n            WindowManagerGlobal_mRoots = proxy\n        }\n        injected = true\n    }\n\n    @Volatile\n    private var fallbacked = false\n\n    private fun prepareWindowGlobal() {\n        if (WindowManagerGlobal_mRoots == null) {\n            if (fallbacked) {\n                throw ClassNotFoundException(\"WindowManagerGlobal_mRoots not found\")\n            }\n            MatrixLog.i(TAG, \"monitor disabled, fallback init\")\n            fallbacked = true\n            WindowManagerGlobal_mRoots = safeLetOrNull(TAG) {\n                Class.forName(\"android.view.WindowManagerGlobal\").let {\n                    val instance = ReflectUtils.invoke<Any>(it, \"getInstance\", null)\n                    ReflectUtils.get(it, \"mRoots\", instance)\n                }\n            }\n        }\n        if (WindowManagerGlobal_mRoots == null) {\n            throw ClassNotFoundException(\"WindowManagerGlobal_mRoots not found\")\n        }\n        if (Field_ViewRootImpl_mView == null) {\n            throw ClassNotFoundException(\"Field_ViewRootImpl_mView not found\")\n        }\n    }\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/Tencent/matrix/blob/3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7/matrix/matrix-android/matrix-android-lib/src/main/java/com/tencent/matrix/lifecycle/owners/OverlayWindowLifecycleOwner.kt#L97-L133","documentation":"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').","triggerScenarios":"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.","commonSituations":"Running on restricted OEM ROMs or newer Android versions where hidden-API restrictions block reflection into WindowManagerGlobal; calling overlay detection APIs on unsupported devices.","solutions":["Check the device's hidden-API policy / targetSdkVersion; reflection on mRoots is restricted on newer Android (9+ hidden API limits).","Wrap callers of hasVisibleWindow/hasOverlayWindow/getAllViews in try-catch for ClassNotFoundException and fall back to non-reflective logic.","Update Matrix to a version with updated reflection paths for the target Android version."],"exampleFix":"// before\nval has = OverlayWindowLifecycleOwner.hasVisibleWindow()\n// after\nval has = try {\n    OverlayWindowLifecycleOwner.hasVisibleWindow()\n} catch (e: ClassNotFoundException) {\n    MatrixLog.w(TAG, \"overlay check unsupported\", e)\n    false\n}","handlingStrategy":"fallback","validationCode":"null","typeGuard":"null","tryCatchPattern":"val has = try {\n    OverlayWindowLifecycleOwner.hasVisibleWindow()\n} catch (e: ClassNotFoundException) {\n    MatrixLog.w(TAG, \"overlay monitor unsupported on this ROM\", e)\n    false\n}","preventionTips":["Test on all target ROMs/Android versions; hidden-API restrictions vary by device.","Treat window-inspection APIs as best-effort and always provide a fallback.","Keep Matrix updated for reflection-path changes across Android releases."],"tags":["android","reflection","hidden-api","class-not-found"],"backgroundTag":"class-not-found","analyzedSha":"3b8293bd65d47eeea7caf1f32a3a5d4d5eab60e7","analyzedAt":"2026-09-08T08:01:39.722Z","contentChangedAt":"2026-09-08T08:01:39.722Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}