/*
 * 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.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.server.usb.descriptors.UsbDescriptorParser;

import com.google.common.io.ByteStreams;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.io.InputStream;

/**
 * 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", descriptors);
        return parser;
    }

    /** A Headset has a microphone and a speaker and is a headset.
     * Descriptors for this example show up on lsusb -v with:
     *   bcdDevice           22.80
     * and a UAC1 audio device with the following control interface:
     *       bInterfaceClass         1 Audio
     * ...
     *       bDescriptorSubtype      2 (INPUT_TERMINAL)
     *       bTerminalID             1
     *       wTerminalType      0x0201 Microphone
     * ...
     *       bDescriptorSubtype      3 (OUTPUT_TERMINAL)
     *       bTerminalID            15
     *       wTerminalType      0x0302 Headphones
     */
    @Test
    @SmallTest
    public void testHeadsetDescriptorParser() {
        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_headset);
        assertTrue(parser.hasInput());
        assertTrue(parser.hasOutput());
        assertTrue(parser.isInputHeadset());
        assertTrue(parser.isOutputHeadset());

        assertTrue(parser.hasAudioInterface());
        assertTrue(parser.hasHIDInterface());
        assertFalse(parser.hasStorageInterface());

        assertEquals(parser.getDeviceDescriptor().getDeviceReleaseString(), "22.80");
    }

    /** Headphones have no microphones but are considered a headset.
     * Descriptors for this example show up on lsusb -v with:
     *   bcdDevice           22.80
     * and a UAC1 audio device with the following control interface:
     *       bInterfaceClass         1 Audio
     * ...
     *       bDescriptorSubtype      3 (OUTPUT_TERMINAL)
     *       bTerminalID            15
     *       wTerminalType      0x0302 Headphones
     */
    @Test
    @SmallTest
    public void testHeadphoneDescriptorParser() {
        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_headphones);
        assertFalse(parser.hasInput());
        assertTrue(parser.hasOutput());
        assertFalse(parser.isInputHeadset());
        assertTrue(parser.isOutputHeadset());

        assertTrue(parser.hasAudioInterface());
        assertTrue(parser.hasHIDInterface());
        assertFalse(parser.hasStorageInterface());

        assertEquals(parser.getDeviceDescriptor().getDeviceReleaseString(), "22.80");
    }

    /** Line out with no microphones aren't considered a headset.
     * Descriptors for this example show up on lsusb -v with:
     *     bcdDevice           22.80
     * and the following UAC1 audio control interface
     *  bInterfaceClass         1 Audio
     *  ...
     *   bDescriptorSubtype      3 (OUTPUT_TERMINAL)
     *   bTerminalID            15
     *   wTerminalType      0x0603 Line Connector
     */
    @Test
    @SmallTest
    public void testLineoutDescriptorParser() {
        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_lineout);
        assertFalse(parser.hasInput());
        assertTrue(parser.hasOutput());
        assertFalse(parser.isInputHeadset());
        assertFalse(parser.isOutputHeadset());

        assertTrue(parser.hasAudioInterface());
        assertTrue(parser.hasHIDInterface());
        assertFalse(parser.hasStorageInterface());

        assertEquals(parser.getDeviceDescriptor().getDeviceReleaseString(), "22.80");
    }

    /** An HID-only device shouldn't be considered anything at all.
    /* Descriptors show up on lsusb -v with:
     *   bcdDevice           22.80
     * and a single HID interface,
     *   bInterfaceClass         3 Human Interface Device
     */
    @Test
    @SmallTest
    public void testNothingDescriptorParser() {
        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_nothing);
        assertFalse(parser.hasInput());
        assertFalse(parser.hasOutput());
        assertFalse(parser.isInputHeadset());
        assertFalse(parser.isOutputHeadset());

        assertFalse(parser.hasAudioInterface());
        assertTrue(parser.hasHIDInterface());
        assertFalse(parser.hasStorageInterface());

        assertEquals(parser.getDeviceDescriptor().getDeviceReleaseString(), "22.80");
    }

    /** A USB mass-storage device.
     * Shows up on lsusb -v with:
     *    bcdDevice            2.08
     * and a single interface descriptor,
     *    bInterfaceClass         8 Mass Storage
     */
    @Test
    @SmallTest
    public void testMassStorageDescriptorParser() {
        UsbDescriptorParser parser = loadParser(R.raw.usbdescriptors_massstorage);
        assertFalse(parser.hasInput());
        assertFalse(parser.hasOutput());
        assertFalse(parser.isInputHeadset());
        assertFalse(parser.isOutputHeadset());

        assertFalse(parser.hasAudioInterface());
        assertFalse(parser.hasHIDInterface());
        assertTrue(parser.hasStorageInterface());

        assertEquals(parser.getDeviceDescriptor().getDeviceReleaseString(), "2.08");
    }

}
