From 24f11c6221609166d196e314904df24bf87d99c1 Mon Sep 17 00:00:00 2001 From: VR-25 <28943176+VR-25@users.noreply.github.com> Date: Sat, 4 Apr 2020 22:04:33 +0100 Subject: [PATCH] **2020.4.4-dev (202004040)** - acc -(e|d): do not do unnecessary work - acc -f: fixed capacity limit bypass - acc -F: general fixes and optimizations - accs: acc foreground service, works exactly as accd, but remains attached to the terminal - "acc -t --" is now "acc -t" - ACC/service trigger vibrations on certain events (charging enabled/disabled, errors, auto-shutdown warnings and acc -C 100% reached); vibration patterns are customizable - Auto-reset broken/invalid config - Enhanced acc -C compatibility - Fixed busybox setup issues on devices not rooted with Magisk - Misc fixes - Major optimizations - Updated documentation --- .github/FUNDING.yml | 13 ++ META-INF/com/google/android/update-binary | 60 ++++-- README.md | 251 +++++++++++++++------- TODO.txt | 15 +- acc/acc.sh | 233 +++++++++----------- acc/acca.sh | 12 +- acc/accd.sh | 56 ++--- acc/accs.sh | 3 + acc/default-config.txt | 99 +++++---- acc/flash-zips.sh | 22 +- acc/init.sh | 26 ++- acc/logf.sh | 15 +- acc/misc-functions.sh | 240 ++++++++++++--------- acc/oem-custom.sh | 34 ++- acc/print-config.sh | 3 +- acc/print-help.sh | 7 +- acc/set-prop.sh | 32 ++- acc/setup-busybox.sh | 6 +- acc/strings.sh | 82 ++++--- acc/translations/pt-PT/strings.sh | 12 +- acc/translations/zh-rCN/strings.sh | 12 -- acc/uninstall.sh | 16 +- acc/wizard.sh | 8 +- acc/write-config.sh | 1 + bin/acc-uninstaller.zip | Bin 1736 -> 1812 bytes build.sh | 22 +- customize.sh | 60 ++++-- install-latest.sh => install-online.sh | 14 +- install-tarball.sh | 8 +- install-current.sh => install.sh | 60 ++++-- module.prop | 4 +- 31 files changed, 793 insertions(+), 633 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 acc/accs.sh rename install-latest.sh => install-online.sh (87%) rename install-current.sh => install.sh (86%) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ca5b932 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,13 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: VR25 # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: VR25 # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: https://paypal.me/vr25xda/ # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] + diff --git a/META-INF/com/google/android/update-binary b/META-INF/com/google/android/update-binary index 84e3533..37c495c 100644 --- a/META-INF/com/google/android/update-binary +++ b/META-INF/com/google/android/update-binary @@ -1,26 +1,40 @@ #!/system/bin/sh -# $id Installer/Upgrader +# ACC Installer/Upgrader # Copyright (c) 2019-2020, VR25 (xda-developers) # License: GPLv3+ # # devs: triple hashtags (###) mark custom code -set +x - # override the official Magisk module installer SKIPUNZIP=1 + echo id=acc umask 077 + # log mkdir -p /data/adb/${id}-data/logs +chmod -R 700 /data/adb/${id}-data/logs exec 2>/data/adb/${id}-data/logs/install.log set -x -trap 'e=$?; echo; exit $e' EXIT + +exxit() { + local e=$? + set +eo pipefail + rm -rf /dev/.${id}-install + [ $e -ne 0 ] && echo || { + rm /sbin/.$id/.ghost-charging ### + /sbin/acca --daemon > /dev/null || /sbin/accd ### workaround, Magisk 20.4+ + } + exit $e +} 2>/dev/null + +trap exxit EXIT + # set up busybox #BB# @@ -34,16 +48,16 @@ else chmod 700 /dev/.busybox case $PATH in /dev/.busybox:*) :;; - *) PATH=/dev/busybox:$PATH;; + *) PATH=/dev/.busybox:$PATH;; esac [ -x /dev/.busybox/busybox ] || { if [ -f /data/adb/magisk/busybox ]; then - [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox + [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox /data/adb/magisk/busybox --install -s /dev/.busybox elif which busybox > /dev/null; then busybox --install -s /dev/.busybox elif [ -f /data/adb/busybox ]; then - [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox + [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox /data/adb/busybox --install -s /dev/.busybox else echo "(!) Install busybox or simply place it in /data/adb/" @@ -53,12 +67,14 @@ else fi #/BB# + # root check [ $(id -u) -ne 0 ] && { echo "(!) $0 must run as root (su)" exit 4 } + get_prop() { sed -n "s|^$1=||p" ${2:-$srcDir/module.prop}; } set_perms() { @@ -70,24 +86,27 @@ set_perms() { } set_perms_recursive() { - local owner=${2:-0} target="" + local owner=${2-0} target="" find $1 2>/dev/null | while read target; do set_perms $target $owner; done } set -euo pipefail 2>/dev/null || : + # set source code directory [ -f $PWD/${0##*/} ] && srcDir=$PWD || srcDir=${0%/*} srcDir=${srcDir/#"${0##*/}"/"."} -# unzip flashable zip if source code is unavailable + +# extract flashable zip if source code is unavailable [ -f $srcDir/module.prop ] || { - srcDir=/dev/.tmp + srcDir=/dev/.${id}-install rm -rf $srcDir 2>/dev/null || : mkdir $srcDir - unzip ${ZIP:-${3-}} -d $srcDir/ >&2 + unzip "$3" -d $srcDir/ >&2 } + name=$(get_prop name) author=$(get_prop author) version=$(get_prop version) @@ -95,6 +114,7 @@ versionCode=$(get_prop versionCode) installDir=${installDir0:=/data/data/mattecarra.${id}app/files} ### config=/data/adb/${id}-data/config.txt + # check/set parent installation directory [ -d $installDir ] || installDir=/sbin/.magisk/modules [ -d $installDir ] || installDir=/data/adb @@ -103,16 +123,15 @@ config=/data/adb/${id}-data/config.txt ### echo "$name $version ($versionCode) -Copyright (c) 2017-2020, $author -License: GPLv3+ +© 2017-2020, $author +GPLv3+ (i) Installing in $installDir/$id/..." # install -cp $config /data/.${id}-config-bkp 2>/dev/null || : -ash $srcDir/$id/uninstall.sh -mv /data/.${id}-config-bkp $config 2>/dev/null || : +ash $srcDir/$id/uninstall.sh install +rm /data/adb/${id}-data/logs/bootlooped 2>/dev/null || : cp -R $srcDir/$id/ $installDir/ installDir=$(readlink -f $installDir/$id) installDir0=$installDir0/$id @@ -165,12 +184,15 @@ fi # disable magic mount (Magisk) touch /sbin/.magisk/modules/$id/skip_mount 2>/dev/null || : + # restore config backup [ -f $config ] || cp /data/media/0/.${id}-config-backup.txt $config 2>/dev/null || : + # flashable uninstaller cp -f $srcDir/bin/${id}-uninstaller.zip /data/media/0/ + # set perms set_perms_recursive ${config%/*} chmod 666 /data/media/0/${id}-uninstaller.zip @@ -186,6 +208,7 @@ case $installDir in ;; esac + set +euo pipefail 2>/dev/null || : @@ -212,7 +235,6 @@ echo " [ $installDir == /data/adb ] && echo -e "\n(i) Use init.d or an app to run $installDir/${id}-init.sh on boot to initialize ${id}." echo -trap - EXIT # initialize $id if [ -f $installDir/service.sh ]; then @@ -221,8 +243,4 @@ else $installDir/${id}-init.sh --override fi -e=$? -[ $e -eq 0 ] || { echo; exit $e; } -rm /sbin/.$id/.ghost-charging 2>/dev/null ### -/sbin/acca --daemon > /dev/null || /sbin/accd ### workaround, Magisk 20.4+ exit 0 diff --git a/README.md b/README.md index 602edd6..ffc126a 100644 --- a/README.md +++ b/README.md @@ -141,16 +141,16 @@ Two universal methods are: `acc --uninstall` and `/sdcard/acc-uninstaller.zip` ( - `sh install-tarball.sh acc` installs the tarball (acc*gz) from the script's location. The archive must be obtained from GitHub: https://github.com/VR-25/acc/archive/$reference.tar.gz ($reference examples: master, dev, 201908290). -- `sh install-current.sh` installs acc from the extracted source. +- `sh install.sh` installs acc from the extracted source. -- `sh install-latest.sh [-c|--changelog] [-f|--force] [-k|--insecure] [-n|--non-interactive] [%install dir%] [reference]` downloads and installs acc from GitHub. e.g., `sh install-latest.sh dev` +- `sh install-online.sh [-c|--changelog] [-f|--force] [-k|--insecure] [-n|--non-interactive] [%install dir%] [reference]` downloads and installs acc from GitHub. e.g., `sh install-online.sh dev` #### Notes -- `install-current.sh` and `install-tarball.sh` take an optional _parent installation directory_ argument (e.g., sh install-current.sh /data - this will install acc in /data/acc/). +- `install.sh` and `install-tarball.sh` take an optional _parent installation directory_ argument (e.g., sh install.sh /data - this will install acc in /data/acc/). -- `install-latest.sh` is the `acc --upgrade` back-end. +- `install-online.sh` is the `acc --upgrade` back-end. - The order of arguments doesn't matter. @@ -159,11 +159,11 @@ The archive must be obtained from GitHub: https://github.com/VR-25/acc/archive/$ - No argument/option is strictly mandatory. The exception is `--non-interactive` for front-end apps. Unofficially supported front-ends must specify the parent installation directory. Otherwise, the installer will follow the order above. -- Remember that unlike the other two installers, `install-latest.sh` requires the _parent installation directory_ to be enclosed in `%` (e.g., sh install-latest.sh %/data% --non-interactive). +- Remember that unlike the other two installers, `install-online.sh` requires the _parent installation directory_ to be enclosed in `%` (e.g., sh install-online.sh %/data% --non-interactive). -- The `--force` option to install-latest.sh is meant for re-installation and downgrading. +- The `--force` option to install-online.sh is meant for re-installation and downgrading. -- `sh install-latest.sh --changelog --non-interactive` prints the version code (integer) and changelog URL (string) when an update is available. +- `sh install-online.sh --changelog --non-interactive` prints the version code (integer) and changelog URL (string) when an update is available. In interactive mode, it also asks the user whether they want to download and install the update. - You may also want to read `NOTES/TIPS FOR FRONT-END DEVELOPERS > Exit Codes` below. @@ -175,7 +175,7 @@ In interactive mode, it also asks the user whether they want to download and ins ``` #DC# -configVerCode=202003301 +configVerCode=202004040 capacity=(-1 60 70 75 +0 false) temperature=(70 80 90) cooldownCurrent=() @@ -195,6 +195,17 @@ prioritizeBattIdleMode=false forceChargingStatusFullAt100= runCmdOnPause=() dynPowerSaving=0 +vibrationPatterns=(5 0.1 5 0.1 4 0.1 6 0.1 3 0.1) + + +# WARNINGS + +# As seen above, whatever is null can be null. +# Nullifying values that should not be null causes nasty errors. + +# Do NOT feel like you must configure everything! +# If you don't know EXACTLY how to and why you want to do it, it's a very dumb idea. +# Help is always avaliable, from multiple sources - plus, you don't have to pay a penny for it. # BASIC CONFIG EXPLANATION @@ -203,7 +214,7 @@ dynPowerSaving=0 # temperature=(cooldown_temp max_temp max_temp_pause) -# cooldownCurrent=(file raw_current charge_seconds pause_seconds) +# cooldownCurrent=cooldown_current=(file raw_current charge_seconds pause_seconds) # cooldownRatio=(cooldown_charge cooldown_pause) @@ -211,31 +222,33 @@ dynPowerSaving=0 # loopDelay=(loop_delay_charging loop_delay_discharging) -# chargingSwitch=charging_switch=(file1 on off file2 on off) +# chargingSwitch=charging_switch=(ctrl_file1 on off ctrl_file2 on off) + +# applyOnBoot=apply_on_boot=(ctrl_file1::value1::default1 ctrl_file2::value2::default2 ... --exit) -# applyOnBoot=apply_on_boot=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN --exit) +# applyOnPlug=apply_on_plug=(ctrl_file1::value1::default1 ctrl_file2::value2::default2 ...) -# applyOnPlug=apply_on_plug=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN) +# maxChargingCurrent=max_charging_current=([value] ctrl_file1::value::default1 ctrl_file2::value::default2 ...) -# maxChargingCurrent=max_charging_current=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN) +# maxChargingVoltage=max_charging_voltage=([value] ctrl_file1::value::default1 ctrl_file2::value::default2 ...) --exit) -# maxChargingVoltage=max_charging_voltage=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN --exit) +# rebootOnPause=reboot_on_pause=seconds -# rebootOnPause=reboot_on_pause +# switchDelay=switch_delay=seconds -# switchDelay=switch_delay +# language=lang=language_code -# language=lang +# wakeUnlock=wake_unlock=(wakelock1 wakelock2 ...) -# wakeUnlock=wake_unlock=(wakelock1 wakelock2 wakelockN) +# prioritizeBattIdleMode=prioritize_batt_idle_mode=true/false -# prioritizeBattIdleMode=prioritize_batt_idle_mode +# forceChargingStatusFullAt100=force_charging_status_full_at_100=status_code -# forceChargingStatusFullAt100=force_charging_status_full_at_100 +# runCmdOnPause=run_cmd_on_pause=(. script) -# runCmdOnPause=run_cmd_on_pause=(sh|. script) +# dynPowerSaving=dyn_power_saving=seconds -# dynPowerSaving=dyn_power_saving +# vibrationPatterns=vibration_patterns=(auto_shutdown_warning_vibrations interval calibration_vibrations interval enable_charging_vibrations interval error_vibrations interval disable_charging_vibrations interval) # VARIABLE ALIASES/SORTCUTS @@ -278,6 +291,7 @@ dynPowerSaving=0 # ff force_charging_status_full_at_100 # rcp run_cmd_on_pause # dps dyn_power_saving +# vp vibration_patterns # COMMAND EXAMPLES @@ -303,14 +317,17 @@ dynPowerSaving=0 # acc -s "ccu=battery/current_now 1450000 100 20" # acc -s "cooldown_current=battery/current_now 1450000 100 20" +# acc -s vp="5 0.1 4 0.1 6 0.1 3 0.1" +# acc -s vp="5 0.1 - - 6 0.1 - -" # disables vibration for charging enabled/disabled events. + # FINE, BUT WHAT DOES EACH OF THESE VARIABLES ACTUALLY MEAN? # configVerCode # -# This is checked during updates - to determine whether config should be patched. Do NOT modify. +# This is checked during updates to determine whether config should be patched. Do NOT modify. # shutdown_capacity (sc) # -# When the battery is discharging and its capacity <= sc, acc daemon turns the phone off to reduce the discharge rate and protect the battery from pottential damage induced by voltages below the operating range. +# When the battery is discharging and its capacity <= sc, acc daemon turns the phone off to reduce the discharge rate and protect the battery from potential damage induced by voltages below the operating range. # On capacity <= shutdown_capacity + 5, accd enables Android battery saver, triggers 5 vibrations once - and again on each subsequent capacity drop. # cooldown_capacity (cc) # @@ -325,12 +342,12 @@ dynPowerSaving=0 # Capacity at which charging should pause. # capacity_offset (co) # -# Change this only if your system reports incorrect battery capacity ("acc -i" (BMS) vs "dumpsys battery" (system)). +# Change this only if your system reports incorrect battery capacity ("acc -i" (BMS) vs "dumpsys battery" (Android system)). # Pixel devices are know for having this issue. # capacity_sync (cs) # # This is an alternative to capacity_offset. -# It tells acc whether the battery capacity reported by Android should be updated every few seconds to reflect the actual value from the battery management system. +# It tells accd whether the battery capacity reported by Android should be updated every few seconds to reflect the actual value from the battery management system. # Most users would prefer this over capacity_offset. # It's more powerful, but has a cosmetic nuisance: small delays (seconds) in charging status reports. # Such inconvenience is not a bug, nor can it be eliminated at this point. @@ -361,63 +378,64 @@ dynPowerSaving=0 # Reset battery stats after pausing charging. # reset_batt_stats_on_unplug (rbsu) # -# Reset battery stats after unplugging the charger and loop_delay_discharging (seconds) have passed. -# If the charger is plugged within the first loop_delay_discharging (seconds) interval, the operation is aborted. +# Reset battery stats after unplugging the charger AND loop_delay_discharging (seconds) have passed. +# If the charger is replugged within loop_delay_discharging (seconds) after unplugging it, the operation is aborted. # loop_delay_charging (ldc) # # loop_delay_discharging (ldd) # # These are delays (seconds) between loop iterations. -# The lower they are, the faster acc responsiveness is - but possibly at the cost of more CPU time. +# The lower they are, the quicker acc responsiveness is - but at the cost of slightly extra CPU time. # Don't touch these (particularly ldd), unless you know exactly what you're doing. -# accd manages both according to the value of capacity_sync. +# accd manages both according to the state of capacity_sync. # charging_switch (s) # -# If unset, acc cycles through its database and uses whatever works. +# If unset, acc cycles through its database and sets the first working switch/group that disables charging. +# If the set switch/group doesn't work, acc unsets chargingSwitch and repeats the above. +# If all switches fail to disable charging, chargingSwitch is unset, switchDelay is reverted to 1.5 and acc/d exit with error code 7. # apply_on_boot (ab) # # Settings to apply on boot or daemon start/restart. # The --exit flag (refer back to applyOnBoot=...) tells the daemon to stop after applying settings. -# When the --exit flag is not set, default values are restored when the daemon stops. +# If the --exit flag is not included, default values are restored when the daemon stops. # apply_on_plug (ap) # -# Settings to apply on plug. +# Settings to apply on plug # This exists because some /sys files (e.g., current_max) are reset on charger re-plug. # Default values are restored on unplug and when the daemon stops. # max_charging_current (mcc) # # apply_on_plug dedicated to current control -# This is managed with "acc --set --current" commands. +# This is managed with "acc --set --current ..." (acc -s c ...) commands. # Refer back to the command examples. # max_charging_voltage (mcv) # # apply_on_boot dedicated to voltage control -# This is managed with "acc --set --voltage" commands. +# This is managed with "acc --set --voltage ..." (acc -s v ...) commands. # reboot_on_pause (rp) # # If this doesn't make sense to you, you probably don't need it. -# Essentially, this is a timeout (seconds) before rebooting (after pausing charging). +# Essentially, this is a timeout (seconds) before rebooting - after pausing charging. # This reboot is a workaround for a firmware issue that causes abnormally fast battery drain after charging is paused on certain devices. -# The issue has reportedly been fixed by the OEM. So, this could just as well not be here. +# The issue has reportedly been fixed by the OEMs. This setting will eventually be removed. # switch_delay (sd) # -# Delay (seconds) between charging status checks after toggling charging switches +# This is a delay (seconds) between charging status checks after toggling charging switches. It exists because some switches don't react immediately after being toggled. # Most devices/switches work with a value of 1. -# Some devices may require a delay as high as 3. The optimal max is probably 3.5. +# Some may require a delay as high as 3. The optimal max is probably 3.5. # If a charging switch seems to work intermittently, or fails completely, increasing this value may fix the issue. -# You absolutely should increase this value if "acc -t --" reports total failure. +# You absolutely should increase this value if "acc -t" reports total failure. # Some MediaTek devices require a delay as high as 15! # accd manages this setting dynamically. # lang (l) # -# acc language, managed with "acc --set --lang". +# acc language, managed with "acc --set --lang" (acc -s l). # wake_unlock (wu) # # This is an attempt to release wakelocks acquired after disabling charging. -# It may or may not work - and may even cause unexpected side effects. More testing is needed. +# It's totally experimental and may or may not work (expect side effects). # prioritize_batt_idle_mode (pbim) # -# Several devices can draw power directly from the external power supply when charging is paused. -# Test yours with "acc -t --". +# Several devices can draw power directly from the external power supply when charging is paused. Test yours with "acc -t". # This setting dictates whether charging switches that support such feature should take precedence. # force_charging_status_full_at_100 (ff) # @@ -426,7 +444,7 @@ dynPowerSaving=0 # For Pixel devices, the status code of "full" is 5 (ff=5). # The status code is found through trial and error, with the commands "dumpsys battery", "dumpsys battery set status #" and "dumpsys battery reset". -# run_cmd_on_pause (rcp) +# run_cmd_on_pause (rcp) # # Run commands* after pausing charging. # * Usually a script ("sh some_file" or ". some_file") @@ -435,6 +453,11 @@ dynPowerSaving=0 # If dyn_power_saving == 0, the feature is disabled. # * On top of loop_delay_discharging +# vibration_patterns (vp) # +# ACC and ACC service (accs) trigger vibrations on specific events (refer back to BASIC CONFIG EXPLANATION > vibrationPatterns). +# vp lets you customize vibration patterns per event type. +# To disable vibrations for an event, replace "_vibrations interval" with "- -" (hyphen space hyphen, excluding quotes). Refer back to COMMAND EXAMPLES. + #/DC# ``` @@ -462,12 +485,24 @@ The config file itself has configuration instructions. Usage - acc (wizard) - acc [options] [args] - acc [pause_capacity] [resume_capacity] (e.g., acc 75 70) - /sbin/acca [options] [args] (acc optimized for front-ends) + acc Wizard + + accd Start/restart accd + + accd. Stop acc/daemon + + accd, Print acc/daemon status (running or not) + + acc [pause_capacity resume_capacity] e.g., acc 75 70 + + acc [options] [args] Refer to the list of options below - A custom config path can be specified as first parameter. If the file doesn't exist, the current config is cloned. + /sbin/acca [options] [args] acc optimized for front-ends + + accs acc foreground service, works exactly as accd, but attached to the terminal + + A custom config path can be specified as first parameter. + If the file doesn't exist, the current config is cloned. e.g., acc /data/acc-night-config.txt --set pause_capacity=45 resume_capacity=43 acc /data/acc-night-config.txt --set --current 500 @@ -482,7 +517,7 @@ Options acc -c less acc -c cat - -C|--calibrate Charge until battery_status == "Full" + -C|--calibrate Charge to true 100% e.g., acc -C -d|--disable [#%, #s, #m or #h (optional)] Disable charging @@ -504,10 +539,11 @@ Options acc -e 75% (recharge to 75%) acc -e 30m (recharge for 30 minutes) - -f|--force|--full [capacity] Charge to a given capacity (default: 100) once and uninterrupted + -f|--force|--full [capacity] Charge to a given capacity (default: 100) once, uninterrupted and without other restrictions e.g., acc -f 95 (charge to 95%) acc -f (charge to 100%) + Note: not to be confused with -C; -f 100 won't allow charging to true 100% capacity -F|--flash ["zip_file"] Flash any zip files whose update-binary is a shell script e.g., @@ -585,19 +621,16 @@ Options acc -s v - (restore default) acc -s v 3920 --exit (stop the daemon after applying settings) - -t|--test Test charging control (on/off) - e.g., acc -t - - -t|--test [file on off file2 on off] Test custom charging switches + -t|--test [ctrl_file1 on off [ctrl_file2 on off]] Test custom charging switches e.g., acc -t battery/charging_enabled 1 0 acc -t /proc/mtk_battery_cmd/current_cmd 0::0 0::1 /proc/mtk_battery_cmd/en_power_path 1 0 ("::" == " ") - -t|--test -- [file] Test charging switches from a file (default: $TMPDIR/charging-switches) + -t|--test [file] Test charging switches from a file (default: $TMPDIR/charging-switches) This will also report whether "battery idle" mode is supported e.g., - acc -t -- (test known switches) - acc -t -- /sdcard/experimental_switches.txt (test custom/foreign switches) + acc -t (test known switches) + acc -t /sdcard/experimental_switches.txt (test custom/foreign switches) -T|--logtail Monitor accd log (tail -F) e.g., acc -T @@ -625,6 +658,23 @@ Options acc -w0 (no extra delay) +Exit Codes + + 0. True/success + 1. False or general failure + 2. Incorrect command syntax + 3. Missing busybox binary + 4. Not running as root + 5. Update available ("--upgrade") + 6. No update available ("--upgrade") + 7. Couldn't disable charging + 8. Daemon already running ("--daemon start") + 9. Daemon not running ("--daemon" and "--daemon stop") + 10. "--test" failed + + Logs are exported automatically ("--log --export") on exit codes 1, 2, 7 and 10. + + Tips Commands can be chained for extended functionality. @@ -653,6 +703,8 @@ It's best to write full commands over short equivalents - e.g., `/sbin/acca --se Include provided descriptions for ACC features/settings in your app(s). Provide additional information (trusted) where appropriate. Explain settings/concepts as clearly and with as few words as possible. +Take advantage of exit codes. Refer back to `SETUP/USAGE > Terminal Commands > Exit Codes`. + ### Online ACC Install @@ -660,12 +712,12 @@ Explain settings/concepts as clearly and with as few words as possible. 1) Check whether ACC is installed (exit code 0) /sbin/acca --version > /dev/null -2) Download the installer (https://raw.githubusercontent.com/VR-25/acc/master/install-latest.sh) +2) Download the installer (https://raw.githubusercontent.com/VR-25/acc/master/install-online.sh) - e.g., curl -#LO URL - wget -O install-latest.sh URL + wget -O install-online.sh URL -3) Run "sh install-latest.sh" (installation progress is shown) +3) Run "sh install-online.sh" (installation progress is shown) ``` ### Offline ACC Install @@ -678,21 +730,6 @@ Refer back to the `BUILDING AND/OR INSTALLING FROM SOURCE` section. - ACC App, a.k.a., AccA (installDir=/data/data/mattecarra.accapp/files/acc/) -### Exit Codes - -0. True or success -1. False or general failure -2. [Contextual] incorrect command usage or external power supply not detected -3. Missing busybox binary -4. Not running as root -5. Update available -6. No update available -7. Couldn't disable charging -8. [Contextual] Daemon already running (`--daemon start`) or not running (`--daemon stop`) - -Logs are exported automatically (`--log --export`) on exit codes `1`, `2` and `7`. - - --- ## TROUBLESHOOTING @@ -756,6 +793,8 @@ Kernel level permissions forbid write access to certain interfaces. ### Diagnostics/Logs +ACC/service trigger vibrations on certain events (charging enabled/disabled, errors, auto-shutdown warnings and acc -C 100% reached). + Volatile logs are in `/sbin/.acc/`. Persistent logs are found at `/data/adb/acc-data/logs/`. @@ -908,6 +947,48 @@ Travel profile: capacity up to 95% and/or voltage no higher than 4200 mV \* https://batteryuniversity.com/index.php/learn/article/how_to_prolong_lithium_based_batteries/ +> I don't really understand what the "-f|--force|--full [capacity]" is meant for. + +Consider the following situation: + +You're almost late for an important event. +You recall that I stole your power bank and sold it on Ebay. +You need your phone and a good battery backup. +The event will take the whole day and you won't have access to an external power supply in the middle of nowhere. +You need your battery charged fast and as much as possible. +However, you don't want to modify ACC config nor manually stop/restart the daemon. + + +> What's DJS? + +It's a standalone program: Daily Job Scheduler. +As the name suggests, it's meant for scheduling "jobs" - in this context, acc profiles/settings. +Underneath, it runs commands/scripts at specified times - either once, daily and/or on boot. + + +> Do I have to install/upgrade both ACC and AccA? + +To really get out of this dilemma, you have to understand what ACC and AccA essentially are. + +ACC is a Android program that controls charging. +It can be installed as an app (e.g., AccA) module, Magisk module or standalone software. Its installer determines the installation path/variant. The user is given the power to override that. +A plain text file holds the program's configuration. It can be edited with any root text editor. +ACC has a command line interface (CLI) - which in essence is a set of Application Programing Interfaces (APIs). The main purpose of a CLI/API is making difficult tasks ordinary. + +AccA is a graphical user interface (GUI) for the ACC command line. The main purpose of a GUI is making ordinary tasks simpler. +AccA ships with a version of ACC that is automatically installed when the app is first launched. + +That said, it should be pretty obvious that ACC is like a fully autonomous car that also happens to have a steering wheel and other controls for a regular driver to hit a tree. +Think of AccA as a robotic driver that often prefers hitting people over trees. +Due to extenuating circumstances, that robot is not upgraded as frequently as the car. +Upgrading the car regularly, makes the driver happier - even though I doubt it has any emotion to speak of. + + +> Does acc work also when Android is off? + +No. + + --- ## LINKS @@ -930,6 +1011,20 @@ Travel profile: capacity up to 95% and/or voltage no higher than 4200 mV --- ## LATEST CHANGES +**2020.4.4-dev (202004040)** +- acc -(e|d): do not do unnecessary work +- acc -f: fixed capacity limit bypass +- acc -F: general fixes and optimizations +- accs: acc foreground service, works exactly as accd, but remains attached to the terminal +- "acc -t --" is now "acc -t" +- ACC/service trigger vibrations on certain events (charging enabled/disabled, errors, auto-shutdown warnings and acc -C 100% reached); vibration patterns are customizable +- Auto-reset broken/invalid config +- Enhanced acc -C compatibility +- Fixed busybox setup issues on devices not rooted with Magisk +- Misc fixes +- Major optimizations +- Updated documentation + **2020.3.30-r1-dev (202003301)** - Misc fixes - Preserve as many config parameters as possible across (up|down)grades @@ -937,7 +1032,7 @@ Travel profile: capacity up to 95% and/or voltage no higher than 4200 mV **2020.3.30-dev (202003300)** - `-C|--calibrate`: charge until battery_status == "Full" - `acc -i`: fixed current_now conversion (Redmi 6 Pro and other msm8953 based devices) -- `acc -u, install-latest.sh`: optional -k|--insecure flag +- `acc -u, install-online.sh`: optional -k|--insecure flag - accd manages capacity_sync loop_delay_charging, loop_delay_discharging and switch_delay parameters dynamically - Charging switch tests take significantly longer (switch_delay=18); this leads to more consistent results - Enable Android battery saver on capacity <= shutdown_capacity + 5 diff --git a/TODO.txt b/TODO.txt index de573d8..97c9911 100644 --- a/TODO.txt +++ b/TODO.txt @@ -4,17 +4,6 @@ cooldown full POSIX compliance -acc not initializing +sometimes, acc is not initialized + Magisk forgetting to run acc boot scripts? logs/bootlooped? - -/sbin/acc/bootooped shouldn't exist - -install log not generated - harpia - unknown cause - -mistakenly created /sbin/.acc/.ghost-charging? - -downgrades: patch config instead of resetting it completely - -vibrate on charging enabled/disabled events diff --git a/acc/acc.sh b/acc/acc.sh index 100d153..35c90a8 100644 --- a/acc/acc.sh +++ b/acc/acc.sh @@ -8,7 +8,7 @@ daemon_ctrl() { local isRunning=true set +eo pipefail 2>/dev/null - local pid="$(pgrep -f '/ac(c|ca) (-|--)(calibrate|[Cdef])|/accd\.sh' | sed s/$$//)" + local pid="$(pgrep -f '/ac(c|ca) (-|--)(calibrate|test|[Cdeft])|/accd\.sh' | sed /$$/d)" set -eo pipefail 2>/dev/null || : [[ ${pid:-x} == *[0-9]* ]] || isRunning=false @@ -27,24 +27,17 @@ daemon_ctrl() { stop) if $isRunning; then - set +eo pipefail 2>/dev/null - echo "$pid" | xargs kill -9 2>/dev/null - { dumpsys battery reset - not_charging && { - enable_charging || try_enabling_again - } - [ ${2:-x} != skipab ] && { - case "${2-}" in - forceab) apply_on_boot default force;; - *) apply_on_boot default;; - esac - } - apply_on_plug default; } > /dev/null 2>&1 + (set +euo pipefail + echo "$pid" | xargs kill $2) 2>/dev/null || : + sleep 0.2 + while [ -n "$(pgrep -f '/ac(c|ca) (-|--)(calibrate|test|[Cdeft])|/accd\.sh' | sed /$$/d)" ]; do + sleep 0.2 + done print_stopped return 0 else print_not_running - return 8 + return 9 fi ;; @@ -63,7 +56,7 @@ daemon_ctrl() { return 0 else print_not_running - return 1 + return 9 fi ;; esac @@ -105,129 +98,86 @@ get_prop() { sed -n "s|^$1=||p" ${2:-$config}; } test_charging_switch() { - local failed=false - - if [ -n "${1-}" ]; then - - chmod +w $1 ${4-} && echo "${3//::/ }" > $1 && echo "${6//::/ }" > ${4:-/dev/null} && sleep $switchDelay + local failed=false switchDelay=20 - ! not_charging && failed=true || { - grep -iq 'not' $batt/status \ - && battIdleMode=true \ - || battIdleMode=false - } + chmod +w $1 ${4-} \ + && echo "${3//::/ }" > $1 \ + && echo "${6//::/ }" > ${4:-/dev/null} \ + && sleep $switchDelay - if ! $failed && echo "${2//::/ }" > $1 && echo "${5//::/ }" > ${4:-/dev/null} \ - && sleep $switchDelay && ! not_charging - then - print_switch_works "$@" - echo "- battIdleMode=$battIdleMode" - return 0 - else - print_switch_fails "$@" - { echo "${2//::/ }" > $1 - echo "${5//::/ }" > ${4:-/dev/null}; } 2>/dev/null - return 1 - fi + ! not_charging && failed=true || { + vibrate ${vibrationPatterns[8]} ${vibrationPatterns[9]} + grep -iq 'not' $batt/status \ + && battIdleMode=true \ + || battIdleMode=false + } + if ! $failed && echo "${2//::/ }" > $1 \ + && echo "${5//::/ }" > ${4:-/dev/null} \ + && sleep $switchDelay && ! not_charging && vibrate ${vibrationPatterns[4]} ${vibrationPatterns[5]} + then + print_switch_works "$@" + echo "- battIdleMode=$battIdleMode" + return 0 else - - { - disable_charging || try_disabling_again - ! not_charging && failed=true || { - enable_charging || try_enabling_again - } - } > /dev/null - - if ! $failed && ! not_charging; then - print_supported - return 0 - else - print_unsupported - ({ enable_charging || try_enabling_again; } > /dev/null 2>&1 &) & - return 1 - fi - + print_switch_fails "$@" + { echo "${2//::/ }" > $1 + echo "${5//::/ }" > ${4:-/dev/null}; } 2>/dev/null + return 1 fi } exxit() { local exitCode=$? - ! { ! ${noEcho:-false} && ${verbose:-true}; } || echo - [[ $exitCode == [0568] ]] || { - vibrate 3 0.3 - [[ $exitCode != [127] ]] || logf --export > /dev/null 2>&1 + set +euxo pipefail 2>/dev/null + ! ${noEcho:-false} && ${verbose:-true} && echo + [[ $exitCode == [05689] ]] || { + [[ $exitCode == [127] || $exitCode == 10 ]] && logf --export + echo + vibrate ${vibrationPatterns[6]-6} ${vibrationPatterns[7]-0.1} } rm /dev/.acc-config 2>/dev/null exit $exitCode } -umask 077 +! ${verbose:-true} || echo isAccd=false modPath=/sbin/.acc/acc -export TMPDIR=${modPath%/*} -config=/data/adb/acc-data/config.txt defaultConfig=$modPath/default-config.txt -[ -f $TMPDIR/.ghost-charging ] && ghostCharging=true || ghostCharging=false - - # load generic functions . $modPath/logf.sh . $modPath/misc-functions.sh -! ${verbose:-true} || echo -. $modPath/setup-busybox.sh - -device=$(getprop ro.product.device | grep .. || getprop ro.build.product) log=$TMPDIR/acc-${device}.log # verbose if ${verbose:-true} && [[ "${1-}" != *-w* ]]; then touch $log - trap exxit EXIT - if [ $(du -m $log | cut -f 1) -lt 2 ]; then - echo "###$(date)###" >> $log - set -x 2>>$log - else - set -x 2>$log - fi + [ $(du -m $log | cut -f 1) -ge 2 ] && : > $log + echo "###$(date)###" >> $log + echo "versionCode=$(sed -n s/versionCode=//p $modPath/module.prop 2>/dev/null)" >> $log + set -x 2>>$log fi -set -euo pipefail 2>/dev/null || : -cd /sys/class/power_supply/ -mkdir -p ${config%/*} -[ -f $config ] || cp $defaultConfig $config -. $config - - -# config backup -[ ! -d /data/media/0/?ndroid ] || { - [ /data/media/0/.acc-config-backup.txt -nt $config ] \ - || install -m 777 $config /data/media/0/.acc-config-backup.txt 2>/dev/null || : -} - -# load config from a custom path -case "${1-}" in - */*) - [ -f $1 ] || cp $config $1 - config=$1 - . $config - shift - ;; -esac - - accVer=$(get_prop version $modPath/module.prop) accVerCode=$(get_prop versionCode $modPath/module.prop) unset -f get_prop -batt=$(echo *attery/capacity | cut -d ' ' -f 1 | sed 's|/capacity||') + +misc_stuff "${1-}" +[[ "${1-}" != */* ]] || shift +config__=$config + + +/system/bin/sh -n $config 2>/dev/null \ + || cp -f $modPath/default-config.txt $config +. $config # load default language (English) @@ -272,10 +222,12 @@ case "${1-}" in ;; -C|--calibrate) - daemon_ctrl stop > /dev/null || : + daemon_ctrl stop > /dev/null && daemonWasUp=true || daemonWasUp=false print_quit CTRL-C sleep 2 - until [ $(cat $batt/status) == Full ]; do + while [ $(cat $batt/status) != Full ] \ + && ! [[ $(cat $batt/status) == Charging && $(cat $batt/charge_type 2>/dev/null || :) != [FS]* ]] + do for i in "¦ % ¦" "\\ > % < /" "- >> % << -" "/ >>> % <<< \\"; do clear echo -n "$i" | sed "s/%/[$(cat $batt/capacity)%]/" @@ -283,15 +235,18 @@ case "${1-}" in done unset i done - vibrate 5 0.3 + vibrate ${vibrationPatterns[2]} ${vibrationPatterns[3]} print_discharge + ! $daemonWasUp || /sbin/accd $config ;; -d|--disable) shift - print_m_mode - ! daemon_ctrl stop > /dev/null || print_stopped - disable_charging "$@" || try_disabling_again "$@" + not_charging && print_already_discharging || { + print_m_mode + ! daemon_ctrl stop > /dev/null || print_stopped + disable_charging "$@" + } ;; -D|--daemon) @@ -300,15 +255,17 @@ case "${1-}" in -e|--enable) shift - print_m_mode - ! daemon_ctrl stop > /dev/null || print_stopped - enable_charging "$@" || try_enabling_again "$@" + ! not_charging && print_already_charging || { + print_m_mode + ! daemon_ctrl stop > /dev/null || print_stopped + enable_charging "$@" + } ;; -f|--force|--full) daemon_ctrl stop > /dev/null && daemonWasUp=true || daemonWasUp=false print_charging_enabled_until ${2:-100}% - (enable_charging ${2:-100}% nodisable || try_enabling_again ${2:-100}% nodisable + (enable_charging ${2:-100}% noap ! $daemonWasUp || /sbin/accd $config &) > /dev/null 2>&1 & ;; @@ -363,52 +320,54 @@ case "${1-}" in -t|--test) shift + ! not_charging || print_unplugged print_wait cp $config /dev/.acc-config - oldConfig=$config config=/dev/.acc-config - daemon_ctrl stop > /dev/null && daemonWasUp=true || daemonWasUp=false + exec 3>&1 + forceVibrations=true + daemon_ctrl stop && daemonWasUp=true || daemonWasUp=false + set +eo pipefail 2>/dev/null - switchDelay=18 # to account for switches with absurdly slow responsiveness - not_charging && { enable_charging || try_enabling_again; } > /dev/null + enable_charging not_charging && { - print_unplugged - config=$oldConfig - $daemonWasUp && /sbin/accd $config - exit 2 + (print_wait_plug + trap '$daemonWasUp && { + /sbin/accd $config__ + print_started + }' EXIT + while not_charging; do + sleep 1 + set +x + done) } - case "${1-}" in - --) - exitCode=1 + case "${2-}" in + "") + exitCode=10 while read chargingSwitch; do [ -f "$(echo "$chargingSwitch" | cut -d ' ' -f 1)" ] && { echo test_charging_switch $chargingSwitch } [ $? -eq 0 ] && exitCode=0 - done < ${2:-$TMPDIR/charging-switches} + done < ${1-$TMPDIR/charging-switches} echo ;; - "") - test_charging_switch - ;; *) test_charging_switch "$@" ;; esac : ${exitCode=$?} - config=$oldConfig - $daemonWasUp && /sbin/accd $config - - if [ $exitCode -ne 0 ]; then - logf --export - exit 1 - else - exit 0 - fi + + $daemonWasUp && { + /sbin/accd $config__ + print_started + } + + exit $exitCode ;; @@ -427,12 +386,12 @@ case "${1-}" in *) insecure=;; esac - curl $insecure -Lo $TMPDIR/install-latest.sh https://raw.githubusercontent.com/VR-25/acc/$reference/install-latest.sh + curl $insecure -Lo $TMPDIR/install-online.sh https://raw.githubusercontent.com/VR-25/acc/$reference/install-online.sh trap - EXIT set +euo pipefail 2>/dev/null installDir=$(readlink -f $modPath) installDir=${installDir%/*} - . $TMPDIR/install-latest.sh "$@" %$installDir% $reference + . $TMPDIR/install-online.sh "$@" %$installDir% $reference ;; -U|--uninstall) diff --git a/acc/acca.sh b/acc/acca.sh index 998897d..b7a6ee7 100644 --- a/acc/acca.sh +++ b/acc/acca.sh @@ -29,12 +29,16 @@ case "${1-}" in ;; esac +# reset broken/invalid config +/system/bin/sh -n $config 2>/dev/null \ + || cp -f $modPath/default-config.txt $config + case "$@" in # check daemon status -D|--daemon) - pgrep -f '/ac(c|ca) (-|--)(calibrate|[Cdef])|/accd\.sh' && exit 0 || exit 8 + pgrep -f '/ac(c|ca) (-|--)(calibrate|test|[Cdeft])|/accd\.sh' && exit 0 || exit 9 ;; # print battery uevent data @@ -60,14 +64,14 @@ case "$@" in # print default config -s\ d|-s\ --print-default|--set\ d|--set\ --print-default) . $defaultConfig - . ./print-config.sh | grep -E "${3:-.}" + . ./print-config.sh | grep -E "${3-.}" exit $? ;; # print current config -s\ p|-s\ --print|--set\ p|--set\ --print) . $config - . ./print-config.sh | grep -E "${3:-.}" + . ./print-config.sh | grep -E "${3-.}" exit $? ;; @@ -75,6 +79,6 @@ esac # other acc commands -set +euo pipefail 2>/dev/null || : +set +euo pipefail 2>/dev/null export verbose=false /sbin/acc $config "$@" diff --git a/acc/accd.sh b/acc/accd.sh index 224a1f8..121ae73 100644 --- a/acc/accd.sh +++ b/acc/accd.sh @@ -20,10 +20,9 @@ exxit() { [[ $exitCode == [127] ]] && { . ${0%/*}/logf.sh logf --export > /dev/null 2>&1 + vibrate ${vibrationPatterns[6]-6} ${vibrationPatterns[7]-0.1} } rm $config - exec 1>&3 3>&- - vibrate 3 0.3 exit $exitCode } @@ -75,9 +74,11 @@ is_charging() { [ -n "$dischgStatusCode" ] || { ! dumpsys battery reset || { ! dischgStatusCode=$(dumpsys battery 2>/dev/null | sed -n 's/^ status: //p') || { - if [ $(dumpsys battery 2>/dev/null | sed -n 's/^ level: //p') -ne $(cat $batt/capacity) ]; then - sleep 1 - [ $(dumpsys battery 2>/dev/null | sed -n 's/^ level: //p') -eq $(cat $batt/capacity) ] || { + if [ $(dumpsys battery 2>/dev/null | sed -n 's/^ level: //p') -ne $(cat $batt/capacity) ] \ + && sleep 2 \ + && [ $(dumpsys battery 2>/dev/null | sed -n 's/^ level: //p') -ne $(cat $batt/capacity) ] + then + ${capacity[5]} || { capacity[4]=+0 capacity[5]=true [ ${loopDelay[0]} -le 5 ] || loopDelay[0]=5 @@ -174,7 +175,7 @@ ctrl_charging() { || [ $(( $(cat $batt/capacity) ${capacity[4]} )) -ge ${capacity[3]} ] then [ -f ${config%/*}/.rebootedOnPause ] || { - disable_charging || try_disabling_again + disable_charging ! ${resetBattStats[0]} || { # reset battery stats on pause dumpsys batterystats --reset || : @@ -216,7 +217,7 @@ ctrl_charging() { then cooldown=true dumpsys battery set status $chgStatusCode || : # to block unwanted display wakeups - disable_charging || try_disabling_again + disable_charging [ $(sed s/-// ${cooldownCurrent[0]:-cooldownCurrent} 2>/dev/null || echo 0) -ge ${cooldownCurrent[1]:-1} ] \ && sleep ${cooldownCurrent[3]:-1} \ || sleep ${cooldownRatio[1]:-1} @@ -254,7 +255,7 @@ ctrl_charging() { c=$(cat $batt/capacity) for i in $warningThresholds; do [ $c -ne $i ] || { - vibrate 5 0.3 >&3 + vibrate ${vibrationPatterns[0]} ${vibrationPatterns[1]} warningThresholds=${warningThresholds/$i} $lowPower || { ! settings put global low_power 1 || lowPower=true @@ -282,7 +283,6 @@ ctrl_charging() { . ${0%/*}/misc-functions.sh -umask 077 isAccd=true cooldown=false hibernate=true @@ -294,55 +294,28 @@ secondsUnplugged=0 frozenBattSvc=false applyOnUnplug=false resetBattStatsOnUnplug=false -modPath=/sbin/.acc/acc -export TMPDIR=${modPath%/*} +log=$TMPDIR/accd-${device}.log forcedChargingStatusFullAt100=false -config=/data/adb/acc-data/config.txt - -[ -f $TMPDIR/.ghost-charging ] \ - && ghostCharging=true \ - || ghostCharging=false -. $modPath/setup-busybox.sh - -device=$(getprop ro.product.device | grep .. || getprop ro.build.product) -log=$TMPDIR/accd-${device}.log - # verbose echo "###$(date)###" >> $log echo "versionCode=$(sed -n s/versionCode=//p $modPath/module.prop 2>/dev/null)" >> $log exec 3>&1 exec >> $log 2>&1 -trap exxit EXIT set -x -pgrep -f '/ac(c|ca) (-|--)(calibrate|[Cdef])|/accd\.sh' | sed s/$$// | xargs kill -9 2>/dev/null -set -euo pipefail 2>/dev/null || : -cd /sys/class/power_supply/ -mkdir -p ${config%/*} -[ -f $config ] || cp $modPath/default-config.txt $config -# config backup -[ ! -d /data/media/0/?ndroid ] || { - [ /data/media/0/.acc-config-backup.txt -nt $config ] \ - || install -m 777 $config /data/media/0/.acc-config-backup.txt 2>/dev/null -} +pgrep -f '/ac(c|ca) (-|--)(calibrate|test|[Cdeft])|/accd\.sh' | sed /$$/d | xargs kill -9 2>/dev/null -# custom config path -case "${1-}" in - */*) - [ -f $1 ] || cp $config $1 - config=$1 - ;; -esac +misc_stuff "${1-}" -batt=$(echo *attery/capacity | cut -d ' ' -f 1 | sed 's|/capacity||') . $modPath/oem-custom.sh . $config -# auto-shutdown warning thresholds + +# set auto-shutdown warning thresholds _warningThresholds=" $( for i in 5 4 3 2 1; do @@ -352,6 +325,7 @@ _warningThresholds=" " warningThresholds=$_warningThresholds + apply_on_boot ctrl_charging exit $? diff --git a/acc/accs.sh b/acc/accs.sh new file mode 100644 index 0000000..68c4a50 --- /dev/null +++ b/acc/accs.sh @@ -0,0 +1,3 @@ +#!/dev/.busybox/ash +/sbin/.acc/acc/accd.sh "$@" +exit $? diff --git a/acc/default-config.txt b/acc/default-config.txt index af9af3b..f599d3d 100644 --- a/acc/default-config.txt +++ b/acc/default-config.txt @@ -1,4 +1,4 @@ -configVerCode=202003301 +configVerCode=202004040 capacity=(-1 60 70 75 +0 false) temperature=(70 80 90) cooldownCurrent=() @@ -18,6 +18,17 @@ prioritizeBattIdleMode=false forceChargingStatusFullAt100= runCmdOnPause=() dynPowerSaving=0 +vibrationPatterns=(5 0.1 5 0.1 4 0.1 6 0.1 3 0.1) + + +# WARNINGS + +# As seen above, whatever is null can be null. +# Nullifying values that should not be null causes nasty errors. + +# Do NOT feel like you must configure everything! +# If you don't know EXACTLY how to and why you want to do it, it's a very dumb idea. +# Help is always avaliable, from multiple sources - plus, you don't have to pay a penny for it. # BASIC CONFIG EXPLANATION @@ -26,7 +37,7 @@ dynPowerSaving=0 # temperature=(cooldown_temp max_temp max_temp_pause) -# cooldownCurrent=(file raw_current charge_seconds pause_seconds) +# cooldownCurrent=cooldown_current=(file raw_current charge_seconds pause_seconds) # cooldownRatio=(cooldown_charge cooldown_pause) @@ -34,31 +45,33 @@ dynPowerSaving=0 # loopDelay=(loop_delay_charging loop_delay_discharging) -# chargingSwitch=charging_switch=(file1 on off file2 on off) +# chargingSwitch=charging_switch=(ctrl_file1 on off ctrl_file2 on off) -# applyOnBoot=apply_on_boot=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN --exit) +# applyOnBoot=apply_on_boot=(ctrl_file1::value1::default1 ctrl_file2::value2::default2 ... --exit) -# applyOnPlug=apply_on_plug=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN) +# applyOnPlug=apply_on_plug=(ctrl_file1::value1::default1 ctrl_file2::value2::default2 ...) -# maxChargingCurrent=max_charging_current=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN) +# maxChargingCurrent=max_charging_current=([value] ctrl_file1::value::default1 ctrl_file2::value::default2 ...) -# maxChargingVoltage=max_charging_voltage=(file1::value1::default1 file2::value2::default2 fileN::valueN::defaultN --exit) +# maxChargingVoltage=max_charging_voltage=([value] ctrl_file1::value::default1 ctrl_file2::value::default2 ...) --exit) -# rebootOnPause=reboot_on_pause +# rebootOnPause=reboot_on_pause=seconds -# switchDelay=switch_delay +# switchDelay=switch_delay=seconds -# language=lang +# language=lang=language_code -# wakeUnlock=wake_unlock=(wakelock1 wakelock2 wakelockN) +# wakeUnlock=wake_unlock=(wakelock1 wakelock2 ...) -# prioritizeBattIdleMode=prioritize_batt_idle_mode +# prioritizeBattIdleMode=prioritize_batt_idle_mode=true/false -# forceChargingStatusFullAt100=force_charging_status_full_at_100 +# forceChargingStatusFullAt100=force_charging_status_full_at_100=status_code -# runCmdOnPause=run_cmd_on_pause=(sh|. script) +# runCmdOnPause=run_cmd_on_pause=(. script) -# dynPowerSaving=dyn_power_saving +# dynPowerSaving=dyn_power_saving=seconds + +# vibrationPatterns=vibration_patterns=(auto_shutdown_warning_vibrations interval calibration_vibrations interval enable_charging_vibrations interval error_vibrations interval disable_charging_vibrations interval) # VARIABLE ALIASES/SORTCUTS @@ -101,6 +114,7 @@ dynPowerSaving=0 # ff force_charging_status_full_at_100 # rcp run_cmd_on_pause # dps dyn_power_saving +# vp vibration_patterns # COMMAND EXAMPLES @@ -126,14 +140,17 @@ dynPowerSaving=0 # acc -s "ccu=battery/current_now 1450000 100 20" # acc -s "cooldown_current=battery/current_now 1450000 100 20" +# acc -s vp="5 0.1 4 0.1 6 0.1 3 0.1" +# acc -s vp="5 0.1 - - 6 0.1 - -" # disables vibration for charging enabled/disabled events. + # FINE, BUT WHAT DOES EACH OF THESE VARIABLES ACTUALLY MEAN? # configVerCode # -# This is checked during updates - to determine whether config should be patched. Do NOT modify. +# This is checked during updates to determine whether config should be patched. Do NOT modify. # shutdown_capacity (sc) # -# When the battery is discharging and its capacity <= sc, acc daemon turns the phone off to reduce the discharge rate and protect the battery from pottential damage induced by voltages below the operating range. +# When the battery is discharging and its capacity <= sc, acc daemon turns the phone off to reduce the discharge rate and protect the battery from potential damage induced by voltages below the operating range. # On capacity <= shutdown_capacity + 5, accd enables Android battery saver, triggers 5 vibrations once - and again on each subsequent capacity drop. # cooldown_capacity (cc) # @@ -148,12 +165,12 @@ dynPowerSaving=0 # Capacity at which charging should pause. # capacity_offset (co) # -# Change this only if your system reports incorrect battery capacity ("acc -i" (BMS) vs "dumpsys battery" (system)). +# Change this only if your system reports incorrect battery capacity ("acc -i" (BMS) vs "dumpsys battery" (Android system)). # Pixel devices are know for having this issue. # capacity_sync (cs) # # This is an alternative to capacity_offset. -# It tells acc whether the battery capacity reported by Android should be updated every few seconds to reflect the actual value from the battery management system. +# It tells accd whether the battery capacity reported by Android should be updated every few seconds to reflect the actual value from the battery management system. # Most users would prefer this over capacity_offset. # It's more powerful, but has a cosmetic nuisance: small delays (seconds) in charging status reports. # Such inconvenience is not a bug, nor can it be eliminated at this point. @@ -184,63 +201,64 @@ dynPowerSaving=0 # Reset battery stats after pausing charging. # reset_batt_stats_on_unplug (rbsu) # -# Reset battery stats after unplugging the charger and loop_delay_discharging (seconds) have passed. -# If the charger is plugged within the first loop_delay_discharging (seconds) interval, the operation is aborted. +# Reset battery stats after unplugging the charger AND loop_delay_discharging (seconds) have passed. +# If the charger is replugged within loop_delay_discharging (seconds) after unplugging it, the operation is aborted. # loop_delay_charging (ldc) # # loop_delay_discharging (ldd) # # These are delays (seconds) between loop iterations. -# The lower they are, the faster acc responsiveness is - but possibly at the cost of more CPU time. +# The lower they are, the quicker acc responsiveness is - but at the cost of slightly extra CPU time. # Don't touch these (particularly ldd), unless you know exactly what you're doing. -# accd manages both according to the value of capacity_sync. +# accd manages both according to the state of capacity_sync. # charging_switch (s) # -# If unset, acc cycles through its database and uses whatever works. +# If unset, acc cycles through its database and sets the first working switch/group that disables charging. +# If the set switch/group doesn't work, acc unsets chargingSwitch and repeats the above. +# If all switches fail to disable charging, chargingSwitch is unset, switchDelay is reverted to 1.5 and acc/d exit with error code 7. # apply_on_boot (ab) # # Settings to apply on boot or daemon start/restart. # The --exit flag (refer back to applyOnBoot=...) tells the daemon to stop after applying settings. -# When the --exit flag is not set, default values are restored when the daemon stops. +# If the --exit flag is not included, default values are restored when the daemon stops. # apply_on_plug (ap) # -# Settings to apply on plug. +# Settings to apply on plug # This exists because some /sys files (e.g., current_max) are reset on charger re-plug. # Default values are restored on unplug and when the daemon stops. # max_charging_current (mcc) # # apply_on_plug dedicated to current control -# This is managed with "acc --set --current" commands. +# This is managed with "acc --set --current ..." (acc -s c ...) commands. # Refer back to the command examples. # max_charging_voltage (mcv) # # apply_on_boot dedicated to voltage control -# This is managed with "acc --set --voltage" commands. +# This is managed with "acc --set --voltage ..." (acc -s v ...) commands. # reboot_on_pause (rp) # # If this doesn't make sense to you, you probably don't need it. -# Essentially, this is a timeout (seconds) before rebooting (after pausing charging). +# Essentially, this is a timeout (seconds) before rebooting - after pausing charging. # This reboot is a workaround for a firmware issue that causes abnormally fast battery drain after charging is paused on certain devices. -# The issue has reportedly been fixed by the OEM. So, this could just as well not be here. +# The issue has reportedly been fixed by the OEMs. This setting will eventually be removed. # switch_delay (sd) # -# Delay (seconds) between charging status checks after toggling charging switches +# This is a delay (seconds) between charging status checks after toggling charging switches. It exists because some switches don't react immediately after being toggled. # Most devices/switches work with a value of 1. -# Some devices may require a delay as high as 3. The optimal max is probably 3.5. +# Some may require a delay as high as 3. The optimal max is probably 3.5. # If a charging switch seems to work intermittently, or fails completely, increasing this value may fix the issue. -# You absolutely should increase this value if "acc -t --" reports total failure. +# You absolutely should increase this value if "acc -t" reports total failure. # Some MediaTek devices require a delay as high as 15! # accd manages this setting dynamically. # lang (l) # -# acc language, managed with "acc --set --lang". +# acc language, managed with "acc --set --lang" (acc -s l). # wake_unlock (wu) # # This is an attempt to release wakelocks acquired after disabling charging. -# It may or may not work - and may even cause unexpected side effects. More testing is needed. +# It's totally experimental and may or may not work (expect side effects). # prioritize_batt_idle_mode (pbim) # -# Several devices can draw power directly from the external power supply when charging is paused. -# Test yours with "acc -t --". +# Several devices can draw power directly from the external power supply when charging is paused. Test yours with "acc -t". # This setting dictates whether charging switches that support such feature should take precedence. # force_charging_status_full_at_100 (ff) # @@ -249,7 +267,7 @@ dynPowerSaving=0 # For Pixel devices, the status code of "full" is 5 (ff=5). # The status code is found through trial and error, with the commands "dumpsys battery", "dumpsys battery set status #" and "dumpsys battery reset". -# run_cmd_on_pause (rcp) +# run_cmd_on_pause (rcp) # # Run commands* after pausing charging. # * Usually a script ("sh some_file" or ". some_file") @@ -257,3 +275,8 @@ dynPowerSaving=0 # This is the maximum number of seconds accd will dynamically sleep* for (while unplugged) to save resources. # If dyn_power_saving == 0, the feature is disabled. # * On top of loop_delay_discharging + +# vibration_patterns (vp) # +# ACC and ACC service (accs) trigger vibrations on specific events (refer back to BASIC CONFIG EXPLANATION > vibrationPatterns). +# vp lets you customize vibration patterns per event type. +# To disable vibrations for an event, replace "_vibrations interval" with "- -" (hyphen space hyphen, excluding quotes). Refer back to COMMAND EXAMPLES. diff --git a/acc/flash-zips.sh b/acc/flash-zips.sh index b0b736a..a010965 100644 --- a/acc/flash-zips.sh +++ b/acc/flash-zips.sh @@ -4,25 +4,25 @@ # License: GPLv3+ # # usage: $0 or $0 "file1 file2 ..." -# the installation log file is stored in the zip_file directory +# the installation log file is stored in the zip_file directory as file.zip.log pick_zips() { clear echo - cd "${1:-/storage/emulated/0/Download/}" + cd "${1-/sdcard/Download/}" echo ": $PWD/" IFS=$'\n' - select_ target $(ls -1Ap | grep -Ei '.*.zip$|/$') "" "" "" + select_ target $(ls -1Ap | grep -Ei '.*.zip$|/$') "" "" "" unset IFS if [ -f "$target" ]; then zipFiles="$zipFiles ${target// /__}" echo echo -e "${zipFiles// /'\n'> }" | sed 's/__/ /' echo - echo -en "+ zip: 1\n: [enter]\n: CTRL-C\n> " + echo -en "Add more zips to the queue: a\nStart fashing: [enter]\nExit: CTRL-C\n> " read -n1 target - [ "$target" == 1 ] && pick_zips . + [ "$target" == a ] && pick_zips . elif [ -d "$target" ]; then echo pick_zips "$target" @@ -32,7 +32,7 @@ pick_zips() { pick_zips . elif [ "$target" == "" ]; then exit 0 - elif [ "$target" == "" ]; then + elif [ "$target" == "" ]; then echo -n "> " read target cd "${target:-.}" @@ -63,12 +63,14 @@ trap 'e=$?; echo; exit $e' EXIT [ -z "$zipFiles" ] && { - PS3="*.zip: " pick_zips unset target } -[[ "$zipFiles" == *" "* ]] && noClear=true + +case "$zipFiles" in + *\ *) noClear=true;; +esac for zipFile in $zipFiles; do @@ -95,8 +97,8 @@ echo -n " (!) ${zipFile//__/ }: *exit $e* > ${zipFile//__/ }.log -: [enter] -: CTRL-C +Continue: [enter] +Exit: CTRL-C > " read } diff --git a/acc/init.sh b/acc/init.sh index f93a2a4..d6385ad 100644 --- a/acc/init.sh +++ b/acc/init.sh @@ -6,10 +6,7 @@ # devs: triple hashtags (###) mark custom code -set +x umask 077 - - ( # log mkdir -p /data/adb/${id}-data/logs @@ -42,6 +39,7 @@ umask 077 ln -fs $TMPDIR/$id/${id}.sh /sbin/${id}d, ln -fs $TMPDIR/$id/${id}.sh /sbin/${id}d. ln -fs $TMPDIR/$id/${id}a.sh /sbin/${id}a + ln -fs $TMPDIR/$id/${id}s.sh /sbin/${id}s ln -fs $TMPDIR/$id/start-${id}d.sh /sbin/${id}d @@ -56,7 +54,7 @@ umask 077 # filter out missing and problematic charging switches (those with unrecognized values) ### cd /sys/class/power_supply/ - : > $TMPDIR/charging-switches + : > $TMPDIR/ch-switches_ grep -Ev '^#|^$' $modPath/charging-switches.txt | \ while IFS= read -r chargingSwitch; do set -f @@ -70,7 +68,7 @@ umask 077 if grep -Eq "^(${2//::/ }|${3//::/ })$" $ctrlFile1 \ || ! cat $ctrlFile1 > /dev/null || [ -z "$(cat $ctrlFile1)" ] then - echo $ctrlFile1 $2 $3 $ctrlFile2 $5 $6 >> $TMPDIR/charging-switches + echo $ctrlFile1 $2 $3 $ctrlFile2 $5 $6 >> $TMPDIR/ch-switches_ fi 2>/dev/null } } @@ -78,20 +76,20 @@ umask 077 # read charging voltage control files ### - : > $TMPDIR/ch-volt-ctrl-files + : > $TMPDIR/ch-volt-ctrl-files_ ls -1 */BatterySenseVoltage */ISenseVoltage */batt_vol */InstatVolt \ */constant_charge_voltage* */voltage_max */batt_tune_float_voltage 2>/dev/null | \ while read file; do chmod +r $file 2>/dev/null && grep -Eq '^4[1-4][0-9]{2}' $file || continue echo ${file}::$(sed -n 's/^..../vvvv/p' $file)::$(cat $file) \ - >> $TMPDIR/ch-volt-ctrl-files + >> $TMPDIR/ch-volt-ctrl-files_ done # read charging current control files (part 1) ### # part 2 is handled by accd - while charging only - : > $TMPDIR/ch-curr-ctrl-files + : > $TMPDIR/ch-curr-ctrl-files_ ls -1 */input_current_limited */restrict*_ch*g* \ /sys/class/qcom-battery/restrict*_ch*g* 2>/dev/null | \ while read file; do @@ -117,16 +115,23 @@ umask 077 if [ $defaultValue -lt 10000 ]; then # milliamps echo ${file}::v::$defaultValue \ - >> $TMPDIR/ch-curr-ctrl-files + >> $TMPDIR/ch-curr-ctrl-files_ else # microamps echo ${file}::v000::$defaultValue \ - >> $TMPDIR/ch-curr-ctrl-files + >> $TMPDIR/ch-curr-ctrl-files_ fi } done + # remove duplicates... + for file in $TMPDIR/ch-*_; do + sort -u $file > ${file%_} + rm $file + done + + # prepare default config help text and version code for write-config.sh sed -n '/^# /,$p' $modPath/default-config.txt > $TMPDIR/.config-help sed -n '/^configVerCode=/s/.*=//p' $modPath/default-config.txt > $TMPDIR/.config-ver @@ -140,6 +145,7 @@ umask 077 pkill -9 -f "$0|${0%/*}/(service|post-fs-data|$id-init)\.sh" 2>/dev/null \ &) & + # start $id daemon $modPath/${id}d.sh \ &) & diff --git a/acc/logf.sh b/acc/logf.sh index 645cead..b2883d9 100644 --- a/acc/logf.sh +++ b/acc/logf.sh @@ -2,16 +2,17 @@ logf() { if [[ "${1:-x}" == -*e* ]]; then set +eo pipefail 2>/dev/null cd $TMPDIR - cp oem-custom oem-custom.txt 2>/dev/null - cp charging-switches charging-switches.txt - cp ch-curr-ctrl-files charging-current-ctrl-files.txt - cp ch-volt-ctrl-files charging-voltage-ctrl-files.txt + { + cp oem-custom oem-custom.txt + cp ch-switches charging-switches.txt + cp ch-curr-ctrl-files charging-current-ctrl-files.txt + cp ch-volt-ctrl-files charging-voltage-ctrl-files.txt + } 2>/dev/null for file in /cache/magisk.log /data/cache/magisk.log; do [ -f $file ] && cp $file ./ && break done - cp $config ${config%/*}/logs/* ./ - dumpsys battery > dumpsys-battery.txt - acpi -V > acpi-V.txt + cp $config_ ${config_%/*}/logs/* ./ + dumpsys battery 2>/dev/null > dumpsys-battery.txt tar -c *.log *.txt 2>/dev/null \ | gzip -9 > /data/media/0/acc-logs-$device.tar.gz chmod 777 /data/media/0/acc-logs-$device.tar.gz diff --git a/acc/misc-functions.sh b/acc/misc-functions.sh index 07b4ee3..e9ea85a 100644 --- a/acc/misc-functions.sh +++ b/acc/misc-functions.sh @@ -3,7 +3,7 @@ apply_on_boot() { local entry="" file="" value="" default="" arg=${1:-value} exitCmd=false force=false [ ${2:-x} != force ] || force=true - + [[ "${applyOnBoot[@]:-x}${maxChargingVoltage[@]-}" != *--exit* ]] || exitCmd=true for entry in "${applyOnBoot[@]-}" "${maxChargingVoltage[@]-}"; do @@ -33,7 +33,7 @@ apply_on_plug() { cycle_switches() { - local on="" off="" + local on="" off="" switchDelayNew=$switchDelay while read -A chargingSwitch; do @@ -54,25 +54,43 @@ cycle_switches() { && eval "echo "\$$1"" > ${chargingSwitch[3]} || : } - sleep $switchDelay - - if [ "$1" == off ] && ! grep -Eiq "${2:-dis|not}" $batt/status; then - # reset switch/group that fails to disable charging - { echo "${chargingSwitch[1]//::/ }" > ${chargingSwitch[0]} || : - echo "${chargingSwitch[4]//::/ }" > ${chargingSwitch[3]:-/dev/null} || :; } 2>/dev/null - else - # enforce working switch/group - . $modPath/write-config.sh - break - fi + [ "$1" != off ] || { + not_charging ${2-} || { + sleep $switchDelay + # find a working switchDelay + while ! not_charging ${2-}; do + switchDelay=$(( ${switchDelay%.?} + 2 )) + sleep $switchDelay + [ $switchDelay -le 20 ] || break + done + } + if ! not_charging ${2-}; then + # reset switch/group that fails to disable charging + { echo "${chargingSwitch[1]//::/ }" > ${chargingSwitch[0]} || : + echo "${chargingSwitch[4]//::/ }" > ${chargingSwitch[3]:-/dev/null} || :; } 2>/dev/null + else + # enforce working charging switch(es) and switchDelay + switchDelay=$switchDelayNew + . $modPath/write-config.sh + break + fi + } } - done < $TMPDIR/charging-switches + done < $TMPDIR/ch-switches +} + + +cycle_switches_off() { + ! $prioritizeBattIdleMode || cycle_switches off not + not_charging || cycle_switches off } disable_charging() { + ! not_charging || return 0 + $isAccd || { apply_on_boot default apply_on_plug default @@ -87,27 +105,26 @@ disable_charging() { chmod +w ${chargingSwitch[3]} && echo "${chargingSwitch[5]//::/ }" > ${chargingSwitch[3]} || { $isAccd || print_switch_fails unset_switch - $isAccd || return 1 + cycle_switches_off } } - sleep $switchDelay + not_charging || sleep ${switchDelay} not_charging || { unset_switch - return 3 + cycle_switches_off } else $isAccd || print_switch_fails unset_switch - $isAccd || return 1 + cycle_switches_off fi else $isAccd || print_invalid_switch unset_switch - $isAccd || return 1 + cycle_switches_off fi else - ! $prioritizeBattIdleMode || cycle_switches off not - not_charging || cycle_switches off + cycle_switches_off fi if not_charging; then @@ -117,9 +134,11 @@ disable_charging() { || sleep ${temperature[2]} } else - return 3 + return 7 # total failure fi + ${cooldown-false} || vibrate ${vibrationPatterns[8]} ${vibrationPatterns[9]} + if [ -n "${1-}" ]; then case $1 in *%) @@ -129,7 +148,7 @@ disable_charging() { sleep ${loopDelay[1]} set +x done) - enable_charging || try_enabling_again + enable_charging ;; *[hms]) print_charging_disabled_for $1 @@ -139,7 +158,7 @@ disable_charging() { *m) sleep $(( ${1%m} * 60 ));; *s) sleep ${1%s};; esac - enable_charging || try_enabling_again + enable_charging ;; *) print_charging_disabled @@ -153,49 +172,32 @@ disable_charging() { enable_charging() { - if ! $ghostCharging || { $ghostCharging && [[ "$(acpi -a)" == *on-line* ]]; }; then + not_charging || return 0 - $isAccd || apply_on_plug + if ! $ghostCharging || { $ghostCharging && [[ "$(cat */online)" == *1* ]]; }; then - if [[ ${chargingSwitch[0]:-x} == */* ]]; then - if [ -f ${chargingSwitch[0]} ]; then - # toggle primary switch - if chmod +w ${chargingSwitch[0]} && echo "${chargingSwitch[1]//::/ }" > ${chargingSwitch[0]}; then - # toggle secondary switch - [ ! -f "${chargingSwitch[3]-}" ] || { - chmod +w ${chargingSwitch[3]} && echo "${chargingSwitch[4]//::/ }" > ${chargingSwitch[3]} || { - $isAccd || print_switch_fails - unset_switch - $isAccd || return 1 - } - } - sleep $switchDelay - else - $isAccd || print_switch_fails - unset_switch - $isAccd || return 1 - fi - else - $isAccd || print_invalid_switch - unset_switch - $isAccd || return 1 - fi - else - cycle_switches on - fi + $isAccd || { + [ "${2-}" == noap ] || apply_on_plug + } + cycle_switches on + (chmod +w ${chargingSwitch[0]-} ${chargingSwitch[3]-} \ + && echo ${chargingSwitch[1]-} > ${chargingSwitch[0]-} \ + && echo ${chargingSwitch[4]-} > ${chargingSwitch[3]-}) 2>/dev/null || : + ! not_charging || sleep ${switchDelay} # detect and block ghost charging - if ! $ghostCharging && ! not_charging && [[ "$(acpi -a)" != *on-line* ]]; then + if ! $ghostCharging && ! not_charging && [[ "$(cat */online)" != *1* ]]; then ghostCharging=true - { disable_charging || try_disabling_again; } > /dev/null + disable_charging > /dev/null touch $TMPDIR/.ghost-charging - $isAccd || { - echo "(i) ghostCharging=true" - print_unplugged - } - $isAccd || return 2 + wait_plug + return 0 fi + ${cooldown-false} || { + not_charging || vibrate ${vibrationPatterns[4]} ${vibrationPatterns[5]} + } + if [ -n "${1-}" ]; then case $1 in *%) @@ -205,9 +207,7 @@ enable_charging() { sleep ${loopDelay[1]} set +x done) - [ -n "${2-}" ] || { - disable_charging || try_disabling_again - } + disable_charging ;; *[hms]) print_charging_enabled_for $1 @@ -217,7 +217,7 @@ enable_charging() { *m) sleep $(( ${1%m} * 60 ));; *s) sleep ${1%s};; esac - disable_charging || try_disabling_again + disable_charging ;; *) print_charging_enabled @@ -228,68 +228,102 @@ enable_charging() { fi else - $isAccd || { - echo "(i) ghostCharging=true" - print_unplugged - } - $isAccd || return 2 + wait_plug fi } -not_charging() { grep -Eiq 'dis|not' $batt/status; } +misc_stuff() { + set -euo pipefail 2>/dev/null || : + mkdir -p ${config%/*} + [ -f $config ] || cp $modPath/default-config.txt $config + + # config backup + [ ! -d /data/media/0/?ndroid ] || { + [ /data/media/0/.acc-config-backup.txt -nt $config ] \ + || install -m 777 $config /data/media/0/.acc-config-backup.txt 2>/dev/null + } + + # custom config path + case "${1-}" in + */*) + [ -f $1 ] || cp $config $1 + config=$1 + ;; + esac + unset -f misc_stuff +} -try_disabling_again() { - local n="" - disable_charging "$@" && return 0 || { - n=$? - [ $n -ne 3 ] && return $n || { - while [ $n -le 18 ]; do - [ ! ${switchDelay%.?} -lt $n ] || { - switchDelay=$n - disable_charging "$@" && break || { - [ $n -ne 18 ] || { - $isAccd || print_unsupported - exit 7 - } - } - } - n=$(( n + 3 )) - done - # save working switchDelay - ! not_charging || . $modPath/write-config.sh - } - } +not_charging() { grep -Eiq "${1-dis|not}" $batt/status; } + + +print_header() { + echo "Advanced Charging Controller $accVer ($accVerCode) +© 2017-2020, VR25 (patreon.com/vr25) +GPLv3+" } -try_enabling_again() { - ! $ghostCharging || { - $isAccd || { - echo "(i) ghostCharging=true" - print_read_curr | tail -n 2 - } - (while [[ "$(acpi -a)" != *on-line* ]]; do - sleep ${loopDelay[1]} - set +x - done) - } - enable_charging "$@" +print_wait_plug() { + print_unplugged + print_quit CTRL-C } unset_switch() { chargingSwitch=() + switchDelay=1.5 . $modPath/write-config.sh } vibrate() { + [ $1 != - ] || return 0 local c=0 while [ $c -lt $1 ]; do - echo -en '\a' + if $isAccd || ${forceVibrations-false}; then + echo -en '\a' >&3 + else + echo -en '\a' + fi sleep $2 c=$(( c + 1 )) done } + + +wait_plug() { + $isAccd || { + echo "(i) ghostCharging=true" + print_wait_plug + } + (while [[ "$(cat */online)" != *1* ]]; do + sleep ${loopDelay[1]} + set +x + done) + enable_charging "$@" +} + + +# environment + +umask 077 +modPath=/sbin/.acc/acc +export TMPDIR=${modPath%/*} +config=/data/adb/acc-data/config.txt +config_=$config + +[ -f $TMPDIR/.ghost-charging ] \ + && ghostCharging=true \ + || ghostCharging=false + +trap exxit EXIT + +. $modPath/setup-busybox.sh + +device=$(getprop ro.product.device | grep .. || getprop ro.build.product) + +cd /sys/class/power_supply/ + +batt=$(echo *attery/capacity | cut -d ' ' -f 1 | sed 's|/capacity||') diff --git a/acc/oem-custom.sh b/acc/oem-custom.sh index ae4cfbb..68ad046 100644 --- a/acc/oem-custom.sh +++ b/acc/oem-custom.sh @@ -5,30 +5,23 @@ get_prop() { sed -n "\|^$1=|s|.*=||p" ${2:-$config}; } set_prop_() { sed -i "\|^${1}=|s|=.*|=$2|" ${3:-$config}; } -patched=false - -# config format patch -[ ! -f $config ] || { - configVer=$(get_prop configVerCode) - dConfVer=$(get_prop configVerCode $modPath/default-config.txt) - if [ $configVer -gt $dConfVer ] || [ $configVer -lt 202003301 ]; then - if /system/bin/sh -n $config 2>/dev/null; then - /sbin/acca --set dummy= - else - cp -f $modPath/default-config.txt $config - rm /sdcard/acc-logs-*.tar.bz2 2>/dev/null || : - fi - patched=true - fi -} +# patch/reset [broken] config +configVer=$(get_prop configVerCode 2>/dev/null || :) +defaultConfVer=$(get_prop configVerCode $modPath/default-config.txt) +if /system/bin/sh -n $config; then + [ ${configVer:-0} -eq $defaultConfVer ] || /sbin/acca --set dummy= +else + cp -f $modPath/default-config.txt $config + rm /sdcard/acc-logs-*.tar.bz2 || : ### legacy +fi 2>/dev/null # /proc/... switches -if grep_ '/proc/' $TMPDIR/charging-switches || grep_ '^chargingSwitch=.*/proc/'; then +if grep_ '/proc/' $TMPDIR/ch-switches || grep_ '^chargingSwitch=.*/proc/'; then # charging switch grep_ '^chargingSwitch=.*/proc/' \ - || set_prop_ chargingSwitch "($(grep '/proc/' $TMPDIR/charging-switches | head -n 1))" + || set_prop_ chargingSwitch "($(grep '/proc/' $TMPDIR/ch-switches | head -n 1))" # switchDelay switchDelay=$(get_prop switchDelay) [ ${switchDelay%.*} -gt 2 ] || set_prop_ switchDelay 3.5 @@ -55,8 +48,9 @@ fi # Razer # default value: 65 -{ echo 30 > /sys/devices/platform/soc/*/*/*/razer_charge_limit_dropdown || : -echo 30 > usb/razer_charge_limit_dropdown || :; } 2>/dev/null +(set +e +echo 30 > /sys/devices/platform/soc/*/*/*/razer_charge_limit_dropdown +echo 30 > usb/razer_charge_limit_dropdown) 2>/dev/null || : # block ghost charging on steroids (Xiaomi Redmi 3 - ido) diff --git a/acc/print-config.sh b/acc/print-config.sh index aab166d..352e12f 100644 --- a/acc/print-config.sh +++ b/acc/print-config.sh @@ -41,4 +41,5 @@ force_charging_status_full_at_100=$forceChargingStatusFullAt100 run_cmd_on_pause=${runCmdOnPause[@]} -dyn_power_saving=${dynPowerSaving}" +dyn_power_saving=${dynPowerSaving} +vibration_patterns=vibrationPatterns[@]}" diff --git a/acc/print-help.sh b/acc/print-help.sh index 4e32d22..b0548e1 100644 --- a/acc/print-help.sh +++ b/acc/print-help.sh @@ -1,5 +1,10 @@ print_help_() { - print_help > $TMPDIR/.help + { + print_header + echo + echo + print_help + } > $TMPDIR/.help case "$language" in en|"") { diff --git a/acc/set-prop.sh b/acc/set-prop.sh index 9d7e1a9..5303e83 100644 --- a/acc/set-prop.sh +++ b/acc/set-prop.sh @@ -22,7 +22,7 @@ set_prop() { # reset config r|--reset) ! $daemonWasUp || daemon_ctrl stop > /dev/null - cp $defaultConfig $config + cp -f $defaultConfig $config print_config_reset ! $daemonWasUp || /sbin/accd return 0 @@ -31,13 +31,13 @@ set_prop() { # print default config d|--print-default) . $defaultConfig - . $modPath/print-config.sh | grep -E "${2:-.}" + . $modPath/print-config.sh | grep -E "${2-.}" return 0 ;; # print current config p|--print) - . $modPath/print-config.sh | grep -E "${2:-.}" + . $modPath/print-config.sh | grep -E "${2-.}" return 0 ;; @@ -50,7 +50,7 @@ set_prop() { print_known_switches echo . $modPath/select.sh - select_ chargingSwitch $(print_auto) $(cat $TMPDIR/charging-switches) $(print_exit) + select_ chargingSwitch $(print_auto) $(cat $TMPDIR/ch-switches) $(print_exit) [ ${chargingSwitch:-x} != $(print_exit) ] || exit 0 [ ${chargingSwitch:-x} != $(print_auto) ] || charging_switch= unset IFS @@ -58,7 +58,7 @@ set_prop() { # print switches s:|--charging*witch:) - cat $TMPDIR/charging-switches + cat $TMPDIR/ch-switches return 0 ;; @@ -69,24 +69,19 @@ set_prop() { # check support grep -q ::v $TMPDIR/ch-curr-ctrl-files || { if not_charging; then - (while not_charging; do - clear - echo - print_read_curr - sleep 1 - set +x - done) - echo + print_read_curr + print_wait_plug + (while not_charging; do sleep 1; set +x; done) echo . $modPath/read-ch-curr-ctrl-files-p2.sh grep -q ::v $TMPDIR/ch-curr-ctrl-files || { - print_unsupported + print_no_ctrl_file return 1 } else . $modPath/read-ch-curr-ctrl-files-p2.sh grep -q ::v $TMPDIR/ch-curr-ctrl-files || { - print_unsupported + print_no_ctrl_file return 1 } fi @@ -96,7 +91,7 @@ set_prop() { # restore if [ $2 == - ]; then - daemon_ctrl stop skipab > /dev/null || apply_on_plug default + daemon_ctrl stop > /dev/null || apply_on_plug default restartDaemon=true max_charging_current= print_curr_restored @@ -133,7 +128,8 @@ set_prop() { # restore if [ $2 == - ]; then - daemon_ctrl stop forceab> /dev/null || apply_on_boot default force + daemon_ctrl stop > /dev/null + apply_on_boot default force restartDaemon=true max_charging_voltage= print_volt_restored @@ -141,7 +137,7 @@ set_prop() { else apply_voltage() { - [ ${2:-x} != --exit ] || { ! $daemonWasUp || daemon_ctrl stop; } + [ ${2-x} != --exit ] || { ! $daemonWasUp || daemon_ctrl stop; } eval "maxChargingVoltage=($1 $(sed "s|vvvv|$1|" $TMPDIR/ch-volt-ctrl-files) ${2-})" \ && apply_on_boot \ && { noEcho=true; print_volt_set $1; } \ diff --git a/acc/setup-busybox.sh b/acc/setup-busybox.sh index 9513dbe..55b9e6a 100644 --- a/acc/setup-busybox.sh +++ b/acc/setup-busybox.sh @@ -15,16 +15,16 @@ else chmod 700 /dev/.busybox case $PATH in /dev/.busybox:*) :;; - *) PATH=/dev/busybox:$PATH;; + *) PATH=/dev/.busybox:$PATH;; esac [ -x /dev/.busybox/busybox ] || { if [ -f /data/adb/magisk/busybox ]; then - [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox + [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox /data/adb/magisk/busybox --install -s /dev/.busybox elif which busybox > /dev/null; then busybox --install -s /dev/.busybox elif [ -f /data/adb/busybox ]; then - [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox + [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox /data/adb/busybox --install -s /dev/.busybox else echo "(!) Install busybox or simply place it in /data/adb/" diff --git a/acc/strings.sh b/acc/strings.sh index c310a5c..548ee21 100644 --- a/acc/strings.sh +++ b/acc/strings.sh @@ -65,7 +65,7 @@ print_charging_enabled() { } print_unplugged() { - echo "(!) External power supply not detected" + echo "(!) Battery must be charging to continue..." } print_switch_works() { @@ -76,12 +76,8 @@ print_switch_fails() { echo "(!) [$@] won't work" } -print_supported() { - echo "(i) Supported device" -} - -print_unsupported() { - echo "(!) Unsupported device" +print_no_ctrl_file() { + echo "(!) No control file found" } print_not_found() { @@ -91,19 +87,26 @@ print_not_found() { print_help() { cat << EOF -Advanced Charging Controller $accVer ($accVerCode) -(c) 2017-2020, VR25 (patreon.com/vr25) -GPLv3+ +Usage + acc Wizard -Usage + accd Start/restart accd + + accd. Stop acc/daemon + + accd, Print acc/daemon status (running or not) + + acc [pause_capacity resume_capacity] e.g., acc 75 70 + + acc [options] [args] Refer to the list of options below + + /sbin/acca [options] [args] acc optimized for front-ends - acc (wizard) - acc [options] [args] - acc [pause_capacity] [resume_capacity] (e.g., acc 75 70) - /sbin/acca [options] [args] (acc optimized for front-ends) + accs acc foreground service, works exactly as accd, but attached to the terminal - A custom config path can be specified as first parameter. If the file doesn't exist, the current config is cloned. + A custom config path can be specified as first parameter. + If the file doesn't exist, the current config is cloned. e.g., acc /data/acc-night-config.txt --set pause_capacity=45 resume_capacity=43 acc /data/acc-night-config.txt --set --current 500 @@ -118,7 +121,7 @@ Options acc -c less acc -c cat - -C|--calibrate Charge until battery_status == "Full" + -C|--calibrate Charge to true 100% e.g., acc -C -d|--disable [#%, #s, #m or #h (optional)] Disable charging @@ -140,10 +143,11 @@ Options acc -e 75% (recharge to 75%) acc -e 30m (recharge for 30 minutes) - -f|--force|--full [capacity] Charge to a given capacity (default: 100) once and uninterrupted + -f|--force|--full [capacity] Charge to a given capacity (default: 100) once, uninterrupted and without other restrictions e.g., acc -f 95 (charge to 95%) acc -f (charge to 100%) + Note: not to be confused with -C; -f 100 won't allow charging to true 100% capacity -F|--flash ["zip_file"] Flash any zip files whose update-binary is a shell script e.g., @@ -221,19 +225,16 @@ Options acc -s v - (restore default) acc -s v 3920 --exit (stop the daemon after applying settings) - -t|--test Test charging control (on/off) - e.g., acc -t - - -t|--test [file on off file2 on off] Test custom charging switches + -t|--test [ctrl_file1 on off [ctrl_file2 on off]] Test custom charging switches e.g., acc -t battery/charging_enabled 1 0 acc -t /proc/mtk_battery_cmd/current_cmd 0::0 0::1 /proc/mtk_battery_cmd/en_power_path 1 0 ("::" == " ") - -t|--test -- [file] Test charging switches from a file (default: $TMPDIR/charging-switches) + -t|--test [file] Test charging switches from a file (default: $TMPDIR/charging-switches) This will also report whether "battery idle" mode is supported e.g., - acc -t -- (test known switches) - acc -t -- /sdcard/experimental_switches.txt (test custom/foreign switches) + acc -t (test known switches) + acc -t /sdcard/experimental_switches.txt (test custom/foreign switches) -T|--logtail Monitor accd log (tail -F) e.g., acc -T @@ -261,6 +262,23 @@ Options acc -w0 (no extra delay) +Exit Codes + + 0. True/success + 1. False or general failure + 2. Incorrect command syntax + 3. Missing busybox binary + 4. Not running as root + 5. Update available ("--upgrade") + 6. No update available ("--upgrade") + 7. Couldn't disable charging + 8. Daemon already running ("--daemon start") + 9. Daemon not running ("--daemon" and "--daemon stop") + 10. "--test" failed + + Logs are exported automatically ("--log --export") on exit codes 1, 2, 7 and 10. + + Tips Commands can be chained for extended functionality. @@ -308,8 +326,6 @@ print_volt_restored() { print_read_curr() { echo "(i) Need to read default max charging current value(s) first" - print_unplugged - echo -n "- Waiting... (press CTRL-C to abort)" } print_curr_set() { @@ -377,8 +393,8 @@ print_edit() { echo "Edit $1" } -print_flash_zip() { - echo "Flash zip" +print_flash_zips() { + echo "Flash zips" } print_reset_bs() { @@ -432,3 +448,11 @@ print_discharge() { print_wait() { echo "(i) This may take a few minutes..." } + +print_already_charging() { + echo "(i) Already charging" +} + +print_already_discharging() { + echo "(i) Already not changing" +} diff --git a/acc/translations/pt-PT/strings.sh b/acc/translations/pt-PT/strings.sh index c126bc9..a7733f1 100644 --- a/acc/translations/pt-PT/strings.sh +++ b/acc/translations/pt-PT/strings.sh @@ -65,7 +65,7 @@ print_charging_enabled() { } print_unplugged() { - echo "(!) Conecte o carregador primeiro" + echo "(!) Conecte o carregador primeiro..." } print_switch_works() { @@ -76,14 +76,6 @@ print_switch_fails() { echo "(!) [$@] não funciona" } -print_supported() { - echo "(i) Este dispositivo é suportado" -} - -print_unsupported() { - echo "(!) Este dispositivo não é suportado" -} - print_not_found() { echo "(!) $1 não encontrado" } @@ -121,7 +113,7 @@ print_volt_restored() { print_read_curr() { echo "(i) Antes the prosseguir, o acc precisa obter os padrões máximos de corrente (I) de recarga" print_unplugged - echo -n "- À espera... (pressione CTRL-C para cancelar)" + echo -n "- À espera..." } print_curr_set() { diff --git a/acc/translations/zh-rCN/strings.sh b/acc/translations/zh-rCN/strings.sh index 013e0b8..dc02d9f 100644 --- a/acc/translations/zh-rCN/strings.sh +++ b/acc/translations/zh-rCN/strings.sh @@ -64,10 +64,6 @@ print_charging_enabled() { echo "(i) 已开始充电" } -print_unplugged() { - echo "(!) 需要设备处于充电状态" -} - print_switch_works() { echo "(i) [$@] 可用" } @@ -76,14 +72,6 @@ print_switch_fails() { echo "(!) [$@] 不可用" } -print_supported() { - echo "(i) 设备受支持" -} - -print_unsupported() { - echo "(!) 设备不受支持" -} - print_not_found() { echo "(!) 未找到 $1 目录" } diff --git a/acc/uninstall.sh b/acc/uninstall.sh index 21d7761..d3de3df 100644 --- a/acc/uninstall.sh +++ b/acc/uninstall.sh @@ -21,16 +21,16 @@ else chmod 700 /dev/.busybox case $PATH in /dev/.busybox:*) :;; - *) PATH=/dev/busybox:$PATH;; + *) PATH=/dev/.busybox:$PATH;; esac [ -x /dev/.busybox/busybox ] || { if [ -f /data/adb/magisk/busybox ]; then - [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox + [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox /data/adb/magisk/busybox --install -s /dev/.busybox elif which busybox > /dev/null; then busybox --install -s /dev/.busybox elif [ -f /data/adb/busybox ]; then - [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox + [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox /data/adb/busybox --install -s /dev/.busybox else echo "(!) Install busybox or simply place it in /data/adb/" @@ -43,16 +43,20 @@ fi exec 2>/dev/null # interrupt $id processes -pkill -f "/($id|${id}a) (-|--)(calibrate|[Cdef])|/${id}d\.sh" ### +pkill -f "/($id|${id}a) (-|--)(calibrate|test|[Cdeft])|/${id}d\.sh" ### +sleep 0.2 +while [ -n "$(pgrep -f '/ac(c|ca) (-|--)(calibrate|test|[Cdeft])|/accd\.sh')" ]; do + sleep 0.2 +done # uninstall $id rm -rf $(readlink -f /sbin/.$id/$id/) \ /data/adb/$id \ - /data/adb/${id}-data \ /data/adb/modules/$id \ /data/adb/service.d/${id}-*.sh \ /data/media/0/${id}-logs-*.tar.* \ - /data/data/mattecarra.accapp/files/$id ### + /data/data/mattecarra.accapp/files/$id + $([ "${1-}" == install ] || echo "/data/adb/${id}-data") ### # remove flashable uninstaller rm ${3:-/data/media/0/${id}-uninstaller.zip} diff --git a/acc/wizard.sh b/acc/wizard.sh index e34c8ec..581f6ef 100644 --- a/acc/wizard.sh +++ b/acc/wizard.sh @@ -2,9 +2,7 @@ wizard() { clear echo - echo "Advanced Charging Controller $accVer ($accVerCode) -(c) 2017-2020, VR25 (patreon.com/vr25) -GPLv3+" + print_header echo { daemon_ctrl | sed "s/ $accVer ($accVerCode)//"; } || : @@ -22,7 +20,7 @@ echo -n "1) $(print_lang) a) $(print_reset_bs) b) $(print_test_cs) c) $(print_update) -d) $(print_flash_zip) +d) $(print_flash_zips) e) $(print_exit) #? " @@ -101,7 +99,7 @@ e) $(print_exit) ;; b) - /sbin/acc --test -- || : + /sbin/acc --test || : print_press_enter read exec wizard diff --git a/acc/write-config.sh b/acc/write-config.sh index 55dfb49..f5efa05 100644 --- a/acc/write-config.sh +++ b/acc/write-config.sh @@ -20,6 +20,7 @@ prioritizeBattIdleMode=${prioritize_batt_idle_mode-${pbim-${prioritizeBattIdleMo forceChargingStatusFullAt100=${force_charging_status_full_at_100-${ff-${forceChargingStatusFullAt100}}} runCmdOnPause=(${run_cmd_on_pause-${rcp-${runCmdOnPause[@]}}}) dynPowerSaving=${dyn_power_saving-${dps-${dynPowerSaving}}} +vibrationPatterns=(${vibration_patterns-${vp-${vibrationPatterns[@]}}}) " diff --git a/bin/acc-uninstaller.zip b/bin/acc-uninstaller.zip index 9828ae5c5314d3145275a71d1b1f37c3edd9841d..382d67d129cc9d5fdfd5851b424c9c4f8a9bb5a5 100644 GIT binary patch literal 1812 zcmWIWW@h1H0D*&3nghTLD8b1f!{F;0;;8HC=cXST!pXo~Rni^@!lf1542&!wWh}hv z3=9D{jo?K#A~`>oOk+gQjY-eXPtQpu(=-_zrX}X36y;~85HwYUfr)_w99mNw*_Mb=JDR3_MuD`8Z1YYPqE1y3<*iUrjy>oRnaDdGmS7 z1inlBA6_4SpzOk}D%4tRlG=Lh=$40W-a0aT4`07M`{$1>cV?eJ9>={`rxa2SrN;Tl zx+F>*o4{?&9BCc@Ou@Ug$8fEilb4&cr{opUmxZSbcP2c%8hYXj%R7a@1F?_S&hK7X zX1uTYz+u)OJlt#wt`nqJnZtmlFP{ggBl|1j{ zU-@I=i4~Lo*Gt(y`*HTrt*WecBW=Zwdq+RiZcjcR7*$}k{)~{8vP#pp5U07Dn`{p^ zg`K-Sy>r>|wu{P7&i+l@;lSB^`nZOfxUaa}+O^vE%{os_6PoLMeAUdnFMbLS1lO*q z)?RC-)TR-s?kVG$_~iyye|G=5_3zh-`u%a<^Gw(8ZZJP*!#c}iwvA0&>=UN=WHE`{ zW@?HH@zp&m{GU_YXj1l1w!Bxox}QB|OeBLy1xVYz)Jai<0Uo82Q^Y>y0!&ht1wVzZxDI4>@f1R1HXkhEoH~Nqg0hlwu*`%5~ zFNp)l24O9tvPqF{adJ^+K?%NmqU`JF?iuXO72wUtB*%=a2$KNX2?7EPKO8|cQh~+_ zDbO$qGu+1UG9Vl0jBFgFa3kGF5fmf4(2ax_bflXsgJSXx93~?QJ$yFcD)Jz~!3Z>a zL!%y$f`=|BIG}Ea*??96;^?A0_z{b)*%uSF8f%4Wj6x@8xYz8EjN(FFfaj42gOYJv;3e6pv6~M85lH)vP(B9 zGcU2I5}#F5Lwxgv4F&f84)@t?`9{o)Z>4}zsP;uUhL!DHih8;HeYUf=KKeW1Eib3< zf9uC*m*w1M@mi9Rdw%wF^Yh$xUObvia9 zEZxb=t#b*_tXW@nd|eZ@@x>#hB&%j=577egENRiCb$6S}1$J1o&QCtcu%v+F@N573 z`y2R*Z_GEe^-HL#y2X?s@gew7C7mw?;bWwzyoF_bwoR{lUIO*NKzMCT0GzG5F)+g8@zR?Uj`Ea8(~EpGMVY{G%$uAH{-QMMf{k4h#l^VDg*Xsm6Mm!~J1 zR(`T=J4dPa+hm3>hnRmRU*>#rMr^_@p0?BwxDGEV5$DgU5Oqt9B~4h?kYzVa}a+sCvqwD8of= zs;_3HS8Y!X-*j|Qlu}CDuDLS;Z@)H=D@v%SH}d`d_V(f4x|hEcWyEEl&iKm~;LXS+ z$Be7kk$@IJ0t{~*K}@7Vh!s)@VH7~PjpJoNHqIH@I7op+x{)F%Ms}ea2``*TH(3V7 zz0ksEAFiSb*}hps*#|GUa9PL7 S26R0G8xYz8{aDHZ;sF5mViY_8 diff --git a/build.sh b/build.sh index 1f0bec3..38b583f 100644 --- a/build.sh +++ b/build.sh @@ -39,7 +39,7 @@ grep -q "$versionCode" module.prop || { # set ID -for file in ./install-*.sh ./$id/*.sh ./bundle.sh; do +for file in ./install*.sh ./$id/*.sh ./bundle.sh; do if [ -f "$file" ] && grep -Eq '(^|\()id=' $file; then grep -Eq "(^|\()id=$id" $file || set_prop id $id $file fi @@ -66,7 +66,7 @@ fi # update busybox config (from acc/setup-busybox.sh) in $id/uninstall.sh and install scripts set -e -for file in ./$id/uninstall.sh ./install-*.sh; do +for file in ./$id/uninstall.sh ./install*.sh; do [ $file -ot $id/setup-busybox.sh ] && { { sed -n '1,/#BB#/p' $file; \ sed -n '/^if /,/^fi/p' $id/setup-busybox.sh; \ @@ -77,9 +77,9 @@ done set +e -# unify installers for flashable zip (customize.sh and update-binary are copies of install-current.sh) -{ cp -u install-current.sh customize.sh -cp -u install-current.sh META-INF/com/google/android/update-binary; } 2>/dev/null +# unify installers for flashable zip (customize.sh and update-binary are copies of install.sh) +{ cp -u install.sh customize.sh +cp -u install.sh META-INF/com/google/android/update-binary; } 2>/dev/null if [ bin/${id}-uninstaller.zip -ot $id/uninstall.sh ] || [ ! -f bin/${id}-uninstaller.zip ]; then @@ -91,7 +91,7 @@ if [ bin/${id}-uninstaller.zip -ot $id/uninstall.sh ] || [ ! -f bin/${id}-uninst echo "#MAGISK" > $tmpDir/updater-script (cd .tmp zip -r9 ../bin/${id}-uninstaller.zip * \ - | sed 's|^.*adding: ||' | grep -iv 'zip warning:') + | sed 's|.*adding: ||' | grep -iv 'zip warning:') rm -rf .tmp echo fi @@ -107,13 +107,13 @@ fi echo "=> _builds/${id}-${versionCode}/${id}-${versionCode}.zip" zip -r9 _builds/${id}-${versionCode}/${id}-${versionCode}.zip \ * .gitattributes .gitignore \ - -x _\*/\* | sed 's|^.*adding: ||' | grep -iv 'zip warning:' + -x _\*/\* | sed 's|.*adding: ||' | grep -iv 'zip warning:' echo # prepare files to be included in $id installable tarball cp install-tarball.sh _builds/${id}-${versionCode}/ - cp -R ${id}/ install-c* *.md module.prop bin/ \ - _builds/${id}-$versionCode/${id}-${versionCode} 2>&1 \ + cp -R ${id}/ install.sh *.md module.prop bin/ \ + _builds/${id}-$versionCode/${id}-${versionCode}/ 2>&1 \ | grep -iv "can't preserve" # generate $id installable tarball @@ -123,5 +123,5 @@ fi rm -rf ${id}-${versionCode}/ echo -} -exit 0) +}) +exit 0 diff --git a/customize.sh b/customize.sh index 84e3533..37c495c 100644 --- a/customize.sh +++ b/customize.sh @@ -1,26 +1,40 @@ #!/system/bin/sh -# $id Installer/Upgrader +# ACC Installer/Upgrader # Copyright (c) 2019-2020, VR25 (xda-developers) # License: GPLv3+ # # devs: triple hashtags (###) mark custom code -set +x - # override the official Magisk module installer SKIPUNZIP=1 + echo id=acc umask 077 + # log mkdir -p /data/adb/${id}-data/logs +chmod -R 700 /data/adb/${id}-data/logs exec 2>/data/adb/${id}-data/logs/install.log set -x -trap 'e=$?; echo; exit $e' EXIT + +exxit() { + local e=$? + set +eo pipefail + rm -rf /dev/.${id}-install + [ $e -ne 0 ] && echo || { + rm /sbin/.$id/.ghost-charging ### + /sbin/acca --daemon > /dev/null || /sbin/accd ### workaround, Magisk 20.4+ + } + exit $e +} 2>/dev/null + +trap exxit EXIT + # set up busybox #BB# @@ -34,16 +48,16 @@ else chmod 700 /dev/.busybox case $PATH in /dev/.busybox:*) :;; - *) PATH=/dev/busybox:$PATH;; + *) PATH=/dev/.busybox:$PATH;; esac [ -x /dev/.busybox/busybox ] || { if [ -f /data/adb/magisk/busybox ]; then - [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox + [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox /data/adb/magisk/busybox --install -s /dev/.busybox elif which busybox > /dev/null; then busybox --install -s /dev/.busybox elif [ -f /data/adb/busybox ]; then - [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox + [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox /data/adb/busybox --install -s /dev/.busybox else echo "(!) Install busybox or simply place it in /data/adb/" @@ -53,12 +67,14 @@ else fi #/BB# + # root check [ $(id -u) -ne 0 ] && { echo "(!) $0 must run as root (su)" exit 4 } + get_prop() { sed -n "s|^$1=||p" ${2:-$srcDir/module.prop}; } set_perms() { @@ -70,24 +86,27 @@ set_perms() { } set_perms_recursive() { - local owner=${2:-0} target="" + local owner=${2-0} target="" find $1 2>/dev/null | while read target; do set_perms $target $owner; done } set -euo pipefail 2>/dev/null || : + # set source code directory [ -f $PWD/${0##*/} ] && srcDir=$PWD || srcDir=${0%/*} srcDir=${srcDir/#"${0##*/}"/"."} -# unzip flashable zip if source code is unavailable + +# extract flashable zip if source code is unavailable [ -f $srcDir/module.prop ] || { - srcDir=/dev/.tmp + srcDir=/dev/.${id}-install rm -rf $srcDir 2>/dev/null || : mkdir $srcDir - unzip ${ZIP:-${3-}} -d $srcDir/ >&2 + unzip "$3" -d $srcDir/ >&2 } + name=$(get_prop name) author=$(get_prop author) version=$(get_prop version) @@ -95,6 +114,7 @@ versionCode=$(get_prop versionCode) installDir=${installDir0:=/data/data/mattecarra.${id}app/files} ### config=/data/adb/${id}-data/config.txt + # check/set parent installation directory [ -d $installDir ] || installDir=/sbin/.magisk/modules [ -d $installDir ] || installDir=/data/adb @@ -103,16 +123,15 @@ config=/data/adb/${id}-data/config.txt ### echo "$name $version ($versionCode) -Copyright (c) 2017-2020, $author -License: GPLv3+ +© 2017-2020, $author +GPLv3+ (i) Installing in $installDir/$id/..." # install -cp $config /data/.${id}-config-bkp 2>/dev/null || : -ash $srcDir/$id/uninstall.sh -mv /data/.${id}-config-bkp $config 2>/dev/null || : +ash $srcDir/$id/uninstall.sh install +rm /data/adb/${id}-data/logs/bootlooped 2>/dev/null || : cp -R $srcDir/$id/ $installDir/ installDir=$(readlink -f $installDir/$id) installDir0=$installDir0/$id @@ -165,12 +184,15 @@ fi # disable magic mount (Magisk) touch /sbin/.magisk/modules/$id/skip_mount 2>/dev/null || : + # restore config backup [ -f $config ] || cp /data/media/0/.${id}-config-backup.txt $config 2>/dev/null || : + # flashable uninstaller cp -f $srcDir/bin/${id}-uninstaller.zip /data/media/0/ + # set perms set_perms_recursive ${config%/*} chmod 666 /data/media/0/${id}-uninstaller.zip @@ -186,6 +208,7 @@ case $installDir in ;; esac + set +euo pipefail 2>/dev/null || : @@ -212,7 +235,6 @@ echo " [ $installDir == /data/adb ] && echo -e "\n(i) Use init.d or an app to run $installDir/${id}-init.sh on boot to initialize ${id}." echo -trap - EXIT # initialize $id if [ -f $installDir/service.sh ]; then @@ -221,8 +243,4 @@ else $installDir/${id}-init.sh --override fi -e=$? -[ $e -eq 0 ] || { echo; exit $e; } -rm /sbin/.$id/.ghost-charging 2>/dev/null ### -/sbin/acca --daemon > /dev/null || /sbin/accd ### workaround, Magisk 20.4+ exit 0 diff --git a/install-latest.sh b/install-online.sh similarity index 87% rename from install-latest.sh rename to install-online.sh index 9243d11..3ccadcf 100644 --- a/install-latest.sh +++ b/install-online.sh @@ -1,12 +1,12 @@ #!/system/bin/sh # # $id Online Installer -# https://raw.githubusercontent.com/VR-25/$id/$branch/install-latest.sh +# https://raw.githubusercontent.com/VR-25/$id/$branch/install-online.sh # # Copyright (c) 2019-2020, VR25 (xda-developers) # License: GPLv3+ # -# Usage: sh install-latest.sh [-c|--changelog] [-f|--force] [-k|--insecure] [-n|--non-interactive] [%install dir%] [reference] +# Usage: sh install-online.sh [-c|--changelog] [-f|--force] [-k|--insecure] [-n|--non-interactive] [%install dir%] [reference] # # Also refer to README.md > NOTES/TIPS FOR FRONT-END DEVELOPERS for > Exit Codes @@ -18,7 +18,7 @@ umask 077 # log mkdir -p /data/adb/${id}-data/logs -exec 2>/data/adb/${id}-data/logs/install-latest.sh.log +exec 2>/data/adb/${id}-data/logs/install-online.sh.log set -x trap 'e=$?; echo; exit $e' EXIT @@ -36,16 +36,16 @@ else chmod 700 /dev/.busybox case $PATH in /dev/.busybox:*) :;; - *) PATH=/dev/busybox:$PATH;; + *) PATH=/dev/.busybox:$PATH;; esac [ -x /dev/.busybox/busybox ] || { if [ -f /data/adb/magisk/busybox ]; then - [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox + [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox /data/adb/magisk/busybox --install -s /dev/.busybox elif which busybox > /dev/null; then busybox --install -s /dev/.busybox elif [ -f /data/adb/busybox ]; then - [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox + [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox /data/adb/busybox --install -s /dev/.busybox else echo "(!) Install busybox or simply place it in /data/adb/" @@ -113,7 +113,7 @@ then trap - EXIT echo curl -L $insecure $tarball | tar -xz \ - && /system/bin/sh ${id}-${reference}/install-current.sh + && /system/bin/sh ${id}-${reference}/install.sh else echo diff --git a/install-tarball.sh b/install-tarball.sh index 79b4036..9505df1 100644 --- a/install-tarball.sh +++ b/install-tarball.sh @@ -23,16 +23,16 @@ else chmod 700 /dev/.busybox case $PATH in /dev/.busybox:*) :;; - *) PATH=/dev/busybox:$PATH;; + *) PATH=/dev/.busybox:$PATH;; esac [ -x /dev/.busybox/busybox ] || { if [ -f /data/adb/magisk/busybox ]; then - [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox + [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox /data/adb/magisk/busybox --install -s /dev/.busybox elif which busybox > /dev/null; then busybox --install -s /dev/.busybox elif [ -f /data/adb/busybox ]; then - [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox + [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox /data/adb/busybox --install -s /dev/.busybox else echo "(!) Install busybox or simply place it in /data/adb/" @@ -78,7 +78,7 @@ tar -xf ${1:-$id}*gz # install ${1:-$id} export installDir0="$2" -/system/bin/sh ${1:-$id}-*/install-current.sh +/system/bin/sh ${1:-$id}-*/install.sh rm -rf ${1:-$id}-*/ exit 0 diff --git a/install-current.sh b/install.sh similarity index 86% rename from install-current.sh rename to install.sh index 84e3533..37c495c 100644 --- a/install-current.sh +++ b/install.sh @@ -1,26 +1,40 @@ #!/system/bin/sh -# $id Installer/Upgrader +# ACC Installer/Upgrader # Copyright (c) 2019-2020, VR25 (xda-developers) # License: GPLv3+ # # devs: triple hashtags (###) mark custom code -set +x - # override the official Magisk module installer SKIPUNZIP=1 + echo id=acc umask 077 + # log mkdir -p /data/adb/${id}-data/logs +chmod -R 700 /data/adb/${id}-data/logs exec 2>/data/adb/${id}-data/logs/install.log set -x -trap 'e=$?; echo; exit $e' EXIT + +exxit() { + local e=$? + set +eo pipefail + rm -rf /dev/.${id}-install + [ $e -ne 0 ] && echo || { + rm /sbin/.$id/.ghost-charging ### + /sbin/acca --daemon > /dev/null || /sbin/accd ### workaround, Magisk 20.4+ + } + exit $e +} 2>/dev/null + +trap exxit EXIT + # set up busybox #BB# @@ -34,16 +48,16 @@ else chmod 700 /dev/.busybox case $PATH in /dev/.busybox:*) :;; - *) PATH=/dev/busybox:$PATH;; + *) PATH=/dev/.busybox:$PATH;; esac [ -x /dev/.busybox/busybox ] || { if [ -f /data/adb/magisk/busybox ]; then - [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox + [ -x /data/adb/magisk/busybox ] || chmod 700 /data/adb/magisk/busybox /data/adb/magisk/busybox --install -s /dev/.busybox elif which busybox > /dev/null; then busybox --install -s /dev/.busybox elif [ -f /data/adb/busybox ]; then - [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox + [ -x /data/adb/busybox ] || chmod 700 /data/adb/busybox /data/adb/busybox --install -s /dev/.busybox else echo "(!) Install busybox or simply place it in /data/adb/" @@ -53,12 +67,14 @@ else fi #/BB# + # root check [ $(id -u) -ne 0 ] && { echo "(!) $0 must run as root (su)" exit 4 } + get_prop() { sed -n "s|^$1=||p" ${2:-$srcDir/module.prop}; } set_perms() { @@ -70,24 +86,27 @@ set_perms() { } set_perms_recursive() { - local owner=${2:-0} target="" + local owner=${2-0} target="" find $1 2>/dev/null | while read target; do set_perms $target $owner; done } set -euo pipefail 2>/dev/null || : + # set source code directory [ -f $PWD/${0##*/} ] && srcDir=$PWD || srcDir=${0%/*} srcDir=${srcDir/#"${0##*/}"/"."} -# unzip flashable zip if source code is unavailable + +# extract flashable zip if source code is unavailable [ -f $srcDir/module.prop ] || { - srcDir=/dev/.tmp + srcDir=/dev/.${id}-install rm -rf $srcDir 2>/dev/null || : mkdir $srcDir - unzip ${ZIP:-${3-}} -d $srcDir/ >&2 + unzip "$3" -d $srcDir/ >&2 } + name=$(get_prop name) author=$(get_prop author) version=$(get_prop version) @@ -95,6 +114,7 @@ versionCode=$(get_prop versionCode) installDir=${installDir0:=/data/data/mattecarra.${id}app/files} ### config=/data/adb/${id}-data/config.txt + # check/set parent installation directory [ -d $installDir ] || installDir=/sbin/.magisk/modules [ -d $installDir ] || installDir=/data/adb @@ -103,16 +123,15 @@ config=/data/adb/${id}-data/config.txt ### echo "$name $version ($versionCode) -Copyright (c) 2017-2020, $author -License: GPLv3+ +© 2017-2020, $author +GPLv3+ (i) Installing in $installDir/$id/..." # install -cp $config /data/.${id}-config-bkp 2>/dev/null || : -ash $srcDir/$id/uninstall.sh -mv /data/.${id}-config-bkp $config 2>/dev/null || : +ash $srcDir/$id/uninstall.sh install +rm /data/adb/${id}-data/logs/bootlooped 2>/dev/null || : cp -R $srcDir/$id/ $installDir/ installDir=$(readlink -f $installDir/$id) installDir0=$installDir0/$id @@ -165,12 +184,15 @@ fi # disable magic mount (Magisk) touch /sbin/.magisk/modules/$id/skip_mount 2>/dev/null || : + # restore config backup [ -f $config ] || cp /data/media/0/.${id}-config-backup.txt $config 2>/dev/null || : + # flashable uninstaller cp -f $srcDir/bin/${id}-uninstaller.zip /data/media/0/ + # set perms set_perms_recursive ${config%/*} chmod 666 /data/media/0/${id}-uninstaller.zip @@ -186,6 +208,7 @@ case $installDir in ;; esac + set +euo pipefail 2>/dev/null || : @@ -212,7 +235,6 @@ echo " [ $installDir == /data/adb ] && echo -e "\n(i) Use init.d or an app to run $installDir/${id}-init.sh on boot to initialize ${id}." echo -trap - EXIT # initialize $id if [ -f $installDir/service.sh ]; then @@ -221,8 +243,4 @@ else $installDir/${id}-init.sh --override fi -e=$? -[ $e -eq 0 ] || { echo; exit $e; } -rm /sbin/.$id/.ghost-charging 2>/dev/null ### -/sbin/acca --daemon > /dev/null || /sbin/accd ### workaround, Magisk 20.4+ exit 0 diff --git a/module.prop b/module.prop index 8874882..78ad909 100644 --- a/module.prop +++ b/module.prop @@ -1,6 +1,6 @@ id=acc name=Advanced Charging Controller (ACC) -version=2020.3.30-r1-dev -versionCode=202003301 +version=2020.4.4-dev +versionCode=202004040 author=VR25 (patreon.com/vr25) description=ACC is an Android software. It's primarily intended for extending battery service life. In a nutshell, this is achieved through limiting charging current, temperature and voltage. Any root solution is supported. A recent stable Magisk version is recommended. If you're reading this from Magisk Manager > Downloads, tap here to open the documentation. Once there, if you're lazy, jump to the quick start section.