sdm660-common: introduce my simple battery management system
* settings page located in Settings -> Battery * soc-based step charger, jeita thermal charger switch (also done something in kernel) * add a mode for user always connected with chagrging cable to limit battery around 40% - 60% * add a switch for user to limit max charge at around 80% Signed-off-by: pix106 <sbordenave@gmail.com>
This commit is contained in:
parent
5b660f6800
commit
9ab5292b0b
24 changed files with 774 additions and 1 deletions
|
@ -10,12 +10,42 @@ android_app {
|
|||
srcs: ["src/**/*.java"],
|
||||
resource_dirs: ["res"],
|
||||
certificate: "platform",
|
||||
init_rc: ["cloverparts.rc"],
|
||||
platform_apis: true,
|
||||
system_ext_specific: true,
|
||||
privileged: true,
|
||||
|
||||
static_libs: [
|
||||
"org.pixelexperience.settings.resources",
|
||||
"androidx.cardview_cardview",
|
||||
"androidx.preference_preference",
|
||||
"androidx.appcompat_appcompat",
|
||||
"androidx.core_core",
|
||||
"SettingsLib"
|
||||
],
|
||||
|
||||
optimize: {
|
||||
proguard_flags_files: ["proguard.flags"],
|
||||
},
|
||||
|
||||
required: [
|
||||
"privapp-permissions_io.alcatraz.cloverparts",
|
||||
"config-io.alcatraz.cloverparts",
|
||||
],
|
||||
}
|
||||
|
||||
prebuilt_etc {
|
||||
name: "privapp-permissions_io.alcatraz.cloverparts",
|
||||
sub_dir: "permissions",
|
||||
src: "privapp-permissions_io.alcatraz.cloverparts.xml",
|
||||
system_ext_specific: true,
|
||||
filename_from_src: true,
|
||||
}
|
||||
|
||||
prebuilt_etc {
|
||||
name: "config-io.alcatraz.cloverparts",
|
||||
sub_dir: "sysconfig",
|
||||
src: "config-io.alcatraz.cloverparts.xml",
|
||||
system_ext_specific: true,
|
||||
filename_from_src: true,
|
||||
}
|
|
@ -19,14 +19,32 @@
|
|||
package="io.alcatraz.cloverparts"
|
||||
android:sharedUserId="android.uid.system">
|
||||
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS" />
|
||||
|
||||
<application
|
||||
android:directBootAware="true"
|
||||
android:label="@string/app_name">
|
||||
|
||||
<activity
|
||||
android:exported="true"
|
||||
android:name=".BMSActivity"
|
||||
android:label="@string/pref_battery_summary"
|
||||
android:theme="@style/Theme.SubSettingsBase">
|
||||
<intent-filter>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<action android:name="com.android.settings.action.EXTRA_SETTINGS" />
|
||||
</intent-filter>
|
||||
<meta-data android:name="com.android.settings.category"
|
||||
android:value="com.android.settings.category.ia.battery" />
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:name="io.alcatraz.cloverparts.VolumePanelTileService"
|
||||
android:name=".VolumePanelTileService"
|
||||
android:icon="@drawable/ic_speaker_cleaner_icon"
|
||||
android:label="@string/volume_panel_trigger_title"
|
||||
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
|
||||
|
@ -36,5 +54,15 @@
|
|||
</intent-filter>
|
||||
</service>
|
||||
|
||||
<service
|
||||
android:name=".BMSService" />
|
||||
|
||||
<receiver android:name=".BootReceiver"
|
||||
android:exported="true">
|
||||
<intent-filter android:priority="999">
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
24
CloverParts/cloverparts.rc
Normal file
24
CloverParts/cloverparts.rc
Normal file
|
@ -0,0 +1,24 @@
|
|||
#
|
||||
# Copyright (c) 2023, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
on boot
|
||||
chown system system /sys/class/power_supply/battery/step_charging_enabled
|
||||
chown system system /sys/class/power_supply/battery/sw_jeita_enabled
|
||||
chown system system /sys/class/power_supply/battery/input_suspend
|
||||
|
||||
chmod 0660 /sys/class/power_supply/battery/step_charging_enabled
|
||||
chmod 0660 /sys/class/power_supply/battery/sw_jeita_enabled
|
||||
chmod 0660 /sys/class/power_supply/battery/input_suspend
|
36
CloverParts/config-io.alcatraz.cloverparts.xml
Normal file
36
CloverParts/config-io.alcatraz.cloverparts.xml
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
|
||||
<!--
|
||||
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of The Linux Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
-->
|
||||
|
||||
<config>
|
||||
<allow-in-power-save package="io.alcatraz.cloverparts" />
|
||||
<hidden-api-whitelisted-app package="io.alcatraz.cloverparts" />
|
||||
</config>
|
21
CloverParts/privapp-permissions_io.alcatraz.cloverparts.xml
Normal file
21
CloverParts/privapp-permissions_io.alcatraz.cloverparts.xml
Normal file
|
@ -0,0 +1,21 @@
|
|||
<!--
|
||||
~ Copyright (c) 2023, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
-->
|
||||
<permissions>
|
||||
<privapp-permissions package="io.alcatraz.cloverparts">
|
||||
<permission name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<permission name="android.permission.WRITE_SETTINGS" />
|
||||
<permission name="android.permission.WRITE_SECURE_SETTINGS" />
|
||||
<permission name="android.permission.BATTERY_STATS" />
|
||||
</privapp-permissions>
|
||||
</permissions>
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#000"
|
||||
android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33v15.33C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V5.33C17,4.6 16.4,4 15.67,4zM11,20v-5.5H9L13,7v5.5h2L11,20z"/>
|
||||
</vector>
|
6
CloverParts/res/drawable/ic_baseline_miscellaneous_services_24.xml
Executable file
6
CloverParts/res/drawable/ic_baseline_miscellaneous_services_24.xml
Executable file
|
@ -0,0 +1,6 @@
|
|||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#000" android:pathData="M14.17,13.71l1.4,-2.42c0.09,-0.15 0.05,-0.34 -0.08,-0.45l-1.48,-1.16c0.03,-0.22 0.05,-0.45 0.05,-0.68s-0.02,-0.46 -0.05,-0.69l1.48,-1.16c0.13,-0.11 0.17,-0.3 0.08,-0.45l-1.4,-2.42c-0.09,-0.15 -0.27,-0.21 -0.43,-0.15L12,4.83c-0.36,-0.28 -0.75,-0.51 -1.18,-0.69l-0.26,-1.85C10.53,2.13 10.38,2 10.21,2h-2.8C7.24,2 7.09,2.13 7.06,2.3L6.8,4.15C6.38,4.33 5.98,4.56 5.62,4.84l-1.74,-0.7c-0.16,-0.06 -0.34,0 -0.43,0.15l-1.4,2.42C1.96,6.86 2,7.05 2.13,7.16l1.48,1.16C3.58,8.54 3.56,8.77 3.56,9s0.02,0.46 0.05,0.69l-1.48,1.16C2,10.96 1.96,11.15 2.05,11.3l1.4,2.42c0.09,0.15 0.27,0.21 0.43,0.15l1.74,-0.7c0.36,0.28 0.75,0.51 1.18,0.69l0.26,1.85C7.09,15.87 7.24,16 7.41,16h2.8c0.17,0 0.32,-0.13 0.35,-0.3l0.26,-1.85c0.42,-0.18 0.82,-0.41 1.18,-0.69l1.74,0.7C13.9,13.92 14.08,13.86 14.17,13.71zM8.81,11c-1.1,0 -2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2s2,0.9 2,2C10.81,10.1 9.91,11 8.81,11z"/>
|
||||
<path android:fillColor="#000" android:pathData="M21.92,18.67l-0.96,-0.74c0.02,-0.14 0.04,-0.29 0.04,-0.44c0,-0.15 -0.01,-0.3 -0.04,-0.44l0.95,-0.74c0.08,-0.07 0.11,-0.19 0.05,-0.29l-0.9,-1.55c-0.05,-0.1 -0.17,-0.13 -0.28,-0.1l-1.11,0.45c-0.23,-0.18 -0.48,-0.33 -0.76,-0.44l-0.17,-1.18C18.73,13.08 18.63,13 18.53,13h-1.79c-0.11,0 -0.21,0.08 -0.22,0.19l-0.17,1.18c-0.27,0.12 -0.53,0.26 -0.76,0.44l-1.11,-0.45c-0.1,-0.04 -0.22,0 -0.28,0.1l-0.9,1.55c-0.05,0.1 -0.04,0.22 0.05,0.29l0.95,0.74c-0.02,0.14 -0.03,0.29 -0.03,0.44c0,0.15 0.01,0.3 0.03,0.44l-0.95,0.74c-0.08,0.07 -0.11,0.19 -0.05,0.29l0.9,1.55c0.05,0.1 0.17,0.13 0.28,0.1l1.11,-0.45c0.23,0.18 0.48,0.33 0.76,0.44l0.17,1.18c0.02,0.11 0.11,0.19 0.22,0.19h1.79c0.11,0 0.21,-0.08 0.22,-0.19l0.17,-1.18c0.27,-0.12 0.53,-0.26 0.75,-0.44l1.12,0.45c0.1,0.04 0.22,0 0.28,-0.1l0.9,-1.55C22.03,18.86 22,18.74 21.92,18.67zM17.63,18.83c-0.74,0 -1.35,-0.6 -1.35,-1.35s0.6,-1.35 1.35,-1.35s1.35,0.6 1.35,1.35S18.37,18.83 17.63,18.83z"/>
|
||||
</vector>
|
5
CloverParts/res/drawable/ic_baseline_whatshot_24.xml
Executable file
5
CloverParts/res/drawable/ic_baseline_whatshot_24.xml
Executable file
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#000" android:pathData="M13.5,0.67s0.74,2.65 0.74,4.8c0,2.06 -1.35,3.73 -3.41,3.73 -2.07,0 -3.63,-1.67 -3.63,-3.73l0.03,-0.36C5.21,7.51 4,10.62 4,14c0,4.42 3.58,8 8,8s8,-3.58 8,-8C20,8.61 17.41,3.8 13.5,0.67zM11.71,19c-1.78,0 -3.22,-1.4 -3.22,-3.14 0,-1.62 1.05,-2.76 2.81,-3.12 1.77,-0.36 3.6,-1.21 4.62,-2.58 0.39,1.29 0.59,2.65 0.59,4.04 0,2.65 -2.15,4.8 -4.8,4.8z"/>
|
||||
</vector>
|
9
CloverParts/res/drawable/information_outline.xml
Normal file
9
CloverParts/res/drawable/information_outline.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<!-- drawable/information_outline.xml -->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="24dp"
|
||||
android:width="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path android:fillColor="#666" android:pathData="M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z" />
|
||||
</vector>
|
|
@ -17,4 +17,19 @@
|
|||
<resources>
|
||||
<string name="app_name">平板扩展</string>
|
||||
<string name="volume_panel_trigger_title">音量面板</string>
|
||||
|
||||
<string name="category_battery">电源</string>
|
||||
<string name="pref_battery">电池</string>
|
||||
<string name="pref_battery_summary">电池管理系统</string>
|
||||
|
||||
<string name="bms_category_step_charging">阶梯充电</string>
|
||||
<string name="bms_step_charging_switch">开启阶梯充电</string>
|
||||
<string name="bms_step_charging_switch_summary">自动根据电池电压以及温度调整充电速度以保护电池</string>
|
||||
<string name="bms_category_charge_limiter">充电限制器</string>
|
||||
<string name="bms_charge_limiter_notice">注意</string>
|
||||
<string name="bms_charge_limiter_description">如果你需要打开任何充电限制器选项,建议关闭“显示 - 连接或断开电源时唤醒”,不然你可能会在充电控制期间触发一些意外唤醒</string>
|
||||
<string name="bms_always_connected_mode">持续充电模式</string>
|
||||
<string name="bms_always_connected_mode_summary" formatted="false">将电量限制在40%-60%以保护电池</string>
|
||||
<string name="bms_limit_to_eighty" formatted="false">限制最高电量为80%左右</string>
|
||||
<string name="bms_limit_to_eighty_summary" formatted="false">电量在80%左右时停止充电以保护电池(持续模式优先)</string>
|
||||
</resources>
|
||||
|
|
|
@ -17,4 +17,19 @@
|
|||
<resources>
|
||||
<string name="app_name">Clover Parts</string>
|
||||
<string name="volume_panel_trigger_title">Volume Panel</string>
|
||||
|
||||
<string name="category_battery">Power Supply</string>
|
||||
<string name="pref_battery">Battery</string>
|
||||
<string name="pref_battery_summary">Battery management system</string>
|
||||
|
||||
<string name="bms_category_step_charging">Step charging</string>
|
||||
<string name="bms_step_charging_switch">Enable step charging</string>
|
||||
<string name="bms_step_charging_switch_summary">Automatically tune charge speed depends on battery data(voltage/temperature) to protect battery</string>
|
||||
<string name="bms_category_charge_limiter">Charge limiter</string>
|
||||
<string name="bms_charge_limiter_notice">Notice</string>
|
||||
<string name="bms_charge_limiter_description">If you turn on any charge limiter option, you would better turn off the “Display - Wake on plug” or you may get some unexpected wakeups during the charge control</string>
|
||||
<string name="bms_always_connected_mode">Always connected mode</string>
|
||||
<string name="bms_always_connected_mode_summary" formatted="false">Limit the battery percent between 40% and 60% to protect battery</string>
|
||||
<string name="bms_limit_to_eighty" formatted="false">Limit to around 80%</string>
|
||||
<string name="bms_limit_to_eighty_summary" formatted="false">Suspend charging when the percent is around 80% to protect battery(Always connected mode will make this never happen)</string>
|
||||
</resources>
|
||||
|
|
53
CloverParts/res/xml/bms_settings.xml
Normal file
53
CloverParts/res/xml/bms_settings.xml
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Copyright (c) 2023, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
-->
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="cat_bms_step"
|
||||
android:title="@string/bms_category_step_charging">
|
||||
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_miscellaneous_services_24"
|
||||
android:key="bms_step_charging_switch"
|
||||
android:summary="@string/bms_step_charging_switch_summary"
|
||||
android:title="@string/bms_step_charging_switch" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:key="cat_charge_limiter"
|
||||
android:title="@string/bms_category_charge_limiter">
|
||||
|
||||
<Preference
|
||||
android:icon="@drawable/information_outline"
|
||||
android:key="cat_charge_limiter_notice"
|
||||
android:selectable="false"
|
||||
android:summary="@string/bms_charge_limiter_description"
|
||||
android:title="@string/bms_charge_limiter_notice" />
|
||||
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_whatshot_24"
|
||||
android:key="bms_always_connected_mode"
|
||||
android:summary="@string/bms_always_connected_mode_summary"
|
||||
android:title="@string/bms_always_connected_mode" />
|
||||
|
||||
<SwitchPreference
|
||||
android:icon="@drawable/ic_baseline_battery_charging_full_24"
|
||||
android:key="bms_limit_to_eighty"
|
||||
android:summary="@string/bms_limit_to_eighty_summary"
|
||||
android:title="@string/bms_limit_to_eighty" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
37
CloverParts/src/io/alcatraz/cloverparts/BMSActivity.java
Executable file
37
CloverParts/src/io/alcatraz/cloverparts/BMSActivity.java
Executable file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.settingslib.collapsingtoolbar.CollapsingToolbarBaseActivity;
|
||||
import com.android.settingslib.widget.R;
|
||||
|
||||
public class BMSActivity extends CollapsingToolbarBaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
|
||||
Fragment fragment = getFragmentManager().findFragmentById(R.id.content_frame);
|
||||
BMSFragment bmsFragment;
|
||||
if (fragment == null) {
|
||||
bmsFragment = new BMSFragment();
|
||||
getFragmentManager().beginTransaction().add(R.id.content_frame, bmsFragment).commit();
|
||||
}
|
||||
}
|
||||
}
|
63
CloverParts/src/io/alcatraz/cloverparts/BMSFragment.java
Executable file
63
CloverParts/src/io/alcatraz/cloverparts/BMSFragment.java
Executable file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import static io.alcatraz.cloverparts.Constants.BMS_STEP_CHG_SWITCH;
|
||||
import static io.alcatraz.cloverparts.Constants.BMS_ALWAYS_CONNECTED_MODE;
|
||||
import static io.alcatraz.cloverparts.Constants.BMS_LIMIT_TO_EIGHTY;
|
||||
|
||||
public class BMSFragment extends PreferenceFragment implements Preference.OnPreferenceChangeListener {
|
||||
private SwitchPreference mStepChargingSwitch;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle bundle, String key) {
|
||||
addPreferencesFromResource(R.xml.bms_settings);
|
||||
findPreferences();
|
||||
bindListeners();
|
||||
updateSwitches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
switch (preference.getKey()) {
|
||||
case BMS_STEP_CHG_SWITCH:
|
||||
boolean enabled = (boolean) o;
|
||||
ShellUtils.execCommand("echo " + (enabled ? "1" : "0") + " > /sys/class/power_supply/battery/step_charging_enabled", false);
|
||||
ShellUtils.execCommand("echo " + (enabled ? "1" : "0") + " > /sys/class/power_supply/battery/sw_jeita_enabled", false);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void findPreferences() {
|
||||
mStepChargingSwitch = findPreference(BMS_STEP_CHG_SWITCH);
|
||||
}
|
||||
|
||||
private void bindListeners() {
|
||||
mStepChargingSwitch.setOnPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
private void updateSwitches() {
|
||||
ShellUtils.CommandResult result = ShellUtils.execCommand("cat /sys/class/power_supply/battery/step_charging_enabled", false);
|
||||
mStepChargingSwitch.setChecked(result.responseMsg.contains("1"));
|
||||
}
|
||||
}
|
76
CloverParts/src/io/alcatraz/cloverparts/BMSReceiver.java
Normal file
76
CloverParts/src/io/alcatraz/cloverparts/BMSReceiver.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
|
||||
import android.os.BatteryManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import static io.alcatraz.cloverparts.Constants.BMS_ALWAYS_CONNECTED_MODE;
|
||||
import static io.alcatraz.cloverparts.Constants.BMS_LIMIT_TO_EIGHTY;
|
||||
|
||||
public class BMSReceiver extends BroadcastReceiver {
|
||||
boolean alwaysConnected, limitToEighty;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
SharedPreferenceUtil sharedPreferenceUtil = SharedPreferenceUtil.getInstance();
|
||||
alwaysConnected = (boolean) sharedPreferenceUtil.get(context, BMS_ALWAYS_CONNECTED_MODE, false);
|
||||
limitToEighty = (boolean) sharedPreferenceUtil.get(context, BMS_LIMIT_TO_EIGHTY, false);
|
||||
|
||||
processBatteryChange(intent);
|
||||
}
|
||||
|
||||
private void resetSuspendState() {
|
||||
ShellUtils.CommandResult result = ShellUtils.execCommand("cat /sys/class/power_supply/battery/input_suspend", false);
|
||||
if(result.responseMsg.contains("1"))
|
||||
ShellUtils.execCommand("echo 0 > /sys/class/power_supply/battery/input_suspend", false);
|
||||
}
|
||||
|
||||
private void suspendCharger() {
|
||||
ShellUtils.CommandResult result = ShellUtils.execCommand("cat /sys/class/power_supply/battery/input_suspend", false);
|
||||
if(result.responseMsg.contains("0"))
|
||||
ShellUtils.execCommand("echo 1 > /sys/class/power_supply/battery/input_suspend", false);
|
||||
}
|
||||
|
||||
private synchronized void processBatteryChange(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
int current = bundle.getInt("level");
|
||||
|
||||
if(alwaysConnected) { // Always connected overrides limit to 80
|
||||
if(current < 40)
|
||||
resetSuspendState();
|
||||
else if(current > 60)
|
||||
suspendCharger();
|
||||
} else if(limitToEighty) {
|
||||
if(current < 78)
|
||||
resetSuspendState();
|
||||
else if(current > 80)
|
||||
suspendCharger();
|
||||
} else {
|
||||
resetSuspendState();
|
||||
}
|
||||
}
|
||||
}
|
38
CloverParts/src/io/alcatraz/cloverparts/BMSService.java
Normal file
38
CloverParts/src/io/alcatraz/cloverparts/BMSService.java
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class BMSService extends Service {
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
|
||||
registerReceiver(new BMSReceiver(), intentFilter);
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
}
|
36
CloverParts/src/io/alcatraz/cloverparts/BootReceiver.java
Executable file
36
CloverParts/src/io/alcatraz/cloverparts/BootReceiver.java
Executable file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class BootReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (context == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
context.startService(new Intent(context, BMSService.class));
|
||||
SharedPreferenceUtil sharedPreferenceUtil = SharedPreferenceUtil.getInstance();
|
||||
boolean stepChargingManualOverride = (boolean) sharedPreferenceUtil.get(context, "bms_step_charging_switch",
|
||||
true);
|
||||
|
||||
ShellUtils.execCommand("echo " + (stepChargingManualOverride ? "1" : "0") + " > /sys/class/power_supply/battery/step_charging_enabled", false);
|
||||
ShellUtils.execCommand("echo " + (stepChargingManualOverride ? "1" : "0") + " > /sys/class/power_supply/battery/sw_jeita_enabled", false);
|
||||
}
|
||||
}
|
21
CloverParts/src/io/alcatraz/cloverparts/Constants.java
Executable file
21
CloverParts/src/io/alcatraz/cloverparts/Constants.java
Executable file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
public class Constants {
|
||||
public static final String BMS_STEP_CHG_SWITCH = "bms_step_charging_switch";
|
||||
public static final String BMS_ALWAYS_CONNECTED_MODE = "bms_always_connected_mode";
|
||||
public static final String BMS_LIMIT_TO_EIGHTY = "bms_limit_to_eighty";
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public final class SharedPreferenceUtil {
|
||||
|
||||
private static final String FILE_NAME = "io.alcatraz.cloverparts_preferences";
|
||||
private static SharedPreferenceUtil mInstance;
|
||||
|
||||
public static SharedPreferenceUtil getInstance() {
|
||||
if (mInstance == null) {
|
||||
synchronized (SharedPreferenceUtil.class) {
|
||||
if (mInstance == null) {
|
||||
mInstance = new SharedPreferenceUtil();
|
||||
}
|
||||
}
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
public boolean put(Context context, String key, Object value) {
|
||||
String type = value.getClass().getSimpleName();
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
if ("Integer".equals(type)) {
|
||||
editor.putInt(key, (Integer) value);
|
||||
} else if ("Boolean".equals(type)) {
|
||||
editor.putBoolean(key, (Boolean) value);
|
||||
} else if ("Float".equals(type)) {
|
||||
editor.putFloat(key, (Float) value);
|
||||
} else if ("Long".equals(type)) {
|
||||
editor.putLong(key, (Long) value);
|
||||
} else if ("String".equals(type)) {
|
||||
editor.putString(key, (String) value);
|
||||
}
|
||||
editor.apply();
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Object get(Context context, String key, Object defValue) {
|
||||
SharedPreferences sharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
|
||||
String type = defValue.getClass().getSimpleName();
|
||||
if ("Integer".equals(type)) {
|
||||
return sharedPreferences.getInt(key, (Integer) defValue);
|
||||
} else if ("Boolean".equals(type)) {
|
||||
return sharedPreferences.getBoolean(key, (Boolean) defValue);
|
||||
} else if ("Float".equals(type)) {
|
||||
return sharedPreferences.getFloat(key, (Float) defValue);
|
||||
} else if ("Long".equals(type)) {
|
||||
return sharedPreferences.getLong(key, (Long) defValue);
|
||||
} else if ("String".equals(type)) {
|
||||
return sharedPreferences.getString(key, (String) defValue);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
148
CloverParts/src/io/alcatraz/cloverparts/ShellUtils.java
Executable file
148
CloverParts/src/io/alcatraz/cloverparts/ShellUtils.java
Executable file
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 2021, Alcatraz323 <alcatraz32323@gmail.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*/
|
||||
package io.alcatraz.cloverparts;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
public class ShellUtils {
|
||||
public static final String ERR_EMPTY_COMMAND = "Command can't be null";
|
||||
|
||||
/**
|
||||
* check whether has root permission
|
||||
*/
|
||||
public static boolean hasRootPermission() {
|
||||
return execCommand("echo root", true, false).result == 0;
|
||||
}
|
||||
|
||||
|
||||
public static CommandResult execCommand(String command, boolean isRoot) {
|
||||
return execCommand(new String[]{command}, isRoot, true);
|
||||
}
|
||||
|
||||
public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
|
||||
|
||||
return execCommand(new String[]{command}, isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
|
||||
return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, isNeedResultMsg);
|
||||
}
|
||||
|
||||
/**
|
||||
* execute shell commands
|
||||
* {@link CommandResult#result} is -1, there maybe some excepiton.
|
||||
*
|
||||
* @param commands command array
|
||||
* @param isRoot whether need to run with root
|
||||
* @param needResponse whether need result msg
|
||||
*/
|
||||
public static CommandResult execCommand(String[] commands, boolean isRoot, boolean needResponse) {
|
||||
|
||||
int result = -1;
|
||||
if (commands == null || commands.length == 0) {
|
||||
return new CommandResult(result, null, ERR_EMPTY_COMMAND);
|
||||
}
|
||||
|
||||
Process process = null;
|
||||
BufferedReader successResult = null;
|
||||
BufferedReader errorResult = null;
|
||||
StringBuilder successMsg = null;
|
||||
StringBuilder errorMsg = null;
|
||||
|
||||
DataOutputStream os = null;
|
||||
try {
|
||||
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
|
||||
os = new DataOutputStream(process.getOutputStream());
|
||||
for (String command : commands) {
|
||||
if (command == null) {
|
||||
continue;
|
||||
}
|
||||
// donnot use os.writeBytes(commmand), avoid chinese charset error
|
||||
os.write(command.getBytes());
|
||||
os.writeBytes(COMMAND_LINE_END);
|
||||
os.flush();
|
||||
}
|
||||
os.writeBytes(COMMAND_EXIT);
|
||||
os.flush();
|
||||
|
||||
result = process.waitFor();
|
||||
if (needResponse) {
|
||||
successMsg = new StringBuilder();
|
||||
errorMsg = new StringBuilder();
|
||||
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
||||
String s;
|
||||
while ((s = successResult.readLine()) != null) {
|
||||
successMsg.append(s).append("\n");
|
||||
}
|
||||
while ((s = errorResult.readLine()) != null) {
|
||||
errorMsg.append(s);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (errorResult != null) {
|
||||
errorResult.close();
|
||||
}
|
||||
if (successResult != null) {
|
||||
successResult.close();
|
||||
}
|
||||
if (os != null) {
|
||||
os.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return new CommandResult(result, successMsg == null ? "" : successMsg.toString(), errorMsg == null ? ""
|
||||
: errorMsg.toString());
|
||||
}
|
||||
|
||||
|
||||
public static class CommandResult {
|
||||
|
||||
public int result;
|
||||
public String responseMsg;
|
||||
public String errorMsg;
|
||||
|
||||
public CommandResult(int result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public CommandResult(int result, String responseMsg, String errorMsg) {
|
||||
this.result = result;
|
||||
this.responseMsg = responseMsg;
|
||||
this.errorMsg = errorMsg;
|
||||
}
|
||||
}
|
||||
|
||||
public static final String COMMAND_SU = "su";
|
||||
public static final String COMMAND_SH = "sh";
|
||||
public static final String COMMAND_EXIT = "exit\n";
|
||||
public static final String COMMAND_LINE_END = "\n";
|
||||
|
||||
}
|
24
sepolicy/private/cloverparts_app.te
Normal file
24
sepolicy/private/cloverparts_app.te
Normal file
|
@ -0,0 +1,24 @@
|
|||
typeattribute cloverparts_app mlstrustedsubject;
|
||||
|
||||
app_domain(cloverparts_app)
|
||||
|
||||
allow cloverparts_app activity_service:service_manager find;
|
||||
allow cloverparts_app activity_task_service:service_manager find;
|
||||
allow cloverparts_app audio_service:service_manager find;
|
||||
allow cloverparts_app autofill_service:service_manager find;
|
||||
allow cloverparts_app content_capture_service:service_manager find;
|
||||
allow cloverparts_app gpu_service:service_manager find;
|
||||
allow cloverparts_app hint_service:service_manager find;
|
||||
allow cloverparts_app surfaceflinger_service:service_manager find;
|
||||
allow cloverparts_app game_service:service_manager find;
|
||||
allow cloverparts_app textservices_service:service_manager find;
|
||||
allow cloverparts_app netstats_service:service_manager find;
|
||||
allow cloverparts_app voiceinteraction_service:service_manager find;
|
||||
allow cloverparts_app batterystats_service:service_manager find;
|
||||
allow cloverparts_app batteryproperties_service:service_manager find;
|
||||
|
||||
# ro.input.resampling, viewroot.profile_rendering
|
||||
dontaudit cloverparts_app default_prop:file read;
|
||||
|
||||
allow cloverparts_app system_app_data_file:dir { create rw_dir_perms search open setattr };
|
||||
allow cloverparts_app system_app_data_file:file { create rw_file_perms rename setattr unlink };
|
1
sepolicy/private/seapp_contexts
Normal file
1
sepolicy/private/seapp_contexts
Normal file
|
@ -0,0 +1 @@
|
|||
user=system seinfo=platform name=io.alcatraz.cloverparts domain=cloverparts_app type=system_app_data_file
|
1
sepolicy/public/cloverparts_app.te
Normal file
1
sepolicy/public/cloverparts_app.te
Normal file
|
@ -0,0 +1 @@
|
|||
type cloverparts_app, domain;
|
2
sepolicy/vendor/cloverparts_app.te
vendored
Normal file
2
sepolicy/vendor/cloverparts_app.te
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
allow cloverparts_app sysfs_battery_supply:file rw_file_perms;
|
||||
allow cloverparts_app sysfs_battery_supply:dir search;
|
Loading…
Reference in a new issue