Android系统开发—手动设置CPU核数之添加自定义系统服务

在以前的平板方案的时候,有过一次客户要求在音量最大、亮度最大、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;

猜你喜欢

转载自blog.csdn.net/zengrunxiu/article/details/80840208
今日推荐