1
\$\begingroup\$

I am trying to parse InputEvents of an Android device.

Background:

  • For an android device we have a utility getevent which gives all the touch events that are sent to a device.
  • getevent -l gives all the input events to the device.
  • Every event has 3 fields - EVENT_TYPE, EVENT_CODE and VALUE.
  • EVENT_TYPE can be of following types - EV_KEY, EV_ABS and EV_SYN.
  • In turn, each EVENT_TYPE can have different EVENT_CODES.
    For e.g.
    EV_KEY --> BTN_TOUCH
    EV_ABS --> ABS_MT_TOUCH_MAJOR, ABS_MT_TRACKING_ID, ABS_MT_POSITION_X, ABS_MT_POSITION_Y and
    EV_SYN --> SYN_MT_REPORT, SYN_REPORT
  • And every EVENT_CODE can have a VALUE.
  • Every event is separated by a SYN_REPORT.
  • Each event can itself be a multi touch event be separated by a SYN_MT_REPORT.
  • Every touch starts with a EV_KEY - BTN_TOUCH - DOWN and ends with a EV_KEY - BTN_TOUCH - UP combination. (There are event separators after EV_KEY - BTN_TOUCH - UP viz. SYN_MT_REPORT and SYN_REPORT, but they are not important.

More description: Event Types and Multi Touch events


EV_KEY       BTN_TOUCH            DOWN     <--------------
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011               |
EV_ABS       ABS_MT_TRACKING_ID   00000000               |
EV_ABS       ABS_MT_POSITION_X    0000011c               |---First event,
EV_ABS       ABS_MT_POSITION_Y    000001f4               |   with DOWN and only
EV_SYN       SYN_MT_REPORT        00000000               |   1 finger touched.
EV_SYN       SYN_REPORT           00000000 <--------------
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011 <--------------
EV_ABS       ABS_MT_TRACKING_ID   00000000 <-------      | 
EV_ABS       ABS_MT_POSITION_X    0000011c        |      | 
EV_ABS       ABS_MT_POSITION_Y    000001f4   Finger 1    | 
EV_SYN       SYN_MT_REPORT        00000000 <-------      | 
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013               |---Second event
EV_ABS       ABS_MT_TRACKING_ID   00000001 <-------      |   with 2 mutitouch events
EV_ABS       ABS_MT_POSITION_X    00000076        |      | 
EV_ABS       ABS_MT_POSITION_Y    0000026e   Finger 2    | 
EV_SYN       SYN_MT_REPORT        00000000 <-------      |         
EV_SYN       SYN_REPORT           00000000 <--------------
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011 <--------------  
EV_ABS       ABS_MT_TRACKING_ID   00000000 <-------      |  
EV_ABS       ABS_MT_POSITION_X    00000190        |      |  
EV_ABS       ABS_MT_POSITION_Y    0000035d   Finger 1    |  
EV_SYN       SYN_MT_REPORT        00000000 <-------      |  
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013               |  
EV_ABS       ABS_MT_TRACKING_ID   00000001 <-------      |   
EV_ABS       ABS_MT_POSITION_X    000000f8        |      |   
EV_ABS       ABS_MT_POSITION_Y    000003cf   Finger 2    |---Third event
EV_SYN       SYN_MT_REPORT        00000000 <-------      |   with 3 mulittouch events  
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015               |
EV_ABS       ABS_MT_TRACKING_ID   00000002 <-------      |  
EV_ABS       ABS_MT_POSITION_X    00000251        |      |  
EV_ABS       ABS_MT_POSITION_Y    00000310   Finger 3    |  
EV_SYN       SYN_MT_REPORT        00000000 <-------      |          
EV_SYN       SYN_REPORT           00000000 <--------------  
EV_KEY       BTN_TOUCH            UP       <--------------  
EV_SYN       SYN_MT_REPORT        00000000               |---Final Event,  
EV_SYN       SYN_REPORT           00000000 <--------------   only 1 finger

An example of actual input is:

EV_KEY       BTN_TOUCH            DOWN                
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000011c            
EV_ABS       ABS_MT_POSITION_Y    000001f4            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    00000076            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    000001cd            
EV_ABS       ABS_MT_POSITION_Y    000001a3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000014b            
EV_ABS       ABS_MT_POSITION_Y    0000026e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000b7            
EV_ABS       ABS_MT_POSITION_Y    000002ef            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    00000209            
EV_ABS       ABS_MT_POSITION_Y    00000225            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000015f            
EV_ABS       ABS_MT_POSITION_Y    000002a1            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000c7            
EV_ABS       ABS_MT_POSITION_Y    00000319            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    0000021e            
EV_ABS       ABS_MT_POSITION_Y    00000258            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    00000167            
EV_ABS       ABS_MT_POSITION_Y    000002cc            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000d4            
EV_ABS       ABS_MT_POSITION_Y    00000339            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    00000228            
EV_ABS       ABS_MT_POSITION_Y    0000027d            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000016f            
EV_ABS       ABS_MT_POSITION_Y    000002ed            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000dd            
EV_ABS       ABS_MT_POSITION_Y    0000035e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    00000231            
EV_ABS       ABS_MT_POSITION_Y    000002a1            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    00000178            
EV_ABS       ABS_MT_POSITION_Y    0000030f            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000e4            
EV_ABS       ABS_MT_POSITION_Y    0000037d            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    0000023a            
EV_ABS       ABS_MT_POSITION_Y    000002c2            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    00000182            
EV_ABS       ABS_MT_POSITION_Y    00000329            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000eb            
EV_ABS       ABS_MT_POSITION_Y    0000039b            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    00000242            
EV_ABS       ABS_MT_POSITION_Y    000002de            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000018a            
EV_ABS       ABS_MT_POSITION_Y    00000343            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000ef            
EV_ABS       ABS_MT_POSITION_Y    000003b3            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    00000247            
EV_ABS       ABS_MT_POSITION_Y    000002f6            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000018e            
EV_ABS       ABS_MT_POSITION_Y    00000354            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000f3            
EV_ABS       ABS_MT_POSITION_Y    000003c2            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    0000024d            
EV_ABS       ABS_MT_POSITION_Y    00000306            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    0000018f            
EV_ABS       ABS_MT_POSITION_Y    0000035c            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000f5            
EV_ABS       ABS_MT_POSITION_Y    000003cb            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    0000024f            
EV_ABS       ABS_MT_POSITION_Y    0000030e            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000011            
EV_ABS       ABS_MT_TRACKING_ID   00000000            
EV_ABS       ABS_MT_POSITION_X    00000190            
EV_ABS       ABS_MT_POSITION_Y    0000035d            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000013            
EV_ABS       ABS_MT_TRACKING_ID   00000001            
EV_ABS       ABS_MT_POSITION_X    000000f8            
EV_ABS       ABS_MT_POSITION_Y    000003cf            
EV_SYN       SYN_MT_REPORT        00000000            
EV_ABS       ABS_MT_TOUCH_MAJOR   00000015            
EV_ABS       ABS_MT_TRACKING_ID   00000002            
EV_ABS       ABS_MT_POSITION_X    00000251            
EV_ABS       ABS_MT_POSITION_Y    00000310            
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000            
EV_KEY       BTN_TOUCH            UP                  
EV_SYN       SYN_MT_REPORT        00000000            
EV_SYN       SYN_REPORT           00000000

This is how I am trying to parse it:

package com.xolo;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Main {

    public Main() {

    }

    public void readFile() {
        File file = new File("....../output2.txt");
        List<Event> listOfEvents = null;
        try {
            BufferedReader is = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
            listOfEvents = createEvents(is);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        if (listOfEvents == null) {
            return;
        }

        for (Event event : listOfEvents) {
            System.out.println(event.toString());
        }
    }

    private List<Event> createEvents(BufferedReader is) {
        List<Event> listOfEvents = new ArrayList<>();
        Event event = null;
        String[] tokens;
        try {
            while (true) {
                tokens = is.readLine().split("\\s+");
                if (tokens[1].equalsIgnoreCase("BTN_TOUCH")) {
                    if (tokens[2].equalsIgnoreCase("DOWN")) {
                        event = new Event();
                        continue;
                    } else if (tokens[2].equalsIgnoreCase("UP")) {
                        tokens = is.readLine().split("\\s+");
                        if (tokens[1].equalsIgnoreCase("SYN_MT_REPORT")) {
                            tokens = is.readLine().split("\\s+");
                            if (tokens[1].equalsIgnoreCase("SYN_REPORT")) {
                                return listOfEvents;
                            } else {
                                throw new IllegalArgumentException();
                            }
                        } else {
                            throw new IllegalArgumentException();
                        }
                    }
                } else if (tokens[1].equalsIgnoreCase("ABS_MT_TOUCH_MAJOR")) {
                    event.mtEvents.add(createMTEvent(is));
                } else if (tokens[1].equalsIgnoreCase("SYN_REPORT")) {
                    if (event == null) {
                        throw new IllegalArgumentException();
                    }
                    listOfEvents.add(event);
                    event = new Event();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private MTEvent createMTEvent(BufferedReader is) {
        String[] tokens;
        try {
            tokens = is.readLine().split("\\s+");
            if (!tokens[1].equalsIgnoreCase("ABS_MT_TRACKING_ID")) {
                throw new IllegalArgumentException();
            }
            int id = Integer.valueOf(tokens[2]);

            tokens = is.readLine().split("\\s+");
            if (!tokens[1].equalsIgnoreCase("ABS_MT_POSITION_X")) {
                throw new IllegalArgumentException();
            }
            int x = Integer.parseInt(tokens[2], 16);

            tokens = is.readLine().split("\\s+");
            if (!tokens[1].equalsIgnoreCase("ABS_MT_POSITION_Y")) {
                throw new IllegalArgumentException();
            }
            int y = Integer.parseInt(tokens[2], 16);

            tokens = is.readLine().split("\\s+");
            if (!tokens[1].equalsIgnoreCase("SYN_MT_REPORT")) {
                throw new IllegalArgumentException();
            }

            return new MTEvent(id, x, y);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {

        }
        return null;
    }

    public static void main(String[] args) {
        Main mn = new Main();
        mn.readFile();
    }

    private class MTEvent {
        int trackingID;
        int x;
        int y;

        public MTEvent(int id, int x, int y) {
            this.trackingID = id;
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return "ID: " + trackingID + ", x: " + x + ", y: " + y;
        }
    }

    private class Event {
        List<MTEvent> mtEvents;

        Event() {
            mtEvents = new ArrayList<>();
        }

        @Override
        public String toString() {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("Event: \n");
            for (MTEvent mtEvent : mtEvents) {
                stringBuilder.append(mtEvent.toString()).append("\n");
            }
            return stringBuilder.toString();
        }
    }
}

I tried to separate the individual event and MultiTouch event into separate methods but I don't think I have done it right.

There are a number of things that I want to correct:

  • The parsing logic itself.
  • The Exceptions thrown (any different way to do it?)
  • The splitting of input on space characters (any better way to do it?).
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

Naming

The first point i'd like to raise is the naming of your class i.e. Main. This isn't very descriptive of what your intention is. I'd expect a class like AndroidTouchInputEventsReader that contains a method such as List<Event> parseAndroidTouchEvents(BufferedReader);. Try to think in terms of another programmer using the code, and attempt to make it clear how to use your methods.

class Main -> lets rename this AndroidTouchInputEventsReader
readFile() -> lets change this to List<Event> parseAndroidTouchEvents(BufferedReader)

Then, external to this class we can handle creation of a BufferedReader which could come from a file or in fact any InputStream.

Data

The classes Event being private to the Main class will hide the implementation to the Users. Currently that's OK as you're only printing the Events to the console, but if you think of your class as a way of getting InputEvents in a different part of your program this won't work. In order for the next step to work, I would enable an MTEvent to be updated using setter methods, so I would add set

Parsing

Firstly, I agree with you splitting your lines on spaces. This certainly fits the file format. I would like to have seen you decouple the reading of the file to the parsing of the lines.

A standard way of dealing with parsing a sequence of things in a certain order is a Finite State Machine. A state machine stores a current state, and has a nextState method, that will verify the input and move to the next state. An easy way of doing this in Java is using an enum.

We have the states

current state      | action                                     | next state
INITIAL            | t[1] = BTN_TOUCH &  t[2] =DOWN             | BT_TOUCH-down   
BTN_TOUCH-down     | t[1] = ABS_MT_TOUCH_MAJOR                  | ABS_MT_TOUCH_MAJOR
ABS_MT_TOUCH_MAJOR | read t[1] trackingid, update MTEvent       | ABS_MT_TRACKING_ID 
ABS_MT_TRACKING_ID | read t[1] =x, update MTEvent               | ABS_MT_POSITION_X    
ABS_MT_POSITION_X  |read t[1] =y, update MTEvent                | ABS_MT_POSITION_Y   
ABS_MT_POSITION_Y  | t[1] = (mt_report)                         | SYN_MT_REPORT
SYN_MT_REPORT      | save MTEvent to event 
                   | if t[1] =(touchMajor)                      | ABS_MT_TOUCH_MAJOR
                   | if t[1] = (synReport)                      | SYN_REPORT
SYN_REPORT         | add the event to list. 
                   | t[1]=(touchMajor)                          | ABS_MT_TOUCH_MAJOR
                   | if t[1]=(BTN_TOUCH-up)                     | BTN_TOUCH-up
                   | if (EOF)                                   | END
BTN_TOUCH-UP       | token[1]= SYN_MT_REPORT                    | SYN_MT_REPORT

At each state, you check whether the input line is valid, and update the Event with data. You know at SYN_MT_REPORT you add the MTEvent to the Event's List and at SYN_REPORT you have read the whole event, so you can add the event to the event list. If the line isn't valid, have it throw a parseException that your main read loop can catch.

Based on the input, you also choose the next state, So, when you're in the SYN_MT_REPORT state, when you next call parseLine, the next command could be a ABS_MT_TOUCH_MAJOR or a SYN_REPORT, so in the nextAction method, the line read will decide between each.

  • If you read the SYN_REPORT state, you know that you have a complete event, and to add the list of MTEvent in to the current Event
  • If you read the ABS_MT_TOUCH_MAJOR you know the next state will be ABS_MT_TRACKING_ID for another multi-touch event.

This is how I would create the enum

private static enum TouchEventState {
    INITIAL{
        @Override
        public TouchEventState processLine(String line, int currentLine, Event currentEvent, List<Event> ret) throws ParseException { 
            String[] tokens = tokenize(line);
            if (validateLine(tokens)){
                return BTN_TOUCH_DOWN;
            } else {
                throw new ParseException(line, currentLine);
            }
        }

        boolean validateLine(String[] tokens){
            return tokens.length == COLS
                && tokens[1].equalsIgnoreCase("BTN_TOUCH") 
                &&  tokens[2].equalsIgnoreCase("DOWN");
        }
    },

    BTN_TOUCH_DOWN{
        @Override
        public TouchEventState processLine(String line,int currentLine, Event currentEvent, List<Event> ret) {
            String[] tokens = tokenize(line);
            if (validateLine(tokens){
                return ABS_MT_TOUCH_MAJOR;
            } else {
               throw new ParseException(line, currentLine);
            }
        } 

        boolean validateLine(String[] tokens){
            return tokens.length == COLS 
            && tokens[1].equalsIgnoreCase("ABS_MT_TOUCH_MAJOR");
        }
    },
    ABS_MT_TOUCH_MAJOR
    {
        TouchEventState processLine(String line, int currentLine,
                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {
            //if valid input (you've read ,EV_ABS       ABS_MT_TRACKING_ID   00000000) do 
            //currentMtEvent.setTrackingId(000000);
        }
    },
    ABS_MT_TRACKING_ID   {
        TouchEventState processLine(String line, int currentLine,
                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {
            //if valid input, currentMtEvent.setPosX(tokens[1]);
        }
    },
    ABS_MT_POSITION_X    {
        TouchEventState processLine(String line, int currentLine,
                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {
            //if valid input, currentMtEvent.setPosY(tokens[1]);
            //return ABS_MT_POSITION_Y
        }
    },
    ABS_MT_POSITION_Y    
    {
    // Read this->  EV_SYN       SYN_MT_REPORT        00000000, 
    // currentEvent.addMtEvent(currentMtEvent);
    // return SYN_MT_REPORT

    },
    SYN_MT_REPORT       {
        TouchEventState processLine(String line, int currentLine,
                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {
            //if valid input = SYN_REPORT   , 
            //ret.addEvent(currentEvent);

        }

    },
    SYN_REPORT           {
        TouchEventState processLine(String line, int currentLine,
                Event currentEvent,MTEvent currentMtEvent, List<Event> ret) throws ParseException {
            //if input = ABS_MT_TOUCH_MAJOR -> currentEvent = new Event, currentMtEvent = new currentMtEvent(), return ABS_MT_TOUCH_MAJOR 

            //if EOF return FINISH
        }

    };


 String[] tokenize(String line) {
     return line.split("\\+s");
 }

so your processing loop becomes

while((currentLine = reader.readLine()) != null){
    try{
        state = state.processLine(currentLine, lineNumber, currentEvent, ret);
        ++lineNumber;
    } catch (ParseException pse) {
        // error with the input - out of sync.
        throw pse;
    }
}
return ret;

Conclusion

When creating a new class I would encourage you to think about how it will be used in the rest of the System, or by another User. This leads to better naming and easier to understand code.

When parsing, a sequence, I would always use a loop to read each line of the file, then a state machine to decide what to do with that line.

\$\endgroup\$
6
  • \$\begingroup\$ The states clean the code. However, I want the events to be available in a List. The way you have suggested, I do not know who(where) the MTEvents would be created. \$\endgroup\$
    – yadav_vi
    May 20, 2015 at 15:03
  • \$\begingroup\$ Yes - change processLine method to add a currentMtEvent object. In the ABS_MT_TRACKING_ID state, you set the currentMtEvent to a new Event. In the ABS_MT_TRACKING_ID ABS_MT_POSITION_X and ABS_MT_POSITION_Y states you update the currentMtEvent. In the SYN_MT_REPORT state you add the currentMtEvent to the currentEvent. In the SYN_REPORT state you add the currentEvent to the ret list. \$\endgroup\$
    – rocka147
    May 20, 2015 at 15:10
  • \$\begingroup\$ I can update the example if you wish \$\endgroup\$
    – rocka147
    May 20, 2015 at 15:11
  • \$\begingroup\$ That would be great, and would clarify a lot. \$\endgroup\$
    – yadav_vi
    May 20, 2015 at 15:55
  • \$\begingroup\$ I have added another parameter to the processLine method (i.e. currentMtEvent, i have added psuedo code to the state transitions to show how to handle them \$\endgroup\$
    – rocka147
    May 20, 2015 at 16:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.