Home | History | Annotate | Download | only in peripheralprofile
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.cts.verifier.audio.peripheralprofile;
     18 
     19 import android.os.Environment;
     20 import androidx.annotation.Nullable;
     21 import android.util.Log;
     22 import android.util.Xml;
     23 
     24 import org.xml.sax.Attributes;
     25 import org.xml.sax.InputSource;
     26 import org.xml.sax.SAXException;
     27 import org.xml.sax.XMLReader;
     28 import org.xml.sax.helpers.DefaultHandler;
     29 
     30 import java.io.ByteArrayInputStream;
     31 import java.io.File;
     32 import java.io.FileInputStream;
     33 import java.io.FileNotFoundException;
     34 import java.io.FileWriter;
     35 import java.io.IOException;
     36 import java.io.InputStream;
     37 import java.util.ArrayList;
     38 
     39 import javax.xml.parsers.ParserConfigurationException;
     40 import javax.xml.parsers.SAXParser;
     41 import javax.xml.parsers.SAXParserFactory;
     42 
     43 public class ProfileManager {
     44     private static final String TAG = "ProfileManager";
     45     private static final boolean DEBUG = false;
     46 
     47     private static final String mBuiltInprofiles =
     48         "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" +
     49         "<ProfileList Version=\"1.0.0\">" +
     50             "<PeripheralProfile ProfileName=\"Audio Interface\" ProfileDescription=\"Presonus AudioVox 44VSL\" ProductName=\"USB-Audio - AudioBox 44 VSL\">" +
     51                 "<OutputDevInfo ChanCounts=\"2,4\" ChanPosMasks=\"12\" ChanIndexMasks=\"15\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\" />" +
     52                 "<InputDevInfo ChanCounts=\"1,2,4\" ChanPosMasks=\"12,16\" ChanIndexMasks=\"15\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\" />" +
     53             "</PeripheralProfile>" +
     54             "<PeripheralProfile ProfileName=\"AudioBox 22VSL\" ProfileDescription=\"Presonus AudioBox 22VSL\" ProductName=\"USB-Audio - AudioBox 22 VSL\">" +
     55                 "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\" />" +
     56                 "<InputDevInfo ChanCounts=\"1,2\" ChanPosMasks=\"12,16\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000,88200,96000\" />" +
     57             "</PeripheralProfile>" +
     58             "<PeripheralProfile ProfileName=\"AudioBox USB\" ProfileDescription=\"Presonus AudioBox USB\" ProductName=\"USB-Audio - AudioBox USB\">" +
     59                 "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000\" />" +
     60                 "<InputDevInfo ChanCounts=\"1,2\" ChanPosMasks=\"12,16\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"44100,48000\" />" +
     61             "</PeripheralProfile>" +
     62             "<PeripheralProfile ProfileName=\"Pixel USB-C Dongle + Wired Analog Headset\" ProfileDescription=\"Reference USB Dongle\" ProductName=\"USB-Audio - USB-C to 3.5mm-Headphone Adapte\">" +
     63                 "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"48000\" />" +
     64                 "<InputDevInfo ChanCounts=\"1,2\" ChanPosMasks=\"12,16\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"48000\" />" +
     65                 "<ButtonInfo HasBtnA=\"1\" HasBtnB=\"1\" HasBtnC=\"1\" />" +
     66             "</PeripheralProfile>" +
     67             "<PeripheralProfile ProfileName=\"HTC Dongle\" ProfileDescription=\"Type-C to 3.5mm Headphone\" ProductName=\"USB-Audio - HTC Type-C to 3.5mm Headphone J\">" +
     68                 "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"48000\" />" +
     69                 "<InputDevInfo ChanCounts=\"1,2\" ChanPosMasks=\"12,16\" ChanIndexMasks=\"3\" Encodings=\"4\" SampleRates=\"48000\"/>" +
     70                 "<ButtonInfo HasBtnA=\"1\" HasBtnB=\"1\" HasBtnC=\"1\" />" +
     71             "</PeripheralProfile>" +
     72             "<PeripheralProfile ProfileName=\"JBL Reflect Aware\" ProfileDescription=\"JBL Reflect Aware\" ProductName=\"USB-Audio - JBL Reflect Aware\">" +
     73                 "<OutputDevInfo ChanCounts=\"2\" ChanPosMasks=\"12\" ChanIndexMasks=\"3\" Encodings=\"2\" SampleRates=\"44100,48000\" />" +
     74                 "<InputDevInfo ChanCounts=\"1\" ChanPosMasks=\"16\" ChanIndexMasks=\"1\" Encodings=\"2\" SampleRates=\"44100,48000\" />" +
     75                 "<ButtonInfo HasBtnA=\"1\" HasBtnB=\"1\" HasBtnC=\"1\" />" +
     76             "</PeripheralProfile>" +
     77         "</ProfileList>";
     78 
     79     // XML Tags and Attributes
     80     private final static String kTag_ProfileList = "ProfileList";
     81     private final static String kAttrName_Version = "Version";
     82     private final static String kValueStr_Version = "1.0.0";
     83 
     84     private final ArrayList<PeripheralProfile> mProfiles =
     85         new ArrayList<PeripheralProfile>();
     86 
     87     private PeripheralProfile mParsingProfile = null;
     88 
     89     public boolean addProfile(PeripheralProfile profile) {
     90         mProfiles.add(profile);
     91 
     92         return true;
     93     }
     94 
     95     private class ProfileLoader extends DefaultHandler {
     96         @Override
     97         public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
     98             if (localName.equals(kTag_ProfileList)) {
     99                 // Maybe check the version here.
    100             } else if (localName.equals(PeripheralProfile.kTag_Profile)){
    101                 mParsingProfile = new PeripheralProfile(null, null, null, null, null);
    102                 mParsingProfile.startElement(namespaceURI, localName, qName, atts);
    103             } else {
    104                 mParsingProfile.startElement(namespaceURI, localName, qName, atts);
    105             }
    106         }
    107 
    108         @Override
    109         public void endElement(String uri, String localName, String qName) {
    110             if (localName.equals(kTag_ProfileList)) {
    111                 // Version Checking here maybe?
    112             } else if (localName.equals(PeripheralProfile.kTag_Profile)){
    113                 mProfiles.add(mParsingProfile);
    114                 mParsingProfile = null;
    115             }
    116         }
    117     }
    118 
    119     @Override
    120     public String toString() {
    121         return super.toString();
    122     }
    123 
    124     public boolean loadProfiles(InputStream inStream) {
    125         SAXParserFactory spf = SAXParserFactory.newInstance();
    126         SAXParser sp;
    127         try {
    128             sp = spf.newSAXParser();
    129             XMLReader xr = sp.getXMLReader();
    130             xr.setContentHandler(new ProfileLoader());
    131             xr.parse(new InputSource(inStream));
    132         } catch (ParserConfigurationException e) {
    133             e.printStackTrace();
    134         } catch (SAXException e) {
    135             e.printStackTrace();
    136         } catch (IOException e) {
    137             e.printStackTrace();
    138         }
    139 
    140         return true;
    141     }
    142 
    143     public boolean loadProfiles(String profilesXML) {
    144         mProfiles.clear();
    145 
    146         return loadProfiles(new ByteArrayInputStream(profilesXML.getBytes()));
    147     }
    148 
    149     public boolean loadProfiles() {
    150         return loadProfiles(mBuiltInprofiles);
    151     }
    152 
    153     //
    154     // Access
    155     //
    156     public ArrayList<PeripheralProfile> getProfiles() { return mProfiles; }
    157 
    158     public int getNumProfiles() {
    159         return mProfiles.size();
    160     }
    161     public PeripheralProfile getProfile(int index) {
    162         return mProfiles.get(index);
    163     }
    164 
    165     @Nullable
    166     public PeripheralProfile getProfile(String productName) {
    167         for(PeripheralProfile profile : mProfiles) {
    168             if (productName.equals(profile.getProductName())) {
    169                 return profile;
    170             }
    171         }
    172         return null;
    173     }
    174 }
    175