使用Android的HIDL+AIDL方式编写从HAL层到APP层的程序
先实现HIDL,打通从HAL到framework层
可以把自己的HIDL模块建立在hardware/interfaces/、frameworks/hardware/interfaces/、 system/hardware/interfaces/、 system/libhidl/transport/ 或者是vendor/<VENDOR>/proprietary/hardware/interfaces/等目录下。
建立HIDL目录:
$ mkdir -p hardware/interfaces/hidl_test/submodule_1/1.0/
那么这个HIDL的package name 应该是 android.hardware.hidl_test.submodule_1@1.0
建立HIDL方式的核心hal文件:
$ vi hardware/interfaces/hidl_test/submodule_1/1.0/IHidlTest.hal
package android.hardware.hidl_test.submodule_1@1.0;
interface IHidlTest {
justTest(string name) generates (string result, EnumHidlTest value);
justTest1(EnumHidlTest name);
};
$ vi hardware/interfaces/hidl_test/submodule_1/1.0/types.hal
package android.hardware.hidl_test.submodule_1@1.0;
@export(name=”EnumHidlTest”, value_prefix=””)
enum EnumHidlTest : uint8_t {
V_TEST1 = 0,
V_TEST2 = 1,
};
利用hidl-gen工具生成Android.bp、源代码等文件:
先编译一次全部的源码,然后hidl-gen就可以用了(生成在 out/host/linux-x86/bin/hidl-gen):
$ source build/envsetup.sh
$ lunch full_ac8257_demo-userdebug
$ hidl-gen -h
生成顶级目录下的Android.bp:
$ hardware/interfaces/update-makefiles.sh
其实调用的就是hidl-gen这个命令来执行的(-Landroidbp表示Generates Soong bp files for -Lc++-headers, -Lc++-sources, -Ljava, -Ljava-constants, and -Lc++-adapter) :
$ hidl-gen -O “” -Landroidbp -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.hidl_test.submodule_1@1.0;
查看下(因为上面hal里面有@export修饰符,所以这里gen_java_constants为true):
$ cat hardware/interfaces/hidl_test/submodule_1/1.0/Android.bp
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: “android.hardware.hidl_test.submodule_1@1.0”,
root: “android.hardware”,
vndk: {
enabled: true,
},
srcs: [
“types.hal”,
“IHidlTest.hal”,
],
interfaces: [
“android.hidl.base@1.0”,
],
types: [
“EnumHidlTest”,
],
gen_java: true,
gen_java_constants: true,
}
在default子目录生成C++实现文件:
$ hidl-gen -O “” -Lc++-impl -o $ANDROID_BUILD_TOP/hardware/interfaces/hidl_test/submodule_1/1.0/default/ -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.hidl_test.submodule_1@1.0;
在default子目录生成Android.bp文件,以便后面对impl源文件编译:
$ hidl-gen -O “” -Landroidbp-impl -o $ANDROID_BUILD_TOP/hardware/interfaces/hidl_test/submodule_1/1.0/default/ -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.hidl_test.submodule_1@1.0;
$ ll hardware/interfaces/hidl_test/submodule_1/1.0/default/
-rw-r–r– 1 shuzhiang development 993 3月 25 10:35 Android.bp
-rw-r–r– 1 shuzhiang development 826 3月 25 10:34 HidlTest.cpp
-rw-r–r– 1 shuzhiang development 1376 3月 25 10:34 HidlTest.h
添加接口哈希值到current.txt:
$ hidl-gen -L hash -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport android.hardware.hidl_test.submodule_1@1.0::types
4b8c76bc9f7dbe48c357ad5b838dbf497bd0af9c3c0ee5a557b947794abe1cd7 android.hardware.hidl_test.submodule_1@1.0::types
把上面的输出结果添加到current.txt,加到最后即可:
$ vi hardware/interfaces/current.txt
…
4b8c76bc9f7dbe48c357ad5b838dbf497bd0af9c3c0ee5a557b947794abe1cd7 android.hardware.hidl_test.submodule_1@1.0::types
然后可以修改HidlTest.cpp来实现接口的函数:
切记:如果hal文件变更了,重新生成该代码时,会被覆盖掉,所以每次hal变更前把default目录mv一下,换个名字,等生成完了,再把老的代码手工移到新生成的文件里面。
$ vi hardware/interfaces/hidl_test/submodule_1/1.0/default/HidlTest.cpp
#define LOG_TAG “HidlTestImpl”
#include <log/log.h>
#include “HidlTest.h”
namespace android {
namespace hardware {
namespace hidl_test {
namespace submodule_1 {
namespace V1_0 {
namespace implementation {
// Methods from ::android::hardware::hidl_test::submodule_1::V1_0::IHidlTest follow.
Return<void> HidlTest::justTest(const hidl_string& name, justTest_cb _hidl_cb) {
// TODO implement
ALOGD(“justTest, name = %s”, name.c_str());
_hidl_cb(name, EnumHidlTest::V_TEST2);
ALOGD(“justTest end.”);
return Void();
}
Return<void> HidlTest::justTest1(::android::hardware::hidl_test::submodule_1::V1_0::EnumHidlTest name) {
// TODO implement
ALOGD(“justTest1, name = %hhu”, name);
return Void();
}
要把它当成service来启动,则还少一个main函数来加载,所以增加一个service.cpp:
$ vi hardware/interfaces/hidl_test/submodule_1/1.0/default/service.cpp
#define LOG_TAG “android.hardware.hidl_test.submodule_1@1.0-service”
#include <android/hardware/hidl_test/submodule_1/1.0/IHidlTest.h>
#include <hidl/LegacySupport.h>
#include “HidlTest.h”
// Generated HIDL files
using android::hardware::hidl_test::submodule_1::V1_0::IHidlTest;
using android::hardware::hidl_test::submodule_1::V1_0::implementation::HidlTest;
using android::hardware::defaultPassthroughServiceImplementation;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
int main() {
#if 0
return defaultPassthroughServiceImplementation<IHidlTest>();
#else
sp<IHidlTest> service = new HidlTest();
configureRpcThreadpool(1, true /*callerWillJoin*/);
if(android::OK != service->registerAsService())
return 1;
joinRpcThreadpool();
#endif
}
既然是service,可以增加一个rc文件来启动它(注意和Android.bp里面的对应):
$ vi hardware/interfaces/hidl_test/submodule_1/1.0/default/android.hardware.hidl_test.submodule_1@1.0-service.rc
service hidltest /vendor/bin/hw/android.hardware.hidl_test.submodule_1@1.0-service
class hal
user system
group system
修改default下的Android.bp文件(添加service.cpp并生成可执行文件),在最前面增加整个cc_binary部分:
$ cat hardware/interfaces/hidl_test/submodule_1/1.0/default/Android.bp
cc_binary {
name: “android.hardware.hidl_test.submodule_1@1.0-service“,
defaults: [“hidl_defaults”],
relative_install_path: “hw”,
vendor: true,
init_rc: [“android.hardware.hidl_test.submodule_1@1.0-service.rc“],
srcs: [
“HidlTest.cpp”,
“service.cpp”
],
shared_libs: [
“liblog”,
“libhidlbase”,
“libhidltransport”,
“libutils”,
“libhardware”,
“android.hardware.hidl_test.submodule_1@1.0”,
],
}
记得把liblog也要加入到cc_library_shared这个模块的shared_libs部分。
插入设备的manifest.xml(autochips/ac8257_demo整个部分要根据自己实际使用的设备来定):
加到尾部</manifest>之前即可:
$ vi device/autochips/ac8257_demo/manifest.xml
<hal format=”hidl”>
<name>android.hardware.hidl_test.submodule_1</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>IHidlTest</name>
<instance>default</instance>
</interface>
</hal>
加入到device.mk,以便启动service:
加到尾部即可:
$ vi device/autochips/ac8257_demo/device.mk
…
PRODUCT_PACKAGES += android.hardware.hidl_test.submodule_1@1.0-service
修改VNDK相关部分:
在current.txt里按字母顺序添加,否则编译不过:
$ vi build/make/target/product/vndk/current.txt
VNDK-core: android.hardware.hidl_test.submodule_1@1.0.so
在28.txt里按字母顺序添加,否则编译不过:
$ vi build/make/target/product/vndk/28.txt
VNDK-core: android.hardware.hidl_test.submodule_1@1.0.so
修改SELINUX相关,以便service能在 rc里面启动:
尾部添加:
$ vi system/sepolicy/vendor/file_contexts
/(vendor|system/vendor)/bin/hw/android\.hardware\.hidl_test\.submodule_1@1\.0-service u:object_r:hal_test_default_exec:s0
新建文件:
$ vi system/sepolicy/vendor/hal_test_default.te
type hal_test_default, domain;
hal_server_domain(hal_test_default, hal_test)
type hal_test_default_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(hal_test_default)
相应位置添加:
$ vi system/sepolicy/public/attributes
hal_attribute(test);
尾部添加:
$ vi system/sepolicy/public/hwservice
type hal_test_hwservice, hwservice_manager_type;
新建文件:
$ vi system/sepolicy/public/hal_test.te
# HwBinder IPC from client to server, and callbacks
binder_call(hal_test_client, hal_test_server)
binder_call(hal_test_server, hal_test_client)
add_hwservice(hal_test_server, hal_test_hwservice)
allow hal_test_client hal_test_hwservice:hwservice_manager find;
和api目录同步:
$ cp system/sepolicy/public/attributes system/sepolicy/prebuilts/api/28.0/public/
$ cp system/sepolicy/public/hwservice.te system/sepolicy/prebuilts/api/28.0/public/
$ cp system/sepolicy/public/hal_test.te system/sepolicy/prebuilts/api/28.0/public/
最前面加一行:
$ vi system/sepolicy/private/hwservice_contexts
android.hardware.hidl_test.submodule_1::IHidlTest u:object_r:hal_test_hwservice:s0
在new_objects里面加入:
$ vi system/sepolicy/private/compat/26.0/26.0.ignore.cil
hal_test_hwservice
$ vi system/sepolicy/private/compat/27.0/27.0.ignore.cil
hal_test_hwservice
和api目录同步:
$ cp system/sepolicy/private/compat/27.0/27.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/27.0/
$ cp system/sepolicy/private/compat/26.0/26.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/26.0/
$ cp system/sepolicy/private/hwservice_contexts system/sepolicy/prebuilts/api/28.0/private/
编译:
编译中间接口:
$ cd hardware/interfaces/hidl_test/submodule_1/1.0/
$ mm showcommands
生成的中间结果:
$ ll out/soong/.intermediates/hardware/interfaces/hidl_test/submodule_1/1.0/
total 56
drwxr-xr-x 14 shuzhiang development 4096 3月 25 10:29 ./
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:16 ../
drwxr-xr-x 10 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0/
drwxr-xr-x 4 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter_genc++/
drwxr-xr-x 10 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter-helper/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter-helper_genc++/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1@1.0-adapter-helper_genc++_headers/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:16 android.hardware.hidl_test.submodule_1@1.0_genc++/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:16 android.hardware.hidl_test.submodule_1@1.0_genc++_headers/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java-constants/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java-constants_gen_java/
drwxr-xr-x 3 shuzhiang development 4096 3月 25 10:29 android.hardware.hidl_test.submodule_1-V1.0-java_gen_java/
这个接口文件做客户端时会用到:
out/soong/.intermediates/hardware/interfaces/hidl_test/submodule_1/1.0/android.hardware.hidl_test.submodule_1-V1.0-java_gen_java/gen/android/hardware/hidl_test/submodule_1/V1_0/IHidlTest.java
编译出最终的库和service:
$ cd hardware/interfaces/hidl_test/submodule_1/1.0/default
$ mm showcommands
输出位置:
$ ll out/target/product/ac8257_demo/vendor/lib/hw/android.hardware.hidl_test.submodule_1@1.0-impl.so
$ ll out/target/product/ac8257_demo/vendor/bin/hw/android.hardware.hidl_test.submodule_1@1.0-service
$ ll out/target/product/ac8257_demo/system/etc/init/android.hardware.hidl_test.submodule_1@1.0-service.rc
因为修改了很多selinux相关的东西,最终需要整个android全部重新编译一次。
$ nohup ./allmake.sh -i &
$ tail -f nohup.out
重新烧录后,就可以看到service起来了:
<SHELL># ps -Afl | grep hidl_test
system 379 1 0 23:59:04 ? 00:00:00 android.hardware.hidl_test.submodule_1@1.0-service
用AIDL来实现framework层到APP层
实现framework层的system service接口:
$ mkdir -p frameworks/base/core/java/android/os/hidltest
$ vi frameworks/base/core/java/android/os/hidltest/IHidlTestService.aidl
// IHidlTestService.aidl
package android.os.hidltest;
// Declare any non-default types here with import statements
interface IHidlTestService {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void justTest1(int enumValue);
void justTest(String str);
}
从app getService后,调用的是该类下的函数:
$ vi frameworks/base/core/java/android/os/hidltest/HidlTestManager.java
package android.os.hidltest;
/**
* android.os.hidltest.HidlTestManager;
*
* @author
* @date
*/
import android.os.RemoteException;
import android.util.Log;
public class HidlTestManager {
private IHidlTestService mService;
public static final String TAG = “HidlTestManager”;
public HidlTestManager(IHidlTestService server) {
Log.d(TAG, “HidlTestManager”);
mService = server;
}
public void justTest1(int enumValue){
Log.d(TAG, “justTest1: enumValue: “+enumValue);
try {
if (mService != null) {
mService.justTest1(enumValue);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
public void justTest(String str){
Log.d(TAG, “justTest: str: “+str);
try {
if (mService != null) {
mService.justTest(str);
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
添加到系统中:
$ vi frameworks/base/Android.bp
在
java_library {
name: “framework”,
srcs: [
下面增加:
“core/java/android/os/hidltest/IHidlTestService.aidl”,
$ vi frameworks/base/services/core/Android.bp
在
static_libs: [
里面定义:
“android.hardware.hidl_test.submodule_1-V1.0-java”,
定义stub类,供上面HidlTestManager.java调用,然后在这个stub里面调用底层HIDL定义的接口:
$ mkdir -p frameworks/base/services/core/java/com/android/server/hidltest
$ vi frameworks/base/services/core/java/com/android/server/hidltest/HidlTestService.java
package com.android.server.hidltest;
import android.hardware.hidl_test.submodule_1.V1_0.IHidlTest;
import android.os.RemoteException;
import android.util.Log;
import android.os.hidltest.IHidlTestService;
import java.util.ArrayList;
/**
* com.android.server.hidltest.HidlTestService
*
* @author
* @date
*/
public class HidlTestService extends IHidlTestService.Stub {
private String TAG = “HidlTestService”;
private IHidlTest halService ;
public HidlTestService(){
try {
halService = IHidlTest.getService();//get service
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void justTest1(int enumValue){
Log.d(TAG, “justTest1: enumValue: “+enumValue);
try{
halService.justTest1((byte)enumValue);
} catch (RemoteException e) {
e.printStackTrace();
}
}
//justTestCallback: produce by HIDL interface, refer to “out/soong/.intermediates/hardware/interfaces/hidl_test/submodule_1/1.0/android.hardware.hidl_test.submodule_1-V1.0-java_gen_java/gen/android/hardware/hidl_test/submodule_1/V1_0/IHidlTest.java”
public void justTest(String str){
Log.d(TAG, “justTest: str: “+str);
android.os.HwParcel _hidl_reply = new android.os.HwParcel();
IHidlTest.justTestCallback aaa = new IHidlTest.justTestCallback() {
@Override
public void onValues(String result, byte value) {
_hidl_reply.writeStatus(android.os.HwParcel.STATUS_SUCCESS);
_hidl_reply.writeString(result);
_hidl_reply.writeInt8(value);
_hidl_reply.send();
}
};
try{
halService.justTest(str, aaa);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
$ vi frameworks/base/core/java/android/content/Context.java
在
@StringDef(suffix = { “_SERVICE” }, value = {
里面增加:
HIDLTEST_SERVICE,
然后在下面其他SERVICE定义位置平行添加一个成员变量:
/**
* {@link android.os.hidltest.HidlTestManager} for receiving intents at a
* time of your choosing.
*
* @see #getSystemService
* @see android.os.hidltest.HidlTestManager
*/
public static final String HIDLTEST_SERVICE = “hidltest”;
$ vi frameworks/base/core/java/android/app/SystemServiceRegistry.java
在import部分增加:
import android.os.hidltest.HidlTestManager;
import android.os.hidltest.IHidlTestService;
在SystemServiceRegistry类的static { 下面添加:
registerService(Context.HIDLTEST_SERVICE, HidlTestManager.class,
new CachedServiceFetcher<HidlTestManager>() {
@Override
public HidlTestManager createService(ContextImpl ctx) {
IBinder iBinder = ServiceManager.getService(Context.HIDLTEST_SERVICE);
if (iBinder == null) {
return null;
}
IHidlTestService service = IHidlTestService.Stub.asInterface(iBinder);
return new HidlTestManager(service);
}});
$ vi frameworks/base/services/java/com/android/server/SystemServer.java
在import部分增加:
import com.android.server.hidltest.HidlTestService;
在startOtherServices函数体的}, SECONDARY_ZYGOTE_PRELOAD); 后面增加:
try {
Slog.i(TAG, “hidltest Service”);
ServiceManager.addService(Context.HIDLTEST_SERVICE, new HidlTestService());
} catch (Throwable e) {
reportWtf(“starting HidlTestService”, e);
}
添加selinux的策略:
$ vi system/sepolicy/public/service.te
尾部添加(hidltest_service这个类型给后面private里面用):
type hidltest_service, system_api_service, system_server_service, service_manager_type;
和api目录同步:
$ cp system/sepolicy/public/service.te system/sepolicy/prebuilts/api/28.0/public/
$ vi system/sepolicy/private/service_contexts
顶部添加(hidltest这个要和frameworks/base/core/java/android/content/Context.java里面HIDLTEST_SERVICE = “hidltest”;的hidltest一致):
hidltest u:object_r:hidltest_service:s0
$ vi system/sepolicy/private/system_server.te
在hal_client_domain部分添加(hal_test为之前定义过的hal_test.te):
hal_client_domain(system_server, hal_test)
$ vi system/sepolicy/private/compat/26.0/26.0.ignore.cil
在(typeattributeset new_objects里面添加:
hidltest_service
$ vi system/sepolicy/private/compat/27.0/27.0.ignore.cil
在(typeattributeset new_objects里面添加:
hidltest_service
和api目录同步:
$ cp system/sepolicy/private/service_contexts system/sepolicy/prebuilts/api/28.0/private/
$ cp system/sepolicy/private/system_server.te system/sepolicy/prebuilts/api/28.0/private/
$ cp system/sepolicy/private/compat/26.0/26.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/26.0/
$ cp system/sepolicy/private/compat/27.0/27.0.ignore.cil system/sepolicy/prebuilts/api/28.0/private/compat/27.0/
重新生成image,并且生成sdk(新的sdk要能再板上用,需要重新烧录新编译的image):
必须做,否则报api没更新的错:
$ source build/envsetup.sh
$ lunch full_ac8257_demo-userdebug
$ make update-api
重新登录编译系统:
$ nohup ./allmake.sh -i &
重新生成sdk库:
$ ./allmake.sh sdklibs
生成位置: ac8257-androidP/sdklibs/
然后可以建立新的android studio 3.5的app
把生成的framework_classes.jar 放到 app/libs目录下。
然后源文件中可以导入以下类文件了:
android.os.hidltest.HildTestManager
然后需要优先使用framework_classes.jar里面的类,而不是android studio默认的sdk类,在app目录下面的build.gradle尾部增加(实际就是把app.iml文件的<orderEntry type=”jdk” jdkName=”Android API 29 Platform” jdkType=”Android SDK”/>这一行挪到其尾部):
preBuild {
doLast {
def imlFile = file(project.name + “.iml”)
println ‘Change ‘ + project.name + ‘.iml order’
try {
def parsedXml = (new XmlParser()).parse(imlFile)
def jdkNode = parsedXml.component[1].orderEntry.find { it.’@type’ == ‘jdk’ }
parsedXml.component[1].remove(jdkNode)
def sdkString = “Android API ” + android.compileSdkVersion.substring(“android-“.length()) + ” Platform”
new Node(parsedXml.component[1], ‘orderEntry’, [‘type’: ‘jdk’, ‘jdkName’: sdkString, ‘jdkType’: ‘Android SDK’])
groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (FileNotFoundException e) {
}
}
}
修改最外层的build.gradle:
在allprojects里面增加:
// 添加下面代码,加入编译参数,只编译,不打包
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << ‘-Xbootclasspath/p:app/libs/framework_classes.jar’
}
}
修改app目录下的build.gradle:
在dependencies部分修改:
//implementation fileTree(dir: ‘libs’, include: [‘*.jar’])
compileOnly files(‘libs/framework_classes.jar’) //只编译,不打包
修改MainActivity.java的代码:
public class MainActivity extends AppCompatActivity {
HidlTestManager mTestManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTestManager = (HidlTestManager)getSystemService(Context.HIDLTEST_SERVICE);
mTestManager.justTest1(1);
mTestManager.justTest(“name=APP:HIDL_client_test”);
}
}
运行起来的输出(justTest函数调用到hardware层的service时会导致问题,后续需要调试修改,所以尽量少使用generates多个返回值的HIDL):
2020-03-26 13:16:09.528 24582-24582/com.maxshu.hidl_client_test D/HidlTestManager: HidlTestManager
2020-03-26 13:16:09.528 24582-24582/com.maxshu.hidl_client_test D/HidlTestManager: justTest1: enumValue: 1
2020-03-26 13:16:09.528 15035-15035/com.maxshu.hidl_client_test D/HidlTestManager: HidlTestManager
2020-03-26 13:16:09.528 15035-15035/com.maxshu.hidl_client_test D/HidlTestManager: justTest: str: name=APP:HIDL_client_test
#include
您好,这个IHidlTest.h如何获取,是可以直接引用吗,小白一枚。
#include ,
您好,小白一枚,
这个IHidlTest.h文件怎么生成的,还是可以直接include进来
就是由hidl-gen命令生成的
首先谢谢您的分享,然后我还想问一下,就关于添加HIDL时需要修改的那么多关于安全的文件,您是怎么知道的?或者说您有没有推荐学习的路线或者方法或者工具?谢谢您
关于android对于文件访问的安全控制,主要还是基于selinux来的,的确比较繁琐,一开始可以不加这些安全相关的文件修改,然后运行的时候可以从log里面看出需要哪些权限,再一个一个去添加。
拜读大全后感觉受益匪浅,在实际操作中,创建APP可以导入android.os.hidltest.HidlTestManager,但是Android Studio编译报错:
错误: 找不到符号
mTestManager = getSystemService(Context.HIDLTEST_SERVICE);
^
符号: 变量 HIDLTEST_SERVICE
位置: 类 Context
请教一下,这个怎么回事?
谢谢!
这个是因为你没有在framework里面(frameworks/base/core/java/android/content/Context.java)增加这个定义吧。