本篇是銜接上一篇:通過ConsumerIrService看完整的系統(tǒng)服務(wù)調(diào)用流程(一)。如不關(guān)心應(yīng)用層的調(diào)用流程可繼續(xù)閱讀,不然建議先移步第一篇。
Frameworks層銜接Hal:
接下來我們看下具體定義和具體實(shí)現(xiàn)。
frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
// 定義AIDL接口
interface IConsumerIrService
{
boolean hasIrEmitter();
void transmit(String packageName, int carrierFrequency, in int[] pattern);
int[] getCarrierFrequencies();
}
以及對其進(jìn)行的實(shí)現(xiàn):
frameworks/base/services/core/java/com/android/server/ConsumerIrService.java
// 實(shí)現(xiàn)系統(tǒng)服務(wù)
public class ConsumerIrService extends IConsumerIrService.Stub {
// 系統(tǒng)服務(wù)集成JNI
private static native boolean halOpen();
private static native int halTransmit(int carrierFrequency, int[] pattern);
private static native int[] halGetCarrierFrequencies();
...
ConsumerIrService(Context context) {
...
mHasNativeHal = halOpen(); // this
...
}
@Override
public boolean hasIrEmitter() {
return mHasNativeHal;
}
...
@Override
public void transmit(String packageName, int carrierFrequency, int[] pattern) {
// 這里有權(quán)限的校驗(yàn)
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires TRANSMIT_IR permission");
}
...
synchronized (mHalLock) {
int err = halTransmit(carrierFrequency, pattern); // this
...
}
}
@Override
public int[] getCarrierFrequencies() {
// 這里有權(quán)限的校驗(yàn)
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.TRANSMIT_IR)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires TRANSMIT_IR permission");
}
throwIfNoIrEmitter();
synchronized(mHalLock) {
return halGetCarrierFrequencies(); // this
}
}
}
權(quán)限的添加在frameworks/base/core/res/AndroidManifest.xml中。
<permission android:name="android.permission.TRANSMIT_IR"
android:label="@string/permlab_transmitIr"
android:description="@string/permdesc_transmitIr"
android:protectionLevel="normal" />
如果對JNI了解的,就能看出。這部分具體就是橋接了JNI的方法。在看jni的部分之前,還有重要的注冊部分。
frameworks/base/services/java/com/android/server/SystemServer.java
// 在SystemServer中注冊服務(wù)
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
...
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
...
}
private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
...
if (!isWatch && !tinySystem) {
t.traceBegin("StartConsumerIrService");
consumerIr = new ConsumerIrService(context);
ServiceManager.addService(Context.CONSUMER_IR_SERVICE, consumerIr);
t.traceEnd();
}
...
}
SystemServer.java具體實(shí)現(xiàn)感興趣的可以繼續(xù)去追,其實(shí)也是通過AIDL來代理的。貼出部分路徑供參考。
frameworks/base/core/java/android/os/ServiceManager.java
frameworks/base/core/java/android/os/ServiceManagerNative.java
frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl
JNI橋接部分:
讓我們回來接著看JNI的實(shí)現(xiàn)。
frameworks/base/services/core/jni/com_android_server_ConsumerIrService.cpp
using ::android::hardware::ir::V1_0::IConsumerIr;
using ::android::hardware::ir::V1_0::ConsumerIrFreqRange;
using ::android::hardware::hidl_vec;
namespace android {
static sp<IConsumerIr> mHal;
static jboolean halOpen(JNIEnv* /* env */, jobject /* obj */) {
mHal = IConsumerIr::getService();
return mHal != nullptr;
}
static jint halTransmit(JNIEnv *env, jobject /* obj */, jint carrierFrequency,
...
bool success = mHal->transmit(carrierFrequency, patternVec);
...
}
static jintArray halGetCarrierFrequencies(JNIEnv *env, jobject /* obj */) {
...
mHal->getCarrierFreqs(cb);
...
}
static const JNINativeMethod method_table[] = {
{ "halOpen", "()Z", (void *)halOpen },
{ "halTransmit", "(I[I)I", (void *)halTransmit },
{ "halGetCarrierFrequencies", "()[I", (void *)halGetCarrierFrequencies},
};
int register_android_server_ConsumerIrService(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/android/server/ConsumerIrService",
method_table, NELEM(method_table));
}
};
HIDL部分:
具體的實(shí)現(xiàn)是通過HIDL來代理承接的,原理和AIDL類似。
hardware/interfaces/ir/1.0/IConsumerIr.hal
// 定義HIDL接口
package android.hardware.ir@1.0;
interface IConsumerIr {
transmit(int32_t carrierFreq, vec<int32_t> pattern) generates (bool success);
getCarrierFreqs() generates (bool success, vec<ConsumerIrFreqRange> ranges);
};
我接著看在Hardware層的實(shí)現(xiàn)。
hardware/interfaces/ir/1.0/default/ConsumerIr.h
#include <android/hardware/ir/1.0/IConsumerIr.h>
#include <hardware/consumerir.h>
...
using ::android::hardware::ir::V1_0::ConsumerIrFreqRange;
using ::android::hardware::ir::V1_0::IConsumerIr;
...
struct ConsumerIr : public IConsumerIr {
ConsumerIr(consumerir_device_t *device);
// Methods from ::android::hardware::ir::V1_0::IConsumerIr follow.
Return<bool> transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) override;
Return<void> getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) override;
private:
consumerir_device_t *mDevice;
};
...
hardware/interfaces/ir/1.0/default/ConsumerIr.cpp
#include <hardware/hardware.h>
#include <hardware/consumerir.h>
...
ConsumerIr::ConsumerIr(consumerir_device_t *device) {
mDevice = device;
}
// Methods from ::android::hardware::consumerir::V1_0::IConsumerIr follow.
Return<bool> ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) {
// 調(diào)用設(shè)備驅(qū)動函數(shù)
return mDevice->transmit(mDevice, carrierFreq, pattern.data(), pattern.size()) == 0;
}
Return<void> ConsumerIr::getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) {
int32_t len = mDevice->get_num_carrier_freqs(mDevice); // 調(diào)用設(shè)備驅(qū)動函數(shù)
...
consumerir_freq_range_t *rangeAr = new consumerir_freq_range_t[len];
bool success = (mDevice->get_carrier_freqs(mDevice, len, rangeAr) >= 0);
...
return Void();
}
...
還有基礎(chǔ)關(guān)鍵的地方。
hardware/interfaces/ir/1.0/default/service.cpp
直通模式:
#define LOG_TAG "android.hardware.ir@1.0-service"
#include <android/hardware/ir/1.0/IConsumerIr.h>
#include <hidl/LegacySupport.h>
using android::hardware::ir::V1_0::IConsumerIr;
using android::hardware::defaultPassthroughServiceImplementation;
int main() {
// 核心注冊函數(shù):自動加載HAL實(shí)現(xiàn)庫
return defaultPassthroughServiceImplementation<IConsumerIr>();
}
通過直通模式及“ 服務(wù)與調(diào)用者處于同一進(jìn)程 ” ,還有一種模式是 綁定式服務(wù)運(yùn)行在獨(dú)立進(jìn)程。
綁定模式:舉例
// hardware/interfaces/hello/1.0/default/HelloService.cpp
#include <hidl/HidlTransportSupport.h>
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
int main() {
configureRpcThreadpool(4, true); // 配置Binder線程池
// 創(chuàng)建Binderized服務(wù)
android::sp<IHello> service = new HelloImpl();
service->registerAsService(); // 注冊到hwservicemanager
joinRpcThreadpool(); // 進(jìn)入Binder循環(huán)
return 0;
}
針對這一層還有.rc 和.bp 的配置,感興趣的自己去找源碼看。
驅(qū)動部分:
最后的最后我們簡單看看實(shí)際調(diào)用的驅(qū)動部分,由于不同模組驅(qū)動有所不同這里僅做參考。
hardware/libhardware/include/hardware/consumerir.h
hardware/libhardware/modules/consumerir/consumerir.c
#include <hardware/consumerir.h>
#include <hardware/hardware.h>
...
static int consumerir_open(const hw_module_t* module, const char* name,
hw_device_t** device){
...
dev->transmit = consumerir_transmit; // 指向?qū)嶋H驅(qū)動函數(shù)
dev->get_num_carrier_freqs = consumerir_get_num_carrier_freqs;
dev->get_carrier_freqs = consumerir_get_carrier_freqs; // 指向?qū)嶋H驅(qū)動函數(shù)
...
}
...
// 向系統(tǒng)注冊HAL
static struct hw_module_methods_t consumerir_module_methods = {.open = consumerir_open,};
consumerir_module_t HAL_MODULE_INFO_SYM = {
.common = {
...
.methods = &consumerir_module_methods,
},
};
如果反這來看,其實(shí)就是完整的通過自定義系統(tǒng)服務(wù)來大同應(yīng)用端和硬件設(shè)備端的調(diào)用。
這里特別提醒,為了保證API 的可見性。我們還需要更新current.txt。
frameworks/base/api/current.txt
public final class ConsumerIrManager.CarrierFrequencyRange {
ctor public ConsumerIrManager.CarrierFrequencyRange(int, int);
method public int getMaxFrequency();
method public int getMinFrequency();
}
部分還需要在frameworks/base/core/res/res/values/public.xml中注冊新資源。
在系統(tǒng)源碼中關(guān)于HIDL都會使用vts進(jìn)行HIDL自動化測試。例子在源碼中有很多自行參考。
有部分細(xì)節(jié)沒有照顧到,還望補(bǔ)充和指正,謝謝~