Add test for UsbDescriptorParser.java

Tests with descriptors from USB-C to 3.5mm adapter in four cases:
 - line level load connected, no microphone
 - low impedance load with microphone
 - low impedance load without microphone
 - no load attached.

Test: Ran tests without fix for bug 73813676, failed.
Ran tests with fix, all passed.

Change-Id: I067a15a122996e80c70bf287c6982611b6deee01
diff --git a/tests/UsbTests/res/raw/readme.txt b/tests/UsbTests/res/raw/readme.txt
new file mode 100644
index 0000000..62b673c
--- /dev/null
+++ b/tests/UsbTests/res/raw/readme.txt
@@ -0,0 +1,35 @@
+The usbdescriptors_ files contain raw USB descriptors from the Google
+USB-C to 3.5mm adapter, with different loads connected to the 3.5mm
+jack.
+
+usbdescriptors_nothing.bin:
+ - The descriptors when the jack is disconnected.
+
+usbdescriptors_headphones.bin:
+ - The descriptors when the jack is connected to 32-ohm headphones,
+   no microphone.
+   The relevant output terminal is:
+        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
+        bTerminalID            15
+        wTerminalType      0x0302 Headphones
+   
+usbdescriptors_lineout.bin:
+ - The descriptors when the jack is connected to a PC line-in jack.
+   The relevant output terminal is:
+        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
+        bTerminalID            15
+        wTerminalType      0x0603 Line Connector
+
+usbdescriptors_headset.bin:
+ - The descriptors when a headset with microphone and low-impedance
+   headphones are connected.
+   The relevant input terminal is:
+        bDescriptorSubtype      2 (INPUT_TERMINAL)
+        bTerminalID             1
+        wTerminalType      0x0201 Microphone
+   The relevant output terminal is:
+        bDescriptorSubtype      3 (OUTPUT_TERMINAL)
+        bTerminalID            15
+        wTerminalType      0x0302 Headphones
+
+
diff --git a/tests/UsbTests/res/raw/usbdescriptors_headphones.bin b/tests/UsbTests/res/raw/usbdescriptors_headphones.bin
new file mode 100644
index 0000000..e8f2932
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_headphones.bin
Binary files differ
diff --git a/tests/UsbTests/res/raw/usbdescriptors_headset.bin b/tests/UsbTests/res/raw/usbdescriptors_headset.bin
new file mode 100644
index 0000000..30eef2a
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_headset.bin
Binary files differ
diff --git a/tests/UsbTests/res/raw/usbdescriptors_lineout.bin b/tests/UsbTests/res/raw/usbdescriptors_lineout.bin
new file mode 100644
index 0000000..d540d33
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_lineout.bin
Binary files differ
diff --git a/tests/UsbTests/res/raw/usbdescriptors_nothing.bin b/tests/UsbTests/res/raw/usbdescriptors_nothing.bin
new file mode 100644
index 0000000..c318abf
--- /dev/null
+++ b/tests/UsbTests/res/raw/usbdescriptors_nothing.bin
Binary files differ
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java b/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java
new file mode 100644
index 0000000..f323952
--- /dev/null
+++ b/tests/UsbTests/src/com/android/server/usb/UsbDescriptorParserTests.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2018 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 com.android.server.usb;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.server.usb.descriptors.UsbDescriptorParser;
+import com.google.common.io.ByteStreams;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.Exception;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link com.android.server.usb.descriptors.UsbDescriptorParser}
+ */
+@RunWith(AndroidJUnit4.class)
+public class UsbDescriptorParserTests {
+
+    public UsbDescriptorParser loadParser(int resource) {
+        Context c = InstrumentationRegistry.getContext();
+        Resources res = c.getResources();
+        InputStream is = null;
+        try {
+            is = res.openRawResource(resource);
+        } catch (NotFoundException e) {
+            fail("Failed to load resource.");
+        }
+
+        byte[] descriptors = null;
+        try {
+            descriptors = ByteStreams.toByteArray(is);
+        } catch (IOException e) {
+            fail("Failed to convert descriptor strema to bytearray.");
+        }
+
+        // Testing same codepath as UsbHostManager.java:usbDeviceAdded
+        UsbDescriptorParser parser = new UsbDescriptorParser("test-usb-addr");
+        if (!parser.parseDescriptors(descriptors)) {
+            fail("failed to parse descriptors.");
+        }
+        return parser;
+    }
+
+    // A Headset has a microphone and a speaker and is a headset.
+    @Test
+    @SmallTest
+    public void testHeadsetDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_headset);
+        assertTrue(parser.hasInput());
+        assertTrue(parser.hasOutput());
+        assertTrue(parser.isInputHeadset());
+        assertTrue(parser.isOutputHeadset());
+    }
+
+    // Headphones have no microphones but are considered a headset.
+    @Test
+    @SmallTest
+    public void testHeadphoneDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_headphones);
+        assertFalse(parser.hasInput());
+        assertTrue(parser.hasOutput());
+        assertFalse(parser.isInputHeadset());
+        assertTrue(parser.isOutputHeadset());
+    }
+
+    // Line out has no microphones and aren't considered a headset.
+    @Test
+    @SmallTest
+    public void testLineoutDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_lineout);
+        assertFalse(parser.hasInput());
+        assertTrue(parser.hasOutput());
+        assertFalse(parser.isInputHeadset());
+        assertFalse(parser.isOutputHeadset());
+    }
+
+    // An HID-only device shouldn't be considered anything at all.
+    @Test
+    @SmallTest
+    public void testNothingDescriptorParser() {
+        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_nothing);
+        assertFalse(parser.hasInput());
+        assertFalse(parser.hasOutput());
+        assertFalse(parser.isInputHeadset());
+        assertFalse(parser.isOutputHeadset());
+    }
+
+}