Monday, July 15, 2013

Week 10: Wrapping up the Mouse Logger

I started off this week by trying to investigate device event files in a new Linux virtual machine I obtained. My startup engineering class provided me with an Amazon EC2 remote instance of Ubuntu LTS 12.04 which was intended to be used as a homogenous development environment. Unfortunately, I ran into the same problem as the virtual machine on the Macbook Pro where mouse event information was not being routed properly to the files due to the virtualized interface.

I then went on to research available libraries that abstract away the lower-level details of getting mouse event data. I had already used the Python binding evdev last week but I was unable to find any way to register mouse clicks with that extension. When I did a little more digging, I found that the preferred library for interfacing with any external device is Xlib. However, I quickly discovered that the library is tedious, outdated, and very poorly documented. For example, the only way to obtain the resolution of the screen is:

width = Display().screen().root.query_pointer().root_x
height = Display().screen().root.query_pointer().root_y

Fortunately, I was able to find a Python library called PyUserInput that abstracts away the complexity of Xlib. I created a class ClickRecorder that inherits PyMouseEvent. This way, I could change the code for the click() and move() functions so they would call WriteInfoLine(), a function I wrote that appends a line containing the timestamp, delta since last move or click, and x and y coordinates to the log file. The function ended up looking like this:

def writeInfoLine(x, y, isClick):
    global MIN_DELTA, lastClick, lastX, lastY, lastMove
    currTime = time.time()
    line = str(currTime) + " (delta "
    if isClick:
        delta = currTime - lastClick
        line += str(delta) + "):\t"
        line += "[" + str(x) + "," + str(y) + "] click\n"
        f.write(line)
        lastClick = currTime
    else:
        delta = currTime - lastMove
        if delta < MIN_DELTA:
            return
        if x == lastX and y == lastY:
            return
       
        line += str(delta) + "):\t"
        line += "[" + str(x) + "," + str(y) + "]\n"
        f.write(line)
        lastX = x
        lastY = y
        lastMove = currTime


I set MIN_DELTA to 0.25 so that mouse movements that are within 250 milliseconds of each other do not get recorded. To finish up my program, I wrapped the import statement for PyUserInput in a try clause that would run a setup.sh script and install the module if an ImportError is caught. With this program completed, we finally have a fully functional robust application for logging mouse events, and the log file formatting will make it easy to extract certain parameters for entropy.

No comments:

Post a Comment