From 55656e4cb923d1aeef4445b3aaa3a6ce3f35c90a Mon Sep 17 00:00:00 2001 From: Siarhei Vishniakou Date: Fri, 31 Mar 2017 17:23:39 -0700 Subject: Fix GamepadTestCase#testButtonA CTS test Hid command, JNI layer: - Removed dependency of the hid device on libandroid_runtime and libutils. Using ALooper from libandroid to process callbacks from /dev/uhid file descriptor. - Switched to using "CREATE2" and "INPUT2" constructs in uhid driver Hid command, Java layer: - Removed delay workarounds, user now responsible for waiting for onInputDeviceChanged notification prior to using the hid commands. UiAutomation: - Added a new executeShellCommandRw function that allows bidirectional communication to shell command platform.xml: - Added uhid permissions to bluetooth stack for /dev/uhid access - CTS test now consistently passes Bug: 34052337 Test: CTS test case invoked with the following command: run cts -t android.hardware.input.cts.tests.GamepadTestCase -m CtsHardwareTestCases --skip-system-status-check com.android.compatibility.common.tradefed.targetprep.NetworkConnectivityChecker Change-Id: Ic916c513b7e652b1e25675f0f38f0f1f3a65d214 --- cmds/hid/src/com/android/commands/hid/Device.java | 26 ++++++++--------------- cmds/hid/src/com/android/commands/hid/Hid.java | 13 +++++++----- 2 files changed, 17 insertions(+), 22 deletions(-) (limited to 'cmds/hid/src') diff --git a/cmds/hid/src/com/android/commands/hid/Device.java b/cmds/hid/src/com/android/commands/hid/Device.java index dbe883bd1136..8c52a8ed1e09 100644 --- a/cmds/hid/src/com/android/commands/hid/Device.java +++ b/cmds/hid/src/com/android/commands/hid/Device.java @@ -29,22 +29,14 @@ import com.android.internal.os.SomeArgs; public class Device { private static final String TAG = "HidDevice"; - // Minimum amount of time to wait before sending input events to a device. Even though we're - // guaranteed that the device has been created and opened by the input system, there's still a - // window in which the system hasn't started reading events out of it. If a stream of events - // begins in during this window (like a button down event) and *then* we start reading, we're - // liable to ignore the whole stream. - private static final int MIN_WAIT_FOR_FIRST_EVENT = 150; - private static final int MSG_OPEN_DEVICE = 1; private static final int MSG_SEND_REPORT = 2; private static final int MSG_CLOSE_DEVICE = 3; - private final int mId; private final HandlerThread mThread; private final DeviceHandler mHandler; - private long mEventTime; + private long mTimeToSend; private final Object mCond = new Object(); @@ -53,7 +45,7 @@ public class Device { } private static native long nativeOpenDevice(String name, int id, int vid, int pid, - byte[] descriptor, MessageQueue queue, DeviceCallback callback); + byte[] descriptor, DeviceCallback callback); private static native void nativeSendReport(long ptr, byte[] data); private static native void nativeCloseDevice(long ptr); @@ -74,22 +66,22 @@ public class Device { args.arg2 = descriptor; args.arg3 = report; mHandler.obtainMessage(MSG_OPEN_DEVICE, args).sendToTarget(); - mEventTime = SystemClock.uptimeMillis() + MIN_WAIT_FOR_FIRST_EVENT; + mTimeToSend = SystemClock.uptimeMillis(); } public void sendReport(byte[] report) { Message msg = mHandler.obtainMessage(MSG_SEND_REPORT, report); - mHandler.sendMessageAtTime(msg, mEventTime); + // if two messages are sent at identical time, they will be processed in order received + mHandler.sendMessageAtTime(msg, mTimeToSend); } public void addDelay(int delay) { - mEventTime += delay; + mTimeToSend = Math.max(SystemClock.uptimeMillis(), mTimeToSend) + delay; } public void close() { Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE); - msg.setAsynchronous(true); - mHandler.sendMessageAtTime(msg, mEventTime + 1); + mHandler.sendMessageAtTime(msg, Math.max(SystemClock.uptimeMillis(), mTimeToSend) + 1); try { synchronized (mCond) { mCond.wait(); @@ -111,8 +103,7 @@ public class Device { case MSG_OPEN_DEVICE: SomeArgs args = (SomeArgs) msg.obj; mPtr = nativeOpenDevice((String) args.arg1, args.argi1, args.argi2, args.argi3, - (byte[]) args.arg2, getLooper().myQueue(), new DeviceCallback()); - nativeSendReport(mPtr, (byte[]) args.arg3); + (byte[]) args.arg2, new DeviceCallback()); pauseEvents(); break; case MSG_SEND_REPORT: @@ -155,6 +146,7 @@ public class Device { } public void onDeviceError() { + Log.e(TAG, "Device error occurred, closing /dev/uhid"); Message msg = mHandler.obtainMessage(MSG_CLOSE_DEVICE); msg.setAsynchronous(true); msg.sendToTarget(); diff --git a/cmds/hid/src/com/android/commands/hid/Hid.java b/cmds/hid/src/com/android/commands/hid/Hid.java index 976a78249bec..234e47f12dee 100644 --- a/cmds/hid/src/com/android/commands/hid/Hid.java +++ b/cmds/hid/src/com/android/commands/hid/Hid.java @@ -16,7 +16,6 @@ package com.android.commands.hid; -import android.os.SystemClock; import android.util.JsonReader; import android.util.JsonToken; import android.util.Log; @@ -91,7 +90,6 @@ public class Hid { } } - private void process(Event e) { final int index = mDevices.indexOfKey(e.getId()); if (index >= 0) { @@ -101,10 +99,16 @@ public class Hid { } else if (Event.COMMAND_REPORT.equals(e.getCommand())) { d.sendReport(e.getReport()); } else { - error("Unknown command \"" + e.getCommand() + "\". Ignoring event."); + if (Event.COMMAND_REGISTER.equals(e.getCommand())) { + error("Device id=" + e.getId() + " is already registered. Ignoring event."); + } else { + error("Unknown command \"" + e.getCommand() + "\". Ignoring event."); + } } - } else { + } else if (Event.COMMAND_REGISTER.equals(e.getCommand())) { registerDevice(e); + } else { + Log.e(TAG, "Unknown device id specified. Ignoring event."); } } @@ -124,7 +128,6 @@ public class Hid { } private static void error(String msg, Exception e) { - System.out.println(msg); Log.e(TAG, msg); if (e != null) { Log.e(TAG, Log.getStackTraceString(e)); -- cgit v1.2.3-59-g8ed1b