在系统开发中有时候使用系统通道的话,实现不了需要的逻辑,此时需要新增自定义的通道 打通 APP-framework-hal
本实例是基于Android 9.0 源码工程
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);
}
新建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 要调用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