HIDL helloWorld
hidl目录文件总结
ac8257/hardware/interfaces/naruto/1.0
└── 1.0
├── Android.bp
├── default
│ ├── Android.bp
│ ├── [email protected]
│ ├── Naruto.cpp
│ ├── Naruto.h
│ └── service.cpp
└── INaruto.hal
ac8257/hardware/interfaces/update-makefiles.sh
build/make/target/product/vndk
├── 28.txt
├── Android.mk
├── current.txt
ac8257/device/autochips/ac8257_demo/manifest.xml
ac8257/device/autochips/ac8257/devices.mk
ac8257/device/autochips/sepolicy/bsp/non_plat
├─── hwservice_contexts
├─── hwservice.te
├─── file_contexts
├─── hal_naruto.te
├─── hwservicemanager.te
├─── system_app.te
├─── platform_app.te
├─── system_server.te
└─── autolog.te
ac8257/device/autochips/ac8257$
├─── device.mk
--client端
frameworks/base/core/java/android/os
├── INarutoEventListener.aidl
├── INarutoService.aidl
├── NarutoEventListener.java
├── NarutoListenerEvent.aidl
├── NarutoListenerEvent.java
└── NarutoManager.java
frameworks/base/Android.bp
frameworks/base/services/core/Android.bp
frameworks/base/services/core/java/com/android/server/naruto
└── NarutoService.java
frameworks/base/ore/java/android/content/Context.java
/frameworks/base/core/java/android/app/SystemServiceRegistry.java
frameworks/base/services/java/com/android/server/SystemServer.java
--给client端添加系统selinux策略
system/sepolicy/public/attributes
system/sepolicy/prebuilts/api/28.0/public/attributes
system/sepolicy/public/service.te
system/sepolicy/prebuilts/api/28.0/public/service.te
system/sepolicy/private/service_context
system/sepolicy/prebuilts/api/28.0/private/service_context
system/sepolicy/prebuilts/api/28.0/private/system_server.te
system/sepolicy/private/system_server.te
systemsepolicy/private/compat/26.0/26.0.ignore.cil
systemsepolicy/prebuilts/api/28.0/private/compat/26.0/26.0.ignore.cil
systemsepolicy/private/compat/27.0/27.0.ignore.cil
systemsepolicy/prebuilts/api/28.0/private/compat/27.0/27.0.ignore.cil
HIDL
#以下所有的naruto全部修改为naruto
#创建目录
mkdir -p hardware/interfaces/naruto/1.0/default
#接着创建接口描述文件INaruto.hal,放在刚才创建的目录中
//INaruto.hal
package android.hardware.naruto@1.0;
interface INaruto{
helloWorld(string name) generates (string result);
};
#执行以下命令
[email protected]
LOC=hardware/interfaces/naruto/1.0/default/
make hidl-gen -j64
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
#然后使用脚本来更新Makefile,自动生成Android,mk, Android.bp
# ./hardware/interfaces/update-makefiles.sh
#添加两个空文件
touch hardware/interfaces/naruto/1.0/default/[email protected]
touch hardware/interfaces/naruto/1.0/default/service.cpp
添加启动service
#hardware/interfaces/naruto/1.0/default/[email protected]
service naruto_hal_service /vendor/bin/hw/[email protected]
class hal
user system
group system
// hardware/interfaces/naruto/1.0/default/service.cpp
//last
#include <android/hardware/naruto/1.0/INaruto.h>
#include <hidl/LegacySupport.h>
#include <android-base/logging.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/LegacySupport.h>
#include "Naruto.h"
using android::hardware::naruto::V1_0::INaruto;
using android::hardware::defaultPassthroughServiceImplementation;
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
using android::hardware::naruto::V1_0::implementation::Naruto;
int main() {
//INaruto service;
android::sp<INaruto> service = new Naruto();
configureRpcThreadpool(1, true);
if(android::OK != service->registerAsService())
{
ALOGI("Naturo registerAsService failure!");
return 1;
}
joinRpcThreadpool();
}
#修改hardware/interfaces/naruto/1.0/default/Android.bp
#Android.bp
cc_binary {
name: "[email protected]",
defaults: ["hidl_defaults"],
relative_install_path: "hw",
vendor: true,
init_rc: ["[email protected]"],
srcs: [
"Naruto.cpp",
"service.cpp"
],
shared_libs: [
"liblog",
"libhidlbase",
"libhidltransport",
"libutils",
"libhardware",
"[email protected]",
],
}
其中 [email protected] 文件会被安装到 /vendor/etc/init/ 目录。
系统启动时会自动加载这个目录下的所有 rc 文件。
#修改完更新一下
./hardware/interfaces/update-makefiles.sh
#修改Test.h和Test.cpp
//hardware/interfaces/naruto/1.0/default/Naruto.h
# ifndef ANDROID_HARDWARE_NARUTO_V1_0_NARUTO_H
# define ANDROID_HARDWARE_NARUTO_V1_0_NARUTO_H
# include <android/hardware/naruto/1.0/INaruto.h>
# include <hidl/MQDescriptor.h>
# include <hidl/Status.h>
namespace android {
namespace hardware {
namespace naruto{
namespace V1_0 {
namespace implementation {
using ::android::hardware::hidl_array;
using ::android::hardware::hidl_memory;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::sp;
struct Naruto: public INaruto{
// Methods from INaruto follow.
Return<void> helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) override;
// Methods from ::android::hidl::base::V1_0::IBase follow.
};
// FIXME: most likely delete, this is only for passthrough implementations
// extern "C" INaruto* HIDL_FETCH_INaruto(const char* name);
} // namespace implementation
} // namespace V1_0
} // namespace naruto
} // namespace hardware
} // namespace android
# endif // ANDROID_HARDWARE_NARUTO_V1_0_NARUTO_H
//hardware/interfaces/naruto/1.0/default/Naruto.cpp
#include "Naruto.h"
#include <stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <pthread.h>
#include <log/log.h>
#include <error.h>
#include <utils/Mutex.h>
#include <utils/Thread.h>
#include <cutils/properties.h>
#define MY_MISCDEV "/dev/my_miscdev"
namespace android {
namespace hardware {
namespace naruto {
namespace V1_0 {
namespace implementation {
Return<void> Naruto::helloWorld(const hidl_string& name, helloWorld_cb _hidl_cb) {
int fd = ::open(MY_MISCDEV, O_WRONLY);
if (fd <= 0){
ALOGE("@@Open %s fail. %s", MY_MISCDEV, strerror(errno));
}
ALOGE("@@open %s successful.", MY_MISCDEV);
char setLedOff[5] = "0 1";
char setLedOn[5] = "1 1";
int ret = -1;
int res = ::strcmp(name.c_str(),"ON");
if (res == 0){
ret = write(fd, setLedOn , sizeof(setLedOn));
}
else {
ret = write(fd, setLedOff, sizeof(setLedOff));
}
if(ret <0){
ALOGE("@@Write error at ret :%d, %s.",ret, MY_MISCDEV);
}
::close(fd);
ALOGE("@@File close ret :%d %s.",ret, MY_MISCDEV);
char buf[100];
::memset(buf, 0x00, 100);
::snprintf(buf, 100, "Hello World, %s", name.c_str());
hidl_string result(buf);
_hidl_cb(result);
return Void();
}}
//INaruto* HIDL_FETCH_INaruto(const char* /* name */) {
// return new Naruto(); //} // } // namespace implementation
} // namespace V1_0
} // namespace naruto
} // namespace hardware
} // namespace android
#指定目录编译
source ./build/envsetup.sh
lunch 15
#单独编译某个指定的目录
mmm hardware/interfaces/naruto/1.0/default/
VNDK相关
#hash值我没有手动添加,只需修改成一样的内容
#current.txt 记录了所有 hal 接口的 hash 值,
#接口有变化时,同时需要更新 current.txt 中的 hash 值
#在 interfaces 目录下新建 current.txt 文件,随便写个 hash 值
#再执行一遍 update-makefiles.sh,这个时候就会发现提示 hash 值不正确了,
#同时会给出正确的 hash 值,我们把正确的 hash 值替换到 current.txt 即可。
#在build\make\target\product\vndk 里
#28.txt
#current.txt
#添加如下行
VNDK-core: [email protected]
#添加完后执行更新 update-makefiles.sh
#更新完后执行单独模块编译 mmm /hardware/interfaces/naruto/1.0/
device部分
xx#在vim device/generic/car/common/manifest.xml添加如下,这一行是错的,修改如下路径:
#ac8257/device/autochips/ac8257_demo$ vim manifest.xml
#百度解释:add the code to the manifest.xm 以至于hwservicemanager 查找到指定的hidl service
<hal format="hidl">
<name>android.hardware.naruto</name>
<transport>hwbinder</transport>
<version>1.0</version>
<interface>
<name>INaruto</name>
<instance>default</instance>
</interface>
</hal>
xx#在car.mk添加 启动 narutoservice,如下:
#ac8257/device/autochips/ac8257$
#vim devices.mk
# Auto modules
PRODUCT_PACKAGES += \
……
[email protected]
#PRODUCT_PACKAGES百度解释如下:
PRODUCT_PACKAGES指定make时需要编译进system中的包,
这部分虽然也生成apk,但用户是删不掉的,
build/target/product/generic.mk中指定android系统自带的应用程序包
PRODUCT_PACKAGES := \
在device/amlogic/c03ref/c03ref.mk中增加芯片原厂的应用程序包
PRODUCT_PACKAGES += \
添加selinux权限(补全)
在ac8257/device/autochips/sepolicy/bsp/non_plat目录做如下修改
#修改hwservice_contexts
#/ac8257/device/autochips/sepolicy/bsp/non_plat$
#vim hwservice_contexts
#Date: 2020/1027
android.hardware.naruto::INarutou:object_r:hal_naruto_hwservice:s0
#android.hardware.naruto::PinData u:object_r:hal_naruto_hwservice:s0
#android.hardware.naruto::Status u:object_r:hal_naruto_hwservice:s0
#ac8257/device/autochips/sepolicy/bsp/non_plat$
#vim hwservice.te
# Date: 2020/10/27 add by luoyankuan
type hal_naruto_hwservice, hwservice_manager_type;
#ac8257/device/autochips/sepolicy/bsp/non_plat$
#vim file_contexts
#add for naruto
/(vendor|system/vendor)/bin/hw/android\.hardware\.naruto@1\.0-service u:object_r:hal_naruto_def
#~/ac8257/device/autochips/sepolicy/bsp/non_plat$
#vim hal_naruto.te
#新建hal_naruto_default.te
type hal_naruto_default, domain;
type hal_naruto_default_exec, exec_type, vendor_file_type, file_type;
allow hal_naruto_default sysfs:file rw_file_perms;
allow hal_naruto_default hwservicemanager_prop:file r_file_perms;
allow hal_naruto_default hwservicemanager:binder {
transfer call };
allow hal_naruto_default system_app:binder {
call transfer };
allow hal_naruto_default platform_app:binder {
call transfer };
allow hal_naruto_default untrusted_app:binder {
call transfer };
allow hal_naruto_default hal_naruto_hwservice:binder call;
allow hal_naruto_default hal_naruto_hwservice:hwservice_manager {
add };
allow hal_naruto_default device:file {
open read write};
allow hal_naruto_default device:chr_file{
open read write};
allow hal_naruto_default hidl_base_hwservice:hwservice_manager add;
#~/ac8257/device/autochips/sepolicy/bsp/non_plat$
#vim hwservicemanager.te
allow hwservicemanager hal_naruto_default:process getattr;
allow hwservicemanager hal_naruto_default:binder {
transfer call};
allow hwservicemanager hal_naruto_default:file r_file_perms;
allow hwservicemanager hal_naruto_default:dir search;
#:~/ac8257/device/autochips/sepolicy/bsp/non_plat$
#vim system_app.te
#Date: 2020/10/27
allow system_app hal_naruto_hwservice:hwservice_manager{
find};
allow system_app hal_naruto_default:binder{
call transfer};
#~/ac8257/device/autochips/sepolicy/bsp/non_plat$
#vim platform_app.te
#Date: 2020/10/27
allow platform_app hal_naruto_hwservice:hwservice_manager{
find};
allow platform_app hal_naruto_default:binder{
call transfer};
#~/ac8257/device/autochips/sepolicy/bsp/non_plat
#vim system_server.te
allow system_server hal_naruto_hwservice:hwservice_manager find;
allow system_server hal_naruto_default:binder {
call transfer};
#~/ac8257/device/autochips/ac8257$
#vim device.mk
PRODUCT_PACKAGES += \
libnaruto_jni \
[email protected] \
[email protected] \
调试问题记录
在编译完成后,烧写到设备中时,还是没有看到有相关的服务存在
这时候应该看下系统启动日志,是否存在报错,执行如下命令:
--查看服务
ps -Af | grep -i "naruto"
echo 0 0 > /dev/my_miscdev
dmesg
#必须要777,app才能正常打开读写操作
chmod 777 /dev/my_miscdev
--看日志
logcat |grep " naruto"
logcat |grep " SystemServer"
发现会报以下权限错误
权限报错
0-30 19:06:34.720 13961 13961 I ps : type=1400 audit(0.0:28357): avc: denied { open } for path="/proc/395/stat" dev="proc" ino=21678 scontext=u:r:autolog:s0 tcontext=u:r:hal_naruto_default:s0 tclass=file permissive=1
10-30 19:06:48.968 14227 14227 I ps : type=1400 audit(0.0:28557): avc: denied { read } for name="stat" dev="proc" ino=21678 scontext=u:r:autolog:s0 tcontext=u:r:hal_naruto_default:s0 tclass=file permissive=1
10-30 19:06:41.828 14059 14059 I ps : type=1400 audit(0.0:28367): avc: denied { getattr } for path="/proc/395" dev="proc" ino=12739 scontext=u:r:autolog:s0 tcontext=u:r:hal_naruto_default:s0 tclass=dir permissive=1
10-30 19:06:41.828 14059 14059 I ps : type=1400 audit(0.0:28368): avc: denied { search } for name="395" dev="proc" ino=12739 scontext=u:r:autolog:s0 tcontext=u:r:hal_naruto_default:s0 tclass=dir permissive=1
10-30 19:06:45.396 14199 14199 I ps : type=1400 audit(0.0:28461): avc: denied { getattr } for path="/proc/395" dev="proc" ino=12739 scontext=u:r:autolog:s0 tcontext=u:r:hal_naruto_default:s0 tclass=dir permissive=1
10-30 19:06:48.968 14227 14227 I ps : type=1400 audit(0.0:28555): avc: denied { getattr } for path="/proc/395" dev="proc" ino=12739 scontext=u:r:autolog:s0 tcontext=u:r:hal_naruto_default:s0 tclass=dir permissive=1
10-30 19:06:48.968 14227 14227 I ps : type=1400 audit(0.0:28556): avc: denied { search } for name="395" dev="proc" ino=12739 scontext=u:r:autolog:s0 tcontext=u:r:hal_naruto_default:s0 tclass=dir permissive=1
#报错格式如下:
avc: denied { 操作权限 } for pid=7201 comm=“进程名” scontext=u:r:源类型:s0 tcontext=u:r:目标类型:s0 tclass=访问类别 permissive=0
解决方法
#找到相关修改权限目录下的 “源类型.te”,进入如下修改
allow 源类型 目标类型:[tclass] { 操作权限 };
allow scontext tcontext:[tclass] { denied: };
allow autolog hal_naruto_default:file { open read };
allow autolog hal_naruto_default:dir { search getattr};
#device/autochips/sepolicy/bsp/non_plat
# vim autolog.te
allow autolog hal_naruto_default:file {
open read };
allow autolog hal_naruto_default:dir {
search getattr};
#device/autochips/sepolicy/bsp/non_plat
# vim hal_naruto_default.te
allow hal_naruto_default device:file {
open read write };
#添加一下语句时报错:
#10803 libsepol.report_failure: neverallow on line 417 of system/sepolicy/public/domain.te (or line 10530 of policy.conf) violated by allow hal_naruto_defa
#10804 libsepol.check_assertions: 1 neverallow failures occurred
#10805 Error while expanding policy
allow hal_naruto_default device:chr_file {
open write};
解决方法
#system/sepolicy/public/domain.te
#注释掉neverallow语句即可
#vim system/sepolicy/public/domain.te
#diff system/sepolicy/public/domain.te system/sepolicy/prebuilts/api/28.0/public/domain.te
#cp system/sepolicy/public/domain.te system/sepolicy/prebuilts/api/28.0/public/domain.te
#diff system/sepolicy/public/domain.te system/sepolicy/prebuilts/api/28.0/public/domain.te
该部分修改为 --》添加selinux权限(补全)
做完前面的步骤,应该是可以编译成功,并且在设备中看到相关的服务
client端实现
frameworks/base/core/java/android/os里 新建naruto目录
创建INarutoService.aidl
//创建INarutoService .aidl
package android.os.naruto;
//import android.os.naturo.NarutoEventListener;
// Declare any non-default types here with import statements
interface INarutoService {
String helloWorld(String str);
}
// 创建INarutoEventListener.aidl
package android.os.naruto;
import android.os.naruto.NarutoListenerEvent;
interface INarutoEventListener {
void onEvent (inout NarutoListenerEvent event);
}
// 创建NarutoListenerEvent.aidl
package android.os.naruto;
parcelable NarutoListenerEvent;
//创建NarutoListenerEvent.java
package android.os.naruto;
import android.os.Parcel;
import android.os.Parcelable;
public class NarutoListenerEvent implements Parcelable {
private int what;
private String msg;
public NarutoListenerEvent(int what, String msg) {
this.what = what;
this.msg = msg;
}
public NarutoListenerEvent(Parcel in) {
what = in.readInt();
msg = in.readString();
}
public void setWhat(int what) {
this.what = what;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getWhat() {
return what;
}
public String getMsg() {
return msg;
}
public static final Creator<NarutoListenerEvent> CREATOR = new Creator<NarutoListenerEvent>() {
@Override
public NarutoListenerEvent createFromParcel(Parcel in) {
return new NarutoListenerEvent(in);
}
@Override
public NarutoListenerEvent[] newArray(int size) {
return new NarutoListenerEvent[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(what);
dest.writeString(msg);
}
/**
* <p>从parcel中读取,从parcel中读取,顺序与write一致</p>
* 如果要支持为 out 或者 inout 的定向 tag 的话,需要实现 readFromParcel() 方法
*/
public void readFromParcel(Parcel dest) {
what = dest.readInt();
msg = dest.readString();
}
}
//创建NarutoManager.java
package android.os.naruto;
/**
* android.os.naruto.NarutoManager;
*/
import android.os.RemoteException;
import android.util.Log;
public class NarutoManager {
private INarutoService mService;
public static final String TAG = "NarutoManager";
public NarutoManager(INarutoService server) {
Log.d(TAG, "NarutoManager: ");
mService = server;
}
public String helloWorld(String str) {
Log.d(TAG, "helloWorld: "+str);
try {
if (mService == null) {
return null;
}
return mService.helloWorld(str);
} catch (RemoteException e) {
e.printStackTrace();
}
return "service connect failed";
}
}
//NarutoEventListener.java
package android.os.naruto;
public abstract class NarutoEventListenerextends INarutoEventListener.Stub {
}
#frameworks/base/Android.bp里添加
#frameworks/base/Android.bp里添加
"core/java/android/os/naruto/INarutoEventListener.aidl",
"core/java/android/os/naruto/INarutoService.aidl",
NarutoService端
在frameworks/base/services/core目录下:
Android.bp添加naruto独有类的引用
#frameworks/base/services/core/Android.bp
static_libs: [
……
"android.hardware.naruto-V1.0-java",
……
],
在目录 aosp\frameworks\base\services\core\java\com\android\server\naruto
//新建NarutoService.java
package com.android.server.naruto;
import android.hardware.naruto.V1_0.INaruto;
import android.os.RemoteException;
import android.os.naruto.INarutoService;
import android.util.Log;
import java.util.ArrayList;
/**
* com.android.server.naruto.NarutoService
*/
public class NarutoService extends INarutoService.Stub {
private String TAG = "NarutoService";
private INaruto halService ;
public NarutoService(){
try {
halService = INaruto.getService();//获取service
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public String helloWorld(String str) throws RemoteException {
Log.d(TAG, "helloWorld: ");
return halService.helloWorld(str);
}
}
#在目录aosp\frameworks\base\core\java\android\content\Context.java里添加
//frameworks/base/ore/java/android/content/Context.java
/**
* {@link android.os.NarutoManager} for receiving intents at a
* time of your choosing.
*
* @see #getSystemService
* @see android.os.NarutoManager
*/
public static final String NARUTO_SERVICE = "naruto";
#在目录\frameworks\base\core\java\android\app
//SystemServiceRegistry.java 里添加
import android.os.naruto.NarutoManager;
import android.os.naruto.INarutoService;
//add by luoyankuan at line 203
registerService(Context.NARUTO_SERVICE, NarutoManager.class,
new CachedServiceFetcher<NarutoManager>(){
@Override
public NarutoManager createService(ContextImpl ctx){
IBinder iBinder = ServiceManager.getService(Context.NARUTO_SERVICE);
if(iBinder == null){
return null;
}
INarutoService service = INarutoService.Stub.asInterface(iBinder);
return new NarutoManager(service);
}});
//add end
#在目录aosp\frameworks\base\services\java\com\android\server
//frameworks\base\services\java\com\android\server\SystemServer.java添加
import com.android.server.naruto.NarutoService;
// add by luoyankuan at line 811
try{
Slog.i(TAG, "naruto Service");
ServiceManager.addService(Context.NARUTO_SERVICE, new NarutoService());
}catch(Throwable e){
reportWtf("start NarutoService", e);
}
// add end
添加selinux策略,(添加)
public 目录:
#system/sepolicy/public/attributes 添加如下内容(补)
#system/sepolicy/prebuilts/api/28.0/public/attributes 添加如下内容(补)
#vim attributes
hal_attribute(naruto);
#system/sepolicy/public/service.te添加
#system/sepolicy/prebuilts/api/28.0/public/service.te添加
#补充添加hal_client_domain(system_server, hal_naruto)
hal_client_domain(system_server, hal_naruto)
type naruto_service, system_api_service, system_server_service, service_manager_type;
#将以上修改同步到system/sepolicy/prebuilts/api/28.0/public/
private 目录:
#system/sepolicy/private/service_context 添加
#system/sepolicy/prebuilts/api/28.0/private/service_context 添加
#service_contexts 添加 和Context 保持一致 NARUTO_SERVICE = “naruto”;
naruto u:object_r:naruto_service:s0
#system/sepolicy/prebuilts/api/28.0/private/system_server.te 添加
#system/sepolicy/private/system_server.te 添加
#hal_client_domain(system_server, hal_naruto)
#systemsepolicy/private/compat/26.0/26.0.ignore.cil 添加
#systemsepolicy/prebuilts/api/28.0/private/compat/26.0/26.0.ignore.cil 添加
naruto_service
#systemsepolicy/private/compat/27.0/27.0.ignore.cil 添加
#systemsepolicy/prebuilts/api/28.0/private/compat/27.0/27.0.ignore.cil 添加
naruto_service
#将以上修改同步到systemsepolicy/prebuilts/api/28.0/private
校验与修改
diff system/sepolicy/prebuilts/api/28.0/private/compat/26.0/26.0.ignore.cil system/sepolicy/private/compat/26.0/26.0.ignore.cil
vim system/sepolicy/private/compat/26.0/26.0.ignore.cil +110
vim system/sepolicy/prebuilts/api/28.0/private/compat/26.0/26.0.ignore.cil +110
diff system/sepolicy/prebuilts/api/28.0/private/compat/27.0/27.0.ignore.cil system/sepolicy/private/compat/27.0/27.0.ignore.cil
vim system/sepolicy/private/compat/27.0/27.0.ignore.cil +95
vim system/sepolicy/prebuilts/api/28.0/private/compat/27.0/27.0.ignore.cil +95
diff system/sepolicy/prebuilts/api/28.0/private/service_contexts system/sepolicy/private/service_contexts
vim system/sepolicy/prebuilts/api/28.0/private/service_contexts +163
vim system/sepolicy/private/service_contexts +163
#编译整个项目
./allmake.sh -c 4G -p ac8257_demo userdebug
编译成功后将镜像烧写到设备上进行测试
使用adb连接设备,进入/vendor/bin/hw/,查看是否有相关的rc文件
使用top命令进行查看相关的服务是否启动成功
使用service list 可查看相关的服务
注意事项
- selinux权限相关修改的文件,必须完全相同,否则会报错
- 不可根据自己以为的方式进行修改,否则很容易进入误区
- service端可先使用mmm对某个项目目录进行编译测试
- selinux修改的 权限目录的方式目前来说已知的有两种,均可以先尝试一下
APP实现调用
安卓Android studio
编写测试代码
烧录到设备
使用adb进行启动服务,测试是否成功输出hello world.
安装Android studio相关工具包
- 安装jdk
- 下载安装Android studio
- 手动下载gradle
项目创建以及相关配置
-
将gradle-6.1.1-all.zip放到一个固定的路径,解压(路径不存在中文)
#修改MyApplication\gradle\wrapper\gradle-wrapper.properties distributionUrl=file:///C\:/luoyankuan/installer/AndroidStudio/plugins/gradle/gradle-6.1.1-all.zip
app调用framework代码
#不需要导入jar包,直接替换相关的文件接口即可
#C:\Users\yk\AppData\Local\Android\Sdk\platforms\android-30
#\\172.168.0.90\luoyankuan\ac8257\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates
#目录下的classes.jar的相应内容替换到android.jar对应目录下
修改完成即可在app中调用
调试笔记
--获取git下载权限:
ssh-keygen -t rsa -C [email protected]
--tmux进入保护模式
--克隆服务器代码
git clone ssh://[email protected]/ac8257Project/ac8257.git
-- 新建一个本地分支,指向origin/master-8257-yige 分支
-- origin分支是远程分支
git checkout -b master-8257-yige origin/master-8257-yige
git checkout -b master-8257-yige-test origin/master-8257-yige
--项目编译 需要好几个小时等待完成
./allmake.sh -c 4G -p ac8257_demo userdebug
--创建网络文件夹位置,便于下载编译后的文件
\\172.168.0.90\luoyankuan
--账号密码
luoyankuan -- lyk
--学习资料共享盘
\\172.168.0.220\shares
借用机车与线材
--查看电脑配置选择硬盘或者选购新电脑
https://item.jd.com/71062921529.html#crumb-wrap
--方式1,开启蓝牙,切换devices模式:
*#82570001#
--方式二,使用串口命令方式切换到devices模式
cat /sys/class/dual_role_usb/dual-role-usb20/data_role //usb 口的模式
echo "host" > /sys/class/dual_role_usb/dual-role-usb20/data_role //切换到host模式
echo "device" > /sys/class/dual_role_usb/dual-role-usb20/data_role //切换到devices模式
--cmd打开中使用adb控制系统:
Adb devices
adb root
adb shell
--驱动路径:
\kernel-4.9\drivers\misc\flygpio
--编译驱动的两种方式:
--1,将驱动源码编译进内核,整个系统编译
--2,将驱动单独编译
--修改gpio代码,编译内核模块
--进入源码根目录执行:
source build/envsetup.sh
lunch 15
--编译驱动
mmm kernel-4.9:kernel
--编译内核镜像
make bootimage
--将ac8257/out/target/product/ac8257_demo目录下的boot.img拷贝出来更新
--烧录镜像
--烧录完成后,需要将板子完全断电才能正常启动,包括电源及其他的外部连接线
--生成驱动路径:
\\172.168.0.90\luoyankuan\ac8257\out\target\product\ac8257_demo\obj\KERNEL_OBJ\drivers\misc\simpleDevDriver
--步骤
编写led驱动,驱动设备树相关的不需要修改,直接用
编译驱动
加载驱动
编写测试程序,即打开设备,写入相关值,观察led灯是否亮灭
--设备树路径:
kernel-4.9/arch/arm64/boot/dts/mediatek/ac8257_demo.dts
--屏蔽原有的驱动
--加载自己写的驱动
adb push \\172.168.0.90\luoyankuan\ac8257\out\target\product\ac8257_demo\obj\KERNEL_OBJ\drivers\misc\simpleDevDriver\driver.ko /data/
adb push \\172.168.0.90\luoyankuan\test /data/
--查看系统日志信息
cat /dev/kmesg
/dev/my_miscdev
--将字符串重定向输入到指定文件端口中
echo "0 0" > /dev/my_miscdev
--如何了解学习驱动:
将对函数和数据结构的理解放在整体的架构背景之中。
--设备树的语法了解
--设备树相关的接口了解
--2020年10月16日10:07:41
这周先对整个框架进行了解,相关的文档资料等
--hidl参考博客:
https://blog.csdn.net/sinat_18179367/article/details/95940030
--创建目录
mkdir -p hardware/interfaces/naruto/1.0/default
--创建文件INaruto.hal 添加如下代码
package [email protected];
interface INaruto {
helloWorld(string name) generates (string result);
};
# [email protected]
# LOC=hardware/interfaces/naruto/1.0/default/
# make hidl-gen -j64
PACKAGE=[email protected]
LOC=hardware/interfaces/test/1.0/default
# hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
# hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
./hardware/interfaces/update-makefiles.sh
touch hardware/interfaces/naruto/1.0/default/[email protected]
touch hardware/interfaces/naruto/1.0/default/service.cpp
--修改和添加.h .c文件,实现输出hello功能
--使用以下命令进行编译
--mmm :编译指定目录下的模块,不编译他所依赖的其他模块
--mma :编译当前目录下的模块及其依赖
--mmma:编译指定路径下所有模块,并且包含依赖
--mm: 编译当前目录下的模块,不编译依赖模块
mmm hardware/interfaces/naruto/1.0/
mmm hardware/interfaces/test/1.0/
out/target/product/ac8257_demo/system/lib/vndk-28/[email protected]
--ubuntu 14 虚拟机账号密码:
root root
ssh -x [email protected]
git status .
git diff domU/kernel/kernel-4.9/drivers/base/firmware_class.c
git diff domU/kernel/kernel-4.9/drivers/input/touchscreen/autochips/GT928/gt9xx_driver.c
source ./build/envsetup.sh
lunch 15
PACKAGE=[email protected]
LOC=hardware/interfaces/naruto/1.0/default
make hidl-gen -j64
hidl-gen -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
hidl-gen -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE
--更新
./hardware/interfaces/update-makefiles.sh
--添加新文件
touch hardware/interfaces/naruto/1.0/default/[email protected]
touch hardware/interfaces/naruto/1.0/default/service.cpp
--修改Naruto.h和Naruto.cpp文件
--执行编译:
mmm hardware/interfaces/naruto/1.0/default/
--ok
uInstall: out/target/product/ac8257_demo/system/lib/vndk-28/[email protected]
[100% 31/31] build 'out/target/product/ac8257_demo/vendor/lib/hw/[email protected]'
--客户端实现
--system_service 实现
system\sepolicy\prebuilts\api\28.0\public
--vim 代码格式化
1,gg 跳转到第一行
2,shift+v 转到可视模式
3,shift+g 全选
4,按下神奇的 =
--先不用管什么,照着做,做完后再用gitk看修改过的内容,从大局角度上看整个过程,有不懂得就继续详细
--问题:
编写的驱动无法正常编译通过
虚拟机gitk无法使用问题
error: VNDK library list has been changed.
Changing the VNDK library list is not allowed in API locked branches.
out/target/product/product_name/obj/PACKAGING/vndk_intermediates/libs.txt
vim ~/ac8257/build/make/target/product/vndk/28.txt
vim ~/ac8257/build/make/target/product/vndk/current.txt
vim out/target/product/ac8257_demo/obj/PACKAGING/vndk_intermediates/libs.txt
VNDK-core: [email protected]
git命令参数:
git clone <版本库的网址>
git fetch <远程主机名> <分支名>
git pull <远程主机名> <远程分支名>:<本地分支名>
git push <远程主机名> <本地分支名>:<远程分支名>
diff system/sepolicy/prebuilts/api/28.0/private/service_contexts system/sepolicy/private/service_contexts
vim system/sepolicy/prebuilts/api/28.0/private/service_contexts
vim system/sepolicy/private/service_contexts
--查看服务
service list
--查看进程
ps -Af | grep -i "naruto"
--看日志
logcat |grep " SystemServer"
--需要熟悉知道相关的命令,大概知道是什么功能,需要的时候可以想的起来就行
--一定要去实验验证自己的想法是否正确,只有验证过了的才能更加确信什么是正确的。
--当然要看是否值得这么去做,如果成本过高就没必要了。
--android app
#修改File->Setting 里找到 Build,Execution,Deployment 里的 grade 设置,选择 Use gradle from 为specified location
#使用一下路径:
C:/Program Files/Android/Android Studio/gradle/gradle-6.1.1
#同样将修改MyApplication4\gradle\wrapper\gradle-wrapper.properties
distributionUrl=file:///C\:/Program Files/Android/Android Studio/gredle/gradle-6.1.1-all.zip
C:\luoyankuan\installer\AndroidStudio\plugins\gradle
distributionUrl=file:///C\:/luoyankuan/installer/AndroidStudio/plugins/gradle/gradle-6.1.1-all.zip
--在app中调用helloworld接口
--如何在app中调用底层的framework接口?
--在helloWorld接口中添加操作led的操作
adb install xxx/xxx/xxx.apk
不使用Proxy代理模式,替换相关gradle
若出错可删除C:\Users\yk\.gradle下的gradle.properties
ac8257/out/target/common/obj/JAVA_LIBRARIES/framework_intermediates
ac8257\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates
\\172.168.0.90\luoyankuan\ac8257\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates
--版本兼容问题,在build.gradle添加:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
maven{
url'http://maven.aliyun.com/nexus/content/groups/public/'}
maven{
url'http://maven.aliyun.com/nexus/content/repositories/jcenter'}
不需要导入jar包,直接替换相关的文件接口即可
C:\Users\yk\AppData\Local\Android\Sdk\platforms\android-30
\\172.168.0.90\luoyankuan\ac8257\out\target\common\obj\JAVA_LIBRARIES\framework_intermediates
目录下的classes.jar的相应内容替换到android.jar对应目录下
--以上就是整个app系统的调用流程,需进一步总结分析。
剩下就是做两个按钮,控制led的亮灭就行了。可直接在helloworld里面加。
#找到相关修改权限目录下的 “源类型.te”,进入如下修改
allow 源类型 目标类型:[tclass] {
操作权限 };
allow scontext tcontext:[tclass] {
denied: };
allow autolog hal_naruto_default:file {
open read };
allow autolog hal_naruto_default:dir {
search getattr};
allow hal_naruto_default device:file {
open read write};
system/sepolicy/public/domain.te +417 注释掉
--调试
echo 0 0 > /dev/my_miscdev
dmesg
#必须要777,app才能正常打开读写操作
chmod 777 /dev/my_miscdev