在Settings->Battery新增选项,以控制电量保持在设定的百分比:
Otimização da vida útil da bateria #电池寿命的优化
Carga Completa ativada #满载启动
->Otimização da vida útil da bateria #电池寿命的优化
->Carga Completa #满载
Carregue seu dispositivo até 100% #为您的设备充电至100%
->Carga Otimizada (Recomendado) #优化负载(推荐)
Carregue seu dispositivo até 85% #为您的设备充电,最高可达85%
->Carga Moderada #中等负荷
Carregue seu dispositivo até 60% #将您的设备充电至60%
Para preservar a vida útil da bateria, mantenha sempre Seu nível entre 20% e 80%. Recomenda-se usar o modo Carga Otimizada.
#为了延长电池寿命,请始终将电量保持在20%到80%之间。建议使用优化的加载模式。
Android 广播Broadcast的两种注册方式静态和动态
方法举例:
1
2
3
4
5
6
7
8
9
10
11
|
import android.provider.Settings;
//设置系统配置文件中的数据,第一个参数固定的,但是需要上下文,第二个参数是保存的Key,第三个参数是保存的value
boolean changeBluetoothName = Settings.System.putInt(getContentResolver(), "changeBluetoothName", 1);
//获取系统配置文件中的数据,第一个参数固定的,但是需要上下文,第二个参数是之前保存的Key,第三个参数表示如果没有这个key的情况的默认值
int blueFlag = Settings.System.getInt(getContentResolver(), "changeBluetoothName", 0);
//据说这个系统数据库的位置是:
//data/data/com.android.providers.settings/databases/
//数据库控制的代码:
//frameworks\base\packages\SettingsProvider\src\com\android\providers\settings的DatabaseHelper类里面
|
\frameworks\base\core\java\android\provider\Settings.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/**
* The Settings provider contains global system-level device preferences.
*/
public final class Settings {
/**
* System settings, containing miscellaneous system preferences. This
* table holds simple name/value pairs. There are convenience
* functions for accessing individual settings entries.
*/
public static final class System extends NameValueTable {
public static final String SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent";
public static final String CHARGE_MODE = "charge_mode"; //cy add chargemode limit 100 or 85 or 60
... ...
}
}
|
\frameworks\base\api\current.txt
1
2
3
4
5
6
7
8
9
|
// Signature format: 2.0
package android {
... ...
public static final class Settings.System extends android.provider.Settings.NameValueTable {
ctor public Settings.System();
... ...
field public static final String CHARGE_MODE = "charge_mode";
}
}
|
\frameworks\base\non-updatable-api\current.txt
1
2
3
4
5
6
7
8
9
|
// Signature format: 2.0
package android {
... ...
public static final class Settings.System extends android.provider.Settings.NameValueTable {
ctor public Settings.System();
... ...
field public static final String CHARGE_MODE = "charge_mode";
}
}
|
\vendor\mediatek\proprietary\packages\apps\MtkSettings\res\values\strings.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
... ...
<!-- [CHAR_LIMIT=40] Battery percentage: Title -->
<string name="battery_percentage">Battery percentage</string>
... ...
<string name="charging_mode">Optimize battery life active</string>
<string name="charging_mode_summary">Full load active</string>
<string name="chargeModeTitle">Optimize battery life</string>
<string name="chargeMode100_title">Full load</string>
<string name="chargeMode100_summary">Charge to 100%</string>
<string name="chargeMode85_title">Optimal load (Recomendado)</string>
<string name="chargeMode85_summary">Charge to 85%</string>
<string name="chargeMode60_title">Middle load</string>
<string name="chargeMode60_summary">Charge to 60%</string>
<string name="chargeModeMessage" formatted="false">In order to prolong the battery life, please keep the power between 20% and 80% at all times. An optimized loading mode is recommended.</string>
</resources>
|
\vendor\mediatek\proprietary\packages\apps\MtkSettings\res\values-pt-rPT\strings.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
... ...
<string name="charging_mode" msgid="8345490568291778641">Otimização da vida útil da bateria</string>
<string name="charging_mode_summary" msgid="8345490568291778642">Carga Completa ativada</string>
<string name="chargeModeTitle" msgid="8345490568291778643">Otimização da vida útil da bateria</string>
<string name="chargeMode100_title" msgid="8345490568291778644">Carga Completa</string>
<string name="chargeMode100_summary" msgid="8345490568291778645">Carregue seu dispositivo até 100%</string>
<string name="chargeMode85_title" msgid="8345490568291778646">Carga Otimizada (Recomendado)</string>
<string name="chargeMode85_summary" msgid="8345490568291778647">Carregue seu dispositivo até 85%</string>
<string name="chargeMode60_title" msgid="8345490568291778648">Carga Moderada</string>
<string name="chargeMode60_summary" msgid="8345490568291778649">Carregue seu dispositivo até 60%</string>
<string name="chargeModeMessage" msgid="8345490568291778650" formatted="false">Para preservar a vida útil da bateria, mantenha sempre Seu nível entre 20% e 80%. Recomenda-se usar o modo Carga Otimizada.</string>
</resources>
|
\vendor\mediatek\proprietary\packages\apps\MtkSettings\res\values-zh-rCN\strings.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
... ...
<string name="charging_mode" msgid="8345490568291778641">电池寿命的优化激活</string>
<string name="charging_mode_summary" msgid="8345490568291778642">满载激活</string>
<string name="chargeModeTitle" msgid="8345490568291778643">电池寿命的优化</string>
<string name="chargeMode100_title" msgid="8345490568291778644">满载</string>
<string name="chargeMode100_summary" msgid="8345490568291778645">为您的设备充电至100%</string>
<string name="chargeMode85_title" msgid="8345490568291778646">优化负载(推荐)</string>
<string name="chargeMode85_summary" msgid="8345490568291778647">为您的设备充电,最高可达85%</string>
<string name="chargeMode60_title" msgid="8345490568291778648">中等负荷</string>
<string name="chargeMode60_summary" msgid="8345490568291778649">将您的设备充电至60%</string>
<string name="chargeModeMessage" msgid="8345490568291778650" formatted="false">为了延长电池寿命,请始终将电量保持在20%到80%之间。建议使用优化的加载模式。</string>
</resources>
|
\vendor\mediatek\proprietary\packages\apps\MtkSettings\res\xml\power_usage_summary.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="power_usage_summary_screen"
android:title="@string/power_usage_summary_title"
settings:keywords="@string/keywords_battery">
... ...
<SwitchPreference
android:key="battery_percentage"
android:title="@string/battery_percentage"
android:summary="@string/battery_percentage_description"
settings:controller="com.android.settings.display.BatteryPercentagePreferenceController" />
<!-- cy add start -->>
<Preference
android:key="charging_mode"
android:title="@string/charging_mode"
android:summary="@string/charging_mode_summary"
settings:controller="com.android.settings.fuelgauge.batterytip.ChargingModePreferenceController" />
<!-- cy add end -->>
<com.android.settings.fuelgauge.PowerGaugePreference
android:key="last_full_charge"
android:title="@string/battery_last_full_charge"
android:selectable="false"
settings:allowDividerAbove="true" />
<com.android.settings.fuelgauge.PowerGaugePreference
android:key="screen_usage"
android:title="@string/device_screen_usage"
android:selectable="false" />
<com.android.settingslib.widget.FooterPreference
android:key="power_usage_footer"
android:title="@string/battery_footer_summary"
android:selectable="false"
settings:searchable="false"/>
</PreferenceScreen>
|
\vendor\mediatek\proprietary\packages\apps\MtkSettings\res\layout\chargemode_radiobutton.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android" >
<RadioGroup
android:id="@+id/chargeMode_radio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:orientation="vertical">
<RadioButton
android:id="@+id/charge_mode100"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/chargeMode100_title"
android:textSize="15dp"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="31dp"
android:text="@string/chargeMode100_summary"/>
<RadioButton
android:id="@+id/charge_mode85"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/chargeMode85_title"
android:textSize="15dp"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="31dp"
android:text="@string/chargeMode85_summary"/>
<RadioButton
android:id="@+id/charge_mode60"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/chargeMode60_title"
android:textSize="15dp"
android:textStyle="bold"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="31dp"
android:text="@string/chargeMode60_summary"/>
</RadioGroup>
<TextView
android:id="@+id/charge_mode_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:text="@string/chargeModeMessage"
android:textSize="14dp"
/>
</LinearLayout>
|
\vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\fuelgauge\batterytip\ChargingModePreferenceController.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/*
* Copyright (C) 2018 The Android Open Source Project
*
* 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.
*/
package com.android.settings.fuelgauge.batterytip;
import static android.provider.Settings.System.CHARGE_MODE;
import android.content.Context;
import android.content.Intent; //cy
import android.text.TextUtils;
import androidx.preference.Preference;
import com.android.settings.R;
import android.provider.Settings;
import com.android.settings.core.BasePreferenceController;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.RadioButton;
import android.widget.RadioGroup;
/**
* Preference controller to control the battery manager
*/
public class ChargingModePreferenceController extends BasePreferenceController {
private static final String KEY_CHARGING_MODE = "charging_mode";
private static AlertDialog chargeModeDialog;
private static AlertDialog.Builder chargeModeDialogBuilder;
public ChargingModePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
}
@Override
public int getAvailabilityStatus() {
return AVAILABLE_UNSEARCHABLE;
}
@Override
public boolean handlePreferenceTreeClick(Preference preference) {
if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
return false;
}
showChargeModeDialog();
return true;
}
private void showChargeModeDialog(){
if(chargeModeDialog != null){
chargeModeDialog.show();
return;
}
LayoutInflater inflaterCharge = LayoutInflater.from(mContext);
View viewChargeMode = inflaterCharge.inflate(R.layout.chargemode_radiobutton,null);
RadioGroup chargeModeRadioGroup = viewChargeMode.findViewById(R.id.chargeMode_radio);
RadioButton chargeMode100 = viewChargeMode.findViewById(R.id.charge_mode100);
RadioButton chargeMode85 = viewChargeMode.findViewById(R.id.charge_mode85);
RadioButton chargeMode60 = viewChargeMode.findViewById(R.id.charge_mode60);
int chargeModeCheck = Settings.System.getInt(mContext.getContentResolver(), CHARGE_MODE, 100);
if(chargeModeCheck == 60){
chargeMode60.setChecked(true);
}
else if(chargeModeCheck == 85){
chargeMode85.setChecked(true);
}
else{
chargeMode100.setChecked(true);
}
chargeModeRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
if (checkedId == R.id.charge_mode100){ //保存变量到Settings 数据库中
Settings.System.putInt(mContext.getContentResolver(), CHARGE_MODE, 100);
}
if (checkedId == R.id.charge_mode85){
Settings.System.putInt(mContext.getContentResolver(), CHARGE_MODE, 85);
}
if (checkedId == R.id.charge_mode60){
Settings.System.putInt(mContext.getContentResolver(), CHARGE_MODE, 60);
}
//
Intent intent = new Intent("Charge.mode.changed");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
intent.addFlags(0x01000000 | 0x00400000);
mContext.sendBroadcast(intent);
}
});
chargeModeDialogBuilder = new AlertDialog.Builder(mContext,AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
chargeModeDialogBuilder.setTitle(R.string.chargeModeTitle);
chargeModeDialogBuilder.setView(viewChargeMode);
chargeModeDialogBuilder.setNegativeButton("CANCELAR", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
chargeModeDialog.cancel();
}
});
chargeModeDialog = chargeModeDialogBuilder.create();
chargeModeDialog.getWindow().setGravity(Gravity.CENTER);
// chargeModeDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
chargeModeDialog.show();
}
}
|
\frameworks\base\services\core\java\com\android\server\BatteryService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
import static android.provider.Settings.System.CHARGE_MODE; //cy add
import java.io.FileWriter; //cy add
import java.io.FileNotFoundException; //cy add
import android.content.BroadcastReceiver; //cy add
import android.content.IntentFilter; //cy add
public final class BatteryService extends SystemService {
... ...
private static int chargeModeLimit;//cy add
private static boolean isFirstStart = true;//cy add
... ...
public BatteryService(Context context) {
super(context);
... ...
mContext.registerReceiver(new ChargeModeChargedReceiver() ,new IntentFilter("Charge.mode.changed"));//cy
... ...
}
//cy add start
private int fileWrite(String fileName, String buffer) {
int i = -1;
try {
File file = new File(fileName);
if(!file.exists()){
if(!file.getParentFile().exists()){
file.getParentFile().mkdirs();
}
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(fileName);
fileWriter.write(buffer);
//android.util.Log.d("cy_batteryservice","write file end");
fileWriter.close();
i = 0;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return i;
}
private void batteryCapacityCtrl(){
int chargeModeLimit = Settings.System.getInt(mContext.getContentResolver(), CHARGE_MODE, 100);
boolean isCharging = (mHealthInfo.batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING);
if((mHealthInfo.batteryLevel >= chargeModeLimit) && isCharging){
fileWrite("/sys/devices/platform/mt-battery/BatteryCapacityCtrl","1");
}else if((mHealthInfo.batteryLevel < chargeModeLimit) && !isCharging){
fileWrite("/sys/devices/platform/mt-battery/BatteryCapacityCtrl","0");
}
}
private class ChargeModeChargedReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
// android.util.Log.d("ChargeModeChargedReceiver", "onReceive: intent="+intent.getAction());
batteryCapacityCtrl();
}
}
//cy add end
private void processValuesLocked(boolean force) {
boolean logOutlier = false;
long dischargeDuration = 0;
mBatteryLevelCritical =
mHealthInfo.batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN
&& mHealthInfo.batteryLevel <= mCriticalBatteryLevel;
if (mHealthInfo.chargerAcOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mHealthInfo.chargerUsbOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_USB;
} else if (mHealthInfo.chargerWirelessOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
} else {
mPlugType = BATTERY_PLUGGED_NONE;
}
batteryCapacityCtrl();//cy add
if (DEBUG) {
Slog.d(TAG, "Processing new values: "
+ "info=" + mHealthInfo
+ ", mBatteryLevelCritical=" + mBatteryLevelCritical
+ ", mPlugType=" + mPlugType);
}
... ...
}
}
|
\kernel-4.19-lc\drivers\misc\mediatek\include\mt-plat\battery_common.h
1
2
3
4
5
6
7
|
#define BATTERY_CAPACITY_CONTROL //Isaac add
typedef struct {
... ...
#ifdef BATTERY_CAPACITY_CONTROL
int battery_capacity_ctrl; //Isaac add
#endif
} PMU_ChargerStruct;
|
\kernel-4.19-lc\drivers\power\supply\mediatek\battery_common.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
void do_chrdet_int_task(void)
{
if (g_bat_init_flag == KAL_TRUE) {
if (upmu_is_chr_det() == KAL_TRUE) {
... ...
} else {
... ...
}
#ifdef BATTERY_CAPACITY_CONTROL
//do_chrdet_int_task()->mt_battery_update_status()->battery_update(), it will set bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_CHARGING
//at the same time, skip_battery_update = KAL_TRUE; will skip BAT_thread()->mt_battery_update_status()
//So we must reset BMT_status.bat_charging_state here according to BMT_status.battery_capacity_ctrl
if (BMT_status.battery_capacity_ctrl) {
BMT_status.bat_charging_state = CHR_ERROR; //bat_data->BAT_STATUS = POWER_SUPPLY_STATUS_DISCHARGING
}
#endif
if (BMT_status.bat_vol > 0) {
mt_battery_update_status();
skip_battery_update = KAL_TRUE;
}
wake_up_bat();
} else {
battery_log(BAT_LOG_CRTI,
"[do_chrdet_int_task] battery thread not ready, will do after bettery init.\n");
}
}
|
\kernel-4.19-lc\drivers\power\supply\mediatek\battery_common.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
void BAT_thread(void)
{
static kal_bool battery_meter_initilized = KAL_FALSE;
if (battery_meter_initilized == KAL_FALSE) {
... ...
}
mt_battery_charger_detect_check(); //CHR_PRE
mt_battery_GetBatteryData(); //BMT_status.temperature、charger_vol、bat_vol
if (BMT_status.charger_exist == KAL_TRUE)
check_battery_exist();
mt_battery_thermal_check();
mt_battery_notify_check();
if ((BMT_status.charger_exist == KAL_TRUE) && (battery_suspended == KAL_FALSE)) {
mt_battery_CheckBatteryStatus(); //CHR_PRE
#ifdef BATTERY_CAPACITY_CONTROL
//do_chrdet_int_task()->mt_battery_charger_detect_check() plug out:set CHR_PRE
//BAT_thread()->mt_battery_charger_detect_check() plug out:set CHR_PRE
//mt_battery_CheckBatteryStatus()->mt_battery_CheckBatteryTemp()->do_batt_temp_state_machine() low_temp/high_temp recharge:set CHR_PRE
//So we must reset BMT_status.bat_charging_state here according to BMT_status.battery_capacity_ctrl
if (BMT_status.battery_capacity_ctrl) {
BMT_status.bat_charging_state = CHR_ERROR;
}
#endif
mt_battery_charging_algorithm();
}
mt_battery_update_status();
mt_kpoc_power_off_check();
}
|
\kernel-4.19-lc\drivers\power\supply\mediatek\battery_common.c
1
2
3
4
5
6
7
|
static int battery_probe(struct platform_device *dev)
{
... ...
#ifdef BATTERY_CAPACITY_CONTROL //Isaac add
BMT_status.battery_capacity_ctrl = 0;
#endif
}
|
\kernel-4.19-lc\drivers\power\supply\mediatek\battery_common.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
/* / */
/* BATTERY_CAPACITY_CONTROL API by Isaac add */
/* /sys/devices/platform/mt-battery/BatteryCapacityCtrl */
/* / */
#ifdef BATTERY_CAPACITY_CONTROL
static ssize_t show_Battery_Capacity_Ctrl(struct device *dev, struct device_attribute *attr, char *buf)
{
battery_log(BAT_LOG_CRTI, "Isaac [show_Battery_Capacity_Ctrl] battery_capacity_ctrl : %d\n", BMT_status.battery_capacity_ctrl);
return sprintf(buf, "%d\n", BMT_status.battery_capacity_ctrl);
}
static ssize_t store_Battery_Capacity_Ctrl(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
//unsigned int charging_enable = false;
if (!kstrtoint(buf, 0, &BMT_status.battery_capacity_ctrl)) {
if (BMT_status.battery_capacity_ctrl){
/* Disable charger */
BMT_status.bat_charging_state = CHR_ERROR;
//charging_enable = KAL_FALSE;
//battery_charging_control(CHARGING_CMD_ENABLE, &charging_enable);
wake_up_bat();
} else {
BMT_status.bat_charging_state = CHR_PRE;
if (BMT_status.charger_exist == KAL_TRUE) {
//BMT_status.bat_charging_state = CHR_CC;
wake_up_bat();
}
}
battery_log(BAT_LOG_CRTI, "Isaac [store_Battery_Capacity_Ctrl] battery_capacity_ctrl: %d\n", BMT_status.battery_capacity_ctrl);
} else {
battery_log(BAT_LOG_CRTI, "Isaac [store_Battery_Capacity_Ctrl] format error!\n");
}
return size;
}
static DEVICE_ATTR(BatteryCapacityCtrl, 0664, show_Battery_Capacity_Ctrl, store_Battery_Capacity_Ctrl);
#endif
|
\kernel-4.19-lc\drivers\power\supply\mediatek\battery_common.c
1
2
3
4
5
6
7
|
static int mt_batteryNotify_probe(struct platform_device *dev)
{
... ...
#ifdef BATTERY_CAPACITY_CONTROL
ret_device_file = device_create_file(&(dev->dev), &dev_attr_BatteryCapacityCtrl);
#endif
}
|
./sys/devices/platform/mt-battery
./sys/bus/platform/devices/mt-battery
BN_TestMode BatteryNotify driver_override of_node subsystem
BatteryCapacityCtrl driver modalias power uevent
127|tb8321p3_bsp:/sys/bus/platform/devices/mt-battery # cat uevent
DRIVER=mt-battery
OF_NAME=BAT_NOTIFY
OF_FULLNAME=/bus/BAT_NOTIFY
OF_COMPATIBLE_0=mediatek,bat_notify
OF_COMPATIBLE_N=1
MODALIAS=of:NBAT_NOTIFYT<NULL>Cmediatek,bat_notify
./sys/bus/platform/drivers/mt-battery
bind mt-battery uevent unbind //drivers下面也保存着device节点
tb8321p3_bsp:/sys/bus/platform/drivers/mt-battery # cat uevent
cat: uevent: Permission denied
============================================================
解决selinux权限问题:
01-15 14:04:55.775987 775 1309 D cy_batteryservice: batteryLevel=71
01-15 14:04:55.776949 775 1309 D cy_batteryservice: oldChargeModeLimit=60, chargeModeLimit=100
01-15 14:04:55.777242 775 1309 D cy_batteryservice: charge mode changed
01-15 14:04:55.783358 775 1309 D cy_batteryservice: FileNotFoundException
01-15 14:04:55.783997 775 1309 W System.err: java.io.FileNotFoundException: /sys/devices/platform/mt-battery/BatteryCapacityCtrl: open failed: EACCES (Permission denied)
01-15 14:04:55.784710 775 1309 W System.err: at libcore.io.IoBridge.open(IoBridge.java:492)
01-15 14:04:55.785169 775 1309 W System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
01-15 14:04:55.785520 775 1309 W System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:125)
01-15 14:04:55.785935 775 1309 W System.err: at java.io.FileWriter.<init>(FileWriter.java:63)
01-15 14:04:55.786593 775 1309 W System.err: at com.android.server.BatteryService.fileWrite(BatteryService.java:485)
01-15 14:04:55.787373 775 1309 W System.err: at com.android.server.BatteryService.processValuesLocked(BatteryService.java:526)
01-15 14:04:55.801425 775 1309 W System.err: at com.android.server.BatteryService.update(BatteryService.java:445)
01-15 14:04:55.802217 775 1309 W System.err: at com.android.server.BatteryService.access$1100(BatteryService.java:122)
01-15 14:04:55.805731 775 1309 W System.err: at com.android.server.BatteryService$HealthHalCallback.healthInfoChanged_2_1(BatteryService.java:1197)
01-15 14:04:55.806749 775 1309 W System.err: at android.hardware.health.V2_1.IHealthInfoCallback$Stub.onTransact(IHealthInfoCallback.java:558)
01-15 14:04:55.815422 775 1309 W System.err: Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
01-15 14:04:55.816357 775 1309 W System.err: at libcore.io.Linux.open(Native Method)
01-15 14:04:55.821533 775 1309 W System.err: at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
01-15 14:04:55.822753 775 1309 W System.err: at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
01-15 14:04:55.823738 775 1309 W System.err: at libcore.io.IoBridge.open(IoBridge.java:478)
01-15 14:04:55.824512 775 1309 W System.err: ... 9 more
<36>[ 505.555309] .(1)[223:logd.auditd]type=1400 audit(1642296439.623:485): avc: denied { read } for comm="cat" name="BatteryCapacityCtrl" dev="sysfs" ino=23191 scontext=u:r:shell:s0 tcontext=u:object_r:sysfs_capacity_ctrl:s0 tclass=file permissive=0
<36>[ 657.526451] .(0)[223:logd.auditd]type=1400 audit(1642296591.588:498): avc: denied { write } for comm="HwBinder:795_5" name="BatteryCapacityCtrl" dev="sysfs" ino=23191 scontext=u:r:system_server:s0 tcontext=u:object_r:sysfs_capacity_ctrl:s0 tclass=file permissive=0
每次开机需要给BMT_status.battery_capacity_ctrl初始化写入一个值:
(220118_09:00:15.403)[ 33.879298] <0>.(0)[774:system_server]BOOTPROF: 33879.275926:AMS:systemReady
(220118_09:00:15.405)[ 33.908790] <0>.(0)[774:system_server]BOOTPROF: 33908.767619:AMS:AMS_READY
(220118_09:00:15.482)[ 33.973157] <0>.(0)[774:system_server]Isaac [store_Battery_Capacity_Ctrl] battery_capacity_ctrl: 0
(220118_09:00:15.486)[ 34.010822] <1>.(1)[774:system_server][MTK-BT]bt_dbg_write: g_bt_turn_on[0], dbg_enable[0], len[19], data = 4w2T8M65K5?2af+a ON
(220118_09:00:15.486)[ 34.012831] <1>.(1)[774:system_server][MTK-BT]bt_dbg_write: g_bt_turn_on[0], dbg_enable[1], len[14], data = 0x12 0x00 0x00
(220118_09:00:15.486)[ 34.014212] <1>.(1)[774:system_server][MTK-BT]bt_dbg_write: y = 0x00000000
(220118_09:00:15.486)[ 34.015065] <1>.(1)[774:system_server][MTK-BT]bt_dbg_write: x(0x00000012), y(0x00000000), z(0x00000000)
(220118_09:00:15.486)[ 34.016272] <1>.(1)[774:system_server][MTK-BT]bt_dbg_write: command id(0x00000012) no handler defined!
(220118_09:00:16.044)[ 34.554620] <3>.(3)[774:system_server]BOOTPROF: 34554.600159:Keyguard bindService
(220118_09:00:16.044)[ 34.560982] <3>.(3)[774:system_server]BOOTPROF: 34560.961851:Keyguard started
(220118_09:00:16.123)[ 34.641879] <0>.(0)[774:system_server]alarm_dev: alarm 3 set 34.609000000
(220118_09:00:16.202)[ 34.679710] <3>.(3)[774:system_server]BOOTPROF: 34679.687544:SystemServer:NetworkStatsService systemReady
(220118_09:00:16.295)[ 34.761269] <3>.(3)[774:system_server]BOOTPROF: 34761.245467:SystemServer:ConnectivityService systemReady
(220118_09:00:16.560)[ 35.086622] <3>.(3)[774:system_server]BOOTPROF: 35086.599621:SystemServer:NetworkPolicyManagerServ systemReady
(220118_09:00:17.234)[ 35.748789] <3>.(3)[774:system_server]BOOTPROF: 35748.765085:SystemServer:PhaseThirdPartyAppsCanStart
(220118_09:00:17.986)[ 36.470049] <2>.(2)[774:system_server]BOOTPROF: 36470.026625:Android:SysServerInit_END
============================================================
最终selinux的权限为:
\device\mediatek\sepolicy\basic\non_plat\file_contexts
/sys/devices/platform/mt-battery/BatteryCapacityCtrl u:object_r:sysfs_capacity_ctrl:s0
\device\mediatek\sepolicy\basic\non_plat\file.te
type sysfs_capacity_ctrl, fs_type, sysfs_type;
\device\mediatek\sepolicy\basic\non_plat\system_app.te
allow system_app sysfs_capacity_ctrl:dir search;
allow system_app sysfs_capacity_ctrl:file rw_file_perms;
\device\mediatek\sepolicy\basic\non_plat\system_server.te
allow system_server sysfs_capacity_ctrl:dir search;
allow system_server sysfs_capacity_ctrl:file rw_file_perms;
\device\mediatek\mt6580\init.mt6580.rc
chmod 0666 /sys/devices/platform/mt-battery/BatteryCapacityCtrl
chown system system /sys/devices/platform/mt-battery/BatteryCapacityCtrl
=====================以下为sysfs_leds/sysfs_vibrator参考代码========================
/device/mediatek/sepolicy/basic/non_plat/genfs_contexts
genfscon sysfs /devices/platform/soc/soc:pwm_leds/leds/lcd-backlight u:object_r:sysfs_leds:s0
/system/sepolicy/private/genfs_contexts
genfscon sysfs /devices/virtual/timed_output/vibrator/enable u:object_r:sysfs_vibrator:s0
=================================================
device_register->device_add()会在/sys目录对应设备目录下创建uevent属性节点
用户态的后台程序(udev)会动态地周期性的扫描/sys目录中的属性项来自动管理设备文件(也称为设备节点),从而在/dev目录会建立或者删除对应的设备文件
./dev/MAINAF
./sys/class/actuatordrv_main_af/MAINAF //模块安装之后会在此目录生成节点, 这里是软链接
./sys/devices/virtual/actuatordrv_main_af/MAINAF //这里是真实的文件节点
./sys/bus/i2c/drivers/MAINAF //i2c_add_driver(&AF_i2c_driver)在i2c-bus上注册驱动,该函数执行成功后会在/sys/bus/i2c/drivers目录下创建.driver.name = AF_DRVNAME为名字的目录。
==============================
/system/sepolicy/prebuilts/api/26.0/private/file_contexts
/sys/class/leds(/.*)? u:object_r:sysfs_leds:s0
/device/mediatek/sepolicy/basic/non_plat/genfs_contexts
genfscon sysfs /devices/platform/leds-mt65xx/leds u:object_r:sysfs_leds:s0
/system/sepolicy/prebuilts/api/30.0/private/genfs_contexts
genfscon sysfs /class/leds u:object_r:sysfs_leds:s0
/system/sepolicy/prebuilts/api/30.0/public/file.te
type sysfs_leds, fs_type, sysfs_type;
/device/mediatek/mt6580/init.mt6580.rc
chown system system /sys/class/leds/lcd-backlight/brightness
chown system system /sys/class/leds/red/brightness
chown system system /sys/class/leds/green/brightness
chmod 0664 /sys/class/leds/lcd-backlight/brightness
chown system system /sys/class/leds/lcd-backlight/brightness
chmod 0664 /sys/class/leds/red/brightness
chown system system /sys/class/leds/red/brightness
chmod 0664 /sys/class/leds/green/brightness
chown system system /sys/class/leds/green/brightness
chmod 0664 /sys/class/leds/blue/brightness
chown system system /sys/class/leds/blue/brightness
/system/sepolicy/private/system_server.te
allow system_server sysfs_vibrator:file { write append };
/device/mediatek/sepolicy/basic/non_plat/mtk_hal_light.te
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# ==============================================================================
# Type Declaration
# ==============================================================================
type mtk_hal_light, domain;
type mtk_hal_light_exec, exec_type, file_type, vendor_file_type;
# hwbinder access
init_daemon_domain(mtk_hal_light)
hwbinder_use(mtk_hal_light)
# call into system_server process (callbacks)
binder_call(mtk_hal_light, system_server)
# system file
allow mtk_hal_light system_file:dir read;
allow mtk_hal_light system_file:dir open;
allow mtk_hal_light sysfs_leds:lnk_file read;
allow mtk_hal_light sysfs_leds:file rw_file_perms;
allow mtk_hal_light sysfs_leds:dir r_dir_perms;
get_prop(mtk_hal_light, hwservicemanager_prop)
hal_server_domain(mtk_hal_light,hal_light);
|
/device/mediatek/sepolicy/basic/non_plat/hal_vibrator.te
1
2
3
4
5
6
7
|
# vibrator sysfs rw access
allow hal_vibrator sysfs_vibrator:dir r_dir_perms;
allow hal_vibrator sysfs_leds:file rw_file_perms;
allow hal_vibrator sysfs_leds:dir r_dir_perms;
allow hal_vibrator sysfs_leds:lnk_file read;
allow hal_vibrator sysfs_vibrator:file rw_file_perms;
allow hal_vibrator_default sysfs_vibrator:file rw_file_perms;
|
./sys/devices/platform/odm/odm:vibrator@0/leds/vibrator/brightness
./sys/devices/platform/leds-mt65xx/leds/lcd-backlight/brightness
tb8321p3_bsp:/sys/class/leds/lcd-backlight # ls
brightness device max_brightness power subsystem trigger uevent
================================================================
BatteryCapacityCtrl电量控制相关推荐
- Android实现电量控制降低耗电
Android实现电量控制降低耗电? 如何才能降低Android应用程序的耗电量呢? 如何有效地控制耗电量问题? 这一个接一个的问题,都和电池的电量有关,下面我们进行详细的有关分析: Android手 ...
- android 电量控制
这个插件是属于设置的一部分,可以在 1 packages\apps\Settings\res\drawable-hdpi 这个文件夹里面查看,呵呵,有没有看到上面目录的斜杠方向,懂吧. 这里找到一个文 ...
- android原生widget 电量控制(PowerSave)设计浅析
1.General 抽象类StateTracker 每个按钮实现一个StateTracker的子类(亮度按钮特殊处理不实现该类): WifiStateTracker BluetoothStateTra ...
- android实现电量控制,Android 删除/定制桌面电量控制插件
这个插件是属于设置的一部分,可以在 packages\apps\Settings\res\drawable-hdpi 这个文件夹里面查看,呵呵,有没有看到上面目录的斜杠方向,懂吧. 这里找到一个文件名 ...
- 安卓情景模式开发-控制GPS/WIFI/蓝牙/飞行模式/控制静音/音量/振动
http://www.cnblogs.com/wii/archive/2012/03/18/2404947.html 对于android上GPS的控制,官方提供了相关的API Settings.Sec ...
- android manager provider模式,安卓情景模式开发(一)-控制GPS/WIFI/蓝牙/飞行模式...
对于android上GPS的控制,官方提供了相关的API Settings.Secure.setLocationProviderEnabled(getContentResolver(), Locati ...
- 教你如何保养iphone电池
本文章提到的如何为您的iphone4S.iphone4省电,是按照此功能耗电的大小排列的,希望对您有一定的帮助!(以下文章绝大部分适用于iphone4和iphone4s有部分适用于ipad1/2) 在 ...
- android 进lanucher的广播,(转)Android中Launcher对于AppWidget处理的分析:AppWidgetHost角色...
图二的时序图描述了,从AppWidgetPickActivity返回之后,Launcher如何处理AppWidget的. 图二.Picked之后Launcher对AppWidget的处理 执行过程: ...
- 手把手教你用ESP32制作一个游戏机
要学嵌入式,关注@我要学嵌入式,嵌入式猛男的加油站. 01 前言 MicroByte 是一款微型主机,能够运行 NES.GameBoy.GameBoy Color.Game Gear 和 Sega ...
最新文章
- EMNLP2020:Hugging Face获最佳demo
- 【Windows 逆向】使用 CE 工具挖掘关键数据内存真实地址 ( 逐层分析分析 静态地址 到 动态地址 的寻址 + 偏移 过程 ) ★
- 【网络安全】如何利用工具发现内部或外部网络攻击面
- python数字转汉字-Python转换数字到中文大写格式
- DTO(领域数据传输对象)是做什么的
- 【已解决】“The import java.sql.Connection conflicts with a type defined in the same file“
- jquery操作select - 代码合集
- final、finally和finalize;throw和throws;collection和collections;==和equals;Statement和PrepareStatement...
- 为长篇文档快速创建目录
- STC89C52点亮LED
- 新手如何使用docker搭建web服务环境
- VoosteQ Material Comp for Mac - 尖端音频压缩器
- 分享几款常用的MySQL管理工具
- PMP考试备考指南基础知识
- RabbitMQ之延迟队列
- 让站群排名稳步上升的策略
- 图书系统(查询图书内容)
- jdk、maven、idea安装配置
- java实现抓包jacap_java 抓包工具 jpcap的下载与eclipse配置
- 【商迪3D】与您细说什么是VR虚拟电子沙盘3D数字沙盘有什么功能
热门文章
- 如何用手机开发单片机编写51或arduino等程序?
- shell从入门到精通(25)你知道什么是login shell和non login shell吗
- 【分享】仿东软OA协同办公服务管理源码
- 【.NET6+Modbus】Modbus TCP协议解析、仿真环境以及基于.NET实现基础通信
- 储留香:从丞相说到文件系统
- 附录 区块链技术名词与核心原理
- PHP项目开发案例全程实录pdf
- Java九十条经验法则之第一条:用静态工厂方法代替构造器
- 锁存器Latch和触发器Flip-flop的区别
- Whitelabel Error PageThis application has no explicit mapping for /error, so you are seeing this as