系统开发,新增自定义framework通道

系统开发,新增自定义framework通道

在系统开发中有时候使用系统通道的话,实现不了需要的逻辑,此时需要新增自定义的通道 打通 APP-framework-hal
本实例是基于Android 9.0 源码工程

framework-hal

framework-hal 要用到jni,所以在frameworks-service 里弄一个service

frameworks/base/services/core/java/com/android/server/drivecontrol/DriveControlService.java

/**
 * @hide service调用jni和hal层通信
 */
public class DriveControlService extends IDriveControlService.Stub implements JniDriveCallBackListener {

private static final String TAG = DriveControlService.class.getSimpleName();
private IJniCallBackListener jniCallBackListener;

static {
    class_init_native();
}

private static native void class_init_native();

private native boolean init_native();

private native void write_native(int type);

private native void writedata_native(int type, byte[] data);

private native void cleanup_native();

public void init(IJniCallBackListener listener) {
    this.jniCallBackListener = listener;
    Log.e(TAG, "init");
    if (!init_native()) {
        try {
            if (jniCallBackListener != null)
                jniCallBackListener.jniInitError();
        } catch (RemoteException e) {
            Log.e(TAG, "init RemoteException", e);
        }
    }
}

public void write(int type) {
    Log.e(TAG, "write type=" + type);
    write_native(type);
}

public void writeData(int type, byte[] data) {
    Log.e(TAG, "write type=" + type + "  data=" + HexUtils.bytesToHexString(data));
    writedata_native(type, data);
}

public void cleanup() {
    Log.e(TAG, "cleanup");
    cleanup_native();
}

@Override
public void receiveData(int type, byte[] data) {
    Log.e(TAG, "receiveData type=" + type + " data=" + HexUtils.bytesToHexString(data));
    if (jniCallBackListener != null) {
        try {
            jniCallBackListener.receiveData(type, data);
        } catch (RemoteException e) {
            Log.e(TAG, "receiveData RemoteException", e);
        }
    }
}
}

frameworks/base/services/core/java/com/android/server/drivecontrol/JniDriveCallBackListener.java

 package com.android.server.drivecontrol;
 
 /**
  * @hide hal层通过该接口返回数据
  */
 public interface JniDriveCallBackListener {
	void receiveData(int type,byte[] data);
 }

frameworks/base/drivecontrol/aidl/com/drivecontrol/IDriveControlService.aidl

/**
 * @hide 提供给frameworks-api调用的接口
 */
interface IDriveControlService {
 void init(IJniCallBackListener listener);
 void write(int type);
 void writeData(int type,inout byte[] data);
 void cleanup();
}

frameworks/base/drivecontrol/aidl/com/drivecontrol/IJniCallBackListener.aidl

 // IJniCallBackListener.aidl
 package com.drivecontrol;
 
 // Declare any non-default types here with import statements
 /**
  * @hide 提供给frameworks-api 回调的接口
  */
 interface IJniCallBackListener {
 void jniInitError();
 void receiveData(int type,inout byte[] data);
 }

然后就是jni 部分

