{"record":{"id":"81286c6c051d244d","repo":"maotoumao/MusicFree","slug":"panel-musicitemlyricoptions-desktoplyricpermission","errorCode":null,"errorMessage":"panel.musicItemLyricOptions.desktopLyricPermissionError","messagePattern":"panel\\.musicItemLyricOptions\\.desktopLyricPermissionError","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/components/panels/types/musicItemLyricOptions.tsx","lineNumber":122,"sourceCode":"\r\n                    if (hasPermission) {\r\n                        const statusBarLyricConfig = {\r\n                            topPercent: Config.getConfig(\"lyric.topPercent\"),\r\n                            leftPercent: Config.getConfig(\"lyric.leftPercent\"),\r\n                            align: Config.getConfig(\"lyric.align\"),\r\n                            color: Config.getConfig(\"lyric.color\"),\r\n                            backgroundColor: Config.getConfig(\"lyric.backgroundColor\"),\r\n                            widthPercent: Config.getConfig(\"lyric.widthPercent\"),\r\n                            fontSize: Config.getConfig(\"lyric.fontSize\"),\r\n                        };\r\n                        LyricUtil.showStatusBarLyric(\r\n                            \"MusicFree\",\r\n                            statusBarLyricConfig ?? {}\r\n                        );\r\n                        Config.setConfig(\"lyric.showStatusBarLyric\", true);\r\n                    } else {\n                        LyricUtil.requestSystemAlertPermission().finally(() => {\r\n                            Toast.warn(t(\"panel.musicItemLyricOptions.desktopLyricPermissionError\"));\r\n                        });\r\n                    }\r\n                } else {\r\n                    LyricUtil.hideStatusBarLyric();\r\n                    Config.setConfig(\"lyric.showStatusBarLyric\", false);\r\n                }\r\n                hidePanel();\r\n            },\r\n        },\r\n        {\r\n            icon: \"arrow-up-tray\",\r\n            title: t(\"panel.musicItemLyricOptions.uploadLocalLyric\"),\r\n            async onPress() {\r\n                try {\r\n                    const result = await getDocumentAsync({\r\n                        copyToCacheDirectory: true,\r\n                    });\r\n                    if (result.canceled) {\r","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/maotoumao/MusicFree/blob/d118b18b3d0c904400f7eea7bf99c0ceec6c1aee/src/components/panels/types/musicItemLyricOptions.tsx#L104-L140","documentation":"When enabling the status-bar (desktop) lyric overlay, the app first checks LyricUtil.checkSystemAlertPermission(). If permission is missing, it requests it via requestSystemAlertPermission() and unconditionally warns with this toast in .finally() — i.e. shown whenever the overlay permission was not already granted (Android 'Display over other apps'). The lyric overlay is not started in this pass.","triggerScenarios":"Pressing the enable-desktop-lyric option in MusicItemLyricOptions (musicItemLyricOptions.tsx:99-124) while lyric.showStatusBarLyric is false and LyricUtil.checkSystemAlertPermission() resolves false; the toast fires in the .finally() of requestSystemAlertPermission regardless of whether the user granted it.","commonSituations":"Fresh Android install where SYSTEM_ALERT_WINDOW is denied by default; user denies the 'draw over other apps' dialog; Android 10+ restrictions on granting overlay permission; running on iOS where the permission model differs and the check fails.","solutions":["Manually grant 'Display over other apps' permission to MusicFree in Android Settings > Apps > Special app access.","Re-toggle the desktop lyric option after granting permission.","Developer: await requestSystemAlertPermission() and re-check checkSystemAlertPermission() before warning, so the toast only appears when the grant actually failed.","Update LyricUtil/native module if permission callbacks are broken on newer Android versions."],"exampleFix":"// before\nLyricUtil.requestSystemAlertPermission().finally(() => {\n    Toast.warn(t(\"panel.musicItemLyricOptions.desktopLyricPermissionError\"));\n});\n// after\nawait LyricUtil.requestSystemAlertPermission();\nif (!(await LyricUtil.checkSystemAlertPermission())) {\n    Toast.warn(t(\"panel.musicItemLyricOptions.desktopLyricPermissionError\"));\n} else {\n    LyricUtil.showStatusBarLyric(\"MusicFree\", statusBarLyricConfig ?? {});\n    Config.setConfig(\"lyric.showStatusBarLyric\", true);\n}","handlingStrategy":"fallback","validationCode":"const hasPermission = await LyricUtil.checkSystemAlertPermission();\nif (!hasPermission) {\n    // prompt user to grant overlay permission manually before enabling the lyric\n    LyricUtil.requestSystemAlertPermission();\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    await LyricUtil.requestSystemAlertPermission();\n    if (await LyricUtil.checkSystemAlertPermission()) {\n        LyricUtil.showStatusBarLyric(\"MusicFree\", config);\n    } else {\n        Toast.warn(t(\"panel.musicItemLyricOptions.desktopLyricPermissionError\"));\n    }\n} catch {\n    Toast.warn(t(\"panel.musicItemLyricOptions.desktopLyricPermissionError\"));\n}","preventionTips":["On first launch, prompt for 'Display over other apps' permission before offering desktop lyrics.","Re-check permission after every request instead of assuming grant/deny.","Provide a deep-link to the app's overlay-permission settings page.","On iOS or unsupported platforms, hide the desktop-lyric option entirely."],"tags":["android","permissions","overlay","toast"],"backgroundTag":"overlay-permission-denied","analyzedSha":"d118b18b3d0c904400f7eea7bf99c0ceec6c1aee","analyzedAt":"2026-08-30T11:49:12.932Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}