安卓系统开发-HIDL

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

猜你喜欢

转载自blog.csdn.net/qq_40904479/article/details/109214705