AntiMonitorService 添加 InputEventReader 服务。
authorsnickersun <scy@incartech.cn>
Tue, 12 Jan 2021 02:13:24 +0000 (10:13 +0800)
committersnickersun <scy@incartech.cn>
Tue, 12 Jan 2021 02:13:24 +0000 (10:13 +0800)
通过配置下面变量,控制佩戴和剪断检测设备的指定。
persist.sys.AntiInputName
persist.sys.CutInputName
注意BoardConfig.mk中的配置仍然生效,注意两个不要冲突。
BOARD_HAVE_PLS := antikey

app/src/main/java/com/enqualcomm/support/service/AntiMonitorService.java
app/src/main/java/com/enqualcomm/support/service/InputEventReader.java [new file with mode: 0644]

index 99f904f..3aa3f90 100644 (file)
@@ -31,14 +31,16 @@ import rx.schedulers.Schedulers;
 import static com.enqualcomm.support.Constants.ACTION_ANTI_OFF;
 import static com.enqualcomm.support.Constants.ACTION_ANTI_OFF0;
 import static com.enqualcomm.support.Constants.ACTION_CHECK_ANTIOFF_EVENT;
+import static com.enqualcomm.support.Constants.ACTION_CHECK_CUTOFF_EVENT;
 import static com.enqualcomm.support.Constants.KEY_ANTI_EVENT;
 import static com.enqualcomm.support.Constants.KEY_ANTI_TXT;
 import static java.lang.Thread.sleep;
 
 
-public class AntiMonitorService extends AbstractInvokeHandlerService {
+public class AntiMonitorService extends AbstractInvokeHandlerService implements InputEventReader.InputEventReceiver{
 
 
+    private InputEventReader m_inputEventReader=null;
     private static final String TAG = "AntiMonitorService";
     Context mContext;
 
@@ -58,9 +60,31 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
     private static int ant_status_event_reported = 0; // 0 表示无消息, 1表示有消息需要发送, 大于1表示timeout时间内又有新消息,可以忽略不计
     private static long anti_event_receivedTime = 0;
     private static int last_send_antoff_event = -1;
+    private static int current_cut_status = 12; //2 佩戴, 大于12 表示脱腕
+    private static int cut_status_event_reported = 0; // 0 表示无消息, 1表示有消息需要发送, 大于1表示timeout时间内又有新消息,可以忽略不计
+    private static long cut_event_receivedTime = 0;
+    private static int last_send_cut_event = -1;
     private Handler mHandler = null;
     PowerManager.WakeLock mWakeLock = null;
 
+    @Override
+    public void onInputEventRecevied(int type, int event) {
+        if(event==2 || event == 12){
+            current_cut_status = event;
+            cut_status_event_reported++;
+            ICLogger.i("近距离 " + current_cut_status + " input event " + cut_status_event_reported + " times !");
+            cut_event_receivedTime = System.currentTimeMillis();
+            reset_timer_cut();
+
+        }else {
+            current_anti_status = event;
+            ant_status_event_reported++;
+            ICLogger.i("近距离 " + current_anti_status + " input event " + ant_status_event_reported + " times !");
+            anti_event_receivedTime = System.currentTimeMillis();
+            reset_timer();
+        }
+    }
+
 
     private static class InnerHandler extends Handler {
 
@@ -101,6 +125,8 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
 //            mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, AntiMonitorService.class.getSimpleName());
             mWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, AntiMonitorService.class.getSimpleName());
         }
+
+        m_inputEventReader=new InputEventReader(this);
     }
 
     private void play_notify() {
@@ -179,7 +205,7 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
         mHandler.removeCallbacks(mUpdateTimeFlagTask);
     };
 
