【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)

这篇具有很好参考价值的文章主要介绍了【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Android双屏异触-指定触摸为副屏触摸

在双屏异显产品中,有时候主副屏都带有触摸屏,并且要求主副屏触摸各自操作互不干扰。

Android 现有框架中已经支持副输入设备的逻辑,只是默认将所有的外部热插拔设备统一指定为副输入设备,这种逻辑我们如果是一个 I2C 加上一个 USB 触摸那么默认就可以支持,USB 触摸就是副 TP。

但,有时候我们是双 I2C 或双 USB 的搭配,我们就需要改造现有逻辑,方案如下:

通过属性配置副屏 TP 的: 设备名、PID&VID、USB 端口,在 EventHub 中获取输入设备的设备名、PID&VID、USB 端口与属性值进行对比,如果是配置中的设备就将其标记为副输入设备。

实现

diff --git a/frameworks/native/services/inputflinger/EventHub.cpp b/frameworks/native/services/inputflinger/EventHub.cpp
old mode 100644
new mode 100755
index 2bcc5c7..1542a7b
--- a/frameworks/native/services/inputflinger/EventHub.cpp
+++ b/frameworks/native/services/inputflinger/EventHub.cpp
@@ -64,6 +64,11 @@
 #define INDENT2 "    "
 #define INDENT3 "      "
 
