Android-Framework新增接口

5 阅读6分钟

Android-Framework新增接口

接到一个新需求,要求提供一个中间件app的接口供客户调用,但是客户并不想用中间件的包,而是想加在framework.jar包里面,原因是因为不同项目为了适配就可以基本都不用做修改就能直接用,接口名字也一样,所以想让我们把接口做到framework里面,没办法,客户最大,无奈之下只能添加,顺便加深aidl,接口相关知识

首先找到framework的位置添加,以我们经常 import android.util.Log;为例,查看到源码位置为\android14\frameworks\base\core\java\android\util,基本上可以确定就是在这个目录下,那我们就在\android14\frameworks\base\core\java\这底下创建一个wkk目录当做我们的接口目录

因为app侧给我们提供的aidl接口是这样的包名和类名,我们创建的目录需要跟他一致(\android14\frameworks\base\core\java\com\wkk\proxy\log\aidl)

package com.wkk.proxy.log.aidl;
import com.wkk.proxy.log.aidl.ILogListenerAidl;

里面放置跟必须跟app侧提供给我们的一致(亲测有一点不一样就会连接失败)

package com.wkk.proxy.log.aidl;
import com.wkk.proxy.log.aidl.ILogListenerAidl;
import android.os.Bundle;

/** @hide */
interface ILogInterfaceAidl {

    int sendLog(int eventType, int source, int result, String detail);

    /**
    * <p>函数说明: 注册Log状态监听器。</p>
    * <p>同步/异步: 同步</p>
    * @param listener Log状态据监听器 {@link ILogListener}
    * @return 注册是否成功,true: 成功;false: 失败
    */
    boolean register(ILogListenerAidl listener);

    /**
    * <p>函数说明: 注销Log状态监听器。</p>
    * <p>同步/异步: 同步</p>
    * @param listener Log状态据监听器 {@link ILogListener}
    * @return 注册是否成功,true: 成功;false: 失败
    */
    boolean unregister(ILogListenerAidl listener);


    /**
     * <p>函数说明: 设置log级别。</p>
     * <p>同步/异步: 同步</p>
     * @param level Log类型
     */
    void setLogLevel(String level);

    /**
     * <p>函数说明: 获取log级别。</p>
     * <p>同步/异步: 同步</p>
     * @return 当前log级别
     */
    String getLogLevel();


    /**
     * <p>函数说明: 开始收集log。</p>
     * <p>同步/异步: 同步</p>
     * @param collectParam Log收集参数,如收集logcat的main、system、radio、event参数
     */
    void startCollect();

    /**
     * <p>函数说明: 停止收集全部log。</p>
     * <p>同步/异步: 同步</p>
     */
    void stopAllCollect();


    /**
     * <p>函数说明: 删除指定类型log。</p>
     * <p>同步/异步: 同步</p>
     * @param list 要删除的所有Log类型
     */
    void deleteLog(in Bundle bundle);


	/**
	 * <p>函数说明: 向USB设备拷贝数据。</p>
	 * <p>同步/异步: 同步</p>
	 */
	void copyData();

    /**
     * <p>函数说明: 启动USB管理器,更新USB状态UI。</p>
     * <p>同步/异步: 同步</p>
     */
    void setupUsbManager();

	/**
	 * <p>函数说明: 判断是否在进行zip打包。</p>
	 * <p>同步/异步: 同步</p>
	 */
	boolean isZipExecuting();
	/**
	 * <p>函数说明: 安全日志接口,给封装好了json的模块使用。</p>
	 * <p>同步/异步: 同步</p>
	 */
    int sendOtherSafeLog(String json);
}

还需要一个manager来进行连接管理的类

// \frameworks\base\core\java\com\wkk\proxy\log\aidl
package com.wkk.proxy.log.aidl
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemService;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

import com.wkk.proxy.log.aidl.ILogInterfaceAidl;


@SystemService(Context.SECURELOG_SERVICE)
public class SecurelogManager {

    private static final String TAG = "SecurelogManager";
	// 这个名称是Native服务注册到ServiceManager中的名称,这个代理类将会调用
	// Java的ServiceManager的getService得到binder代理
	private static final String SECURELOG_SERVICE_BINDER_NAME = "wkk.log";

