Android 7.0-自定义系统进程

有时候我们需要自定义一个系统进程,以便给上层调用需要系统权限的功能。
本文仅将我的实践过程做一个笔记,方便以后查阅。
特别提醒,本次实践是在Android7.0版本上进行的,如果是更高的版本,可能实现会有不同。

完整的过程如下
1.系统进程实现
(1)为了在Android studio中能够方便调用该进程,所以先实现两个aidl文件:
frameworks/base/services/lock/java/com/android/internal/lock/ILockManager.aidl
frameworks/base/services/lock/java/com/android/internal/lock/IStateCallback.aidl
其中,IStateCallback会在ILockManager中被调用,它作为一个client端的服务,使系统进程ILockManager能够调用client端的功能。
ILockManager的具体内容如下:

package com.android.internal.lock;
import com.android.internal.lock.IStateCallback;
interface ILockManager {
    boolean setGpioHigh();
    int getLockState();
    void setStateCallback(IStateCallback stateCallback);
}

IStateCallback的具体内容如下:

package com.android.internal.lock;

oneway interface IStateCallback {
    void onStateChange(int oldState, int newState);
}

(2)aidl接口实现类frameworks/base/services/lock/java/com/android/internal/lock/LockManager.java,它就是系统进程类。
大致内容如下:

package com.android.internal.lock;

import com.android.internal.lock.ILockManager;
import com.android.internal.lock.IStateCallback;

public class LockManager extends ILockManager.Stub {
    private IStateCallback mStateCallback;
    private Context mContext;

    public LockManager(Context context) {
        mContext = context;
        //mValue = getValue();
    }
    @Override
    public boolean setGpioHigh() throws RemoteException {
        return true;
    }
    @Override
    public int getLockState() throws RemoteException {
        return 0;
    }
     @Override
    public void setStateCallback(IStateCallback stateCallback) throws RemoteException {
        mStateCallback = stateCallback;
    }
}

如上是LockManager 类的一个缩减版,这里没有完全将代码贴上来,具体业务代码就不贴了,因为没有这个必要,这里目的是知道这个实现过程,否则完全代码贴上来也会占用太多的篇幅。

2.新增加一个编译脚本文件frameworks/base/services/lock/Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := services.lock

LOCAL_SRC_FILES +=
$(call all-java-files-under,java)

LOCAL_JAVA_LIBRARIES := services.core

include $(BUILD_STATIC_JAVA_LIBRARY)

3.frameworks/base/services/Android.mk文件
在services := \中加入lock
services := \lock
这里其实是引用frameworks/base/services/lock/Android.mk中编译出的services.lock.jar。

4.frameworks/base/Android.mk文件
LOCAL_SRC_FILES += \命令行增加:
services/lock/java/com/android/internal/lock/IStateCallback.aidl
services/lock/java/com/android/internal/lock/ILockManager.aidl
并在后面另起一行添加:
LOCAL_AIDL_INCLUDES += frameworks/base/services/lock/java
这句是为了让ILockManager.aidl文件中能够找到IStateCallback.aidl,如果没有上面这句,是无法编译通过的,而且注意这句“=”右边一定要是“frameworks/base/services/lock/java”,不能是“frameworks/base/services/lock”,因为java目录后面的目录是作为类的包名存在的,如果写成“frameworks/base/services/lock”,那么就应该lock目录后面的目录为包名,即包名变成java.com.android.internal.lock,这样就会与实际的ILockManager类的包名为com.android.internal.lock相悖。

5.使ILockManager成为系统进程
在frameworks/base/services/java/com/android/server/SystemServer.java文件,方法startOtherServices中加入代码:

 traceBeginAndSlog("LockManager");
    ServiceManager.addService("lock", new LockManager(context));
    Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

这样LockManager的实例就创建了,并add到ServiceManager。

6.为了支持context.getSystemService(“lock”)来获取该系统进程
所以在文件frameworks/base/core/java/android/app/SystemServiceRegistry.java的静态代码块加入:

registerService("lock", ILockManager.class,
            new CachedServiceFetcher<ILockManager>() {
        @Override
        public ILockManager createService(ContextImpl ctx) {
            IBinder b = ServiceManager.getService("lock");
            return ILockManager.Stub.asInterface(b);
        }});

7.最后是sepolicy的配置,这个是权限配置
device/rockchip/common/sepolicy/service.te文件加入
type lock_service, app_api_service, system_server_service, service_manager_type;
这是定义了一个名字为lock_service的service。

device/rockchip/common/sepolicy/service_contexts文件加入
lock u:object_r:lock_service:s0
这是将lock_service与名为lock系统进程进行绑定关系。

device/rockchip/common/sepolicy/system_server.te文件加入
allow system_server lock_service:service_manager { find add };
这里的意思让系统进程system_server 可以从service_manager中获取和add我们定义的lock_service。

device/rockchip/common/sepolicy/system_app.te加入
allow system_app lock_service:service_manager { find };
这是让system_app 进程可以从service_manager获取我们定义的lock_service。

完成如上7步工作,最后进行编译,编译前先执行:make update-api,然后make -j24,编译通过就可以提交了,然后在Android studio中,在同样的包名com.android.internal.lock下,将上面的两个aidl文件copy进去,然后Android studio中先编译一下APP,最后就可以在代码中调用:
ILockManager lockManager = (ILockManager) context.getSystemService(“lock”);
这样就获取到了ILockManager 的实例,进而可以调用其他的各个功能方法了。

猜你喜欢

转载自blog.csdn.net/songqinging/article/details/87952193