1 /* 2 * Copyright (C) 2018 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 package com.android.car; 17 18 import android.annotation.XmlRes; 19 import android.content.Context; 20 import android.content.res.TypedArray; 21 import android.content.res.XmlResourceParser; 22 import android.util.AttributeSet; 23 import android.util.Log; 24 import android.util.Xml; 25 26 import org.xmlpull.v1.XmlPullParserException; 27 28 import java.io.IOException; 29 import java.util.ArrayList; 30 import java.util.List; 31 32 /* package */ class CarVolumeGroupsHelper { 33 34 private static final String TAG_VOLUME_GROUPS = "volumeGroups"; 35 private static final String TAG_GROUP = "group"; 36 private static final String TAG_CONTEXT = "context"; 37 38 private final Context mContext; 39 private final @XmlRes int mXmlConfiguration; 40 CarVolumeGroupsHelper(Context context, @XmlRes int xmlConfiguration)41 CarVolumeGroupsHelper(Context context, @XmlRes int xmlConfiguration) { 42 mContext = context; 43 mXmlConfiguration = xmlConfiguration; 44 } 45 loadVolumeGroups()46 CarVolumeGroup[] loadVolumeGroups() { 47 List<CarVolumeGroup> carVolumeGroups = new ArrayList<>(); 48 try (XmlResourceParser parser = mContext.getResources().getXml(mXmlConfiguration)) { 49 AttributeSet attrs = Xml.asAttributeSet(parser); 50 int type; 51 // Traverse to the first start tag 52 while ((type=parser.next()) != XmlResourceParser.END_DOCUMENT 53 && type != XmlResourceParser.START_TAG) { 54 } 55 56 if (!TAG_VOLUME_GROUPS.equals(parser.getName())) { 57 throw new RuntimeException("Meta-data does not start with volumeGroups tag"); 58 } 59 int outerDepth = parser.getDepth(); 60 int id = 0; 61 while ((type=parser.next()) != XmlResourceParser.END_DOCUMENT 62 && (type != XmlResourceParser.END_TAG || parser.getDepth() > outerDepth)) { 63 if (type == XmlResourceParser.END_TAG) { 64 continue; 65 } 66 if (TAG_GROUP.equals(parser.getName())) { 67 carVolumeGroups.add(parseVolumeGroup(id, attrs, parser)); 68 id++; 69 } 70 } 71 } catch (Exception e) { 72 Log.e(CarLog.TAG_AUDIO, "Error parsing volume groups configuration", e); 73 } 74 return carVolumeGroups.toArray(new CarVolumeGroup[carVolumeGroups.size()]); 75 } 76 parseVolumeGroup(int id, AttributeSet attrs, XmlResourceParser parser)77 private CarVolumeGroup parseVolumeGroup(int id, AttributeSet attrs, XmlResourceParser parser) 78 throws XmlPullParserException, IOException { 79 int type; 80 81 List<Integer> contexts = new ArrayList<>(); 82 int innerDepth = parser.getDepth(); 83 while ((type=parser.next()) != XmlResourceParser.END_DOCUMENT 84 && (type != XmlResourceParser.END_TAG || parser.getDepth() > innerDepth)) { 85 if (type == XmlResourceParser.END_TAG) { 86 continue; 87 } 88 if (TAG_CONTEXT.equals(parser.getName())) { 89 TypedArray c = mContext.getResources().obtainAttributes( 90 attrs, R.styleable.volumeGroups_context); 91 contexts.add(c.getInt(R.styleable.volumeGroups_context_context, -1)); 92 c.recycle(); 93 } 94 } 95 96 return new CarVolumeGroup(mContext, id, 97 contexts.stream().mapToInt(i -> i).filter(i -> i >= 0).toArray()); 98 } 99 } 100