+// for multi touch panel
+#define DEVICE_MATCH_METHOD_MAX 10
+#define USB_LOCATION_MATCH_START 13 //"usb-ff540000."
+#define USB_LOCATION_MATCH_LEN 7 //"usb-1.1"
+
 namespace android {
 
 static const char *WAKE_LOCK_ID = "KeyEvents";
@@ -1184,17 +1189,17 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
     int32_t deviceId = mNextDeviceId++;
     Device* device = new Device(fd, deviceId, String8(devicePath), identifier);
 
-    ALOGV("add device %d: %s\n", deviceId, devicePath);
-    ALOGV("  bus:        %04x\n"
+    ALOGI("add device %d: %s\n", deviceId, devicePath);
+    ALOGI("  bus:        %04x\n"
          "  vendor      %04x\n"
          "  product     %04x\n"
          "  version     %04x\n",
         identifier.bus, identifier.vendor, identifier.product, identifier.version);
-    ALOGV("  name:       \"%s\"\n", identifier.name.string());
-    ALOGV("  location:   \"%s\"\n", identifier.location.string());
-    ALOGV("  unique id:  \"%s\"\n", identifier.uniqueId.string());
-    ALOGV("  descriptor: \"%s\"\n", identifier.descriptor.string());
-    ALOGV("  driver:     v%d.%d.%d\n",
+    ALOGI("  name:       \"%s\"\n", identifier.name.string());
+    ALOGI("  location:   \"%s\"\n", identifier.location.string());
+    ALOGI("  unique id:  \"%s\"\n", identifier.uniqueId.string());
+    ALOGI("  descriptor: \"%s\"\n", identifier.descriptor.string());
+    ALOGI("  driver:     v%d.%d.%d\n",
         driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff);
 
     // Load the configuration file for the device.
@@ -1357,10 +1362,35 @@ status_t EventHub::openDeviceLocked(const char *devicePath) {
     }
 
     // Determine whether the device is external or internal.
-    if (isExternalDeviceLocked(device)) {
+    if((device->classes & 0x04) == INPUT_DEVICE_CLASS_TOUCH) {
+        int count = 0;
+        char flag[DEVICE_MATCH_METHOD_MAX][PROPERTY_VALUE_MAX];
+        char value[PROPERTY_VALUE_MAX] = {0};
+    
+        property_get("ro.input.external", value, "");
+
+        if (isExternalDeviceLocked(device)) {
+            sprintf(flag[count++], "%04x:%04x", identifier.vendor, identifier.product);
+            if (identifier.location.length() >= USB_LOCATION_MATCH_START+USB_LOCATION_MATCH_LEN) {
+                strncpy(flag[count++], identifier.location.string()+USB_LOCATION_MATCH_START, USB_LOCATION_MATCH_LEN);
+            }
+        } else {
+            sprintf(flag[count++], "%s", device->identifier.name.string());
+        }
+
+        for (int i=0; i<count; i++) {
+            ALOGI("openDeviceLocked:%d, value=%s flag=%s\n", __LINE__, value, flag[i]);
+            if (strstr(value, flag[i])) {
+                device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
+                ALOGI("openDeviceLocked:%d, name:\"%s\" id:%d device_class:%x vid:%04x pid:%04x is external input device\n",
+                    __LINE__, device->identifier.name.string(), device->id, device->classes, identifier.vendor, identifier.product);
+                break;
+            }
+        }
+    } else {
         device->classes |= INPUT_DEVICE_CLASS_EXTERNAL;
     }
-
+    
     if (device->classes & (INPUT_DEVICE_CLASS_JOYSTICK | INPUT_DEVICE_CLASS_DPAD)
             && device->classes & INPUT_DEVICE_CLASS_GAMEPAD) {
         device->controllerNumber = getNextControllerNumberLocked(device);

属性配置格式说明
属性名:ro.input.external
【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)也可以同时配置多个设备,各属性值之间用“,”隔开。
例如

ro.input.external=222a:0001,Hanvon electromagnetic pen,usb-1.4

以上属性配置“vid=222a,pid=0001”的 USB TP 和设备名为“Hanvon electromagnetic pen”的 I2C TP 以及 USB 端口为 1.4 的 TP 为副屏 TP,其它未配置的都默认为主屏 TP。

源码:https://github.com/aystshen/Android-MultiTouchPanel

二、Android定时开关机与看门狗
此方案用于实现 Android 主板的定时开机与看门狗功能,应用于一些特殊产品,如:广告机、自动售货机等。
【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)看门狗

看门狗功能默认关闭,直到 Android 发送命令打开看门狗功能。如果看门狗功能处于打开状态,Android 系统会在小于看门狗超时时长内定时发送心跳数据给 MCU,如果看门狗超时时长到,仍未收到心跳数据,则拉低 RESET 引脚10ms,使 CPU 复位重启。

定时开机
当 MCU 收到数据后启动计时,时间到拉低 POWER 引脚10ms,使 CPU 开机,同时清除本次定时任务,直到下次 CPU 重新下发新的定时任务。

协议
通信接口为 I2C,从机地址:0x61。
【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)源码 https://github.com/aystshen/Android-TimedBootDriver

API

heartbeat
发送看门狗(Watchdog)心跳,至少在每个看门狗超时周期内发送一次心跳,否则超时复位。
定义:

int heartbeat();
返回值 <0:失败,>=0:成功。

setUptime 设置定时开机倒计时,当倒计时结束则开机。
定义:

int setUptime(int time);//time 开机倒计时(单位:秒)。
返回 <0:失败,>=0:成功。

getUptime 获取定时开机剩余时间。

int getUptime(); // <0:失败,>=0:剩余时间(单位:秒)。

openWatchdog 打开看门狗。

int openWatchdog(); // 返回 <0:失败,>=0:成功。

closeWatchdog 关闭看门狗。

int closeWatchdog(); //<0:失败,>=0:成功。

setWatchdogDuration 设置看门狗超时时长。

int setWatchdogDuration(int duration);//duration 看门狗超时时长(单位:秒)
返回值 <0:失败,>=0:成功。

getWatchdogDuration 获取看门狗超时时长。

int getWatchdogDuration();//<0:失败,>=0:看门狗超时时长(单位:秒)

watchdogIsOpen 判断看门狗是否开启。

boolean watchdogIsOpen();//true:看门狗打开,false:看门狗关闭。

使用

  1. 在 APP 源码 src/main 目录下新建 aidl/android/os/ 这样的目录结构。
  2. 在 aidl/android/os/ 目录下新建 IMcuService.aidl 文件,内容如下:
package android.os;
 
/** {@hide} */
interface IMcuService
{
    int heartbeat();
    int setUptime(int time);
    int getUptime();
    int openWatchdog();
    int closeWatchdog();
    int setWatchdogDuration(int duration);
    int getWatchdogDuration();
    boolean watchdogIsOpen();
}

3.参考源码 Mcu.java文章来源地址https://www.toymoban.com/news/detail-498224.html

package com.ayst.androidx.supply;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.IBinder;
import android.os.IMcuService;
import android.os.RemoteException;

import java.lang.reflect.Method;

/**
 * Created by Administrator on 2018/11/6.
 */
public class Mcu {
    private IMcuService mMcuService;

    @SuppressLint("WrongConstant")
    public Mcu(Context context) {
        Method method = null;
        try {
            method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
            IBinder binder = (IBinder) method.invoke(null, new Object[]{"mcu"});
            mMcuService = IMcuService.Stub.asInterface(binder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Heartbeat
     */
    public void heartbeat() {
        if (null != mMcuService) {
            try {
                mMcuService.heartbeat();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Set the boot countdown
     * @param time (unit: second)
     * @return <0:error
     */
    public int setUptime(int time) {
        if (null != mMcuService) {
            try {
                return mMcuService.setUptime(time);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    /**
     * Get the boot countdown
     * @return time
     */
    public int getUptime() {
        if (null != mMcuService) {
            try {
                return mMcuService.getUptime();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return 0;
    }

    /**
     * Enable watchdog
     * @return <0:error
     */
    public int openWatchdog() {
        if (null != mMcuService) {
            try {
                return mMcuService.openWatchdog();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    /**
     * Disable watchdog
     * @return <0:error
     */
    public int closeWatchdog() {
        if (null != mMcuService) {
            try {
                return mMcuService.closeWatchdog();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    /**
     * Watchdog is open
     * @return
     */
    public boolean watchdogIsOpen() {
        if (null != mMcuService) {
            try {
                return mMcuService.watchdogIsOpen();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * Set watchdog over time duration
     * @param duration (unit: second)
     * @return <0:error
     */
    public int setWatchdogDuration(int duration) {
        if (null != mMcuService) {
            try {
                return mMcuService.setWatchdogDuration(duration);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return -1;
    }

    /**
     * Get watchdog over time duration
     * @return
     */
    public int getWatchdogDuration() {
        if (null != mMcuService) {
            try {
                return mMcuService.getWatchdogDuration();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        return 0;
    }
}

到了这里,关于【干货】Android系统定制基础篇:第十六部分(双屏异触、定时开关机与看门狗)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【干货】Android系统定制基础篇:第三部分(Android静默安装、Android支持usb打印机)

    一些产品要求APP在升级时能够实现静默安装,而无需弹出安装界面让用户确认。这里提出两种实现方案: 方案一 APP调用『pm』命令实现静默安装,此方案无须修改Android源码,但需要root权限。 方案二 修改Android PackageInstaller 源码,增加Intent参数来指定是否要静默安装,同时支

    2024年02月10日
    浏览(32)
  • 【干货】Android系统定制基础篇:第一部分(文件权限、增加信号强度、双路背光控制)

    当需要修改某文件或路径权限时,我们可以在init.rc开机启动某节点添加chmod命令进行修改。但是对于system分区,由于是ro权限,在init.rc使用chmod修改权限无效。需要在文件编译时,对权限进行修改。不同的Android版本改法一样,但是文件所在目录有差异,Android O主要修改文件是

    2024年02月09日
    浏览(38)
  • 【干货】Android系统定制基础篇:第二部分(Launcher3支持键盘切换焦点、开发者模式密码确认、禁止非预装应用安装、配置时间)

    Android Launcher3 默认并不支持键盘操作,无法切换焦点,在一些需要支持键盘或遥控操作的设备中无法使用,因些对 Launcher3 做简单修改,使其支持键盘切换焦点。 在安全性要求比较高的产品中,一般会默认关闭『adb调试』,同时禁止用户打开『adb调试』功能。在Android8.1中默认

    2024年02月10日
    浏览(42)
  • 学习Android的第十六天

    目录 Android 自定义 Adapter Adapter 接口 SpinnerAdapter ListAdapter BaseAdapter 自定义 BaseAdapter 参考文档 Android ListView 列表控件 ListView 的属性和方法 表头表尾分割线的设置 列表从底部开始显示 android:stackFromBottom 设置点击颜色 cacheColorHint 隐藏滑动条 在上一篇文章中我们知道了啥是 Adap

    2024年02月19日
    浏览(46)
  • 【STM32】基础知识 第十六课 窗口看门狗 WWDG 深入浅出

    在嵌入式开发中, 可靠性和稳定性是至关重要的. 这就是为什么许多单片机, 比如 STM32, 提供了窗口看门狗 (Window Watchdog, WWDF) 的功能. WWDG 是一种硬件定时器, 其目的在于防止软件错误导致的系统故障. WWDG 是通过监控软件运行的正常新, 并在检测到异常情况时自动重启系统, 从而

    2024年02月16日
    浏览(24)
  • 第十六章 使用MariaDB数据库管理系统

    一、数据库管理系统 1、数据库介绍 数据库是指按照某些特定结构来存储数据资料的数据仓库。在当今这个大数据技术迅速崛起的年代,互联网上每天都会生成海量的数据信息,数据库技术也从最初只能存储简单的表格数据的单一集中存储模式,发展到了现如今存储海量数据

    2024年02月05日
    浏览(40)
  • 系统集成项目管理工程师(软考中级)—— 第十六章 项目人力资源管理 笔记分享

    现在分享一些笔记给大家,希望能够帮助大家并顺利通过软考。 幕布地址:第十六章 项目人力资源管理 - 幕布 1.编制项目人力资源计划(计划) 确定与识别项目中的角色、所需技能、分配项目职责和汇报关系,并记录下来形成书面文件,其中也包括项目人员配备管理计划

    2024年02月05日
    浏览(37)
  • stm32串口自定义协议接收一串十六进制数据(将其中两个字节转化为十进制数据)+部分串口基础知识

    位(bit): 二进制数中的一个数位,可以是0或者1,是计算机中数据的最小单位。 字节(Byte): 计算机中数据的基本单位,每8位组成一个字节。各种信息在计算机中存储、处理至少需要一个字节。 例如,一个ASCII码用一个字节表示,一个汉字用两个字节表示。 字(Word):

    2023年04月08日
    浏览(49)
  • Android 11 定制系统全局监听触摸事件接口

    1.定义创建aidl接口(由于需要回调这里优先需要增加一个回调接口 ) frameworksbasecorejavaandroidappIOnTouchListener.aidl package android.app; oneway interface IOnTouchListener {      void onTouchEvent( int action); }   2.新增调用接口 在 base/core/java/android/view/IWindowManager.aidl 修改如下: import android.ap

    2023年04月08日
    浏览(44)
  • Android显示系统SurfaceFlinger详解 超级干货

    本文详细讲解了Android显示系统SurfaceFlinger,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 目录 一、Android系统启动 二、SurfaceFlinger代码剖析[Android 11] 1.【执行文件-surfaceflinger】 2.【动态库-libsurfaceflinger.so】 3. 服务启

    2024年03月14日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包