-    private void send_antiof_cutoff_event() {
+    private void send_antiof_event() {
         if (last_send_antoff_event == current_anti_status) {
             ICLogger.i("佩戴状态未变,skip!");
             return;
@@ -189,43 +215,6 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
         //current_anti_status == 0 表示佩戴       ==10 表示脱腕
 
         switch (current_anti_status) {
-            case STATUS_LOCK_ON:
-                //锁定
-            {
-                if (Config.needBroadcastCutoffAlarm) {
-                    //  play_notify();
-                    send_cutoff_event_broadcast(0);
-                }
-                mRuntime.Cut_off_flag = 0;
-                if (mRuntime.setAlarmType(Runtime.AlarmType.ALARM_LOCK_WATCH)) {
-                    //发送消息定位报警消息
-                    ICLogger.i("triggerSOSLocationProcess ");
-                    LocationClient.getInstance().triggerSOSLocationProcess();
-                }
-
-
-            }
-            break;
-            case STATUS_CUT_OFF: {
-                //非法解锁
-                if (Config.needBroadcastCutoffAlarm) {
-
-                    send_cutoff_event_broadcast(1);
-                }
-                mRuntime.Cut_off_flag = 1;
-                if (mRuntime.setAlarmType(Runtime.AlarmType.ALARM_CUTOFF)) {
-                    ICLogger.i("triggerSOSLocationProcess ");
-                    LocationClient.getInstance().triggerSOSLocationProcess();
-//                    StringMessage msg = protocolAPIHelper.getWarningMSG(mRuntime);
-//                    Deliver.sendLocationMSG(msg); //消息很重要,所以利用带buffer的对列来发送!
-                }
-//            try {
-//                sleep(1000);
-//            } catch (InterruptedException e) {
-//                e.printStackTrace();
-//            }
-            }
-            break;
             case STATUS_WEARED:
                 //佩戴
             {
@@ -278,7 +267,60 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
         last_send_antoff_event = current_anti_status;
         ICLogger.i("AntiOff Timeout! send antioff event " + current_anti_status);
     }
+    private void send_cutoff_event() {
+        if (last_send_cut_event == current_cut_status) {
+            ICLogger.i("剪断状态未变,skip!");
+            return;
+        }
+
+        //current_anti_status == 2 表示表带 锁定 , ==12 表示表带非法解锁
+        //current_anti_status == 0 表示佩戴       ==10 表示脱腕
+
+        switch (current_cut_status) {
+            case STATUS_LOCK_ON:
+                //锁定
+            {
+                if (Config.needBroadcastCutoffAlarm) {
+                    //  play_notify();
+                    send_cutoff_event_broadcast(0);
+                }
+                mRuntime.Cut_off_flag = 0;
+                if (mRuntime.setAlarmType(Runtime.AlarmType.ALARM_LOCK_WATCH)) {
+                    //发送消息定位报警消息
+                    ICLogger.i("triggerSOSLocationProcess ");
+                    LocationClient.getInstance().triggerSOSLocationProcess();
+                }
+
+
+            }
+            break;
+            case STATUS_CUT_OFF: {
+                //非法解锁
+                if (Config.needBroadcastCutoffAlarm) {
+
+                    send_cutoff_event_broadcast(1);
+                }
+                mRuntime.Cut_off_flag = 1;
+                if (mRuntime.setAlarmType(Runtime.AlarmType.ALARM_CUTOFF)) {
+                    ICLogger.i("triggerSOSLocationProcess ");
+                    LocationClient.getInstance().triggerSOSLocationProcess();
+//                    StringMessage msg = protocolAPIHelper.getWarningMSG(mRuntime);
+//                    Deliver.sendLocationMSG(msg); //消息很重要,所以利用带buffer的对列来发送!
+                }
+//            try {
+//                sleep(1000);
+//            } catch (InterruptedException e) {
+//                e.printStackTrace();
+//            }
+            }
+            break;
+            default:
+                break;
+        }
 
+        last_send_cut_event = current_cut_status;
+        ICLogger.i("CutOff Timeout! send cutoff event " + current_cut_status);
+    }
     public boolean CheckAntiByPoling() {
         //检查是否佩戴。佩戴返回true
         //send_antiof_event();
@@ -295,7 +337,7 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
         );
 
         if ((currenttime - anti_event_receivedTime) >= 2000) {
-            send_antiof_cutoff_event();
+            send_antiof_event();
 
             ant_status_event_reported = 0;
             return 0;
@@ -307,10 +349,31 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
         }
     }
 
+    public int check_cut_event() {
+
+        long currenttime = System.currentTimeMillis();
+        ICLogger.i("cut_event_receivedTime in " + (currenttime - cut_event_receivedTime)
+                + "ms ago ,cut_event_count_when_start_timer " + cut_status_event_reported
+        );
+
+        if ((currenttime - cut_event_receivedTime) >= 2000) {
+            send_cutoff_event();
+
+            cut_status_event_reported = 0;
+            return 0;
+        } else {
+            long restTimeNeedDelay = (2000 + cut_event_receivedTime - currenttime);
+            ICLogger.i("Still need delay " + restTimeNeedDelay + "ms to check cut_event again!");
+            setCutCheckAlarm((int) restTimeNeedDelay);
+            return 1;
+        }
+    }
     public void setAntiCheckAlarm(int ms) {
         AlarmHelper.setRealTimeAlarmInMicorSeconds(mRuntime.getContextProxy().context, ms, ACTION_CHECK_ANTIOFF_EVENT);
     }
-
+    public void setCutCheckAlarm(int ms) {
+        AlarmHelper.setRealTimeAlarmInMicorSeconds(mRuntime.getContextProxy().context, ms, ACTION_CHECK_CUTOFF_EVENT);
+    }
     private void reset_timer() {
 
         if (1 == ant_status_event_reported) //出现 ant_status_event_reported=0表示 有消息到来,需要开始,
@@ -319,7 +382,14 @@ public class AntiMonitorService extends AbstractInvokeHandlerService {
             setAntiCheckAlarm(2000);
         }
     }
+    private void reset_timer_cut() {
 
+        if (1 == cut_status_event_reported) //出现 ant_status_event_reported=0表示 有消息到来,需要开始,
+        {
+            //    antioff_timer.schedule(antioff_timeout_handler,1000); //两秒后发送消息
+            setCutCheckAlarm(2000);
+        }
+    }
     /**
      * 启动传感器。
      */
diff --git a/app/src/main/java/com/enqualcomm/support/service/InputEventReader.java b/app/src/main/java/com/enqualcomm/support/service/InputEventReader.java
new file mode 100644 (file)
index 0000000..596114d
--- /dev/null
@@ -0,0 +1,256 @@
+package com.enqualcomm.support.service;
+
+import com.enqualcomm.support.utils.ICLogger;
+import com.enqualcomm.support.utils.ThreadPool;
+import com.enqualcomm.support.utils.Util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.InputStream;
+
+public class InputEventReader {
+    public static final int EVENT_TYPE_ANTI=0;
+    public static final int EVENT_TYPE_CUT=0;
+    public static final int EVENT_ANTI_OFF=10;
+    public static final int EVENT_WEARED=1;
+    public static final int EVENT_CUT_OFF=12;
+    public static final int EVENT_LOCKED=2;
+
+    /***
+     *循环读取设备的name 匹配对应的设备名,确定是否制定设备
+     * /sys/class/input/input0/name
+     * /sys/class/input/input1/name
+     * ...
+     * /sys/class/input/inputX/name
+     */
+    private static final String SYS_INPUT_BASE="/sys/class/input/input";
+    private static final String EVENT_PATH_BASE="/dev/input/event";
+    /***
+     * 读取/sys/class/input/inputX/name 对应的名称 符合 antiDevNames 即是 佩戴检测事件节点
+     * 检测对应 /dev/input/eventX 节点可以获取佩戴事件
+     */
+    private static final String antiDevNames= Util.getSystemProperties("persist.sys.AntiInputName","");
+    /***
+     * 读取/sys/class/input/inputX/name 对应的名称 符合 cutDevNames 即是 剪断检测事件节点
+     * 检测对应 /dev/input/eventX 节点可以获取剪断事件
+     */
+    private static final String cutDevNames= Util.getSystemProperties("persist.sys.CutInputName","");
+
+
+    private String getInputDevNameByID(int id){
+        byte buffer[]=new byte[255];
+        String ret="";
+        String input=SYS_INPUT_BASE+id+"/name";
+        try {
+            FileInputStream fis=new FileInputStream(input);
+            int len=fis.read(buffer);
+            if (len > 0){
+                ret=new String(buffer,0,len);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        ICLogger.i("getInputDevNameByID "+input+ " "+ret);
+        return ret.trim();
+    }
+
+    private int get_DevID_By_Name(String name){
+        int devid=-1;
+        for ( int i=0;i< 10;i++){
+            if(getInputDevNameByID(i).startsWith(name.trim())) {
+                devid = i;
+                break;
+            }
+        }
+        return devid;
+    }
+
+
+
+    public int getEventFromData(boolean isAntiEvent,byte[] eventMsgs){
+    /***
+     * 4d3bfc5fd1ab0a0001008e00010000004d3bfc5fd1ab0a0001008e00000000004d3bfc5fd1ab0a000000000000000000
+     *
+     * 4d3bfc5fd1ab0a00    timestamp  8bytes
+     * 0100             eventtype   2bytes
+     * 8e00             eventcode   2bytes
+     * 01000000          value      4bytes
+     * 4d3bfc5fd1ab0a00   timestamp
+     * 0100             eventtype
+     * 8e00             eventcode
+     * 00000000        value
+     * 4d3bfc5fd1ab0a00   timestamp
+     * 0000             eventtype
+     * 0000             eventcode
+     * 00000000         value
+     *
+     * 0001 008e 00000001
+     * 0001 008e 00000000
+     * 0000 0000 00000000
+     */
+        int ret=0;
+        byte int_bytes[]=new byte[4];
+        if(eventMsgs.length==48){
+            int eventtype,eventvalue;
+            long eventcode;
+            for(int i=0;i<eventMsgs.length/16;i++)
+            {
+                StringBuilder sb=new StringBuilder("Received EventType ");
+                int_bytes[0]=int_bytes[1]=int_bytes[2]=int_bytes[3]=0;
+                int_bytes[3]=eventMsgs[8+i*16];
+                int_bytes[2]=eventMsgs[9+i*16];
+                eventtype=Util.byteArray4ToInt(int_bytes);
+                sb.append(Util.byte2hex(int_bytes));
+                int_bytes[3]=eventMsgs[10+i*16];
+                int_bytes[2]=eventMsgs[11+i*16];
+                eventcode=Util.byteArray4ToInt(int_bytes);
+                sb.append(" EventCode ").append(Util.byte2hex(int_bytes));
+                int_bytes[3]=eventMsgs[12+i*16];
+                int_bytes[2]=eventMsgs[13+i*16];
+                int_bytes[1]=eventMsgs[14+i*16];
+                int_bytes[0]=eventMsgs[15+i*16];
+                eventvalue=Util.byteArray4ToInt(int_bytes);
+                sb.append(" Value ").append(Util.byte2hex(int_bytes));
+                ICLogger.i("Received EventType "+eventtype +" EventCode "+eventcode+" Value "+eventvalue );
+                if(eventtype==1 && eventvalue==1){
+                    /***
+                     *     case 0x8e: //KeyCode AntiOff 脱腕
+                     *         if(value==1){
+                     * #ifdef GPIO_CUTOFF
+                     *             value= 12;
+                     * #else
+                     *             value= 10;
+                     *
+                     * #endif
+                     *     case 0x8d: //KeyCode Wear 佩戴
+                     *         if(value==1){
+                     * #ifdef GPIO_CUTOFF
+                     *             value=2;
+                     * #else
+                     *             value=0;
+                     * #endif
+                     */
+                    int f=Math.abs((int)eventcode);
+//                    ICLogger.i(" eventcode "+eventcode+" "+f+" 0x8e "+0x8e+" 0x8d "+0x8d);
+                    switch(f){
+                        case 0x8e: //KeyCode AntiOff 脱腕
+                            if(isAntiEvent){
+                                ret=EVENT_ANTI_OFF;
+                            }else{
+                                ret=EVENT_CUT_OFF;
+                            }
+                            break;
+                        case 0x8d://KeyCode Wear 佩戴
+                            if(isAntiEvent){
+                                ret=EVENT_WEARED;
+                            }else{
+                                ret=EVENT_LOCKED;
+                            }
+                            break;
+                    }
+                    sb.append(" ret ").append(ret);
+
+                }
+                ICLogger.i(sb.toString());
+            }
+
+        }else{
+            ICLogger.e("Error Input Event Format!");
+        }
+        return ret;
+    }
+    /***
+     * 佩戴检测事件读取线程
+     */
+    private Runnable antiEventThread=new Runnable() {
+        @Override
+        public void run() {
+            ICLogger.i("Enter antiEventThread "+Thread.currentThread().getName()+" "+ antiDevNames);
+            int devid=get_DevID_By_Name(antiDevNames);
+            if (devid>-1){
+
+                try{
+                    String antipath=EVENT_PATH_BASE+devid;
+                    ICLogger.i("open AntiEventPATH "+antipath);
+                    FileInputStream br=new FileInputStream(antipath);
+                    byte buf[]=new byte[50];
+                    int len=0;
+                    br.available()
+                    while(true){
+                        len=br.read(buf);
+                        if(len>0) {
+                            byte t[]=new byte[len];
+                            for(int i=0;i<len;i++)
+                                t[i]=buf[i];
+                            ICLogger.i("read anti Event " + len+ " "+ Util.bytesToHexString(t));
+                            int event=getEventFromData(true,t);
+                            if(callback!=null){
+                                callback.onInputEventRecevied(EVENT_TYPE_ANTI,event);
+                            }
+                        }
+                    }
+                }catch (Exception e){
+                    ICLogger.e(e.getMessage(),e);
+                }
+
+            }else{
+                ICLogger.e("no AntiDev antiEventThread exit! ");
+            }
+        }
+    } ;
+    /***
+     * 剪断检测事件读取线程
+     */
+    private Runnable cutEventThread=new Runnable() {
+        @Override
+        public void run() {
+            ICLogger.i("Enter cutEventThread "+Thread.currentThread().getName() +" "+cutDevNames);
+            int devid=get_DevID_By_Name(cutDevNames);
+            if (devid>-1){
+
+                try{
+                    String cutpath=EVENT_PATH_BASE+devid;
+                    ICLogger.i("open CutEventPATH "+cutpath);
+                    FileInputStream br=new FileInputStream(cutpath);
+                    byte buf[]=new byte[50];
+                    int len=0;
+                    while(true){
+                        len=br.read(buf);
+                        if(len>0) {
+                            byte t[]=new byte[len];
+                            for(int i=0;i<len;i++)
+                                t[i]=buf[i];
+                            ICLogger.i("read cut Event " + len+ " "+ Util.bytesToHexString(t));
+                            int event=getEventFromData(false,t);
+                            if(callback!=null){
+                                callback.onInputEventRecevied(EVENT_TYPE_CUT,event);
+                            }
+                        }
+                    }
+                }catch (Exception e){
+                    ICLogger.e(e.getMessage(),e);
+                }
+
+            }else{
+                ICLogger.e("no CutDev cutEventThread exit! ");
+            }
+        }
+    } ;
+
+    private InputEventReceiver callback=null;
+
+    public InputEventReader(InputEventReceiver ier){
+        callback=ier;
+        ThreadPool.getInstance().submitThreadPool(antiEventThread);
+        ThreadPool.getInstance().submitThreadPool(cutEventThread);
+
+    }
+
+    public interface InputEventReceiver{
+        public void onInputEventRecevied(int type,int event);
+    }
+}