• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.uxr;
17 
18 import android.content.Context;
19 import android.content.res.TypedArray;
20 import android.content.res.XmlResourceParser;
21 import android.util.AttributeSet;
22 import android.util.Log;
23 import android.util.Xml;
24 import android.view.View;
25 
26 import androidx.annotation.XmlRes;
27 
28 import com.android.car.uxr.CarUxRestrictionsAppConfig.ListConfig;
29 
30 import org.xmlpull.v1.XmlPullParser;
31 import org.xmlpull.v1.XmlPullParserException;
32 
33 import java.io.IOException;
34 import java.util.HashMap;
35 import java.util.Map;
36 
37 /**
38  * A parser that can read an XML resource file and construct the corresponding
39  * {@link CarUxRestrictionsAppConfig} object.
40  *
41  * See car-uxr-client-lib/res/values/attrs.xml for the definition of the relevant XML tags.
42  */
43 public class CarUxRestrictionsAppConfigParser {
44     private static final String TAG = "UxrAppConfigParser";
45 
parseConfig(Context context, @XmlRes int xmlRes)46     static CarUxRestrictionsAppConfig parseConfig(Context context, @XmlRes int xmlRes) {
47         try (XmlResourceParser parser = context.getResources().getXml(xmlRes)) {
48             AttributeSet attrs = Xml.asAttributeSet(parser);
49             Map<Integer, ListConfig> mapping = new HashMap<>();
50 
51             // Skip over the xml version tag
52             parser.next();
53             // Skip over the copyright comment block
54             parser.next();
55             parser.require(XmlPullParser.START_TAG, null, "Mapping");
56             while (parser.next() != XmlPullParser.END_TAG) {
57                 ListConfig listConfig = parseListConfigItem(context, parser, attrs);
58                 mapping.put(listConfig.getId(), listConfig);
59             }
60 
61             return new CarUxRestrictionsAppConfig(mapping);
62         } catch (XmlPullParserException | IOException e) {
63             throw new RuntimeException("Unable to parse CarUxRestrictionsAppConfig", e);
64         }
65     }
66 
parseListConfigItem( Context context, XmlResourceParser parser, AttributeSet attrs)67     private static ListConfig parseListConfigItem(
68             Context context, XmlResourceParser parser, AttributeSet attrs)
69             throws XmlPullParserException, IOException {
70 
71         parser.require(XmlPullParser.START_TAG, null, "ListConfig");
72 
73         TypedArray a = context.obtainStyledAttributes(
74                 attrs, R.styleable.CarUxRestrictionsAppConfig_ListConfig);
75 
76         try {
77             int id = a.getResourceId(R.styleable.CarUxRestrictionsAppConfig_ListConfig_id,
78                     View.NO_ID);
79             if (id == View.NO_ID) {
80                 throw new IllegalStateException("Id field is required");
81             }
82 
83             boolean messageExists = a.hasValue(
84                     R.styleable.CarUxRestrictionsAppConfig_ListConfig_message);
85             int messageResId = a.getResourceId(
86                     R.styleable.CarUxRestrictionsAppConfig_ListConfig_message, View.NO_ID);
87             if (Log.isLoggable(TAG, Log.DEBUG)) {
88                 Log.d(TAG, messageExists
89                         ? "message field is set to " + messageResId
90                         : "message field not specified");
91             }
92 
93             boolean maxLengthExists = a.hasValue(
94                     R.styleable.CarUxRestrictionsAppConfig_ListConfig_maxLength);
95             int maxLengthInt = a.getInt(
96                     R.styleable.CarUxRestrictionsAppConfig_ListConfig_maxLength, 0);
97             if (Log.isLoggable(TAG, Log.DEBUG)) {
98                 Log.d(TAG, maxLengthExists
99                         ? "maxLength field is set to " + maxLengthInt
100                         : "maxLength field not specified");
101             }
102 
103             parser.next();
104             parser.require(XmlPullParser.END_TAG, null, "ListConfig");
105 
106             ListConfig.Builder builder = ListConfig.builder(id);
107             if (maxLengthExists) {
108                 builder.setContentLimit(maxLengthInt);
109             }
110             if (messageExists) {
111                 builder.setScrollingLimitedMessageResId(messageResId);
112             }
113             return builder.build();
114         } finally {
115             a.recycle();
116         }
117     }
118 }
119