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;
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 {
// 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() {
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;
//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:
//佩戴
{
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();
);
if ((currenttime - anti_event_receivedTime) >= 2000) {
- send_antiof_cutoff_event();
+ send_antiof_event();
ant_status_event_reported = 0;
return 0;
}
}
+ 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表示 有消息到来,需要开始,
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);
+ }
+ }
/**
* 启动传感器。
*/
--- /dev/null
+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);
+ }
+}