Android Input Software Nightmare
Lets now look at the wonders of Android Input. I was trying to get a touchscreen to work.
The first challenge is that the Android input code was not designed to handle any device that requires calibration. It assumes that the ABS_X/Y coords that come from Linux input is already screen accurate. Sure, that works fine on your factory calibrated capacitive HTC Booyah but it doesn't quite meet the needs of many common technologies like resistive, let alone flexible touchscreens. Okay, nevermind, I implemented a workaround transform and I'm able to get past that.
Next challenge. Lots of odd behavior. CPU utilization at 70-90% just for drawing on the screen. What's going on? Meanwhile, other issues as well. Semi functional touch. Sometimes picks up gestures fine, sometimes not. When drawing slowly, stuff works mostly okay. Draw fast, and a curve becomes a straight line. What's going on, dropping samples? data flooding?
It wasn't the hardware. It wasn't the driver. It wasn't Linux input. So, I started looking at the wonderful Android input layer code.
a) KIQ
588 synchronized (mFirst) {
589 // NOTE: The event timebase absolutely must be the same
590 // timebase as SystemClock.uptimeMillis().
591 //curTime = gotOne ? ev.when : SystemClock.uptimeMillis();
592 final long curTime = SystemClock.uptimeMillis();
593 final long curTimeNano = System.nanoTime();
Hmm. Suspicious.
775 me = ms.generateAbsMotion(di, curTime,
776 curTimeNano, mDisplay,
777 mOrientation, mGlobalMetaState);
Hmm. Generating motion needs to store nanosecond accurate time of every single sample? Ok. Maybe there are good reasons for that.
783 if (me != null) {
784 if (WindowManagerPolicy.WATCH_POINTER) {
785 Log.i(TAG, "Enqueueing: " + me);
786 }
787 addLocked(di, curTimeNano, ev.flags,
663 if (currentMove != null) {
664 if (false) Log.i("InputDevice", "Adding batch x="
665 + reportData[MotionEvent.SAMPLE_X]
666 + " y=" + reportData[MotionEvent.SAMPLE_Y]
667 + " to " + currentMove);
668 currentMove.addBatch(curTime, reportData, metaState);
669 if (WindowManagerPolicy.WATCH_POINTER) {
670 Log.i("KeyInputQueue", "Updating: " + currentMove);
671 }
672 return null;
673 }
um-huh-what? generate motion and then the result is intentionally typically null? Look through the code history. Maybe there's a patch I can pick up that'll fix my problems. Oh, wonderful, nice, confident developments like:
"Maybe fix issue #2145012: Array bounds exception in touch event processing"
This software looks like rasam. Great swearware Googlers. Okay, give up trying to understand their code. Lets see what other people have discovered. Oh, great: Known Issue 7836. Check these excellent cpu utilization numbers just for doing input:
The first challenge is that the Android input code was not designed to handle any device that requires calibration. It assumes that the ABS_X/Y coords that come from Linux input is already screen accurate. Sure, that works fine on your factory calibrated capacitive HTC Booyah but it doesn't quite meet the needs of many common technologies like resistive, let alone flexible touchscreens. Okay, nevermind, I implemented a workaround transform and I'm able to get past that.
Next challenge. Lots of odd behavior. CPU utilization at 70-90% just for drawing on the screen. What's going on? Meanwhile, other issues as well. Semi functional touch. Sometimes picks up gestures fine, sometimes not. When drawing slowly, stuff works mostly okay. Draw fast, and a curve becomes a straight line. What's going on, dropping samples? data flooding?
It wasn't the hardware. It wasn't the driver. It wasn't Linux input. So, I started looking at the wonderful Android input layer code.
a) KIQ
588 synchronized (mFirst) {
589 // NOTE: The event timebase absolutely must be the same
590 // timebase as SystemClock.uptimeMillis().
591 //curTime = gotOne ? ev.when : SystemClock.uptimeMillis();
592 final long curTime = SystemClock.uptimeMillis();
593 final long curTimeNano = System.nanoTime();
Hmm. Suspicious.
775 me = ms.generateAbsMotion(di, curTime,
776 curTimeNano, mDisplay,
777 mOrientation, mGlobalMetaState);
Hmm. Generating motion needs to store nanosecond accurate time of every single sample? Ok. Maybe there are good reasons for that.
783 if (me != null) {
784 if (WindowManagerPolicy.WATCH_POINTER) {
785 Log.i(TAG, "Enqueueing: " + me);
786 }
787 addLocked(di, curTimeNano, ev.flags,
663 if (currentMove != null) {
664 if (false) Log.i("InputDevice", "Adding batch x="
665 + reportData[MotionEvent.SAMPLE_X]
666 + " y=" + reportData[MotionEvent.SAMPLE_Y]
667 + " to " + currentMove);
668 currentMove.addBatch(curTime, reportData, metaState);
669 if (WindowManagerPolicy.WATCH_POINTER) {
670 Log.i("KeyInputQueue", "Updating: " + currentMove);
671 }
672 return null;
673 }
um-huh-what? generate motion and then the result is intentionally typically null? Look through the code history. Maybe there's a patch I can pick up that'll fix my problems. Oh, wonderful, nice, confident developments like:
"Maybe fix issue #2145012: Array bounds exception in touch event processing"
This software looks like rasam. Great swearware Googlers. Okay, give up trying to understand their code. Lets see what other people have discovered. Oh, great: Known Issue 7836. Check these excellent cpu utilization numbers just for doing input:
36% CPU usage on my G1/1.6Nice. The CPU vendors must love Android. But I'm frustrated and exhausted. I'm going to sleep and hope to wake up from this nightware.
Labels: android input