下面列出了android.content.res.XmlResourceParser#getDepth() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Reads all signatures at the current depth (within the current provider) from the XML parser.
*/
private static String[] readSignatures(XmlResourceParser parser) throws IOException,
XmlPullParserException {
List<String> signatures = new ArrayList<String>();
int outerDepth = parser.getDepth();
while(XmlUtils.nextElementWithin(parser, outerDepth)) {
if (parser.getName().equals(TAG_SIGNATURE)) {
// Parse the value within the signature tag
String signature = parser.nextText();
signatures.add(signature);
} else {
Log.e(TAG, "Found an element in a webview provider that is not a signature");
}
}
return signatures.toArray(new String[signatures.size()]);
}
/**
* Parses the layout and returns the number of elements added on the homescreen.
*/
protected int parseLayout(int layoutId, ArrayList<Long> screenIds)
throws XmlPullParserException, IOException {
XmlResourceParser parser = mSourceRes.getXml(layoutId);
beginDocument(parser, mRootTag);
final int depth = parser.getDepth();
int type;
HashMap<String, TagParser> tagParserMap = getLayoutElementsMap();
int count = 0;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
count += parseAndAddNode(parser, tagParserMap, screenIds);
}
return count;
}
private ArrayList<Intent> parseIntents(int xml_res) {
ArrayList<Intent> intents = new ArrayList<Intent>();
XmlResourceParser parser = mContext.getResources().getXml(xml_res);
try {
DefaultLayoutParser.beginDocument(parser, DefaultLayoutParser.TAG_RESOLVE);
final int depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
} else if (DefaultLayoutParser.TAG_FAVORITE.equals(parser.getName())) {
final String uri = DefaultLayoutParser.getAttributeValue(
parser, DefaultLayoutParser.ATTR_URI);
intents.add(Intent.parseUri(uri, 0));
}
}
} catch (URISyntaxException | XmlPullParserException | IOException e) {
Log.e(TAG, "Unable to parse " + xml_res, e);
} finally {
parser.close();
}
return intents;
}
@Override
public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
IOException {
final int groupDepth = parser.getDepth();
int type;
long addedId = -1;
while ((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > groupDepth) {
if (type != XmlPullParser.START_TAG || addedId > -1) {
continue;
}
final String fallback_item_name = parser.getName();
if (TAG_FAVORITE.equals(fallback_item_name)) {
addedId = mChildParser.parseAndAdd(parser);
}
}
return addedId;
}
/**
* Parses the layout and returns the number of elements added on the homescreen.
*/
private int parseLayout(int layoutId, ArrayList<Long> screenIds)
throws XmlPullParserException, IOException {
XmlResourceParser parser = mSourceRes.getXml(layoutId);
beginDocument(parser, mRootTag);
final int depth = parser.getDepth();
int type;
HashMap<String, TagParser> tagParserMap = getLayoutElementsMap();
int count = 0;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
count += parseAndAddNode(parser, tagParserMap, screenIds);
}
return count;
}
@Override
public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
IOException {
final int groupDepth = parser.getDepth();
int type;
long addedId = -1;
while ((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > groupDepth) {
if (type != XmlPullParser.START_TAG || addedId > -1) {
continue;
}
final String fallback_item_name = parser.getName();
if (TAG_FAVORITE.equals(fallback_item_name)) {
addedId = mChildParser.parseAndAdd(parser);
} else {
Log.e(TAG, "Fallback groups can contain only favorites, found "
+ fallback_item_name);
}
}
return addedId;
}
private PinSet parsePinSet(XmlResourceParser parser)
throws IOException, XmlPullParserException, ParserException {
String expirationDate = parser.getAttributeValue(null, "expiration");
long expirationTimestampMilis = Long.MAX_VALUE;
if (expirationDate != null) {
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
Date date = sdf.parse(expirationDate);
if (date == null) {
throw new ParserException(parser, "Invalid expiration date in pin-set");
}
expirationTimestampMilis = date.getTime();
} catch (ParseException e) {
throw new ParserException(parser, "Invalid expiration date in pin-set", e);
}
}
int outerDepth = parser.getDepth();
Set<Pin> pins = new ArraySet<>();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
String tagName = parser.getName();
if (tagName.equals("pin")) {
pins.add(parsePin(parser));
} else {
XmlUtils.skipCurrentTag(parser);
}
}
return new PinSet(pins, expirationTimestampMilis);
}
private Collection<CertificatesEntryRef> parseTrustAnchors(XmlResourceParser parser,
boolean defaultOverridePins)
throws IOException, XmlPullParserException, ParserException {
int outerDepth = parser.getDepth();
List<CertificatesEntryRef> anchors = new ArrayList<>();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
String tagName = parser.getName();
if (tagName.equals("certificates")) {
anchors.add(parseCertificatesEntry(parser, defaultOverridePins));
} else {
XmlUtils.skipCurrentTag(parser);
}
}
return anchors;
}
/**
* 解析Application节点
*/
private void parseApplication(XmlResourceParser parser) throws IOException, XmlPullParserException {
String name = parser.getAttributeValue(ANDROID_RESOURCES, "name");
applicationClass = buildClassName(pkg, name);
final int innerDepth = parser.getDepth();
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("activity")) {
// Activity Info
ComponentBean activity = parseComponent(parser);
activities.add(activity);
} else if (tagName.equals("receiver")) {
// Recevier Info
ComponentBean receiver = parseComponent(parser);
receivers.add(receiver);
} else if (tagName.equals("service")) {
// Service Info
ComponentBean service = parseComponent(parser);
services.add(service);
} else if (tagName.equals("provider")) {
// Providers
ComponentBean provider = parseComponent(parser);
providers.add(provider);
}
}
}
/**
* 解析Activity、Service、Recevier等组件节点
*/
private ComponentBean parseComponent(XmlResourceParser parser) throws IOException, XmlPullParserException {
ComponentBean bean = new ComponentBean();
String name = parser.getAttributeValue(ANDROID_RESOURCES, "name");
bean.className = buildClassName(pkg, name);
int outerDepth = parser.getDepth();
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
continue;
}
String tagName = parser.getName();
if (tagName.equals("intent-filter")) {
IntentFilter intentFilter = parseIntent(parser);
if (intentFilter != null) {
bean.intentFilters.add(intentFilter);
}
}
}
return bean;
}
@Override
public long parseAndAdd(XmlResourceParser parser)
throws XmlPullParserException, IOException {
final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(className)) {
return -1;
}
mValues.put(Favorites.SPANX, getAttributeValue(parser, ATTR_SPAN_X));
mValues.put(Favorites.SPANY, getAttributeValue(parser, ATTR_SPAN_Y));
mValues.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPWIDGET);
// Read the extras
Bundle extras = new Bundle();
int widgetDepth = parser.getDepth();
int type;
while ((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > widgetDepth) {
if (type != XmlPullParser.START_TAG) {
continue;
}
if (TAG_EXTRA.equals(parser.getName())) {
String key = getAttributeValue(parser, ATTR_KEY);
String value = getAttributeValue(parser, ATTR_VALUE);
if (key != null && value != null) {
extras.putString(key, value);
} else {
throw new RuntimeException("Widget extras must have a key and value");
}
} else {
throw new RuntimeException("Widgets can contain only extras");
}
}
return verifyAndInsert(new ComponentName(packageName, className), extras);
}
private Collection<CertificatesEntryRef> parseTrustAnchors(XmlResourceParser parser,
boolean defaultOverridePins)
throws IOException, XmlPullParserException, ParserException {
int outerDepth = parser.getDepth();
List<CertificatesEntryRef> anchors = new ArrayList<>();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
String tagName = parser.getName();
if (tagName.equals("certificates")) {
anchors.add(parseCertificatesEntry(parser, defaultOverridePins));
} else {
XmlUtils.skipCurrentTag(parser);
}
}
return anchors;
}
private List<Pair<NetworkSecurityConfig.Builder, Set<Domain>>> parseConfigEntry(
XmlResourceParser parser, Set<String> seenDomains,
NetworkSecurityConfig.Builder parentBuilder, int configType)
throws IOException, XmlPullParserException, ParserException {
List<Pair<NetworkSecurityConfig.Builder, Set<Domain>>> builders = new ArrayList<>();
NetworkSecurityConfig.Builder builder = new NetworkSecurityConfig.Builder();
builder.setParent(parentBuilder);
Set<Domain> domains = new ArraySet<>();
boolean seenPinSet = false;
boolean seenTrustAnchors = false;
boolean defaultOverridePins = configType == CONFIG_DEBUG;
String configName = parser.getName();
int outerDepth = parser.getDepth();
// Add this builder now so that this builder occurs before any of its children. This
// makes the final build pass easier.
builders.add(new Pair<>(builder, domains));
// Parse config attributes. Only set values that are present, config inheritence will
// handle the rest.
for (int i = 0; i < parser.getAttributeCount(); i++) {
String name = parser.getAttributeName(i);
if ("hstsEnforced".equals(name)) {
builder.setHstsEnforced(
parser.getAttributeBooleanValue(i,
NetworkSecurityConfig.DEFAULT_HSTS_ENFORCED));
} else if ("cleartextTrafficPermitted".equals(name)) {
builder.setCleartextTrafficPermitted(
parser.getAttributeBooleanValue(i,
NetworkSecurityConfig.DEFAULT_CLEARTEXT_TRAFFIC_PERMITTED));
}
}
// Parse the config elements.
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
String tagName = parser.getName();
if ("domain".equals(tagName)) {
if (configType != CONFIG_DOMAIN) {
throw new ParserException(parser,
"domain element not allowed in " + getConfigString(configType));
}
Domain domain = parseDomain(parser, seenDomains);
domains.add(domain);
} else if ("trust-anchors".equals(tagName)) {
if (seenTrustAnchors) {
throw new ParserException(parser,
"Multiple trust-anchor elements not allowed");
}
builder.addCertificatesEntryRefs(
parseTrustAnchors(parser, defaultOverridePins));
seenTrustAnchors = true;
} else if ("pin-set".equals(tagName)) {
if (configType != CONFIG_DOMAIN) {
throw new ParserException(parser,
"pin-set element not allowed in " + getConfigString(configType));
}
if (seenPinSet) {
throw new ParserException(parser, "Multiple pin-set elements not allowed");
}
builder.setPinSet(parsePinSet(parser));
seenPinSet = true;
} else if ("domain-config".equals(tagName)) {
if (configType != CONFIG_DOMAIN) {
throw new ParserException(parser,
"Nested domain-config not allowed in " + getConfigString(configType));
}
builders.addAll(parseConfigEntry(parser, seenDomains, builder, configType));
} else {
XmlUtils.skipCurrentTag(parser);
}
}
if (configType == CONFIG_DOMAIN && domains.isEmpty()) {
throw new ParserException(parser, "No domain elements in domain-config");
}
return builders;
}
private NetworkSecurityConfig.Builder parseDebugOverridesResource()
throws IOException, XmlPullParserException, ParserException {
Resources resources = mContext.getResources();
String packageName = resources.getResourcePackageName(mResourceId);
String entryName = resources.getResourceEntryName(mResourceId);
int resId = resources.getIdentifier(entryName + "_debug", "xml", packageName);
// No debug-overrides resource was found, nothing to parse.
if (resId == 0) {
return null;
}
NetworkSecurityConfig.Builder debugConfigBuilder = null;
// Parse debug-overrides out of the _debug resource.
XmlResourceParser parser=null;
try {
parser = resources.getXml(resId);
XmlUtils.beginDocument(parser, "network-security-config");
int outerDepth = parser.getDepth();
boolean seenDebugOverrides = false;
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
if ("debug-overrides".equals(parser.getName())) {
if (seenDebugOverrides) {
throw new ParserException(parser, "Only one debug-overrides allowed");
}
if (mDebugBuild) {
debugConfigBuilder =
parseConfigEntry(parser, null, null, CONFIG_DEBUG).get(0).first;
} else {
XmlUtils.skipCurrentTag(parser);
}
seenDebugOverrides = true;
} else {
XmlUtils.skipCurrentTag(parser);
}
}
}
finally {
if (parser!=null) parser.close();
}
return debugConfigBuilder;
}
/**
* Constructor.
* @hide
*/
public SpellCheckerInfo(Context context, ResolveInfo service)
throws XmlPullParserException, IOException {
mService = service;
ServiceInfo si = service.serviceInfo;
mId = new ComponentName(si.packageName, si.name).flattenToShortString();
final PackageManager pm = context.getPackageManager();
int label = 0;
String settingsActivityComponent = null;
XmlResourceParser parser = null;
try {
parser = si.loadXmlMetaData(pm, SpellCheckerSession.SERVICE_META_DATA);
if (parser == null) {
throw new XmlPullParserException("No "
+ SpellCheckerSession.SERVICE_META_DATA + " meta-data");
}
final Resources res = pm.getResourcesForApplication(si.applicationInfo);
final AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
&& type != XmlPullParser.START_TAG) {
}
final String nodeName = parser.getName();
if (!"spell-checker".equals(nodeName)) {
throw new XmlPullParserException(
"Meta-data does not start with spell-checker tag");
}
TypedArray sa = res.obtainAttributes(attrs,
com.android.internal.R.styleable.SpellChecker);
label = sa.getResourceId(com.android.internal.R.styleable.SpellChecker_label, 0);
settingsActivityComponent = sa.getString(
com.android.internal.R.styleable.SpellChecker_settingsActivity);
sa.recycle();
final int depth = parser.getDepth();
// Parse all subtypes
while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth)
&& type != XmlPullParser.END_DOCUMENT) {
if (type == XmlPullParser.START_TAG) {
final String subtypeNodeName = parser.getName();
if (!"subtype".equals(subtypeNodeName)) {
throw new XmlPullParserException(
"Meta-data in spell-checker does not start with subtype tag");
}
final TypedArray a = res.obtainAttributes(
attrs, com.android.internal.R.styleable.SpellChecker_Subtype);
SpellCheckerSubtype subtype = new SpellCheckerSubtype(
a.getResourceId(com.android.internal.R.styleable
.SpellChecker_Subtype_label, 0),
a.getString(com.android.internal.R.styleable
.SpellChecker_Subtype_subtypeLocale),
a.getString(com.android.internal.R.styleable
.SpellChecker_Subtype_languageTag),
a.getString(com.android.internal.R.styleable
.SpellChecker_Subtype_subtypeExtraValue),
a.getInt(com.android.internal.R.styleable
.SpellChecker_Subtype_subtypeId, 0));
mSubtypes.add(subtype);
}
}
} catch (Exception e) {
Slog.e(TAG, "Caught exception: " + e);
throw new XmlPullParserException(
"Unable to create context for: " + si.packageName);
} finally {
if (parser != null) parser.close();
}
mLabel = label;
mSettingsActivityName = settingsActivityComponent;
}
private RestrictionEntry loadRestriction(Context appContext, TypedArray a, XmlResourceParser xml)
throws IOException, XmlPullParserException {
String key = a.getString(R.styleable.RestrictionEntry_key);
int restrictionType = a.getInt(
R.styleable.RestrictionEntry_restrictionType, -1);
String title = a.getString(R.styleable.RestrictionEntry_title);
String description = a.getString(R.styleable.RestrictionEntry_description);
int entries = a.getResourceId(R.styleable.RestrictionEntry_entries, 0);
int entryValues = a.getResourceId(R.styleable.RestrictionEntry_entryValues, 0);
if (restrictionType == -1) {
Log.w(TAG, "restrictionType cannot be omitted");
return null;
}
if (key == null) {
Log.w(TAG, "key cannot be omitted");
return null;
}
RestrictionEntry restriction = new RestrictionEntry(restrictionType, key);
restriction.setTitle(title);
restriction.setDescription(description);
if (entries != 0) {
restriction.setChoiceEntries(appContext, entries);
}
if (entryValues != 0) {
restriction.setChoiceValues(appContext, entryValues);
}
// Extract the default value based on the type
switch (restrictionType) {
case RestrictionEntry.TYPE_NULL: // hidden
case RestrictionEntry.TYPE_STRING:
case RestrictionEntry.TYPE_CHOICE:
restriction.setSelectedString(
a.getString(R.styleable.RestrictionEntry_defaultValue));
break;
case RestrictionEntry.TYPE_INTEGER:
restriction.setIntValue(
a.getInt(R.styleable.RestrictionEntry_defaultValue, 0));
break;
case RestrictionEntry.TYPE_MULTI_SELECT:
int resId = a.getResourceId(R.styleable.RestrictionEntry_defaultValue, 0);
if (resId != 0) {
restriction.setAllSelectedStrings(
appContext.getResources().getStringArray(resId));
}
break;
case RestrictionEntry.TYPE_BOOLEAN:
restriction.setSelectedState(
a.getBoolean(R.styleable.RestrictionEntry_defaultValue, false));
break;
case RestrictionEntry.TYPE_BUNDLE:
case RestrictionEntry.TYPE_BUNDLE_ARRAY:
final int outerDepth = xml.getDepth();
List<RestrictionEntry> restrictionEntries = new ArrayList<>();
while (XmlUtils.nextElementWithin(xml, outerDepth)) {
RestrictionEntry childEntry = loadRestrictionElement(appContext, xml);
if (childEntry == null) {
Log.w(TAG, "Child entry cannot be loaded for bundle restriction " + key);
} else {
restrictionEntries.add(childEntry);
if (restrictionType == RestrictionEntry.TYPE_BUNDLE_ARRAY
&& childEntry.getType() != RestrictionEntry.TYPE_BUNDLE) {
Log.w(TAG, "bundle_array " + key
+ " can only contain entries of type bundle");
}
}
}
restriction.setRestrictions(restrictionEntries.toArray(new RestrictionEntry[
restrictionEntries.size()]));
break;
default:
Log.w(TAG, "Unknown restriction type " + restrictionType);
}
return restriction;
}
@NonNull
private NavDestination inflate(@NonNull Resources res, @NonNull XmlResourceParser parser,
@NonNull AttributeSet attrs) throws XmlPullParserException, IOException {
Navigator navigator = mNavigatorProvider.getNavigator(parser.getName());
final NavDestination dest = navigator.createDestination();
dest.onInflate(mContext, attrs);
final int innerDepth = parser.getDepth() + 1;
int type;
int depth;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& ((depth = parser.getDepth()) >= innerDepth
|| type != XmlPullParser.END_TAG)) {
if (type != XmlPullParser.START_TAG) {
continue;
}
if (depth > innerDepth) {
continue;
}
final String name = parser.getName();
if (TAG_ARGUMENT.equals(name)) {
inflateArgument(res, dest, attrs);
} else if (TAG_DEEP_LINK.equals(name)) {
inflateDeepLink(res, dest, attrs);
} else if (TAG_ACTION.equals(name)) {
inflateAction(res, dest, attrs);
} else if (TAG_INCLUDE.equals(name) && dest instanceof NavGraph) {
final TypedArray a = res.obtainAttributes(attrs, R.styleable.NavInclude);
final int id = a.getResourceId(R.styleable.NavInclude_graph, 0);
((NavGraph) dest).addDestination(inflate(id));
a.recycle();
} else if (dest instanceof NavGraph) {
((NavGraph) dest).addDestination(inflate(res, parser, attrs));
}
}
return dest;
}
@Override
public long parseAndAdd(XmlResourceParser parser)
throws XmlPullParserException, IOException {
final String title;
final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
if (titleResId != 0) {
title = mSourceRes.getString(titleResId);
} else {
title = mContext.getResources().getString(R.string.folder_name);
}
mValues.put(Favorites.TITLE, title);
mValues.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_FOLDER);
mValues.put(Favorites.SPANX, 1);
mValues.put(Favorites.SPANY, 1);
mValues.put(Favorites._ID, mCallback.generateNewItemId());
long folderId = mCallback.insertAndCheck(mDb, mValues);
if (folderId < 0) {
return -1;
}
final ContentValues myValues = new ContentValues(mValues);
ArrayList<Long> folderItems = new ArrayList<Long>();
int type;
int folderDepth = parser.getDepth();
int rank = 0;
while ((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > folderDepth) {
if (type != XmlPullParser.START_TAG) {
continue;
}
mValues.clear();
mValues.put(Favorites.CONTAINER, folderId);
mValues.put(Favorites.RANK, rank);
TagParser tagParser = mFolderElements.get(parser.getName());
if (tagParser != null) {
final long id = tagParser.parseAndAdd(parser);
if (id >= 0) {
folderItems.add(id);
rank++;
}
} else {
throw new RuntimeException("Invalid folder item " + parser.getName());
}
}
long addedId = folderId;
// We can only have folders with >= 2 items, so we need to remove the
// folder and clean up if less than 2 items were included, or some
// failed to add, and less than 2 were actually added
if (folderItems.size() < 2) {
// Delete the folder
Uri uri = Favorites.getContentUri(folderId);
SqlArguments args = new SqlArguments(uri, null, null);
mDb.delete(args.table, args.where, args.args);
addedId = -1;
// If we have a single item, promote it to where the folder
// would have been.
if (folderItems.size() == 1) {
final ContentValues childValues = new ContentValues();
copyInteger(myValues, childValues, Favorites.CONTAINER);
copyInteger(myValues, childValues, Favorites.SCREEN);
copyInteger(myValues, childValues, Favorites.CELLX);
copyInteger(myValues, childValues, Favorites.CELLY);
addedId = folderItems.get(0);
mDb.update(Favorites.TABLE_NAME, childValues,
Favorites._ID + "=" + addedId, null);
}
}
return addedId;
}
@Override
public long parseAndAdd(XmlResourceParser parser)
throws XmlPullParserException, IOException {
final String title;
final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
if (titleResId != 0) {
title = mSourceRes.getString(titleResId);
} else {
title = mContext.getResources().getString(R.string.folder_name);
}
mValues.put(Favorites.TITLE, title);
mValues.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_FOLDER);
mValues.put(Favorites.SPANX, 1);
mValues.put(Favorites.SPANY, 1);
mValues.put(Favorites._ID, mCallback.generateNewItemId());
long folderId = mCallback.insertAndCheck(mDb, mValues);
if (folderId < 0) {
if (LOGD) Log.e(TAG, "Unable to add folder");
return -1;
}
final ContentValues myValues = new ContentValues(mValues);
ArrayList<Long> folderItems = new ArrayList<Long>();
int type;
int folderDepth = parser.getDepth();
int rank = 0;
while ((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > folderDepth) {
if (type != XmlPullParser.START_TAG) {
continue;
}
mValues.clear();
mValues.put(Favorites.CONTAINER, folderId);
mValues.put(Favorites.RANK, rank);
TagParser tagParser = mFolderElements.get(parser.getName());
if (tagParser != null) {
final long id = tagParser.parseAndAdd(parser);
if (id >= 0) {
folderItems.add(id);
rank++;
}
} else {
throw new RuntimeException("Invalid folder item " + parser.getName());
}
}
long addedId = folderId;
// We can only have folders with >= 2 items, so we need to remove the
// folder and clean up if less than 2 items were included, or some
// failed to add, and less than 2 were actually added
if (folderItems.size() < 2) {
// Delete the folder
Uri uri = Favorites.getContentUri(folderId);
SqlArguments args = new SqlArguments(uri, null, null);
mDb.delete(args.table, args.where, args.args);
addedId = -1;
// If we have a single item, promote it to where the folder
// would have been.
if (folderItems.size() == 1) {
final ContentValues childValues = new ContentValues();
copyInteger(myValues, childValues, Favorites.CONTAINER);
copyInteger(myValues, childValues, Favorites.SCREEN);
copyInteger(myValues, childValues, Favorites.CELLX);
copyInteger(myValues, childValues, Favorites.CELLY);
addedId = folderItems.get(0);
mDb.update(LauncherProvider.TABLE_FAVORITES, childValues,
Favorites._ID + "=" + addedId, null);
}
}
return addedId;
}
private void parseNetworkSecurityConfig(XmlResourceParser parser)
throws IOException, XmlPullParserException, ParserException {
Set<String> seenDomains = new HashSet<>();
List<Pair<NetworkSecurityConfig.Builder, Set<Domain>>> builders = new ArrayList<>();
NetworkSecurityConfig.Builder baseConfigBuilder = null;
NetworkSecurityConfig.Builder debugConfigBuilder = null;
boolean seenDebugOverrides = false;
boolean seenBaseConfig = false;
XmlUtils.beginDocument(parser, "network-security-config");
int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
if ("base-config".equals(parser.getName())) {
if (seenBaseConfig) {
throw new ParserException(parser, "Only one base-config allowed");
}
seenBaseConfig = true;
baseConfigBuilder =
parseConfigEntry(parser, seenDomains, null, CONFIG_BASE).get(0).first;
} else if ("domain-config".equals(parser.getName())) {
builders.addAll(
parseConfigEntry(parser, seenDomains, baseConfigBuilder, CONFIG_DOMAIN));
} else if ("debug-overrides".equals(parser.getName())) {
if (seenDebugOverrides) {
throw new ParserException(parser, "Only one debug-overrides allowed");
}
if (mDebugBuild) {
debugConfigBuilder =
parseConfigEntry(parser, null, null, CONFIG_DEBUG).get(0).first;
} else {
XmlUtils.skipCurrentTag(parser);
}
seenDebugOverrides = true;
} else {
XmlUtils.skipCurrentTag(parser);
}
}
// If debug is true and there was no debug-overrides in the file check for an extra
// _debug resource.
if (mDebugBuild && debugConfigBuilder == null) {
debugConfigBuilder = parseDebugOverridesResource();
}
// Use the platform default as the parent of the base config for any values not provided
// there. If there is no base config use the platform default.
NetworkSecurityConfig.Builder platformDefaultBuilder =
NetworkSecurityConfig.getDefaultBuilder(mTargetSdkVersion);
addDebugAnchorsIfNeeded(debugConfigBuilder, platformDefaultBuilder);
if (baseConfigBuilder != null) {
baseConfigBuilder.setParent(platformDefaultBuilder);
addDebugAnchorsIfNeeded(debugConfigBuilder, baseConfigBuilder);
} else {
baseConfigBuilder = platformDefaultBuilder;
}
// Build the per-domain config mapping.
Set<Pair<Domain, NetworkSecurityConfig>> configs = new HashSet<>();
for (Pair<NetworkSecurityConfig.Builder, Set<Domain>> entry : builders) {
NetworkSecurityConfig.Builder builder = entry.first;
Set<Domain> domains = entry.second;
// Set the parent of configs that do not have a parent to the base-config. This can
// happen if the base-config comes after a domain-config in the file.
// Note that this is safe with regards to children because of the order that
// parseConfigEntry returns builders, the parent is always before the children. The
// children builders will not have build called until _after_ their parents have their
// parent set so everything is consistent.
if (builder.getParent() == null) {
builder.setParent(baseConfigBuilder);
}
addDebugAnchorsIfNeeded(debugConfigBuilder, builder);
NetworkSecurityConfig config = builder.build();
for (Domain domain : domains) {
configs.add(new Pair<>(domain, config));
}
}
mDefaultConfig = baseConfigBuilder.build();
mDomainMap = configs;
}