    // ===============================
    // 安全事件类型定义
    // ===============================
    public static final int EVENT_AUTOMOTIVE_CONTROL  = 0;  // 自动驾驶控制相关事件
    public static final int EVENT_CABIN_CONTROL       = 1;  // 车舱控制相关事件
    public static final int EVENT_SECOC_ERROR         = 2;  // SecOC通信异常事件    
    public static final int EVENT_WIFI                = 3;  // WiFi相关事件
    public static final int EVENT_BLUETOOTH           = 4;  // 蓝牙模块相关事件
    public static final int EVENT_USB                 = 5;  // USB接口相关事件
    public static final int EVENT_DEBUG_ACCESS        = 6;  // 调试接口访问事件
    public static final int EVENT_DIAG                = 7;  // 诊断相关事件
    public static final int EVENT_ENGINEERING_MODE    = 8;  // 工程模式相关事件
    public static final int EVENT_LOG_EXPORT          = 9;  // 日志导出事件
    public static final int EVENT_APPLICATION_MANAGER = 10; // 应用管理相关事件
    public static final int EVENT_IDS_WARN            = 11; // IDS警告事件
    public static final int EVENT_LOGIN               = 12; // 登录相关事件
    public static final int EVENT_SECURE_BOOT_ERROR   = 13; // 安全启动失败事件
    public static final int EVENT_REMOTE_CONTROL      = 14; // 远程控制服务相关事件
    public static final int EVENT_SOMEIP_ERROR        = 15; // SOMEIP通信异常事件
    public static final int EVENT_DOIP_ERROR          = 16; // DoIP通信异常事件
    public static final int EVENT_NFS_ERROR           = 17; // NFS服务器相关事件
    public static final int EVENT_TLS_ERROR           = 18; // TLS通信异常事件
    public static final int EVENT_KMS                 = 19; // 密钥管理服务事件           
    public static final int EVENT_TEE_ERROR           = 20; // TEE服务异常事件
    public static final int EVENT_OTA                 = 21; // OTA升级相关事件    
    public static final int EVENT_DATA_UPDATE         = 22; // 数据更新相关事件  
    public static final int EVENT_VIP_HEARTBEAT       = 23; // VIP监控T-BOX心跳事件
    public static final int EVENT_COUNT               = 24; // 事件数量

