aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/parental/ContentRatingsParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/parental/ContentRatingsParser.java')
-rw-r--r--src/com/android/tv/parental/ContentRatingsParser.java453
1 files changed, 278 insertions, 175 deletions
diff --git a/src/com/android/tv/parental/ContentRatingsParser.java b/src/com/android/tv/parental/ContentRatingsParser.java
index b999f938..d9f62473 100644
--- a/src/com/android/tv/parental/ContentRatingsParser.java
+++ b/src/com/android/tv/parental/ContentRatingsParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,318 +16,421 @@
package com.android.tv.parental;
-import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
-import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.res.Resources;
import android.content.res.XmlResourceParser;
+import android.media.tv.TvContentRatingSystemInfo;
import android.net.Uri;
import android.util.Log;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
+import com.android.tv.parental.ContentRatingSystem.Order;
import com.android.tv.parental.ContentRatingSystem.Rating;
import com.android.tv.parental.ContentRatingSystem.SubRating;
-import com.android.tv.parental.ContentRatingSystem.Order;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
public class ContentRatingsParser {
- private final static String TAG = "ContentRatingsParser";
-
- private final static String TAG_RATING_SYSTEM_DEFINITIONS = "rating-system-definitions";
- private final static String TAG_RATING_SYSTEM_DEFINITION = "rating-system-definition";
- private final static String TAG_SUB_RATING_DEFINITION = "sub-rating-definition";
- private final static String TAG_RATING_DEFINITION = "rating-definition";
- private final static String TAG_SUB_RATING = "sub-rating";
- private final static String TAG_ORDER = "order";
- private final static String TAG_RATING = "rating";
-
- private final static String ATTR_ID = "id";
- private final static String ATTR_DISPLAY_NAME = "displayName";
- private final static String ATTR_COUNTRY = "country";
- private final static String ATTR_ICON = "icon";
- private final static String ATTR_DESCRIPTION = "description";
- private final static String ATTR_AGE_HINT = "ageHint";
-
- private ContentRatingsParser() {
- // Prevent instantiation.
+ private static final String TAG = "ContentRatingsParser";
+ private static final boolean DEBUG = false;
+
+ public static final String DOMAIN_SYSTEM_RATINGS = "com.android.tv";
+
+ private static final String TAG_RATING_SYSTEM_DEFINITIONS = "rating-system-definitions";
+ private static final String TAG_RATING_SYSTEM_DEFINITION = "rating-system-definition";
+ private static final String TAG_SUB_RATING_DEFINITION = "sub-rating-definition";
+ private static final String TAG_RATING_DEFINITION = "rating-definition";
+ private static final String TAG_SUB_RATING = "sub-rating";
+ private static final String TAG_RATING = "rating";
+ private static final String TAG_RATING_ORDER = "rating-order";
+
+ private static final String ATTR_VERSION_CODE = "versionCode";
+ private static final String ATTR_NAME = "name";
+ private static final String ATTR_TITLE = "title";
+ private static final String ATTR_COUNTRY = "country";
+ private static final String ATTR_ICON = "icon";
+ private static final String ATTR_DESCRIPTION = "description";
+ private static final String ATTR_CONTENT_AGE_HINT = "contentAgeHint";
+ private static final String VERSION_CODE = "1";
+
+ private final Context mContext;
+ private Resources mResources;
+ private String mXmlVersionCode;
+
+ public ContentRatingsParser(Context context) {
+ mContext = context;
}
- public static List<ContentRatingSystem> parse(Context context, Uri uri) {
+ public List<ContentRatingSystem> parse(TvContentRatingSystemInfo info) {
List<ContentRatingSystem> ratingSystems = null;
- XmlResourceParser parser = null;
+ Uri uri = info.getXmlUri();
+ if (DEBUG) Log.d(TAG, "Parsing rating system for " + uri);
try {
- if (!uri.getScheme().equals(ContentResolver.SCHEME_ANDROID_RESOURCE)) {
- throw new IllegalArgumentException("Invalid URI scheme " + uri);
- }
String packageName = uri.getAuthority();
int resId = (int) ContentUris.parseId(uri);
- parser = context.getPackageManager().getXml(packageName, resId, null);
- if (parser == null) {
- throw new IllegalArgumentException("Cannot get XML with URI " + uri);
+ try (XmlResourceParser parser = mContext.getPackageManager()
+ .getXml(packageName, resId, null)) {
+ if (parser == null) {
+ throw new IllegalArgumentException("Cannot get XML with URI " + uri);
+ }
+ ratingSystems = parse(parser, packageName, !info.isSystemDefined());
}
- ratingSystems = parse(parser, packageName);
} catch (Exception e) {
// Catching all exceptions and print which URI is malformed XML with description
// and stack trace here.
- // TODO: We may want to print message to stdout. see b/16803331
+ // TODO: We may want to print message to stdout.
Log.w(TAG, "Error parsing XML " + uri, e);
- } finally {
- if (parser != null) {
- parser.close();
- }
}
-
return ratingSystems;
}
- private static void assertEquals(int a, int b, String msg) throws XmlPullParserException {
- if (a != b) {
- throw new XmlPullParserException(msg);
+ private List<ContentRatingSystem> parse(XmlResourceParser parser, String domain,
+ boolean isCustom)
+ throws XmlPullParserException, IOException {
+ try {
+ mResources = mContext.getPackageManager().getResourcesForApplication(domain);
+ } catch (NameNotFoundException e) {
+ Log.w(TAG, "Failed to get resources for " + domain, e);
+ mResources = mContext.getResources();
}
- }
-
- private static void assertEquals(String a, String b, String msg) throws XmlPullParserException {
- if (!b.equals(a)) {
- throw new XmlPullParserException(msg);
+ // TODO: find another way to replace the domain the content rating systems defined in TV.
+ // Live TV app provides public content rating systems. Therefore, the domain of
+ // the content rating systems defined in TV app should be com.android.tv instead of
+ // this app's package name.
+ if (domain.equals(mContext.getPackageName())) {
+ domain = DOMAIN_SYSTEM_RATINGS;
}
- }
- private static List<ContentRatingSystem> parse(XmlResourceParser parser, String domain)
- throws XmlPullParserException, IOException {
// Consume all START_DOCUMENT which can appear more than once.
- while (parser.next() == XmlPullParser.START_DOCUMENT);
+ while (parser.next() == XmlPullParser.START_DOCUMENT) {}
int eventType = parser.getEventType();
assertEquals(eventType, XmlPullParser.START_TAG, "Malformed XML: Not a valid XML file");
assertEquals(parser.getName(), TAG_RATING_SYSTEM_DEFINITIONS,
"Malformed XML: Should start with tag " + TAG_RATING_SYSTEM_DEFINITIONS);
- List<ContentRatingSystem> ratingSystems = new ArrayList<ContentRatingSystem>();
- while (true) {
- eventType = parser.nextTag();
+ boolean hasVersionAttr = false;
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ String attr = parser.getAttributeName(i);
+ if (ATTR_VERSION_CODE.equals(attr)) {
+ hasVersionAttr = true;
+ mXmlVersionCode = parser.getAttributeValue(i);
+ }
+ }
+ if (!hasVersionAttr) {
+ throw new XmlPullParserException("Malformed XML: Should contains a version attribute"
+ + " in " + TAG_RATING_SYSTEM_DEFINITIONS);
+ }
- switch (eventType) {
+ List<ContentRatingSystem> ratingSystems = new ArrayList<>();
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ switch (parser.getEventType()) {
case XmlPullParser.START_TAG:
- assertEquals(parser.getName(), TAG_RATING_SYSTEM_DEFINITION,
- "Malformed XML: Should contains " +
- TAG_RATING_SYSTEM_DEFINITION);
- ratingSystems.add(parseRatingSystem(parser, domain));
+ if (TAG_RATING_SYSTEM_DEFINITION.equals(parser.getName())) {
+ ratingSystems.add(parseRatingSystemDefinition(parser, domain, isCustom));
+ } else {
+ checkVersion("Malformed XML: Should contains " +
+ TAG_RATING_SYSTEM_DEFINITION);
+ }
break;
case XmlPullParser.END_TAG:
- assertEquals(parser.getName(), TAG_RATING_SYSTEM_DEFINITIONS,
- "Malformed XML: Should end with tag " +
- TAG_RATING_SYSTEM_DEFINITIONS);
- eventType = parser.next();
- assertEquals(eventType, XmlPullParser.END_DOCUMENT,
- "Malformed XML: Should end with tag " +
- TAG_RATING_SYSTEM_DEFINITIONS);
- return ratingSystems;
- default:
- throw new XmlPullParserException("Malformed XML: Error in " +
- TAG_RATING_SYSTEM_DEFINITIONS);
+ if (TAG_RATING_SYSTEM_DEFINITIONS.equals(parser.getName())) {
+ eventType = parser.next();
+ assertEquals(eventType, XmlPullParser.END_DOCUMENT,
+ "Malformed XML: Should end with tag " +
+ TAG_RATING_SYSTEM_DEFINITIONS);
+ return ratingSystems;
+ } else {
+ checkVersion("Malformed XML: Should end with tag " +
+ TAG_RATING_SYSTEM_DEFINITIONS);
+ }
}
}
+ throw new XmlPullParserException(TAG_RATING_SYSTEM_DEFINITIONS +
+ " section is incomplete or section ending tag is missing");
}
- private static ContentRatingSystem parseRatingSystem(XmlResourceParser parser, String domain)
- throws XmlPullParserException, IOException {
- ContentRatingSystem.Builder builder = new ContentRatingSystem.Builder();
+ private static void assertEquals(int a, int b, String msg) throws XmlPullParserException {
+ if (a != b) {
+ throw new XmlPullParserException(msg);
+ }
+ }
+
+ private static void assertEquals(String a, String b, String msg) throws XmlPullParserException {
+ if (!b.equals(a)) {
+ throw new XmlPullParserException(msg);
+ }
+ }
+
+ private void checkVersion(String msg) throws XmlPullParserException {
+ if (!VERSION_CODE.equals(mXmlVersionCode)) {
+ throw new XmlPullParserException(msg);
+ }
+ }
+
+ private ContentRatingSystem parseRatingSystemDefinition(XmlResourceParser parser, String domain,
+ boolean isCustom) throws XmlPullParserException, IOException {
+ ContentRatingSystem.Builder builder = new ContentRatingSystem.Builder(mContext);
builder.setDomain(domain);
for (int i = 0; i < parser.getAttributeCount(); i++) {
String attr = parser.getAttributeName(i);
switch (attr) {
- case ATTR_ID:
- builder.setId(parser.getAttributeValue(i));
+ case ATTR_NAME:
+ builder.setName(parser.getAttributeValue(i));
break;
case ATTR_COUNTRY:
- builder.setCountry(parser.getAttributeValue(i));
+ for (String country : parser.getAttributeValue(i).split("\\s*,\\s*")) {
+ builder.addCountry(country);
+ }
break;
- case ATTR_DISPLAY_NAME:
- builder.setDisplayName(parser.getAttributeValue(i));
+ case ATTR_TITLE:
+ builder.setTitle(getTitle(parser, i));
break;
case ATTR_DESCRIPTION:
- builder.setDisplayName(parser.getAttributeValue(i));
+ builder.setDescription(
+ mResources.getString(parser.getAttributeResourceValue(i, 0)));
break;
default:
- throw new XmlPullParserException("Malformed XML: Unknown attribute " + attr +
- " in " + TAG_RATING_SYSTEM_DEFINITIONS);
+ checkVersion("Malformed XML: Unknown attribute " + attr + " in " +
+ TAG_RATING_SYSTEM_DEFINITION);
}
}
- while (true) {
- int eventType = parser.nextTag();
- switch (eventType) {
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ switch (parser.getEventType()) {
case XmlPullParser.START_TAG:
String tag = parser.getName();
switch (tag) {
case TAG_RATING_DEFINITION:
- builder.addRatingBuilder(parseRating(parser));
+ builder.addRatingBuilder(parseRatingDefinition(parser));
break;
case TAG_SUB_RATING_DEFINITION:
- builder.addSubRatingBuilder(parseSubRating(parser));
+ builder.addSubRatingBuilder(parseSubRatingDefinition(parser));
break;
- case TAG_ORDER:
+ case TAG_RATING_ORDER:
builder.addOrderBuilder(parseOrder(parser));
break;
default:
- throw new XmlPullParserException("Malformed XML: Unknown tag " + tag +
- " in " + TAG_RATING_SYSTEM_DEFINITION);
+ checkVersion("Malformed XML: Unknown tag " + tag + " in " +
+ TAG_RATING_SYSTEM_DEFINITION);
}
break;
case XmlPullParser.END_TAG:
- assertEquals(parser.getName(), TAG_RATING_SYSTEM_DEFINITION,
- "Malformed XML: Tag mismatch for " + TAG_RATING_SYSTEM_DEFINITION);
- return builder.build();
- default:
- throw new XmlPullParserException("Malformed XML: Tag is expected in " +
- TAG_RATING_SYSTEM_DEFINITION);
+ if (TAG_RATING_SYSTEM_DEFINITION.equals(parser.getName())) {
+ builder.setIsCustom(isCustom);
+ return builder.build();
+ } else {
+ checkVersion("Malformed XML: Tag mismatch for " +
+ TAG_RATING_SYSTEM_DEFINITION);
+ }
}
}
+ throw new XmlPullParserException(TAG_RATING_SYSTEM_DEFINITION +
+ " section is incomplete or section ending tag is missing");
}
- private static Rating.Builder parseRating(XmlResourceParser parser)
+ private Rating.Builder parseRatingDefinition(XmlResourceParser parser)
throws XmlPullParserException, IOException {
Rating.Builder builder = new Rating.Builder();
for (int i = 0; i < parser.getAttributeCount(); i++) {
String attr = parser.getAttributeName(i);
switch (attr) {
- case ATTR_ID:
- builder.setId(parser.getAttributeValue(i));
+ case ATTR_NAME:
+ builder.setName(parser.getAttributeValue(i));
break;
- case ATTR_DISPLAY_NAME:
- builder.setDisplayName(parser.getAttributeValue(i));
+ case ATTR_TITLE:
+ builder.setTitle(getTitle(parser, i));
break;
case ATTR_DESCRIPTION:
- builder.setDisplayName(parser.getAttributeValue(i));
+ builder.setDescription(
+ mResources.getString(parser.getAttributeResourceValue(i, 0)));
break;
case ATTR_ICON:
- builder.setIconUri(Uri.parse(parser.getAttributeValue(i)));
+ builder.setIcon(
+ mResources.getDrawable(parser.getAttributeResourceValue(i, 0), null));
break;
- case ATTR_AGE_HINT:
- int ageHint = -1;
+ case ATTR_CONTENT_AGE_HINT:
+ int contentAgeHint = -1;
try {
- ageHint = Integer.parseInt(parser.getAttributeValue(i));
- } catch (NumberFormatException e) {
+ contentAgeHint = Integer.parseInt(parser.getAttributeValue(i));
+ } catch (NumberFormatException ignored) {
}
- if (ageHint < 0) {
- throw new XmlPullParserException("Malformed XML: " + ATTR_AGE_HINT +
+ if (contentAgeHint < 0) {
+ throw new XmlPullParserException("Malformed XML: " + ATTR_CONTENT_AGE_HINT +
" should be a non-negative number");
}
- builder.setAgeHint(ageHint);
+ builder.setContentAgeHint(contentAgeHint);
break;
default:
- throw new XmlPullParserException("Malformed XML: Unknown attribute " + attr +
- " in " + TAG_RATING_DEFINITION);
+ checkVersion("Malformed XML: Unknown attribute " + attr + " in " +
+ TAG_RATING_DEFINITION);
}
}
- while (true) {
- int eventType = parser.nextTag();
- switch (eventType) {
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ switch (parser.getEventType()) {
case XmlPullParser.START_TAG:
- assertEquals(parser.getName(), TAG_SUB_RATING,
- "Malformed XML: Only " + TAG_SUB_RATING + " is allowed in " +
- TAG_RATING_DEFINITION);
- if (parser.getAttributeCount() != 1 ||
- !ATTR_ID.equals(parser.getAttributeName(0))) {
- throw new XmlPullParserException("Malformed XML: " + TAG_SUB_RATING +
- " should only contain " + ATTR_ID);
- }
- builder.addSubRatingId(parser.getAttributeValue(0));
- eventType = parser.nextTag();
- if (eventType != XmlPullParser.END_TAG ||
- !TAG_SUB_RATING.equals(parser.getName())) {
- throw new XmlPullParserException("Malformed XML: " + TAG_SUB_RATING +
- " has child");
+ if (TAG_SUB_RATING.equals(parser.getName())) {
+ builder = parseSubRating(parser, builder);
+ } else {
+ checkVersion(("Malformed XML: Only " + TAG_SUB_RATING + " is allowed in " +
+ TAG_RATING_DEFINITION));
}
break;
case XmlPullParser.END_TAG:
- assertEquals(parser.getName(), TAG_RATING_DEFINITION,
- "Malformed XML: Tag mismatch for " + TAG_RATING_DEFINITION);
- return builder;
-
- default:
- throw new XmlPullParserException("Malformed XML: Error in " +
- TAG_RATING_DEFINITION);
+ if (TAG_RATING_DEFINITION.equals(parser.getName())) {
+ return builder;
+ } else {
+ checkVersion("Malformed XML: Tag mismatch for " + TAG_RATING_DEFINITION);
+ }
}
}
+ throw new XmlPullParserException(TAG_RATING_DEFINITION +
+ " section is incomplete or section ending tag is missing");
}
- private static SubRating.Builder parseSubRating(XmlResourceParser parser)
+ private SubRating.Builder parseSubRatingDefinition(XmlResourceParser parser)
throws XmlPullParserException, IOException {
SubRating.Builder builder = new SubRating.Builder();
for (int i = 0; i < parser.getAttributeCount(); i++) {
String attr = parser.getAttributeName(i);
switch (attr) {
- case ATTR_ID:
- builder.setId(parser.getAttributeValue(i));
+ case ATTR_NAME:
+ builder.setName(parser.getAttributeValue(i));
break;
- case ATTR_DISPLAY_NAME:
- builder.setDisplayName(parser.getAttributeValue(i));
+ case ATTR_TITLE:
+ builder.setTitle(getTitle(parser, i));
break;
case ATTR_DESCRIPTION:
- builder.setDisplayName(parser.getAttributeValue(i));
+ builder.setDescription(
+ mResources.getString(parser.getAttributeResourceValue(i, 0)));
break;
case ATTR_ICON:
- builder.setIconUri(Uri.parse(parser.getAttributeValue(i)));
+ builder.setIcon(
+ mResources.getDrawable(parser.getAttributeResourceValue(i, 0), null));
break;
default:
- throw new XmlPullParserException("Malformed XML: Unknown attribute " + attr +
- " in " + TAG_SUB_RATING_DEFINITION);
+ checkVersion("Malformed XML: Unknown attribute " + attr + " in " +
+ TAG_SUB_RATING_DEFINITION);
}
}
- assertEquals(parser.nextTag(), XmlPullParser.END_TAG,
- "Malformed XML: " + TAG_SUB_RATING_DEFINITION + " has child");
- assertEquals(parser.getName(), TAG_SUB_RATING_DEFINITION,
- "Malformed XML: " + TAG_SUB_RATING_DEFINITION + " isn't closed");
-
- return builder;
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ switch (parser.getEventType()) {
+ case XmlPullParser.END_TAG:
+ if (TAG_SUB_RATING_DEFINITION.equals(parser.getName())) {
+ return builder;
+ } else {
+ checkVersion("Malformed XML: " + TAG_SUB_RATING_DEFINITION +
+ " isn't closed");
+ }
+ break;
+ default:
+ checkVersion("Malformed XML: " + TAG_SUB_RATING_DEFINITION + " has child");
+ }
+ }
+ throw new XmlPullParserException(TAG_SUB_RATING_DEFINITION +
+ " section is incomplete or section ending tag is missing");
}
- private static Order.Builder parseOrder(XmlResourceParser parser)
+ private Order.Builder parseOrder(XmlResourceParser parser)
throws XmlPullParserException, IOException {
Order.Builder builder = new Order.Builder();
assertEquals(parser.getAttributeCount(), 0,
- "Malformed XML: Attribute isn't allowed in " + TAG_ORDER);
+ "Malformed XML: Attribute isn't allowed in " + TAG_RATING_ORDER);
- while (true) {
- int eventType = parser.nextTag();
- switch (eventType) {
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ switch (parser.getEventType()) {
case XmlPullParser.START_TAG:
- assertEquals(parser.getName(), TAG_RATING,
- "Malformed XML: Only " + TAG_RATING + " is allowed in " +
- TAG_ORDER);
- if (parser.getAttributeCount() != 1 ||
- !ATTR_ID.equals(parser.getAttributeName(0))) {
- throw new XmlPullParserException("Malformed XML: " + TAG_ORDER +
- " should only contain " + ATTR_ID);
- }
- builder.addRatingId(parser.getAttributeValue(0));
- eventType = parser.nextTag();
- if (eventType != XmlPullParser.END_TAG ||
- !TAG_RATING.equals(parser.getName())) {
- throw new XmlPullParserException("Malformed XML: " + TAG_RATING +
- " has child");
+ if (TAG_RATING.equals(parser.getName())) {
+ builder = parseRating(parser, builder);
+ } else {
+ checkVersion("Malformed XML: Only " + TAG_RATING + " is allowed in " +
+ TAG_RATING_ORDER);
}
break;
case XmlPullParser.END_TAG:
- assertEquals(parser.getName(), TAG_ORDER,
- "Malformed XML: Tag mismatch for " + TAG_ORDER);
+ assertEquals(parser.getName(), TAG_RATING_ORDER,
+ "Malformed XML: Tag mismatch for " + TAG_RATING_ORDER);
return builder;
+ }
+ }
+ throw new XmlPullParserException(TAG_RATING_ORDER +
+ " section is incomplete or section ending tag is missing");
+ }
+
+ private Order.Builder parseRating(XmlResourceParser parser, Order.Builder builder)
+ throws XmlPullParserException, IOException {
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ String attr = parser.getAttributeName(i);
+ switch (attr) {
+ case ATTR_NAME:
+ builder.addRatingName(parser.getAttributeValue(i));
+ break;
default:
- throw new XmlPullParserException("Malformed XML: Error in " + TAG_ORDER);
+ checkVersion("Malformed XML: " + TAG_RATING_ORDER + " should only contain "
+ + ATTR_NAME);
}
}
+
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ if (parser.getEventType() == XmlPullParser.END_TAG) {
+ if (TAG_RATING.equals(parser.getName())) {
+ return builder;
+ } else {
+ checkVersion("Malformed XML: " + TAG_RATING + " has child");
+ }
+ }
+ }
+ throw new XmlPullParserException(TAG_RATING +
+ " section is incomplete or section ending tag is missing");
+ }
+
+ private Rating.Builder parseSubRating(XmlResourceParser parser, Rating.Builder builder)
+ throws XmlPullParserException, IOException {
+ for (int i = 0; i < parser.getAttributeCount(); i++) {
+ String attr = parser.getAttributeName(i);
+ switch (attr) {
+ case ATTR_NAME:
+ builder.addSubRatingName(parser.getAttributeValue(i));
+ break;
+ default:
+ checkVersion("Malformed XML: " + TAG_SUB_RATING + " should only contain " +
+ ATTR_NAME);
+ }
+ }
+
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ if (parser.getEventType() == XmlPullParser.END_TAG) {
+ if (TAG_SUB_RATING.equals(parser.getName())) {
+ return builder;
+ } else {
+ checkVersion("Malformed XML: " + TAG_SUB_RATING + " has child");
+ }
+ }
+ }
+ throw new XmlPullParserException(TAG_SUB_RATING +
+ " section is incomplete or section ending tag is missing");
+ }
+
+ // Title might be a resource id or a string value. Try loading as an id first, then use the
+ // string if that fails.
+ private String getTitle(XmlResourceParser parser, int index) {
+ int titleResId = parser.getAttributeResourceValue(index, 0);
+ if (titleResId != 0) {
+ return mResources.getString(titleResId);
+ }
+ return parser.getAttributeValue(index);
}
}