summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Daniel Norman <danielnorman@google.com> 2024-01-03 22:18:04 +0000
committer Daniel Norman <danielnorman@google.com> 2024-02-17 01:29:46 +0000
commit211ef98d3fac11bb4351738c17af7efff21c21d0 (patch)
tree39ffc3f7beaebac275c1f1b9691cf3759ca08957
parenta82202a5634f3d0cfc7e17460aa5dc5fe138d32c (diff)
Ensure that the BD's HID descriptor includes the BD usage page (0x41).
Bug: 316036493 Test: (CTS) atest BrailleDisplayTest Test: (Internal) atest BrailleDisplayConnectionTest Change-Id: I191d1df8391d5b803f7fba0d2ee3f21c540abea5
-rw-r--r--services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java60
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java381
2 files changed, 292 insertions, 149 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java b/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java
index 9b27dd347caf..40b6ff01965e 100644
--- a/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/BrailleDisplayConnection.java
@@ -232,9 +232,63 @@ class BrailleDisplayConnection extends IBrailleDisplayConnection.Stub {
}
/** Returns true if this descriptor includes usages for the Braille display usage page 0x41. */
- private static boolean isBrailleDisplay(byte[] descriptor) {
- // TODO: b/316036493 - Check that descriptor includes 0x41 reports.
- return true;
+ @VisibleForTesting
+ static boolean isBrailleDisplay(byte[] descriptor) {
+ boolean foundMatch = false;
+ for (int i = 0; i < descriptor.length; i++) {
+ // HID Spec "6.2.2.2 Short Items" defines that the report descriptor is a collection of
+ // items: each item is a collection of bytes where the first byte defines info about
+ // the type of item and the following 0, 1, 2, or 4 bytes are data bytes for that item.
+ // All items in the HID descriptor are expected to be Short Items.
+ final byte itemInfo = descriptor[i];
+ if (!isHidItemShort(itemInfo)) {
+ Slog.w(LOG_TAG, "Item " + itemInfo + " declares unsupported long type");
+ return false;
+ }
+ final int dataSize = getHidItemDataSize(itemInfo);
+ if (i + dataSize >= descriptor.length) {
+ Slog.w(LOG_TAG, "Item " + itemInfo + " specifies size past the remaining bytes");
+ return false;
+ }
+ // The item we're looking for (usage page declaration) should have size 1.
+ if (dataSize == 1) {
+ final byte itemData = descriptor[i + 1];
+ if (isHidItemBrailleDisplayUsagePage(itemInfo, itemData)) {
+ foundMatch = true;
+ }
+ }
+ // Move to the next item by skipping past all data bytes in this item.
+ i += dataSize;
+ }
+ return foundMatch;
+ }
+
+ private static boolean isHidItemShort(byte itemInfo) {
+ // Info bits 7-4 describe the item type, and HID Spec "6.2.2.3 Long Items" says that long
+ // items always have type bits 1111. Otherwise, the item is a short item.
+ return (itemInfo & 0b1111_0000) != 0b1111_0000;
+ }
+
+ private static int getHidItemDataSize(byte itemInfo) {
+ // HID Spec "6.2.2.2 Short Items" says that info bits 0-1 specify the optional data size:
+ // 0, 1, 2, or 4 bytes.
+ return switch (itemInfo & 0b0000_0011) {
+ case 0b00 -> 0;
+ case 0b01 -> 1;
+ case 0b10 -> 2;
+ default -> 4;
+ };
+ }
+
+ private static boolean isHidItemBrailleDisplayUsagePage(byte itemInfo, byte itemData) {
+ // From HID Spec "6.2.2.7 Global Items"
+ final byte usagePageType = 0b0000_0100;
+ // From HID Usage Tables version 1.2.
+ final byte brailleDisplayUsagePage = 0x41;
+ // HID Spec "6.2.2.2 Short Items" says item info bits 2-7 describe the type and
+ // function of the item.
+ final byte itemType = (byte) (itemInfo & 0b1111_1100);
+ return itemType == usagePageType && itemData == brailleDisplayUsagePage;
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java
index b322dd709c2d..aec3f451fac6 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/BrailleDisplayConnectionTest.java
@@ -17,6 +17,7 @@
package com.android.server.accessibility;
import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -33,17 +34,24 @@ import android.testing.DexmakerShareClassLoaderRule;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.internal.util.HexDump;
+
import com.google.common.truth.Expect;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.io.File;
import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
/**
@@ -51,184 +59,265 @@ import java.util.List;
*
* <p>Prefer adding new tests in CTS where possible.
*/
+@RunWith(Enclosed.class)
public class BrailleDisplayConnectionTest {
- private static final Path NULL_PATH = Path.of("/dev/null");
-
- private BrailleDisplayConnection mBrailleDisplayConnection;
- @Mock
- private BrailleDisplayConnection.NativeInterface mNativeInterface;
- @Mock
- private AccessibilityServiceConnection mServiceConnection;
-
- @Rule
- public final Expect expect = Expect.create();
-
- private Context mContext;
-
- // To mock package-private class
- @Rule
- public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
- new DexmakerShareClassLoaderRule();
-
- @Before
- public void setup() {
- MockitoAnnotations.initMocks(this);
- mContext = InstrumentationRegistry.getInstrumentation().getContext();
- when(mServiceConnection.isConnectedLocked()).thenReturn(true);
- mBrailleDisplayConnection =
- spy(new BrailleDisplayConnection(new Object(), mServiceConnection));
- }
- @Test
- public void defaultNativeScanner_getHidrawNodePaths_returnsHidrawPaths() throws Exception {
- File testDir = mContext.getFilesDir();
- Path hidrawNode0 = Path.of(testDir.getPath(), "hidraw0");
- Path hidrawNode1 = Path.of(testDir.getPath(), "hidraw1");
- Path otherDevice = Path.of(testDir.getPath(), "otherDevice");
- Path[] nodePaths = {hidrawNode0, hidrawNode1, otherDevice};
- try {
- for (Path node : nodePaths) {
- assertThat(node.toFile().createNewFile()).isTrue();
+ public static class ScannerTest {
+ private static final Path NULL_PATH = Path.of("/dev/null");
+
+ private BrailleDisplayConnection mBrailleDisplayConnection;
+ @Mock
+ private BrailleDisplayConnection.NativeInterface mNativeInterface;
+ @Mock
+ private AccessibilityServiceConnection mServiceConnection;
+
+ @Rule
+ public final Expect expect = Expect.create();
+
+ private Context mContext;
+
+ // To mock package-private class
+ @Rule
+ public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+ new DexmakerShareClassLoaderRule();
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = InstrumentationRegistry.getInstrumentation().getContext();
+ when(mServiceConnection.isConnectedLocked()).thenReturn(true);
+ mBrailleDisplayConnection =
+ spy(new BrailleDisplayConnection(new Object(), mServiceConnection));
+ }
+
+ @Test
+ public void defaultNativeScanner_getHidrawNodePaths_returnsHidrawPaths() throws Exception {
+ File testDir = mContext.getFilesDir();
+ Path hidrawNode0 = Path.of(testDir.getPath(), "hidraw0");
+ Path hidrawNode1 = Path.of(testDir.getPath(), "hidraw1");
+ Path otherDevice = Path.of(testDir.getPath(), "otherDevice");
+ Path[] nodePaths = {hidrawNode0, hidrawNode1, otherDevice};
+ try {
+ for (Path node : nodePaths) {
+ assertThat(node.toFile().createNewFile()).isTrue();
+ }
+
+ BrailleDisplayConnection.BrailleDisplayScanner scanner =
+ mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+
+ assertThat(scanner.getHidrawNodePaths(testDir.toPath()))
+ .containsExactly(hidrawNode0, hidrawNode1);
+ } finally {
+ for (Path node : nodePaths) {
+ node.toFile().delete();
+ }
}
+ }
+
+ @Test
+ public void defaultNativeScanner_getReportDescriptor_returnsDescriptor() {
+ int descriptorSize = 4;
+ byte[] descriptor = {0xB, 0xE, 0xE, 0xF};
+ when(mNativeInterface.getHidrawDescSize(anyInt())).thenReturn(descriptorSize);
+ when(mNativeInterface.getHidrawDesc(anyInt(), eq(descriptorSize))).thenReturn(
+ descriptor);
BrailleDisplayConnection.BrailleDisplayScanner scanner =
mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
- assertThat(scanner.getHidrawNodePaths(testDir.toPath()))
- .containsExactly(hidrawNode0, hidrawNode1);
- } finally {
- for (Path node : nodePaths) {
- node.toFile().delete();
- }
+ assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isEqualTo(descriptor);
}
- }
- @Test
- public void defaultNativeScanner_getReportDescriptor_returnsDescriptor() {
- int descriptorSize = 4;
- byte[] descriptor = {0xB, 0xE, 0xE, 0xF};
- when(mNativeInterface.getHidrawDescSize(anyInt())).thenReturn(descriptorSize);
- when(mNativeInterface.getHidrawDesc(anyInt(), eq(descriptorSize))).thenReturn(descriptor);
+ @Test
+ public void defaultNativeScanner_getReportDescriptor_invalidSize_returnsNull() {
+ when(mNativeInterface.getHidrawDescSize(anyInt())).thenReturn(0);
- BrailleDisplayConnection.BrailleDisplayScanner scanner =
- mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+ BrailleDisplayConnection.BrailleDisplayScanner scanner =
+ mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
- assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isEqualTo(descriptor);
- }
+ assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isNull();
+ }
- @Test
- public void defaultNativeScanner_getReportDescriptor_invalidSize_returnsNull() {
- when(mNativeInterface.getHidrawDescSize(anyInt())).thenReturn(0);
+ @Test
+ public void defaultNativeScanner_getUniqueId_returnsUniq() {
+ String macAddress = "12:34:56:78";
+ when(mNativeInterface.getHidrawUniq(anyInt())).thenReturn(macAddress);
- BrailleDisplayConnection.BrailleDisplayScanner scanner =
- mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+ BrailleDisplayConnection.BrailleDisplayScanner scanner =
+ mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
- assertThat(scanner.getDeviceReportDescriptor(NULL_PATH)).isNull();
- }
+ assertThat(scanner.getUniqueId(NULL_PATH)).isEqualTo(macAddress);
+ }
+
+ @Test
+ public void defaultNativeScanner_getDeviceBusType_busUsb() {
+ when(mNativeInterface.getHidrawBusType(anyInt()))
+ .thenReturn(BrailleDisplayConnection.BUS_USB);
- @Test
- public void defaultNativeScanner_getUniqueId_returnsUniq() {
- String macAddress = "12:34:56:78";
- when(mNativeInterface.getHidrawUniq(anyInt())).thenReturn(macAddress);
+ BrailleDisplayConnection.BrailleDisplayScanner scanner =
+ mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
- BrailleDisplayConnection.BrailleDisplayScanner scanner =
- mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+ assertThat(scanner.getDeviceBusType(NULL_PATH))
+ .isEqualTo(BrailleDisplayConnection.BUS_USB);
+ }
- assertThat(scanner.getUniqueId(NULL_PATH)).isEqualTo(macAddress);
- }
+ @Test
+ public void defaultNativeScanner_getDeviceBusType_busBluetooth() {
+ when(mNativeInterface.getHidrawBusType(anyInt()))
+ .thenReturn(BrailleDisplayConnection.BUS_BLUETOOTH);
- @Test
- public void defaultNativeScanner_getDeviceBusType_busUsb() {
- when(mNativeInterface.getHidrawBusType(anyInt()))
- .thenReturn(BrailleDisplayConnection.BUS_USB);
+ BrailleDisplayConnection.BrailleDisplayScanner scanner =
+ mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
- BrailleDisplayConnection.BrailleDisplayScanner scanner =
- mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+ assertThat(scanner.getDeviceBusType(NULL_PATH))
+ .isEqualTo(BrailleDisplayConnection.BUS_BLUETOOTH);
+ }
- assertThat(scanner.getDeviceBusType(NULL_PATH))
- .isEqualTo(BrailleDisplayConnection.BUS_USB);
- }
+ @Test
+ public void write_bypassesServiceSideCheckWithLargeBuffer_disconnects() {
+ Mockito.doNothing().when(mBrailleDisplayConnection).disconnect();
+ mBrailleDisplayConnection.write(
+ new byte[IBinder.getSuggestedMaxIpcSizeBytes() * 2]);
- @Test
- public void defaultNativeScanner_getDeviceBusType_busBluetooth() {
- when(mNativeInterface.getHidrawBusType(anyInt()))
- .thenReturn(BrailleDisplayConnection.BUS_BLUETOOTH);
+ verify(mBrailleDisplayConnection).disconnect();
+ }
- BrailleDisplayConnection.BrailleDisplayScanner scanner =
- mBrailleDisplayConnection.getDefaultNativeScanner(mNativeInterface);
+ @Test
+ public void write_notConnected_throwsIllegalStateException() {
+ when(mServiceConnection.isConnectedLocked()).thenReturn(false);
- assertThat(scanner.getDeviceBusType(NULL_PATH))
- .isEqualTo(BrailleDisplayConnection.BUS_BLUETOOTH);
- }
+ assertThrows(IllegalStateException.class,
+ () -> mBrailleDisplayConnection.write(new byte[1]));
+ }
- @Test
- public void write_bypassesServiceSideCheckWithLargeBuffer_disconnects() {
- Mockito.doNothing().when(mBrailleDisplayConnection).disconnect();
- mBrailleDisplayConnection.write(
- new byte[IBinder.getSuggestedMaxIpcSizeBytes() * 2]);
+ @Test
+ public void write_unableToCreateWriteStream_disconnects() {
+ Mockito.doNothing().when(mBrailleDisplayConnection).disconnect();
+ // mBrailleDisplayConnection#connectLocked was never called so the
+ // connection's mHidrawNode is still null. This will throw an exception
+ // when attempting to create FileOutputStream on the node.
+ mBrailleDisplayConnection.write(new byte[1]);
- verify(mBrailleDisplayConnection).disconnect();
- }
+ verify(mBrailleDisplayConnection).disconnect();
+ }
- @Test
- public void write_notConnected_throwsIllegalStateException() {
- when(mServiceConnection.isConnectedLocked()).thenReturn(false);
+ // BrailleDisplayConnection#setTestData() is used to enable CTS testing with
+ // test Braille display data, but its own implementation should also be tested
+ // so that issues in this helper don't cause confusing failures in CTS.
+
+ @Test
+ public void setTestData_scannerReturnsTestData() {
+ Bundle bd1 = new Bundle(), bd2 = new Bundle();
+
+ Path path1 = Path.of("/dev/path1"), path2 = Path.of("/dev/path2");
+ bd1.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_HIDRAW_PATH,
+ path1.toString());
+ bd2.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_HIDRAW_PATH,
+ path2.toString());
+ byte[] desc1 = {0xB, 0xE}, desc2 = {0xE, 0xF};
+ bd1.putByteArray(BrailleDisplayController.TEST_BRAILLE_DISPLAY_DESCRIPTOR, desc1);
+ bd2.putByteArray(BrailleDisplayController.TEST_BRAILLE_DISPLAY_DESCRIPTOR, desc2);
+ String uniq1 = "uniq1", uniq2 = "uniq2";
+ bd1.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_UNIQUE_ID, uniq1);
+ bd2.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_UNIQUE_ID, uniq2);
+ int bus1 = BrailleDisplayConnection.BUS_USB, bus2 =
+ BrailleDisplayConnection.BUS_BLUETOOTH;
+ bd1.putBoolean(BrailleDisplayController.TEST_BRAILLE_DISPLAY_BUS_BLUETOOTH,
+ bus1 == BrailleDisplayConnection.BUS_BLUETOOTH);
+ bd2.putBoolean(BrailleDisplayController.TEST_BRAILLE_DISPLAY_BUS_BLUETOOTH,
+ bus2 == BrailleDisplayConnection.BUS_BLUETOOTH);
- assertThrows(IllegalStateException.class,
- () -> mBrailleDisplayConnection.write(new byte[1]));
- }
+ BrailleDisplayConnection.BrailleDisplayScanner scanner =
+ mBrailleDisplayConnection.setTestData(List.of(bd1, bd2));
+
+ expect.that(scanner.getHidrawNodePaths(Path.of("/dev"))).containsExactly(path1, path2);
+ expect.that(scanner.getDeviceReportDescriptor(path1)).isEqualTo(desc1);
+ expect.that(scanner.getDeviceReportDescriptor(path2)).isEqualTo(desc2);
+ expect.that(scanner.getUniqueId(path1)).isEqualTo(uniq1);
+ expect.that(scanner.getUniqueId(path2)).isEqualTo(uniq2);
+ expect.that(scanner.getDeviceBusType(path1)).isEqualTo(bus1);
+ expect.that(scanner.getDeviceBusType(path2)).isEqualTo(bus2);
+ }
- @Test
- public void write_unableToCreateWriteStream_disconnects() {
- Mockito.doNothing().when(mBrailleDisplayConnection).disconnect();
- // mBrailleDisplayConnection#connectLocked was never called so the
- // connection's mHidrawNode is still null. This will throw an exception
- // when attempting to create FileOutputStream on the node.
- mBrailleDisplayConnection.write(new byte[1]);
+ @Test
+ public void setTestData_emptyTestData_returnsNullNodePaths() {
+ BrailleDisplayConnection.BrailleDisplayScanner scanner =
+ mBrailleDisplayConnection.setTestData(List.of());
- verify(mBrailleDisplayConnection).disconnect();
+ expect.that(scanner.getHidrawNodePaths(Path.of("/dev"))).isNull();
+ }
}
- // BrailleDisplayConnection#setTestData() is used to enable CTS testing with
- // test Braille display data, but its own implementation should also be tested
- // so that issues in this helper don't cause confusing failures in CTS.
-
- @Test
- public void setTestData_scannerReturnsTestData() {
- Bundle bd1 = new Bundle(), bd2 = new Bundle();
-
- Path path1 = Path.of("/dev/path1"), path2 = Path.of("/dev/path2");
- bd1.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_HIDRAW_PATH, path1.toString());
- bd2.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_HIDRAW_PATH, path2.toString());
- byte[] desc1 = {0xB, 0xE}, desc2 = {0xE, 0xF};
- bd1.putByteArray(BrailleDisplayController.TEST_BRAILLE_DISPLAY_DESCRIPTOR, desc1);
- bd2.putByteArray(BrailleDisplayController.TEST_BRAILLE_DISPLAY_DESCRIPTOR, desc2);
- String uniq1 = "uniq1", uniq2 = "uniq2";
- bd1.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_UNIQUE_ID, uniq1);
- bd2.putString(BrailleDisplayController.TEST_BRAILLE_DISPLAY_UNIQUE_ID, uniq2);
- int bus1 = BrailleDisplayConnection.BUS_USB, bus2 = BrailleDisplayConnection.BUS_BLUETOOTH;
- bd1.putBoolean(BrailleDisplayController.TEST_BRAILLE_DISPLAY_BUS_BLUETOOTH,
- bus1 == BrailleDisplayConnection.BUS_BLUETOOTH);
- bd2.putBoolean(BrailleDisplayController.TEST_BRAILLE_DISPLAY_BUS_BLUETOOTH,
- bus2 == BrailleDisplayConnection.BUS_BLUETOOTH);
-
- BrailleDisplayConnection.BrailleDisplayScanner scanner =
- mBrailleDisplayConnection.setTestData(List.of(bd1, bd2));
-
- expect.that(scanner.getHidrawNodePaths(Path.of("/dev"))).containsExactly(path1, path2);
- expect.that(scanner.getDeviceReportDescriptor(path1)).isEqualTo(desc1);
- expect.that(scanner.getDeviceReportDescriptor(path2)).isEqualTo(desc2);
- expect.that(scanner.getUniqueId(path1)).isEqualTo(uniq1);
- expect.that(scanner.getUniqueId(path2)).isEqualTo(uniq2);
- expect.that(scanner.getDeviceBusType(path1)).isEqualTo(bus1);
- expect.that(scanner.getDeviceBusType(path2)).isEqualTo(bus2);
- }
+ @RunWith(Parameterized.class)
+ public static class BrailleDisplayDescriptorTest {
+ @Parameterized.Parameters(name = "{0}")
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][]{
+ {"match_BdPage", new byte[]{
+ // Just one item, defines the BD page
+ 0x05, 0x41}},
+ {"match_BdPageAfterAnotherPage", new byte[]{
+ // One item defines another page
+ 0x05, 0x01,
+ // Next item defines BD page
+ 0x05, 0x41}},
+ {"match_BdPageAfterSizeZeroItem", new byte[]{
+ // Size-zero item (last 2 bits are 00)
+ 0x00,
+ // Next item defines BD page
+ 0x05, 0x41}},
+ {"match_BdPageAfterSizeOneItem", new byte[]{
+ // Size-one item (last 2 bits are 01)
+ 0x01, 0x7F,
+ // Next item defines BD page
+ 0x05, 0x41}},
+ {"match_BdPageAfterSizeTwoItem", new byte[]{
+ // Size-two item (last 2 bits are 10)
+ 0x02, 0x7F, 0x7F,
+ 0x05, 0x41}},
+ {"match_BdPageAfterSizeFourItem", new byte[]{
+ // Size-four item (last 2 bits are 11)
+ 0x03, 0x7F, 0x7F, 0x7F, 0x7F,
+ 0x05, 0x41}},
+ {"match_BdPageInBetweenOtherPages", new byte[]{
+ // One item defines another page
+ 0x05, 0x01,
+ // Next item defines BD page
+ 0x05, 0x41,
+ // Next item defines another page
+ 0x05, 0x02}},
+ {"fail_OtherPage", new byte[]{
+ // Just one item, defines another page
+ 0x05, 0x01}},
+ {"fail_BdPageBeforeMissingData", new byte[]{
+ // This item defines BD page
+ 0x05, 0x41,
+ // Next item specifies size-one item (last 2 bits are 01) but
+ // that one data byte is missing; this descriptor is malformed.
+ 0x01}},
+ {"fail_BdPageWithWrongDataSize", new byte[]{
+ // This item defines a page with two-byte ID 0x41 0x7F, not 0x41.
+ 0x06, 0x41, 0x7F}},
+ {"fail_LongItem", new byte[]{
+ // Item has type bits 1111, indicating Long Item.
+ (byte) 0xF0}},
+ });
+ }
- @Test
- public void setTestData_emptyTestData_returnsNullNodePaths() {
- BrailleDisplayConnection.BrailleDisplayScanner scanner =
- mBrailleDisplayConnection.setTestData(List.of());
- expect.that(scanner.getHidrawNodePaths(Path.of("/dev"))).isNull();
+ @Parameterized.Parameter(0)
+ public String mTestName;
+ @Parameterized.Parameter(1)
+ public byte[] mDescriptor;
+
+ @Test
+ public void isBrailleDisplay() {
+ final boolean expectedMatch = mTestName.startsWith("match_");
+ assertWithMessage(
+ "Expected isBrailleDisplay==" + expectedMatch
+ + " for descriptor " + HexDump.toHexString(mDescriptor))
+ .that(BrailleDisplayConnection.isBrailleDisplay(mDescriptor))
+ .isEqualTo(expectedMatch);
+ }
}
}