From 9ab5292b0bfaaa7deee4c0e976d82261bcf833d3 Mon Sep 17 00:00:00 2001 From: Alcatraz323 Date: Sun, 16 Apr 2023 23:44:15 +0800 Subject: [PATCH] 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 --- CloverParts/Android.bp | 30 ++++ CloverParts/AndroidManifest.xml | 30 +++- CloverParts/cloverparts.rc | 24 +++ .../config-io.alcatraz.cloverparts.xml | 36 +++++ ...pp-permissions_io.alcatraz.cloverparts.xml | 21 +++ .../ic_baseline_battery_charging_full_24.xml | 10 ++ .../ic_baseline_miscellaneous_services_24.xml | 6 + .../res/drawable/ic_baseline_whatshot_24.xml | 5 + .../res/drawable/information_outline.xml | 9 ++ CloverParts/res/values-zh-rCN/strings.xml | 15 ++ CloverParts/res/values/strings.xml | 15 ++ CloverParts/res/xml/bms_settings.xml | 53 +++++++ .../io/alcatraz/cloverparts/BMSActivity.java | 37 +++++ .../io/alcatraz/cloverparts/BMSFragment.java | 63 ++++++++ .../io/alcatraz/cloverparts/BMSReceiver.java | 76 +++++++++ .../io/alcatraz/cloverparts/BMSService.java | 38 +++++ .../io/alcatraz/cloverparts/BootReceiver.java | 36 +++++ .../io/alcatraz/cloverparts/Constants.java | 21 +++ .../cloverparts/SharedPreferenceUtil.java | 74 +++++++++ .../io/alcatraz/cloverparts/ShellUtils.java | 148 ++++++++++++++++++ sepolicy/private/cloverparts_app.te | 24 +++ sepolicy/private/seapp_contexts | 1 + sepolicy/public/cloverparts_app.te | 1 + sepolicy/vendor/cloverparts_app.te | 2 + 24 files changed, 774 insertions(+), 1 deletion(-) create mode 100644 CloverParts/cloverparts.rc create mode 100644 CloverParts/config-io.alcatraz.cloverparts.xml create mode 100644 CloverParts/privapp-permissions_io.alcatraz.cloverparts.xml create mode 100644 CloverParts/res/drawable/ic_baseline_battery_charging_full_24.xml create mode 100755 CloverParts/res/drawable/ic_baseline_miscellaneous_services_24.xml create mode 100755 CloverParts/res/drawable/ic_baseline_whatshot_24.xml create mode 100644 CloverParts/res/drawable/information_outline.xml create mode 100644 CloverParts/res/xml/bms_settings.xml create mode 100755 CloverParts/src/io/alcatraz/cloverparts/BMSActivity.java create mode 100755 CloverParts/src/io/alcatraz/cloverparts/BMSFragment.java create mode 100644 CloverParts/src/io/alcatraz/cloverparts/BMSReceiver.java create mode 100644 CloverParts/src/io/alcatraz/cloverparts/BMSService.java create mode 100755 CloverParts/src/io/alcatraz/cloverparts/BootReceiver.java create mode 100755 CloverParts/src/io/alcatraz/cloverparts/Constants.java create mode 100644 CloverParts/src/io/alcatraz/cloverparts/SharedPreferenceUtil.java create mode 100755 CloverParts/src/io/alcatraz/cloverparts/ShellUtils.java create mode 100644 sepolicy/private/cloverparts_app.te create mode 100644 sepolicy/private/seapp_contexts create mode 100644 sepolicy/public/cloverparts_app.te create mode 100644 sepolicy/vendor/cloverparts_app.te diff --git a/CloverParts/Android.bp b/CloverParts/Android.bp index 2f82f59c..ca463c89 100644 --- a/CloverParts/Android.bp +++ b/CloverParts/Android.bp @@ -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, +} \ No newline at end of file diff --git a/CloverParts/AndroidManifest.xml b/CloverParts/AndroidManifest.xml index 3000941a..e0a0ef8e 100644 --- a/CloverParts/AndroidManifest.xml +++ b/CloverParts/AndroidManifest.xml @@ -19,14 +19,32 @@ package="io.alcatraz.cloverparts" android:sharedUserId="android.uid.system"> + + + + + + + + + + + + + @@ -36,5 +54,15 @@ + + + + + + + + diff --git a/CloverParts/cloverparts.rc b/CloverParts/cloverparts.rc new file mode 100644 index 00000000..b670cc30 --- /dev/null +++ b/CloverParts/cloverparts.rc @@ -0,0 +1,24 @@ +# +# Copyright (c) 2023, Alcatraz323 +# +# 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 \ No newline at end of file diff --git a/CloverParts/config-io.alcatraz.cloverparts.xml b/CloverParts/config-io.alcatraz.cloverparts.xml new file mode 100644 index 00000000..273b3a5f --- /dev/null +++ b/CloverParts/config-io.alcatraz.cloverparts.xml @@ -0,0 +1,36 @@ + + + + + + + + \ No newline at end of file diff --git a/CloverParts/privapp-permissions_io.alcatraz.cloverparts.xml b/CloverParts/privapp-permissions_io.alcatraz.cloverparts.xml new file mode 100644 index 00000000..d57eb5cb --- /dev/null +++ b/CloverParts/privapp-permissions_io.alcatraz.cloverparts.xml @@ -0,0 +1,21 @@ + + + + + + + + + \ No newline at end of file diff --git a/CloverParts/res/drawable/ic_baseline_battery_charging_full_24.xml b/CloverParts/res/drawable/ic_baseline_battery_charging_full_24.xml new file mode 100644 index 00000000..52f716e3 --- /dev/null +++ b/CloverParts/res/drawable/ic_baseline_battery_charging_full_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/CloverParts/res/drawable/ic_baseline_miscellaneous_services_24.xml b/CloverParts/res/drawable/ic_baseline_miscellaneous_services_24.xml new file mode 100755 index 00000000..6c8efe31 --- /dev/null +++ b/CloverParts/res/drawable/ic_baseline_miscellaneous_services_24.xml @@ -0,0 +1,6 @@ + + + + diff --git a/CloverParts/res/drawable/ic_baseline_whatshot_24.xml b/CloverParts/res/drawable/ic_baseline_whatshot_24.xml new file mode 100755 index 00000000..05d22635 --- /dev/null +++ b/CloverParts/res/drawable/ic_baseline_whatshot_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/CloverParts/res/drawable/information_outline.xml b/CloverParts/res/drawable/information_outline.xml new file mode 100644 index 00000000..35f2aa4d --- /dev/null +++ b/CloverParts/res/drawable/information_outline.xml @@ -0,0 +1,9 @@ + + + + \ No newline at end of file diff --git a/CloverParts/res/values-zh-rCN/strings.xml b/CloverParts/res/values-zh-rCN/strings.xml index 03f7a379..05311cb1 100644 --- a/CloverParts/res/values-zh-rCN/strings.xml +++ b/CloverParts/res/values-zh-rCN/strings.xml @@ -17,4 +17,19 @@ 平板扩展 音量面板 + + 电源 + 电池 + 电池管理系统 + + 阶梯充电 + 开启阶梯充电 + 自动根据电池电压以及温度调整充电速度以保护电池 + 充电限制器 + 注意 + 如果你需要打开任何充电限制器选项,建议关闭“显示 - 连接或断开电源时唤醒”,不然你可能会在充电控制期间触发一些意外唤醒 + 持续充电模式 + 将电量限制在40%-60%以保护电池 + 限制最高电量为80%左右 + 电量在80%左右时停止充电以保护电池(持续模式优先) diff --git a/CloverParts/res/values/strings.xml b/CloverParts/res/values/strings.xml index 595365bb..d25177a5 100644 --- a/CloverParts/res/values/strings.xml +++ b/CloverParts/res/values/strings.xml @@ -17,4 +17,19 @@ Clover Parts Volume Panel + + Power Supply + Battery + Battery management system + + Step charging + Enable step charging + Automatically tune charge speed depends on battery data(voltage/temperature) to protect battery + Charge limiter + Notice + 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 + Always connected mode + Limit the battery percent between 40% and 60% to protect battery + Limit to around 80% + Suspend charging when the percent is around 80% to protect battery(Always connected mode will make this never happen) diff --git a/CloverParts/res/xml/bms_settings.xml b/CloverParts/res/xml/bms_settings.xml new file mode 100644 index 00000000..e423c973 --- /dev/null +++ b/CloverParts/res/xml/bms_settings.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/CloverParts/src/io/alcatraz/cloverparts/BMSActivity.java b/CloverParts/src/io/alcatraz/cloverparts/BMSActivity.java new file mode 100755 index 00000000..ab092a2d --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/BMSActivity.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023, Alcatraz323 + * + * 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(); + } + } +} \ No newline at end of file diff --git a/CloverParts/src/io/alcatraz/cloverparts/BMSFragment.java b/CloverParts/src/io/alcatraz/cloverparts/BMSFragment.java new file mode 100755 index 00000000..98e7dce5 --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/BMSFragment.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023, Alcatraz323 + * + * 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")); + } +} diff --git a/CloverParts/src/io/alcatraz/cloverparts/BMSReceiver.java b/CloverParts/src/io/alcatraz/cloverparts/BMSReceiver.java new file mode 100644 index 00000000..7580aa65 --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/BMSReceiver.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023, Alcatraz323 + * + * 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(); + } + } +} diff --git a/CloverParts/src/io/alcatraz/cloverparts/BMSService.java b/CloverParts/src/io/alcatraz/cloverparts/BMSService.java new file mode 100644 index 00000000..8b747081 --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/BMSService.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021, Alcatraz323 + * + * 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); + } +} diff --git a/CloverParts/src/io/alcatraz/cloverparts/BootReceiver.java b/CloverParts/src/io/alcatraz/cloverparts/BootReceiver.java new file mode 100755 index 00000000..2dd543f1 --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/BootReceiver.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023, Alcatraz323 + * + * 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); + } +} diff --git a/CloverParts/src/io/alcatraz/cloverparts/Constants.java b/CloverParts/src/io/alcatraz/cloverparts/Constants.java new file mode 100755 index 00000000..e96164f5 --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/Constants.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2021, Alcatraz323 + * + * 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"; +} diff --git a/CloverParts/src/io/alcatraz/cloverparts/SharedPreferenceUtil.java b/CloverParts/src/io/alcatraz/cloverparts/SharedPreferenceUtil.java new file mode 100644 index 00000000..2c19cf45 --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/SharedPreferenceUtil.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021, Alcatraz323 + * + * 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; + } +} diff --git a/CloverParts/src/io/alcatraz/cloverparts/ShellUtils.java b/CloverParts/src/io/alcatraz/cloverparts/ShellUtils.java new file mode 100755 index 00000000..3b714abe --- /dev/null +++ b/CloverParts/src/io/alcatraz/cloverparts/ShellUtils.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021, Alcatraz323 + * + * 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 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"; + +} diff --git a/sepolicy/private/cloverparts_app.te b/sepolicy/private/cloverparts_app.te new file mode 100644 index 00000000..a7d1d5db --- /dev/null +++ b/sepolicy/private/cloverparts_app.te @@ -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 }; diff --git a/sepolicy/private/seapp_contexts b/sepolicy/private/seapp_contexts new file mode 100644 index 00000000..41025545 --- /dev/null +++ b/sepolicy/private/seapp_contexts @@ -0,0 +1 @@ +user=system seinfo=platform name=io.alcatraz.cloverparts domain=cloverparts_app type=system_app_data_file \ No newline at end of file diff --git a/sepolicy/public/cloverparts_app.te b/sepolicy/public/cloverparts_app.te new file mode 100644 index 00000000..e46e6274 --- /dev/null +++ b/sepolicy/public/cloverparts_app.te @@ -0,0 +1 @@ +type cloverparts_app, domain; \ No newline at end of file diff --git a/sepolicy/vendor/cloverparts_app.te b/sepolicy/vendor/cloverparts_app.te new file mode 100644 index 00000000..c85295eb --- /dev/null +++ b/sepolicy/vendor/cloverparts_app.te @@ -0,0 +1,2 @@ +allow cloverparts_app sysfs_battery_supply:file rw_file_perms; +allow cloverparts_app sysfs_battery_supply:dir search; \ No newline at end of file