本文是接續上文,針對于HAL層的接口封裝Framework層的接口
HAL層框架搭建:https://blog.csdn.net/m0_50408097/article/details/151148637?spm=1001.2014.3001.5502
在 Android 系統架構中,Framework 層(框架層) 位于 HAL 層(硬件抽象層)之上,是連接底層硬件能力與上層應用的核心中間層。它基于 HAL 層提供的硬件抽象接口,封裝出更易用、更貼近應用開發的標準化服務和 API,供應用層調用。Framework框架搭建
Step1. 創建framework service(用于與hal層通信)
1.1?? ?定義aidl接口(用于與manager進程間通信)
路徑:/frameworks/base/core/java/android/app/ITestService.aidl
package android.app;/** {@hide} */
interface ITestService {int additionTest(int a, int b);
}
注意:這里的接口要與.hal中定義的接口相同(函數名、返回值類型、參數類型和數量)
1.2?? ?實現service
路徑:/frameworks/base/services/core/java/com/android/server/TestService.java
package com.android.server;import android.app.ITestService;
import android.content.Context;public class TestService extends ITestService.Stub {private static final String TAG = " TestService ";private Context mContext;public TestService(Context context) {android.util.Log.d(TAG,"Start TestService...");mContext = context;}@Overridepublic int additionTest(int a, int b) {android.util.Log.d(TAG,"yuan TestService additionTest()...");return additionTest_native(a, b);}private static native int additionTest_native(int a, int b);}
1.3?? ?在Context.java中定義新規的service
路徑:/frameworks/base/core/java/android/content/Context.java
public static final String TEST_SERVICE = "test";
1.4?? ?注冊 Service 到 SystemServer
路徑:frameworks/base/services/java/com/android/server/SystemServer.java#startOtherServices()
TestService testService = null;traceBeginAndSlog("yuan StartTestService");
try {testService = new TestService(context);ServiceManager.addService(Context.TEST_SERVICE, testService);
} catch (Throwable e) {reportWtf("starting TestService", e);
}
traceEnd();
Step2. 創建JNI橋接代碼(連接framework service和hal)
具體的JNI框架搭建可以參考:https://blog.csdn.net/m0_50408097/article/details/151115313?spm=1001.2014.3001.5506
2.1 定義jni文件
路徑:frameworks/base/services/core/jni/com_android_server_Test.cpp
#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include <binder/IServiceManager.h>
#include <vendor/xxx/hardware/test/1.0/ITest.h>
#include <log/log.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/Log.h>using android::hardware::Return;
using android::hardware::Void;
using android::sp;
using vendor::xxx::hardware::test::V1_0::ITest;namespace android {sp<ITest> rw_device;
std::string asyncResult;void serialNoCallback(const ::android::hardware::hidl_string& serialNo) {asyncResult = serialNo.c_str();
}static jint additionTest_native(JNIEnv *env, jobject /* thiz */, jint a, jint b) {ALOGI("additionTest_native.....");sp<IServiceManager> sm = defaultServiceManager();if (sm == nullptr) {ALOGE("failed to get ServiceManager");return -1;}rw_device = ITest::getService();if (rw_device == nullptr) {ALOGE("failed to get ITest service");return -1;}return rw_device->additionTest(a, b);
}static const JNINativeMethod method_table[] = {{ "additionTest_native", "(II)I", (void *)additionTest_native },
};int register_android_server_TestService(JNIEnv* env) {return jniRegisterNativeMethods(env, "com/android/server/TestService",method_table, NELEM(method_table));
}}; // namespace android
在additionTest_native()函數中直接調用HAL層的函數additionTest()
2.2 在 Android.bp 中添加編譯依賴
① 新增JNI文件
路徑:frameworks/base/services/core/jni/Android.bp#cc_library_static
"com_android_server_Test.cpp",
② 添加HAL依賴
路徑:frameworks/base/services/core/jni/Android.bp# cc_defaults
"vendor.xxx.hardware.test@1.0",
2.3 注冊 JNI 到 Android Runtime
① 聲明一個 JNI 注冊函數,用于將 TestService 的 Native 方法(C++ 實現)綁定到 Java 層
路徑:frameworks/base/services/core/jni/onload.cpp
int register_android_server_TestService(JNIEnv* env);
② 在 JNI_OnLoad 函數中調用注冊方法,完成 TestService 的 JNI 方法綁定
register_android_server_TestService(env);
Step3. 創建framework manager(給app提供API)
3.1 定義manager類
路徑:frameworks/base/core/java/android/os/TestManager.java
package android.os;import android.annotation.SuppressLint;
import android.annotation.SystemService;
import android.app.ITestService;
import android.content.Context;
import android.util.Log;@SystemService(Context.TEST_SERVICE)
public class TestManager {private ITestService mService;private Context mContext;private static final String TAG = " TestManager ";private static final boolean Debug = true;/** @hide */public TestManager(Context context, ITestService service){mContext = context;mService = service;}@SuppressLint({"MissingNullability", "StartWithLower"})public int additionTest(int a, int b){Log.d(TAG, "yuan additionTest");try {return mService.additionTest(a, b);} catch (RemoteException e) {if (Debug) Log.e(TAG, e.getMessage());}return 0;}
}
在additionTest()方法中調用 mService.additionTest() 會通過 Binder IPC 將請求發送到系統服務端
3.2 注冊 Manager 到 SystemServiceRegistry
路徑:frameworks/base/core/java/android/app/SystemServiceRegistry.java
registerService(Context.TEST_SERVICE, TestManager.class,new CachedServiceFetcher<TestManager>() {@Overridepublic TestManager createService(ContextImpl ctx)throws ServiceNotFoundException {IBinder b = ServiceManager.getServiceOrThrow(Context.TEST_SERVICE);return new TestManager(ctx.getOuterContext(),ITestService.Stub.asInterface(b));}});
Step4. 配置 SELinux 策略
4.1 允許 system_server 注冊服務
路徑:/system/sepolicy/private/system_server.te
#test service
allow system_server test_service:service_manager add;
4.2 允許普通應用查找服務
路徑:/system/sepolicy/private/untrusted_app_all.te
allow untrusted_app_all test_service:service_manager find;
4.3 定義新的服務類型
路徑:/system/sepolicy/public/service.te
type test_service, system_api_service, system_server_service, service_manager_type;
注意:以下te文件都需要添加4.1-4.3
/system/sepolicy/prebuilts/api/下所有的system_server.te && untrusted_app_all.te && service.te
/system/sepolicy/private/system_server.te
/system/sepolicy/private/untrusted_app_all.te
/system/sepolicy/public/service.te
4.4 允許 system_server 訪問 HAL
路徑:/device/xxx/xxx/sepolicy/non_plat/hal_test.te
allow system_app hal_test_hwservice:hwservice_manager { find };
4.5 允許 system_server 查找 hal_test_hwservice
路徑:/device/xxx/xxx/sepolicy/non_plat/system_sever.te
allow system_server hal_test_hwservice:hwservice_manager find;
Step5. 更新framework 的公開 API 定義文件
用source和lunch加載一下環境變量
make update-api
執行后,自動更新current.txt
可以在frameworks/base庫下,用git diff查看一下
?