新建cpp文件frameworks/base/services/core/jni/com_android_server_drivecontrol_DriveControlService.cpp

 #define LOG_TAG"DriveControlServiceJni"
 #define LOG_NDEBUG 0
 
 #include "nativehelper/JNIHelp.h"
 #include "jni.h"
 #include "utils/Log.h"
 #include "utils/misc.h"
 #include "android_runtime/AndroidRuntime.h"
 #include "android_runtime/Log.h"
 
 #include 
 #include 
 #include 
 #include 
 #include 
 
 static jobject mCallbacksObj = NULL;
 static jmethodID method_receiveData;
 
 namespace android {
 
 static void android_DriveControlService_class_init_native(JNIEnv* env, jclass clazz)
 {
 ALOGE("android_DriveControlService_class_init_native\n");
 method_receiveData = env->GetMethodID(clazz, "receiveData", "(I[B)V");
 }
 
 static jboolean android_DriveControlService_init(JNIEnv* env, jobject obj)
 {
 ALOGE("android_DriveControlService_init\n");
 // this must be set before calling into the HAL library
 if (!mCallbacksObj)
 mCallbacksObj = env->NewGlobalRef(obj);

 return JNI_FALSE;
 }
 
 static void android_DriveControlService_write(JNIEnv* env, jobject obj, jint type)
 {
 ALOGE("android_DriveControlService_write type=%d\n",type);
 }
 
 
 
 static void android_DriveControlService_writedata(JNIEnv* env, jobject obj, jint type,jbyteArray data)
 {
 ALOGE("android_DriveControlService_writedata=%d \n",type);
 
 }
 
 static void android_DriveControlService_cleanup(JNIEnv* env, jobject obj)
 {
 ALOGE("android_DriveControlService_cleanup\n");

 }
 
 static JNINativeMethod sMethods[] = {
  /* name, signature, funcPtr */
 {"class_init_native", "()V", (void *)android_DriveControlService_class_init_native},
 {"init_native", "()Z", (void*)android_DriveControlService_init},
 {"write_native", "(I)V", (void*)android_DriveControlService_write},
 {"writedata_native", "(I[B)V", (void*)android_DriveControlService_writedata},
 {"cleanup_native", "()V", (void*)android_DriveControlService_cleanup}
 };
 
 int register_android_server_drivecontrol_DriveControlService(JNIEnv* env)
 {
 ALOGE("register_android_server_drivecontrol_DriveControlService\n");
 
 return jniRegisterNativeMethods(
 env,
 "com/android/server/drivecontrol/DriveControlService",
 sMethods,
 NELEM(sMethods));
 }
 
 } /* namespace android */

在service jni onload中增加 新增的service

frameworks/base/services/core/jni/onload.cpp

 int register_android_server_GraphicsStatsService(JNIEnv* env);
 int register_android_hardware_display_DisplayViewport(JNIEnv* env);
 int register_android_server_net_NetworkStatsService(JNIEnv* env);
 + int register_android_server_drivecontrol_DriveControlService(JNIEnv* env);
 #ifdef USE_ARC
 int register_android_server_ArcVideoService();
 #endif
@@ -107,5 +108,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
 #ifdef USE_ARC
 register_android_server_ArcVideoService();
 #endif
 + register_android_server_drivecontrol_DriveControlService(env);
 return JNI_VERSION_1_4;
 }

frameworks/base/services/core/jni/Android.bp

 "com_android_server_VibratorService.cpp",
 "com_android_server_PersistentDataBlockService.cpp",
 "com_android_server_GraphicsStatsService.cpp",
+ "com_android_server_drivecontrol_DriveControlService.cpp",
 "onload.cpp",
 ],

APP-framework

App 要调用frameworks的的代码 需要在frameworks 新增api接口 给 App,系统编译完后拿frameworks-classes.jar给app开发就可以,具体的可以参考
https://blog.csdn.net/yxdspirit/article/details/104503451

frameworks/base/drivecontrol/java/com/drivecontrol/DriveControl.java

 package com.drivecontrol;
 
 import android.os.RemoteException;
 import android.os.ServiceManager;
 
 import com.drivecontrol.IJniCallBackListener;
 
 import android.util.Log;
 
 
 /**
  * @hide 提供给App 调用的api类
  */
 public class DriveControl {

 private IDriveControlService driveControlService = null;//DriveControlService
 private String TAG = DriveControl.class.getSimpleName();
 private JniCallBackListener jniCallBackListener;

 private DriveControl() {

 }

 private volatile static DriveControl instance;

 public static DriveControl getInstance() {
     if (instance == null) {
         synchronized (DriveControl.class) {
             if (instance == null) {
                 instance = new DriveControl();
             }
         }
     }
     return instance;
 }

 public void init(JniCallBackListener listener) {
     this.jniCallBackListener = listener;
     Log.e(TAG, "init");
     driveControlService = IDriveControlService.Stub.asInterface(ServiceManager.getService("drivecontrol"));
     if (driveControlService != null) {
         try {
             driveControlService.init(iJniCallBackListener);
         } catch (RemoteException e) {
             Log.e(TAG, "init RemoteException", e);
         }
     }
 }

 /**
  * @hide
  */
 private IJniCallBackListener iJniCallBackListener = new IJniCallBackListener.Stub() {

     public void jniInitError() {
         if (jniCallBackListener != null)
             jniCallBackListener.jniInitError();
     }

     public void receiveData(int type, byte[] data) {
         if (jniCallBackListener != null)
             jniCallBackListener.receiveData(type, data);
     }
 };


 public void write(int type) {
     if (driveControlService != null) {
         try {
             driveControlService.write(type);
         } catch (RemoteException e) {
             Log.e(TAG, "write RemoteException", e);
         }
     }
 }

 public void write(int type, byte[] data) {
     if (driveControlService != null) {
         try {
             driveControlService.writeData(type, data);
         } catch (RemoteException e) {
             Log.e(TAG, "write RemoteException", e);
         }
     }
 }

 public void cleanup() {
     if (driveControlService != null) {
         try {
             driveControlService.cleanup();
         } catch (RemoteException e) {
             Log.e(TAG, "cleanup RemoteException", e);
         }
     }
 }
 }

