fix: use permission_handler for battery optimization checks - #3227
Merged
Conversation
Replaces the forked disable_battery_optimization plugin with permission_handler's Permission.ignoreBatteryOptimizations, which was already a dependency and calls the same PowerManager.isIgnoringBatteryOptimizations() and ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS under the hood. The plugin was 2,633 lines of Java across 26 files, of which the app used two methods. The rest is OEM autostart handling reachable only through methods the app never calls. More importantly, the part the app did use was wrong. Its isAllBatteryOptimizationDisabled ANDed the real OS check with two SharedPreferences flags that cached !KillerManager.isActionAvailable(...) on first read and were only ever set by dialog flows the app never invoked. On any device whose OEM ships an autostart settings screen — Samsung, Xiaomi, Oppo, Huawei — that cached false permanently, so the check reported "not disabled" even after the user granted the exemption. Those are the manufacturers whose battery management makes the check matter most. Also: - Declares REQUEST_IGNORE_BATTERY_OPTIMIZATIONS in the app manifest. It used to arrive via the plugin's manifest merger; permission_handler_android ships an empty manifest by design, so without this the permission silently disappears and request() never opens the system prompt. Drops the plugin's stray oppo.permission.OPPO_COMPONENT_SAFE at the same time. - Removes android.enableJetifier. The plugin's material-dialogs 0.9.6.0 pulled com.android.support and was the only thing keeping Jetifier on; with it gone ./gradlew checkJetifier reports all 57 projects clean. AGP 9.1+ rejects the flag outright, so this had to happen eventually. - Both surfaces now re-read status on AppLifecycleState.resumed. The exemption is granted in a system dialog, so returning to the foreground is the only signal that it changed; previously the setup page checked once and never updated. - The setup page shows status in both states — it previously rendered nothing at all when optimizations were still enabled. - The Developer Tools tile routes to openAppSettings() when already exempt. Android has no API to revoke the exemption, so undoing it has to be a trip to system settings rather than the "Already Disabled" dead end it was before. Verified on an Android 16 emulator: the prompt opens, Allow adds the app to the deviceidle whitelist, and the status flips to a green check without a restart. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces the forked
disable_battery_optimizationplugin withpermission_handler'sPermission.ignoreBatteryOptimizations, which was already a dependency and calls the samePowerManager.isIgnoringBatteryOptimizations()/ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONSunder the hood.Split out of the Android build work so the Gradle/AGP upgrade can be reviewed separately.
Why
The plugin was 2,633 lines of Java across 26 files; the app used two methods. The rest is OEM autostart handling reachable only through methods we never call.
The part we did use was wrong.
isAllBatteryOptimizationDisabledANDed the real OS check with two SharedPreferences flags that cached!KillerManager.isActionAvailable(...)on first read and were only ever set by dialog flows the app never invoked. On any device whose OEM ships an autostart settings screen — Samsung, Xiaomi, Oppo, Huawei — that cachedfalsepermanently, so the check reported "not disabled" even after the user granted the exemption. Those are exactly the manufacturers whose battery management makes the check matter.Changes
REQUEST_IGNORE_BATTERY_OPTIMIZATIONSdirectly. It used to arrive via the plugin's manifest merger, andpermission_handler_androidships an empty manifest by design — without this the permission silently disappears andrequest()never opens the system prompt. Also drops the plugin's strayoppo.permission.OPPO_COMPONENT_SAFE.material-dialogs:0.9.6.0pulledcom.android.supportand was the only thing keepingandroid.enableJetifieron. With it gone,./gradlew checkJetifierreports 57/57 projects clean. AGP 9.1+ rejects the flag outright, so this had to happen regardless.AppLifecycleState.resumed. The exemption is granted in a system dialog, so returning to the foreground is the only signal it changed; the setup page previously checked once and never updated.openAppSettings()when already exempt. Android has no revoke API, so undoing this has to be a trip to system settings rather than the "Already Disabled" dead end it was.Testing
Verified on an Android 16 (API 36) emulator, prod flavor:
com.android.settings/.fuelgauge.RequestIgnoreBatteryOptimizationsdialogNoClassDefFoundErrorNot verified: the Developer Tools tile itself — it sits behind a configured server I don't have. It shares the same helpers as the setup page, which are verified, but the tile UI is untested.
🤖 Generated with Claude Code