Android的LocalSocket(应用层和native通信)是android为系统不同层间或同一层内的不同进程间通信封装的一种通信方法,多用来实现上层因没有操作底层的权限而向底层发送消息进行通信.因此大多时候native层常作为服务端,应用层常作为客户端.
native层service与应用层建立client/server模式socket通信主要代码:
应用层主要代码:
String SOCKET_NAME="myserver";
LocalSocket s =null;
LocalSocketAddress l;
s = new LocalSocket();
l = new LocalSocketAddress(SOCKET_NAME,
LocalSocketAddress.Namespace.RESERVED);
s.connect(l);
native层主要代码:(可以在system目录下,与netd/vold等进程并列创建自己的进程文件夹)
s_fdListen = android_get_control_socket(SOCKET_NAME;
ret = listen(s_fdListen, n);
s_fdCommand = accept(s_fdListen, (sockaddr *) &peeraddr, &socklen);
文件夹下包含有main函数的.cpp文件和对应的.h文件以及其它你所需要的头文件和源文件,另外还有Android.mk文件.
我的Android.mk文件内容如下(可仿照此编写):
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SHARED_LIBRARIES := \
libcrypto \
libutils \
libdl \
libhardware_legacy \
liblog \
liblogwrap \
libmdnssd \
libnetutils \
libsysutils \
libwpa_client \
libcutils \
libqsap_sdk\
libstlport \
libstdc++ \
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
LOCAL_MODULE:=myserver
LOCAL_SRC_FILES := \
IpCmdController.cpp \
***.cpp
LOCAL_C_INCLUDES += external/stlport/stlport
LOCAL_C_INCLUDES += bionic
include $(BUILD_EXECUTABLE)
/system/core/rootdir/init.rc中加入:
service myserver /system/bin/myserver
class main
socket myserver stream 0660 root system
编译完native层的代码后把生成的myserver文件(out/target/product/**/system/bin/下)push到手机的system/bin/下.然而此时还未运行,也无法开机自启动,需要将init.rc中更改的内容编入手机内.于是重新make bootimage,刷机重启.好了,手机中有了myserver进程了,然而由于我通信的一方应用层缺少权限,依旧无法正常通信,可能出现如下错误,关键原因在于SELinux在作怪.
错误:creat localsocket filed!java.io.IOException: No such file or directory
creat localsocket filed!java.io.IOException: Permission denied
此时每次重启手机后在adb shell /root下setenforce 0可正常通信,但每次重启手机设置,不能从根本上解决问题.
解决SELinux权限问题:
这里需要几处配置,
1.首先,在device/qcom/sepolicy/common下新建myservice.te文件,内容如下:
type myservice, domain;
type myservice_exec, exec_type, file_type;
init_daemon_domain(myservice)
allow system_app socket_device:sock_file {read write};
2.在device/qcom/sepolicy/common/file_contexts中添加一句:
/system/bin/myservice u:object_r:myservice_exec:s0
3.如果external/sepolicy/app.te中有"neverallow appdomain socket_device:sock_file write;",可能需要注释掉
配置完之后,再次重新编译boot.img即可.