    /**
     * @hide
     */
    @IntDef({
            EVENT_AUTOMOTIVE_CONTROL,
            EVENT_CABIN_CONTROL,
            EVENT_SECOC_ERROR,
            EVENT_WIFI,
            EVENT_BLUETOOTH,
            EVENT_USB,
            EVENT_DEBUG_ACCESS,
            EVENT_DIAG,
            EVENT_ENGINEERING_MODE,
            EVENT_LOG_EXPORT,
            EVENT_APPLICATION_MANAGER,
            EVENT_IDS_WARN,
            EVENT_LOGIN,
            EVENT_SECURE_BOOT_ERROR,
            EVENT_REMOTE_CONTROL,
            EVENT_SOMEIP_ERROR,
            EVENT_DOIP_ERROR,
            EVENT_NFS_ERROR,
            EVENT_TLS_ERROR,
            EVENT_KMS,
            EVENT_TEE_ERROR,
            EVENT_OTA,
            EVENT_DATA_UPDATE,
            EVENT_VIP_HEARTBEAT
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface EventType {}

    // ===============================
    // 安全日志来源定义
    // ===============================
    public static final int SOURCE_ANDROID    = 0;
    public static final int SOURCE_TBOX       = 1;
    public static final int SOURCE_QNX        = 2;
    public static final int SOURCE_VIP        = 3;
    public static final int SOURCE_HYPERVISOR = 4;
    public static final int SOURCE_COUNT      = 5;

    /**
     * @hide
     */
    @IntDef({SOURCE_ANDROID, SOURCE_TBOX, SOURCE_QNX, SOURCE_VIP, SOURCE_HYPERVISOR})
    @Retention(RetentionPolicy.SOURCE)
    public @interface SourceType {}

    // ===============================
    // 安全日志结果定义
    // ===============================
    public static final int RESULT_CONN    = 0;  // 连接成功
    public static final int RESULT_DISCONN = 1;  // 连接断开
    public static final int RESULT_SUCCESS = 2;  // 操作成功
    public static final int RESULT_FAILURE = 3;  // 操作失败
    public static final int RESULT_DENIED  = 4;  // 权限拒绝
    public static final int RESULT_ERROR   = 5;  // 一般错误
    public static final int RESULT_WARNING = 6;  // 警告
    public static final int RESULT_COUNT   = 7;  // 结果数量

    /**
     * @hide
     */
    @IntDef({RESULT_CONN, RESULT_DISCONN, RESULT_SUCCESS, RESULT_FAILURE,
            RESULT_DENIED, RESULT_ERROR, RESULT_WARNING})
    @Retention(RetentionPolicy.SOURCE)
    public @interface ResultType {}


    private Context mContext;

    /**
     * @hide
     */
    public SecurelogManager(Context ctx) {
        Log.d(TAG, "new SecurelogManager");
        mContext = ctx;
    }

    // 对参数加 @NonNull 或 @Nullable
    public int packet_and_send_secure_log( @SecurelogManager.EventType int event_type, @SecurelogManager.SourceType int source, @SecurelogManager.ResultType int result, @Nullable String detail){
        Log.d(TAG, "packet_and_send_secure_log ");
        // 通过内部类SecurelogManagerGlobal获取代理对象
        ILogInterfaceAidl service  = SecurelogManagerGlobal.get().getSecurelogService();
        if (service  == null) {
            Log.w(TAG, "SecurelogServer is null!!!");
            return -1;
        }

        try {
        	// 通过代理对象调用服务函数
            return service.sendLog(event_type, source, result, detail);
        } catch (RemoteException e) {
            throw new RuntimeException("Securelog service failed", e);
        }
    }
	
	// String
    public int packet_and_send_secure_log( @Nullable String json){
        Log.d(TAG, "packet_and_send_secure_log json ");
        // 通过内部类SecurelogManagerGlobal获取代理对象
        ILogInterfaceAidl service  = SecurelogManagerGlobal.get().getSecurelogService();
        if (service  == null) {
            Log.w(TAG, "SecurelogServer is null!!!");
            return -1;
        }

        try {
        	// 通过代理对象调用服务函数
            return service.sendOtherSafeLog(json);
        } catch (RemoteException e) {
            throw new RuntimeException("Securelog service failed", e);
        }
    }

	// 内部类,获取服务端binder代理,封装对native服务的调用
    private static final class SecurelogManagerGlobal implements IBinder.DeathRecipient {

        private ILogInterfaceAidl mSecurelogService;

        private static final SecurelogManagerGlobal gSecurelogManager =
            new SecurelogManagerGlobal();

        private SecurelogManagerGlobal() { }

        public static SecurelogManagerGlobal get() {
            return gSecurelogManager;
        }

        public void binderDied() {
            mSecurelogService = null;
        }

		// 获取服务binder代理
        public ILogInterfaceAidl getSecurelogService() {
            connectSecurelogServiceLocked();
            if (mSecurelogService == null) {
                Log.e(TAG, "securelog service is unavailable");
            }
            return mSecurelogService;
        }

        private void connectSecurelogServiceLocked() {

            int myUid = android.os.Process.myUid();  // 获取当前进程 UID
            Log.i(TAG, "Current process UID: " + myUid);
            // Only reconnect if necessary
            if (mSecurelogService != null)
                return;

            Log.i(TAG, "Connecting to securelog service: " + SECURELOG_SERVICE_BINDER_NAME);
			// 通过ServiceManager对象拿到服务代理
            IBinder securelogServiceBinder = ServiceManager.getService(SECURELOG_SERVICE_BINDER_NAME);
            if (securelogServiceBinder == null) {
                Log.e(TAG, "securelog service not found");
                // Securelog service is now down, leave mSecurelogService as null
                return;
            }
            try {
                Log.d(TAG, "securelog service found!");
                securelogServiceBinder.linkToDeath(this, /* flags */ 0);
            } catch (RemoteException e) {
                // Securelog service is now down, leave mSecurelogService as null
                return;
            }
			// 拿到代理对象,后续对服务收到操作都是通过这里拿到的mSecurelogService代理对象
            mSecurelogService = ILogInterfaceAidl.Stub.asInterface(securelogServiceBinder);
        }
    }

}

添加完我们的管理类之后,还需要在\android14\frameworks\base\core\java\android\content\Context.java添加我们定义的服务名wkk.log

/**
     * Use with {@link #getSystemService(String)} to retrieve a
     * {@link com.wkk.proxy.log.aidl} for accessing wkk.log service.
     *
     * @see #getSystemService(String)
     * @hide
     */
    public static final String SECURELOG_SERVICE = "wkk.log";

添加完之后进行编译,发现编译报错,系统不能识别我们新增的这个目录路径,需要再添加android14/build/scripts/check_boot_jars/package_allowed_list.txt,这样就能导入framework.jar包就可以import我们定义的类来调用到中间件服务提供的接口了

###################################################
# Packages used for semidrive-framework.jar and semidrive-services.jar
semidrive\..*
com\.semidrive\..*
com\.wkk\..*
com\.cns\.android\..*