aboutsummaryrefslogtreecommitdiff
path: root/src/com/android/tv/parental/ContentRatingSystem.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/tv/parental/ContentRatingSystem.java')
-rw-r--r--src/com/android/tv/parental/ContentRatingSystem.java428
1 files changed, 428 insertions, 0 deletions
diff --git a/src/com/android/tv/parental/ContentRatingSystem.java b/src/com/android/tv/parental/ContentRatingSystem.java
new file mode 100644
index 00000000..7985adf5
--- /dev/null
+++ b/src/com/android/tv/parental/ContentRatingSystem.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.tv.parental;
+
+import android.net.Uri;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ContentRatingSystem {
+ private final static String TAG = "ContentRatingSystem";
+
+ // Id of this content rating system. It should be unique in an XML file.
+ private String mId;
+
+ // Domain of this content rating system. It's package name now.
+ private String mDomain;
+
+ // Display name of this content rating system. (e.g. TV-PG)
+ private String mDisplayName;
+
+ // Description of this content rating system.
+ private String mDescription;
+
+ // Country code of this content rating system.
+ private String mCountry;
+
+ // Ordered list of main content ratings. UX should respect the order.
+ private List<Rating> mRatings;
+
+ // Ordered list of sub content ratings. UX should respect the order.
+ private List<SubRating> mSubRatings;
+
+ // List of orders. This describes the automatic lock/unlock relationship between ratings.
+ // For example, let say we have following order.
+ // <order>
+ // <rating id="US_TVPG_Y" />
+ // <rating id="US_TVPG_Y7" />
+ // </order>
+ // This means that locking US_TVPG_Y7 automatically locks US_TVPG_Y and
+ // unlocking US_TVPG_Y automatically unlocks US_TVPG_Y7 from the UX.
+ // An user can still unlock US_TVPG_Y while US_TVPG_Y7 is locked by manually.
+ private List<Order> mOrders;
+
+ public String getId(){
+ return mId;
+ }
+
+ public String getDomain() {
+ return mDomain;
+ }
+
+ public String getDisplayName(){
+ return mDisplayName;
+ }
+
+ public String getDescription(){
+ return mDescription;
+ }
+
+ public String getCountry(){
+ return mCountry;
+ }
+
+ public List<Rating> getRatings(){
+ return mRatings;
+ }
+
+ public List<SubRating> getSubRatings(){
+ return mSubRatings;
+ }
+
+ public List<Order> getOrders(){
+ return mOrders;
+ }
+
+ private ContentRatingSystem(
+ String id, String domain, String displayName, String description, String country,
+ List<Rating> ratings, List<SubRating> subRatings, List<Order> orders) {
+ mId = id;
+ mDomain = domain;
+ mDisplayName = displayName;
+ mDescription = description;
+ mCountry = country;
+ mRatings = ratings;
+ mSubRatings = subRatings;
+ mOrders = orders;
+ }
+
+ public static class Builder {
+ private String mId;
+ private String mDomain;
+ private String mDisplayName;
+ private String mDescription;
+ private String mCountry;
+ private List<Rating.Builder> mRatingBuilders = new ArrayList<Rating.Builder>();
+ private List<SubRating.Builder> mSubRatingBuilders = new ArrayList<SubRating.Builder>();
+ private List<Order.Builder> mOrderBuilders = new ArrayList<Order.Builder>();
+
+ public void setId(String id) {
+ mId = id;
+ }
+
+ public void setDomain(String domain) {
+ mDomain = domain;
+ }
+
+ public void setDisplayName(String displayName) {
+ mDisplayName = displayName;
+ }
+
+ public void setDescription(String description) {
+ mDescription = description;
+ }
+
+ public void setCountry(String country) {
+ mCountry = country;
+ }
+
+ public void addRatingBuilder(Rating.Builder ratingBuilder) {
+ // To provide easy access to the SubRatings in it,
+ // Rating has reference to SubRating, not Id of it.
+ // (Note that Rating/SubRating is ordered list so we cannot use Map)
+ // To do so, we need to have list of all SubRatings which might not be available
+ // at this moment. Keep builders here and build it with SubRatings later.
+ mRatingBuilders.add(ratingBuilder);
+ }
+
+ public void addSubRatingBuilder(SubRating.Builder subRatingBuilder) {
+ // SubRatings would be built rather to keep consistency with other fields.
+ mSubRatingBuilders.add(subRatingBuilder);
+ }
+
+ public void addOrderBuilder(Order.Builder orderBuilder) {
+ // To provide easy access to the Ratings in it,
+ // Order has reference to Rating, not Id of it.
+ // (Note that Rating/SubRating is ordered list so we cannot use Map)
+ // To do so, we need to have list of all Rating which might not be available
+ // at this moment. Keep builders here and build it with Ratings later.
+ mOrderBuilders.add(orderBuilder);
+ }
+
+ public ContentRatingSystem build() {
+ if (TextUtils.isEmpty(mId)) {
+ throw new IllegalArgumentException("Id cannot be empty");
+ }
+ if (TextUtils.isEmpty(mDomain)) {
+ throw new IllegalArgumentException("Domain cannot be empty");
+ }
+
+ List<SubRating> subRatings = new ArrayList<SubRating>();
+ if (mSubRatingBuilders != null) {
+ for (SubRating.Builder builder : mSubRatingBuilders) {
+ subRatings.add(builder.build());
+ }
+ }
+
+ if (mRatingBuilders.size() <= 0) {
+ throw new IllegalArgumentException("Rating isn't available.");
+ }
+ List<Rating> ratings = new ArrayList<Rating>();
+ if (mRatingBuilders != null) {
+ // Map string ID to object.
+ for (Rating.Builder builder : mRatingBuilders) {
+ ratings.add(builder.build(subRatings));
+ }
+
+ // Sanity check.
+ for (SubRating subRating : subRatings) {
+ boolean used = false;
+ for (Rating rating : ratings) {
+ if (rating.getSubRatings().contains(subRating)) {
+ used = true;
+ break;
+ }
+ }
+ if (!used) {
+ throw new IllegalArgumentException("Subrating " + subRating.getId() +
+ " isn't used by any rating");
+ }
+ }
+ }
+
+ List<Order> orders = new ArrayList<Order>();
+ if (mOrderBuilders != null) {
+ for (Order.Builder builder : mOrderBuilders) {
+ orders.add(builder.build(ratings));
+ }
+ }
+
+ return new ContentRatingSystem(mId, mDomain, mDisplayName, mDescription, mCountry,
+ ratings, subRatings, orders);
+ }
+ }
+
+ public static class Rating {
+ private String mId;
+ private String mDisplayName;
+ private String mDescription;
+ private Uri mIconUri;
+ private int mAgeHint;
+ private List<SubRating> mSubRatings;
+
+ public String getId() {
+ return mId;
+ }
+
+ public String getDisplayName() {
+ return mDisplayName;
+ }
+
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public Uri getIconUri() {
+ return mIconUri;
+ }
+
+ public int getAgeHint() {
+ return mAgeHint;
+ }
+
+ public List<SubRating> getSubRatings() {
+ return mSubRatings;
+ }
+
+ private Rating(String id, String displayName, String description, Uri iconUri,
+ int ageHint, List<SubRating> subRatings) {
+ mId = id;
+ mDisplayName = displayName;
+ mDescription = description;
+ mIconUri = iconUri;
+ mAgeHint = ageHint;
+ mSubRatings = subRatings;
+ }
+
+ public static class Builder {
+ private String mId;
+ private String mDisplayName;
+ private String mDescription;
+ private Uri mIconUri;
+ private Integer mAgeHint;
+ private List<String> mSubRatingIds = new ArrayList<String>();
+
+ public Builder() {
+ }
+
+ public void setId(String id) {
+ mId = id;
+ }
+
+ public void setDisplayName(String displayName) {
+ mDisplayName = displayName;
+ }
+
+ public void setDescription(String description) {
+ mDescription = description;
+ }
+
+ public void setIconUri(Uri iconUri) {
+ mIconUri = iconUri;
+ }
+
+ public void setAgeHint(int ageHint) {
+ mAgeHint = (mAgeHint == null) ? new Integer(ageHint) : (Integer) ageHint;
+ }
+
+ public void addSubRatingId(String subRatingId) {
+ mSubRatingIds.add(subRatingId);
+ }
+
+ private Rating build(List<SubRating> allDefinedSubRatings) {
+ if (TextUtils.isEmpty(mId)) {
+ throw new IllegalArgumentException("A rating should have non-empty id");
+ }
+ if (allDefinedSubRatings == null && mSubRatingIds.size() > 0) {
+ throw new IllegalArgumentException("Invalid subrating for rating " +
+ mId);
+ }
+ if (mAgeHint == null || mAgeHint < 0) {
+ throw new IllegalArgumentException("Rating " + mId + " should define " +
+ "non-negative ageHint");
+ }
+
+ List<SubRating> subRatings = new ArrayList<SubRating>();
+ for (String subRatingId : mSubRatingIds) {
+ boolean found = false;
+ for (SubRating subRating : allDefinedSubRatings) {
+ if (subRatingId.equals(subRating.getId())) {
+ found = true;
+ subRatings.add(subRating);
+ break;
+ }
+ }
+ if (!found) {
+ throw new IllegalArgumentException("Unknown subrating Id " + subRatingId +
+ " in rating " + mId);
+ }
+ }
+ return new Rating(
+ mId, mDisplayName, mDescription, mIconUri, (int) mAgeHint, subRatings);
+ }
+ }
+ }
+
+ public static class SubRating {
+ private String mId;
+ private String mDisplayName;
+ private String mDescription;
+ private Uri mIconUri;
+
+ public String getId() {
+ return mId;
+ }
+
+ public String getDisplayName() {
+ return mDisplayName;
+ }
+
+ public String getDescription() {
+ return mDescription;
+ }
+
+ public Uri getIconUri() {
+ return mIconUri;
+ }
+
+ private SubRating(String id, String displayName, String description, Uri iconUri) {
+ mId = id;
+ mDisplayName = displayName;
+ mDescription = description;
+ mIconUri = iconUri;
+ }
+
+ public static class Builder {
+ private String mId;
+ private String mDisplayName;
+ private String mDescription;
+ private Uri mIconUri;
+
+ public Builder() {
+ }
+
+ public void setId(String id) {
+ mId = id;
+ }
+
+ public void setDisplayName(String displayName) {
+ mDisplayName = displayName;
+ }
+
+ public void setDescription(String description) {
+ mDescription = description;
+ }
+
+ public void setIconUri(Uri iconUri) {
+ mIconUri = iconUri;
+ }
+
+ private SubRating build() {
+ if (TextUtils.isEmpty(mId)) {
+ throw new IllegalArgumentException("A subrating should have non-empty id");
+ }
+ return new SubRating(mId, mDisplayName, mDescription, mIconUri);
+ }
+ }
+ }
+
+ public static class Order {
+ private List<Rating> mRatingOrder;
+
+ public List<Rating> getRatingOrder() {
+ return mRatingOrder;
+ }
+
+ private Order(List<Rating> ratingOrder) {
+ mRatingOrder = ratingOrder;
+ }
+
+ public static class Builder {
+ private final List<String> mRatingIds = new ArrayList<String>();
+
+ public Builder() {
+ }
+
+ private Order build(List<Rating> ratings) {
+ List<Rating> ratingOrder = new ArrayList<Rating>();
+ for (String ratingId : mRatingIds) {
+ boolean found = false;
+ for (Rating rating : ratings) {
+ if (ratingId.equals(rating.getId())) {
+ found = true;
+ ratingOrder.add(rating);
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new IllegalArgumentException("Unknown rating " + ratingId +
+ " in order tag");
+ }
+ }
+
+ return new Order(ratingOrder);
+ }
+
+ public void addRatingId(String ratingId) {
+ mRatingIds.add(ratingId);
+ }
+ }
+ }
+}