使用Android隐藏API SerialPort进行串口通信

本文介绍了在RK3368平台,Android 6.0系统上使用隐藏API SerialPort进行串口通信的方法,包括修改源码、配置系统资源、设置串口设备权限,以及解决因SElinux导致的权限问题。并提到了测试工具SerialChat的使用和参考链接。

Platform: RK3368

OS: Android 6.0

Kernel: 3.10.0


1.修改源码编译

因为串口相关的api是隐藏的,所以需要自己修改源码将相关需要用到的api的"@hide"注解去掉:

diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5cccb15..748be5d 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2490,7 +2490,7 @@ public abstract class Context {
             //@hide: SIP_SERVICE,
             USB_SERVICE,
             LAUNCHER_APPS_SERVICE,
-            //@hide: SERIAL_SERVICE,
+            SERIAL_SERVICE,
             //@hide: HDMI_CONTROL_SERVICE,
             INPUT_SERVICE,
             DISPLAY_SERVICE,
@@ -3201,7 +3201,6 @@ public abstract class Context {
      * @see #getSystemService
      * @see android.hardware.SerialManager
      *
-     * @hide
      */
     public static final String SERIAL_SERVICE = "serial";
 
diff --git a/core/java/android/hardware/ISerialManager.aidl b/core/java/android/hardware/ISerialManager.aidl
index 74d30f7..7cd8828 100644
--- a/core/java/android/hardware/ISerialManager.aidl
+++ b/core/java/android/hardware/ISerialManager.aidl
@@ -18,7 +18,6 @@ package android.hardware;
 
 import android.os.ParcelFileDescriptor;
 
-/** @hide */
 interface ISerialManager
 {
     /* Returns a list of all available serial ports */
diff --git a/core/java/android/hardware/SerialManager.java b/core/java/android/hardware/SerialManager.java
index e0680bf..d6030c5 100644
--- a/core/java/android/hardware/SerialManager.java
+++ b/core/java/android/hardware/SerialManager.java
@@ -24,18 +24,12 @@ import android.util.Log;
 
 import java.io.IOException;
 
-/**
- * @hide
- */
 public class SerialManager {
     private static final String TAG = "SerialManager";
 
     private final Context mContext;
     private final ISerialManager mService;
 
-    /**
-     * {@hide}
-     */
     public SerialManager(Context context, ISerialManager service) {
         mContext = context;
         mService = service;
diff --git a/core/java/android/hardware/SerialPort.java b/core/java/android/hardware/SerialPort.java
index 5d83d9c..24e0e9e 100644
--- a/core/java/android/hardware/SerialPort.java
+++ b/core/java/android/hardware/SerialPort.java
@@ -23,9 +23,6 @@ import java.io.IOException;
 
 import java.nio.ByteBuffer;
 
-/**
- * @hide
- */
 public class SerialPort {
 
     private static final String TAG = "SerialPort";
@@ -37,7 +34,6 @@ public class SerialPort {
 
     /**
      * SerialPort should only be instantiated by SerialManager
-     * @hide
      */
     public SerialPort(String name) {
         mName = name;
@@ -49,7 +45,6 @@ public class SerialPort {
      * 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000,
      * 1500000, 2000000, 2500000, 3000000, 3500000, 4000000
      *
-     * @hide
      */
     public void open(ParcelFileDescriptor pfd, int speed) throws IOException {
         native_open(pfd.getFileDescriptor(), speed);

2. 在系统资源配置中添加串口,SerialService用到这个配置:
frameworks/base/core/res/res/values/config.xml
     <string-array translatable="false" name="config_serialPorts">
+         <item>"/dev/ttyS1"</item>
+         <item>"/dev/ttyS4"</item>
     </string-array>
3. 串口设备权限

在init.rc中配置串口设备权限:

# serialport
    chmod 0600 /dev/ttyS1
    chown system system /dev/ttyS1
    chmod 0600 /dev/ttyS4
    chown system system /dev/ttyS4
4. 测试

安卓提供了个测试工具,在framework/base/tests/SerialChat;
可以编译push到设备/system/priv-app/中,然后用SerialChat进行串口测试;SerialChat默认打开的是串口列表中的第一个串口(波特率为115200).

自己写APP可以参考SerialChat,注意用平台签名或者放到系统/system/priv-app/下面(使APP成为platform-app).在Android Studio中使用隐藏API参考:https://blog.youkuaiyun.com/dpppppp/article/details/98939733


遇到的问题

由于系统启动了SElinux,所以app通过SerialManager打开串口时logcat会报以下错误:

type=1400 audit(0.0:9): avc: denied { read write } for path="/dev/ttyS1" dev="tmpfs" ino=8704 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:serial_device:s0 tclass=chr_file permissive=0

根据avc:denied日志,在platform_app.te添加对串口设备的读写权限:

allow platform_app serial_device:chr_file rw_file_perms;

结果发现app还是打开不了串口,没有写权限:

type=1400 audit(0.0:9): avc: denied { write } for path="/dev/ttyS1" dev="tmpfs" ino=9225 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:serial_device:s0 tclass=chr_file permissive=0
解决方法

在device.te中定义serial_device所在行添加mlstrustedobject.

type serial_device, dev_type, mlstrustedobject;

原因:seapp_contexts对platform app定义了以下内容,灵感来自 https://www.jianshu.com/p/9374e4421d38:

user=_app seinfo=platform domain=platform_app type=app_data_file levelFrom=user
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值