blob: 97719fd11cc157d5a399cfa298325feee9164614 [file] [log] [blame]
/*
* Copyright 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.input.cts.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.hardware.input.InputManager;
import android.os.SystemClock;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Log;
import android.view.InputDevice;
import com.android.cts.input.HidDevice;
import com.android.cts.input.HidResultData;
import com.android.cts.input.HidTestData;
import com.android.cts.input.HidVibratorTestData;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
public class InputHidTestCase extends InputTestCase {
private static final String TAG = "InputHidTestCase";
// Sync with linux uhid_event_type::UHID_OUTPUT
private static final byte UHID_EVENT_TYPE_UHID_OUTPUT = 6;
private HidDevice mHidDevice;
private int mDeviceId;
private final int mRegisterResourceId;
InputHidTestCase(int registerResourceId) {
super(registerResourceId);
mRegisterResourceId = registerResourceId;
}
/**
* Get a vibrator from input device with specified Vendor Id and Product Id.
* @return Vibrator object in specified InputDevice
*/
private Vibrator getVibrator() {
final InputManager inputManager =
mInstrumentation.getTargetContext().getSystemService(InputManager.class);
final int[] inputDeviceIds = inputManager.getInputDeviceIds();
final int vid = mParser.readVendorId(mRegisterResourceId);
final int pid = mParser.readProductId(mRegisterResourceId);
for (int inputDeviceId : inputDeviceIds) {
final InputDevice inputDevice = inputManager.getInputDevice(inputDeviceId);
Vibrator vibrator = inputDevice.getVibrator();
if (vibrator.hasVibrator() && inputDevice.getVendorId() == vid
&& inputDevice.getProductId() == pid) {
Log.v(TAG, "Input device: " + inputDeviceId + " VendorId: "
+ inputDevice.getVendorId() + " ProductId: " + inputDevice.getProductId());
return vibrator;
}
}
return null;
}
@Override
protected void setUpDevice(int deviceId, String registerCommand) {
mDeviceId = deviceId;
mHidDevice = new HidDevice(mInstrumentation, deviceId, registerCommand);
assertNotNull(mHidDevice != null);
}
@Override
protected void tearDownDevice() {
mHidDevice.close();
}
@Override
protected void testInputDeviceEvents(int resourceId) {
List<HidTestData> tests = mParser.getHidTestData(resourceId);
for (HidTestData testData: tests) {
mCurrentTestCase = testData.name;
// Send all of the HID reports
for (int i = 0; i < testData.reports.size(); i++) {
final String report = testData.reports.get(i);
mHidDevice.sendHidReport(report);
}
verifyEvents(testData.events);
}
}
private boolean verifyReportData(HidVibratorTestData test, HidResultData result) {
for (Map.Entry<Integer, Integer> entry : test.verifyMap.entrySet()) {
final int index = entry.getKey();
final int value = entry.getValue();
if ((result.reportData[index] & 0XFF) != value) {
Log.v(TAG, "index=" + index + " value= " + value
+ "actual= " + (result.reportData[index] & 0XFF));
return false;
}
}
final int ffLeft = result.reportData[test.leftFfIndex] & 0xFF;
final int ffRight = result.reportData[test.rightFfIndex] & 0xFF;
return ffLeft > 0 && ffRight > 0;
}
public void testInputVibratorEvents(int resourceId) {
final List<HidVibratorTestData> tests = mParser.getHidVibratorTestData(resourceId);
for (HidVibratorTestData test : tests) {
assertEquals(test.durations.size(), test.amplitudes.size());
assertTrue(test.durations.size() > 0);
final long timeoutMills;
final long totalVibrations = test.durations.size();
final VibrationEffect effect;
if (test.durations.size() == 1) {
long duration = test.durations.get(0);
int amplitude = test.amplitudes.get(0);
effect = VibrationEffect.createOneShot(duration, amplitude);
// Set timeout to be 2 times of the effect duration.
timeoutMills = duration * 2;
} else {
long[] durations = test.durations.stream().mapToLong(Long::longValue).toArray();
int[] amplitudes = test.amplitudes.stream().mapToInt(Integer::intValue).toArray();
effect = VibrationEffect.createWaveform(
durations, amplitudes, -1);
// Set timeout to be 2 times of the effect total duration.
timeoutMills = Arrays.stream(durations).sum() * 2;
}
final Vibrator vibrator = getVibrator();
assertNotNull(vibrator != null);
// Start vibration
vibrator.vibrate(effect);
final long startTime = SystemClock.elapsedRealtime();
List<HidResultData> results = new ArrayList<>();
int vibrationCount = 0;
// Check the vibration ffLeft and ffRight amplitude to be expected.
while (vibrationCount < totalVibrations
&& SystemClock.elapsedRealtime() - startTime < timeoutMills) {
SystemClock.sleep(1000);
try {
results = mHidDevice.getResults(mDeviceId, UHID_EVENT_TYPE_UHID_OUTPUT);
if (results.size() < totalVibrations) {
continue;
}
vibrationCount = 0;
for (int i = 0; i < results.size(); i++) {
HidResultData result = results.get(i);
if (result.deviceId == mDeviceId && verifyReportData(test, result)) {
int ffLeft = result.reportData[test.leftFfIndex] & 0xFF;
int ffRight = result.reportData[test.rightFfIndex] & 0xFF;
Log.v(TAG, "eventId=" + result.eventId + " reportType="
+ result.reportType + " left=" + ffLeft + " right=" + ffRight);
// Check the amplitudes of FF effect are expected.
if (ffLeft == test.amplitudes.get(vibrationCount)
&& ffRight == test.amplitudes.get(vibrationCount)) {
vibrationCount++;
}
}
}
} catch (IOException ex) {
throw new RuntimeException("Could not get JSON results from HidDevice");
}
}
assertEquals(vibrationCount, totalVibrations);
}
}
}