frameworks/base/drivecontrol/java/com/drivecontrol/JniCallBackListener.java

 package com.drivecontrol;
 /**
  * @hide
  */
 public interface JniCallBackListener {
 void jniInitError();
 void receiveData(int type, byte[] data);
 }

编译集成

java aidl文件加完后 需要将这些文件在编译framework 的时候加入编译

首先service 需要在开机的时候启动

修改 frameworks/base/services/java/com/android/server/SystemServer.java 在startOtherServices 中添加启动自定义service

 import com.android.server.vr.VrManagerService;
 import com.android.server.webkit.WebViewUpdateService;
 import com.android.server.wm.WindowManagerService;
 + import com.android.server.drivecontrol.DriveControlService;
 
 import dalvik.system.VMRuntime;
 import dalvik.system.PathClassLoader;
@@ -972,7 +973,12 @@ public final class SystemServer {
 }
 traceEnd();
 }
 
+ try {
+      Slog.i(TAG, "addService DriveControlService");
+      ServiceManager.addService("drivecontrol",new DriveControlService());
+ } catch (Throwable e) {
+      reportWtf("starting DriveControlService", e);
+ }
 traceBeginAndSlog("MakeDisplayReady");
 try {
 wm.displayReady();

frameworks新增代码加入编译 frameworks/base/Android.bp

@@ -32,6 +32,7 @@ java_library {
 // From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
 "core/java/**/*.java",
 "graphics/java/**/*.java",
 + "drivecontrol/java/**/*.java",
 "location/java/**/*.java",
 "lowpan/java/**/*.java",
 "media/java/**/*.java",
@@ -405,6 +406,8 @@ java_library {
 "core/java/com/android/internal/widget/IRemoteViewsFactory.aidl",
 "keystore/java/android/security/IKeyChainAliasCallback.aidl",
 "keystore/java/android/security/IKeyChainService.aidl",
 + "drivecontrol/aidl/com/drivecontrol/IJniCallBackListener.aidl",
 + "drivecontrol/aidl/com/drivecontrol/IDriveControlService.aidl",
 "location/java/android/location/IBatchedLocationCallback.aidl",
 "location/java/android/location/ICountryDetector.aidl",
 "location/java/android/location/ICountryListener.aidl",
@@ -621,6 +624,7 @@ java_library {
 // From build/make/core/pathmap.mk FRAMEWORK_BASE_SUBDIRS
 "core/java",
 "graphics/java",
 + "drivecontrol/aidl",
 "location/java",
 "lowpan/java",
 "media/java",

build/make/core/pathmap.mk

 FRAMEWORKS_BASE_SUBDIRS := \
 	$(addsuffix /java, \
 	core \
 	+	drivecontrol \
 	graphics \
 	location \
 	media \

自定义service 名称drivecontrol 增加 device/qcom/sepolicy/private/service_contexts

 drivecontrol   u:object_r:drivecontrol_service:s0

device/qcom/sepolicy/private/service.te

type drivecontrol_service,	app_api_service, system_server_service, service_manager_type;

至此就完了,需要注意的是在frameworks中添加java文件需要在类头添加 @hide 不然编译的时候会要求make update-api

你可能感兴趣的:(framework,android,jni)