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.settings.intelligence.search.indexing; 18 19 import android.content.Context; 20 import android.content.res.TypedArray; 21 import androidx.annotation.Nullable; 22 import android.text.TextUtils; 23 import android.util.AttributeSet; 24 import android.util.Log; 25 import android.util.TypedValue; 26 27 import com.android.settings.intelligence.R; 28 29 /** 30 * Utility class to parse elements of XML preferences 31 */ 32 public class XmlParserUtils { 33 34 private static final String TAG = "XmlParserUtils"; 35 private static final String NS_APP_RES_AUTO = "http://schemas.android.com/apk/res-auto"; 36 private static final String ENTRIES_SEPARATOR = "|"; 37 getDataKey(Context context, AttributeSet attrs)38 public static String getDataKey(Context context, AttributeSet attrs) { 39 return getData(context, attrs, 40 R.styleable.Preference, 41 R.styleable.Preference_android_key); 42 } 43 getDataTitle(Context context, AttributeSet attrs)44 public static String getDataTitle(Context context, AttributeSet attrs) { 45 return getData(context, attrs, 46 R.styleable.Preference, 47 R.styleable.Preference_android_title); 48 } 49 getDataSummary(Context context, AttributeSet attrs)50 public static String getDataSummary(Context context, AttributeSet attrs) { 51 return getData(context, attrs, 52 R.styleable.Preference, 53 R.styleable.Preference_android_summary); 54 } 55 getDataSummaryOn(Context context, AttributeSet attrs)56 public static String getDataSummaryOn(Context context, AttributeSet attrs) { 57 return getData(context, attrs, 58 R.styleable.CheckBoxPreference, 59 R.styleable.CheckBoxPreference_android_summaryOn); 60 } 61 getDataSummaryOff(Context context, AttributeSet attrs)62 public static String getDataSummaryOff(Context context, AttributeSet attrs) { 63 return getData(context, attrs, 64 R.styleable.CheckBoxPreference, 65 R.styleable.CheckBoxPreference_android_summaryOff); 66 } 67 getDataEntries(Context context, AttributeSet attrs)68 public static String getDataEntries(Context context, AttributeSet attrs) { 69 return getDataEntries(context, attrs, 70 R.styleable.ListPreference, 71 R.styleable.ListPreference_android_entries); 72 } 73 getDataKeywords(Context context, AttributeSet attrs)74 public static String getDataKeywords(Context context, AttributeSet attrs) { 75 final String keywordRes = attrs.getAttributeValue(NS_APP_RES_AUTO, "keywords"); 76 if (TextUtils.isEmpty(keywordRes)) { 77 return null; 78 } 79 // The format of keyword is either a string, or @ followed by int (@123456). 80 // When it's int, we need to look up the actual string from context. 81 if (!keywordRes.startsWith("@")) { 82 // It's a string. 83 return keywordRes; 84 } else { 85 // It's a resource 86 try { 87 final int resValue = Integer.parseInt(keywordRes.substring(1)); 88 return context.getString(resValue); 89 } catch (NumberFormatException e) { 90 Log.w(TAG, "Failed to parse keyword attribute, skipping " + keywordRes); 91 return null; 92 } 93 } 94 } 95 getDataIcon(Context context, AttributeSet attrs)96 public static int getDataIcon(Context context, AttributeSet attrs) { 97 final TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.Preference); 98 final int dataIcon = ta.getResourceId(R.styleable.Preference_android_icon, 0); 99 ta.recycle(); 100 return dataIcon; 101 } 102 103 /** 104 * Returns the fragment name if this preference launches a child fragment. 105 */ getDataChildFragment(Context context, AttributeSet attrs)106 public static String getDataChildFragment(Context context, AttributeSet attrs) { 107 return getData(context, attrs, R.styleable.Preference, 108 R.styleable.Preference_android_fragment); 109 } 110 111 @Nullable getData(Context context, AttributeSet set, int[] attrs, int resId)112 private static String getData(Context context, AttributeSet set, int[] attrs, int resId) { 113 final TypedArray ta = context.obtainStyledAttributes(set, attrs); 114 String data = ta.getString(resId); 115 ta.recycle(); 116 return data; 117 } 118 119 getDataEntries(Context context, AttributeSet set, int[] attrs, int resId)120 private static String getDataEntries(Context context, AttributeSet set, int[] attrs, 121 int resId) { 122 final TypedArray sa = context.obtainStyledAttributes(set, attrs); 123 final TypedValue tv = sa.peekValue(resId); 124 sa.recycle(); 125 String[] data = null; 126 if (tv != null && tv.type == TypedValue.TYPE_REFERENCE) { 127 if (tv.resourceId != 0) { 128 data = context.getResources().getStringArray(tv.resourceId); 129 } 130 } 131 final int count = (data == null) ? 0 : data.length; 132 if (count == 0) { 133 return null; 134 } 135 final StringBuilder result = new StringBuilder(); 136 for (int n = 0; n < count; n++) { 137 result.append(data[n]); 138 result.append(ENTRIES_SEPARATOR); 139 } 140 return result.toString(); 141 } 142 } 143