2024-12-30 update: As promised, this project is discontinued now that GrapheneOS supports enabling the 80% battery charge limit.
ChargeLimit is a bare-bones app for toggling the 80% battery charge limit on Google Pixel devices with the Tensor SOC. It is also compatible with Pixel devices not running the stock Pixel OS as long as the google_battery
HAL is included in the OS.
ChargeLimit has no UI and does not show up in the launcher. It is only a quick settings tile.
- Quick settings tile
- Minimal permissions
- Does not run in the background
- Only works with Google Pixel devices (Tensor SOC) and Android versions (>= 15 QPR1) where Google officially supports the charge limit feature.
- There are no configuration options because the
google_battery
HAL does not expose anything more than an on/off switch for the charge limit feature. It is possible to implement fancier charge limit functionality by ignoring thegoogle_battery
HAL and configuring the USB controller directly, but this will never be supported in ChargeLimit. - Issues that only happen when not running the stock Pixel OS:
- When the device is plugged in, the battery icon in the status bar will always show the shield and the lock screen will show
Charging on hold to protect battery
, even while the device is still charging. The logic to show better icons and messages are sadly part of Pixel OS' proprietary components, not in AOSP. - As a side effect of not running a background service, when switching between two Android users that are already unlocked, the charge limit setting does not get applied. This only matters when the users have different charge limit settings. This can be worked around by opening the quick settings panel once (without tapping on anything) after switching users.
- When the device is plugged in, the battery icon in the status bar will always show the shield and the lock screen will show
- I plan to stop maintaining this project once GrapheneOS has a native charge limit feature because I'll no longer have a user for it.
-
Download the latest version from the releases page. To verify the digital signature, see the verifying digital signatures section.
-
Install the module in Magisk/KernelSU.
-
Add the ChargeLimit tile to the quick settings panel.
-
That's it!
If you're building a custom OS:
-
Add the following files from the zip:
/system/etc/permissions/privapp-permissions-com.chiller3.chargelimit.xml
/system/priv-app/com.chiller3.chargelimit/app-release.apk
-
Create an SELinux type named
chargelimit_app
as an untrusted app domain:type chargelimit_app, domain, coredomain; app_domain(chargelimit_app) untrusted_app_domain(chargelimit_app) allow chargelimit_app hal_googlebattery_service:service_manager find; binder_call(chargelimit_app, hal_googlebattery)
Alternatively, if you're modifying an already-built OS, use
chargelinux-selinux
to modify the policy../chargelinux-selinux.<arch> -s <old policy> -t <new policy>
-
Add the contents of
plat_seapp_contexts
from the zip to/system/etc/selinux/plat_seapp_contexts
.
RECEIVE_BOOT_COMPLETED
: This permission is used for applying the charge limit setting when the device initially boots and when logging into different Android users.WRITE_SECURE_SETTINGS
: This permission is used to store the charge limit setting in the same place as the stock Pixel OS' builtin setting.
No other permissions are required.
Although ChargeLimit is installed in /system/priv-app/
, the SELinux policy is configured so that the app runs in a new unprivileged SELinux context. This context is given access to the google_battery
HAL so that the app can change the charge limit state.
Both the zip file and the APK contained within are digitally signed.
To verify the digital signatures of the downloads, follow the steps here.
First, extract the apk from the zip and then run:
apksigner verify --print-certs system/priv-app/com.chiller3.chargelimit/app-release.apk
Then, check that the SHA-256 digest of the APK signing certificate is:
441b15be01f7826e8c3bdaba29a2ecc765d87af4672276ca8615e4bd3a3ae78e
Make sure the Rust toolchain is installed. Rust must be installed via rustup because it provides the required Android toolchains:
rustup target add aarch64-linux-android
rustup target add x86_64-linux-android
cargo-android must also be installed.
Then, ChargeLimit can be built like most other Android apps using Android Studio or the gradle command line.
To build the APK:
./gradlew assembleDebug
To build the Magisk/KernelSU module zip (which automatically runs the assembleDebug
task if needed):
./gradlew zipDebug
The output file is written to app/build/distributions/debug/
. The APK will be signed with the default autogenerated debug key.
To create a release build with a specific signing key, set up the following environment variables:
export RELEASE_KEYSTORE=/path/to/keystore.jks
export RELEASE_KEY_ALIAS=alias_name
read -r -s RELEASE_KEYSTORE_PASSPHRASE
read -r -s RELEASE_KEY_PASSPHRASE
export RELEASE_KEYSTORE_PASSPHRASE
export RELEASE_KEY_PASSPHRASE
and then build the release zip:
./gradlew zipRelease
Bug fix pull requests are welcome and much appreciated!
However, aside from that, ChargeLimit will only ever support Google Pixel devices and is intentionally featureless. I am unlikely to implement any new features.
ChargeLimit is licensed under GPLv3. Please see LICENSE
for the full license text.