在以前的平板方案的时候,有过一次客户要求在音量最大、亮度最大、wifi打开、蓝牙和GPS打开的条件下,播放视频要达8小时以上。调了一段时间的驱动,因为电池储量等原因,一直无法达到客户要求,后来是通过上层在播放视频的时候关闭几个CPU核心以达到省电作用。
第一步:创建aidl文件
1.在源码frameworks/base/core/java/android下创建home文件夹
2.在源码frameworks/base/core/java/android/home下新增一个IHomeService.aidl。代码如下:
package android.home;
interface IHomeService {
/** {@hide} */
void setLevel(int level);
}
3.在源码frameworks/base/Android.mk里的LOCAL_SRC_FILES后面添加
LOCAL_SRC_FILES += \
<!--IHomeService.aidl文件的路径-->
core/java/android/home/IHomeService.aidl \
第二步:创建Service文件,具体实现aidl文件定义的接口
1.在源码frameworks/base/services/core/java/com/android/server/创建home文件夹
2.在源码frameworks/base/services/core/java/com/android/server/home新增一个HomeService文件,代码如下:
package com.android.server.home;
import com.android.server.IoThread;
import android.content.pm.PackageManager;
import android.content.Context;
import android.home.IHomeService;
import android.util.Log;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.File;
public class HomeService extends IHomeService.Stub {
private static final String TAG = "HomeService";
private Context mContext;
private String packagename1 = "com.android.gallery3d";
private String packagename2 = "com.mxtech.videoplayer.ad";
private String cpuPath="/proc/hps/enabled"; //多核控制开关
private String cpuNumber2="/sys/devices/system/cpu/cpu2/online";//第3个cpu核心
private String cpuNumber3="/sys/devices/system/cpu/cpu3/online";//第4个cpu核心
private String cpuNumber4="/sys/devices/system/cpu/cpu4/online";//第5个cpu核心
private String cpuNumber5="/sys/devices/system/cpu/cpu5/online";//第6个cpu核心
private String cpuNumber6="/sys/devices/system/cpu/cpu6/online";//第7个cpu核心
private String cpuNumber7="/sys/devices/system/cpu/cpu7/online";//第8个cpu核心
private String cpuHz="/proc/cpufreq/cpufreq_oppidx";//cpu频率
private boolean flag1=true;
private boolean flag2=true;
private boolean oldflag=false;
private int defaultlevel=35;
private BatteryReceiver batteryReceiver;
public HomeService(Context context) {
super();
Log.d(TAG, "HomeService context");
mContext = context;
IntentFilter intentFilter = new IntentFilter(
Intent.ACTION_BATTERY_CHANGED);
batteryReceiver = new BatteryReceiver();
context.registerReceiver(batteryReceiver, intentFilter);
}
// 查看应用是否在运行
public boolean isRuning(String pname1, String pname2, Context context) {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> list = am.getRunningTasks(100);
RunningTaskInfo info=list.get(0);
Log.d(TAG, "packagename1:"+info.topActivity.getPackageName());
Log.d(TAG, "packagename2:"+info.baseActivity.getPackageName());
if (info.topActivity.getPackageName().equals(pname1)
/*&& info.baseActivity.getPackageName().equals(pname1)*/) {
return true;
}else if(info.topActivity.getPackageName().equals(pname2)
/*&& info.baseActivity.getPackageName().equals(pname2)*/){
return true;
}
return false;
}
public void wirteValue(String path,String value) {
BufferedWriter bw=null;
try {
bw=new BufferedWriter(new FileWriter(new File(path)));
bw.write(value);
} catch (IOException e) {
e.printStackTrace();
}finally{
if (bw!=null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/** @hide */
public void setLevel(int value){
Log.d(TAG, "setLevel:"+value);
defaultlevel=value;
}
class BatteryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 判断它是否是为电量变化的Broadcast Action
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
boolean flagapp=isRuning(packagename1, packagename2, mContext);
// 获取当前电量
int level = intent.getIntExtra("level", 0);
Log.d(TAG, "level:"+level);
Log.d(TAG, "defaultlevel:"+defaultlevel);
Log.d(TAG, "flagapp:"+flagapp+", oldflag:"+oldflag);
if (oldflag != flagapp){
if(flagapp){
Log.d(TAG, "flagapp is true, close six cores");
wirteValue(cpuPath,"0");//关闭多核自动设置
wirteValue(cpuHz,"5");//设置cpu频率
wirteValue(cpuNumber2,"0");//关闭cpu2
wirteValue(cpuNumber3,"0");//关闭cpu3
wirteValue(cpuNumber4,"0");//关闭cpu4
wirteValue(cpuNumber5,"0");//关闭cpu5
wirteValue(cpuNumber6,"0");//关闭cpu6
wirteValue(cpuNumber7,"0");关闭cpu7
}else {
Log.d(TAG, "flagapp is false.");
wirteValue(cpuPath,"1");//恢复最初cpu core设置
}
oldflag=flagapp;
flag1 = true;
flag2 = true;
}
if(!flagapp){
if (level <= defaultlevel && flag1) {//低电时
Log.d(TAG, "cpuPath:01");
wirteValue(cpuPath,"0");
wirteValue(cpuHz,"5");
wirteValue(cpuNumber2,"1");
wirteValue(cpuNumber3,"1");
wirteValue(cpuNumber4,"0");
wirteValue(cpuNumber5,"0");
wirteValue(cpuNumber6,"0");
wirteValue(cpuNumber7,"0");
Log.d(TAG, "cpuPath:01");
flag1 = false;
flag2 = true;
} else if (level > defaultlevel && flag2) {
wirteValue(cpuPath,"1");
Log.d(TAG, "cpuPath:11");
flag1 = true;
flag2 = false;
}
}
}
}
}
}
第三步:将自定义Service 加入到SystemServer 启动进程
修改frameworks/base/services/java/com/android/server/SystemServer.java
在startOtherServices()中增加以下代码:
try {
ServiceManager.addService("ctrlcpu", new HomeService(context));
} catch (Throwable e) {
Log.e(TAG, "Failure starting Home Service", e);
}
第四步:解决SELinux : avc: denied。修改sepolicy权限
1.打开device/mediatek/project/init.project.rc文件,在init.project.rc文件中为节点设置访问权限,增加以下代码
#为节点设置权限
chown system system /proc/hps/enabled
chmod 0660 /proc/hps/enabled
chown system system /proc/cpufreq/cpufreq_oppidx
chmod 0660 /proc/cpufreq/cpufreq_oppidx
chown system system /sys/devices/system/cpu/cpu2/online
chmod 0660 /sys/devices/system/cpu/cpu2/online
chown system system /sys/devices/system/cpu/cpu3/online
chmod 0660 /sys/devices/system/cpu/cpu3/online
chown system system /sys/devices/system/cpu/cpu4/online
chmod 0660 /sys/devices/system/cpu/cpu4/online
chown system system /sys/devices/system/cpu/cpu5/online
chmod 0660 /sys/devices/system/cpu/cpu5/online
chown system system /sys/devices/system/cpu/cpu6/online
chmod 0660 /sys/devices/system/cpu/cpu6/online
chown system system /sys/devices/system/cpu/cpu7/online
chmod 0660 /sys/devices/system/cpu/cpu7/online
2.打开/device/mediatek/common/sepolicy/service.te文件,在service.te文件增加
type home_service, service_manager_type;
3.在device/mediatek/common/sepolicy/service_contexts文件增加
HomeService u:object_r:home_service:s0
4.在device/mediatek/common/sepolicy/system_server.te文件增加
allow system_server home_service:service_manager add;