summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Sungsoo Lim <sungsoo@google.com> 2014-07-29 11:48:36 +0900
committer Sungsoo Lim <sungsoo@google.com> 2014-08-01 13:47:28 +0900
commit5c5b83fcd58d21c9ab7ac986bf84f604ec5bb4b5 (patch)
tree042670f975c8ad51f618483bd9a636961e61a64c
parent012ef36a6c5e9745d112c734aed916cab052558c (diff)
TIF: Use XML file for representing TvContentRating
This change addresses the following API council feedback. - Remove all constants from TvContentRating. Instead this class becomes a general parser for a tuple of "rating domain"+type+subtype(s). - Instead of constants in the API, the rating definitions should come from parsed XML meta-data tied to a TvInputService entry in the AndroidManifest. This XML should define a ranked order of the rating constants along with @string references for displaying in the Settings UI. Mention that the "rating domain" should be scoped similar to a package name, for example "com.youtube.ratings". - For system-defined rating types (like US, Korea, etc) we should parse this same XML format, but it may come from a hard-coded XML resource (since they aren't tied to a single TvInputService.) - Thoroughly document the built-in supported types in javadoc on TvContentRating. Change-Id: I0a9526c73c8ca67fd0eeac63f3c63c05657a45e3
-rw-r--r--api/current.txt23
-rw-r--r--core/res/res/values/attrs.xml4
-rw-r--r--core/res/res/values/public.xml2
-rw-r--r--core/res/res/values/strings.xml37
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/res/res/xml/tv_content_rating_systems.xml127
-rw-r--r--media/java/android/media/tv/ITvInputManager.aidl2
-rw-r--r--media/java/android/media/tv/TvContentRating.java471
-rw-r--r--media/java/android/media/tv/TvInputInfo.java33
-rw-r--r--media/java/android/media/tv/TvInputManager.java13
-rw-r--r--services/core/java/com/android/server/tv/TvInputManagerService.java33
11 files changed, 533 insertions, 213 deletions
diff --git a/api/current.txt b/api/current.txt
index 74fdd31cf148..a8bbeed111bf 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -465,6 +465,7 @@ package android {
field public static final int contentInsetLeft = 16843863; // 0x1010457
field public static final int contentInsetRight = 16843864; // 0x1010458
field public static final int contentInsetStart = 16843861; // 0x1010455
+ field public static final int contentRatingSystemXml = 16843957; // 0x10104b5
field public static final int controlX1 = 16843798; // 0x1010416
field public static final int controlX2 = 16843800; // 0x1010418
field public static final int controlY1 = 16843799; // 0x1010417
@@ -16843,28 +16844,14 @@ package android.media.session {
package android.media.tv {
public final class TvContentRating {
- ctor public TvContentRating(java.lang.String);
- ctor public TvContentRating(java.lang.String, java.lang.String[]);
+ method public static android.media.tv.TvContentRating createRating(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String...);
method public java.lang.String flattenToString();
+ method public java.lang.String getCountry();
+ method public java.lang.String getDomain();
method public java.lang.String getMainRating();
+ method public java.lang.String getRatingSystem();
method public java.util.List<java.lang.String> getSubRatings();
method public static android.media.tv.TvContentRating unflattenFromString(java.lang.String);
- field public static final java.lang.String RATING_KR_12 = "RATING_KR_12";
- field public static final java.lang.String RATING_KR_15 = "RATING_KR_15";
- field public static final java.lang.String RATING_KR_19 = "RATING_KR_19";
- field public static final java.lang.String RATING_KR_7 = "RATING_KR_7";
- field public static final java.lang.String RATING_KR_ALL = "RATING_KR_ALL";
- field public static final java.lang.String RATING_US_TV_14 = "RATING_US_TV_14";
- field public static final java.lang.String RATING_US_TV_G = "RATING_US_TV_G";
- field public static final java.lang.String RATING_US_TV_MA = "RATING_US_TV_MA";
- field public static final java.lang.String RATING_US_TV_PG = "RATING_US_TV_PG";
- field public static final java.lang.String RATING_US_TV_Y = "RATING_US_TV_Y";
- field public static final java.lang.String RATING_US_TV_Y7 = "RATING_US_TV_Y7";
- field public static final java.lang.String SUBRATING_US_D = "SUBRATING_US_D";
- field public static final java.lang.String SUBRATING_US_FV = "SUBRATING_US_FV";
- field public static final java.lang.String SUBRATING_US_L = "SUBRATING_US_L";
- field public static final java.lang.String SUBRATING_US_S = "SUBRATING_US_S";
- field public static final java.lang.String SUBRATING_US_V = "SUBRATING_US_V";
}
public final class TvContract {
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d07d0abf73fd..a31f18f1054b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7259,7 +7259,9 @@
<!-- Component name of an activity that allows the user to modify
the settings for this service. -->
<attr name="settingsActivity" />
- <!-- Type of this service. -->
+ <!-- Component name of an xml file that describes the structure of TV content ratings that
+ this service uses. -->
+ <attr name="contentRatingSystemXml" format="reference" />
</declare-styleable>
<declare-styleable name="ResolverDrawerLayout">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index d8f9665e679b..08398f0932ca 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2560,4 +2560,6 @@
<public type="raw" name="loaderror" id="0x01100000"/>
<!-- WebView error page for when domain lookup fails. @hide @SystemApi -->
<public type="raw" name="nodomain"/>
+
+ <public type="attr" name="contentRatingSystemXml"/>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 11c41e3b0c9f..18211158e139 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4841,4 +4841,41 @@
<!-- Lock-to-app unlock password string -->
<string name="lock_to_app_unlock_password">password</string>
+ <string name="display_name_ustvpg" translatable="false">US-TV</string>
+ <string name="description_ustvpg">The TV Parental Guidelines</string>
+ <string name="display_name_krtv" translatable="false">KR-TV</string>
+
+ <string name="display_name_ustvpg_d" translatable="false">D</string>
+ <string name="display_name_ustvpg_l" translatable="false">L</string>
+ <string name="display_name_ustvpg_s" translatable="false">S</string>
+ <string name="display_name_ustvpg_v" translatable="false">V</string>
+ <string name="display_name_ustvpg_fv" translatable="false">FV</string>
+ <string name="display_name_ustvpg_y" translatable="false">TV-Y</string>
+ <string name="display_name_ustvpg_y7" translatable="false">TV-Y7</string>
+ <string name="display_name_ustvpg_g" translatable="false">TV-G</string>
+ <string name="display_name_ustvpg_pg" translatable="false">TV-PG</string>
+ <string name="display_name_ustvpg_14" translatable="false">TV-14</string>
+ <string name="display_name_ustvpg_ma" translatable="false">TV-MA</string>
+ <string name="display_name_krtv_all" translatable="false">모든연령시청가</string>
+ <string name="display_name_krtv_7" translatable="false">7세이상시청가</string>
+ <string name="display_name_krtv_12" translatable="false">12세이상시청가</string>
+ <string name="display_name_krtv_15" translatable="false">15세이상시청가</string>
+ <string name="display_name_krtv_19" translatable="false">19세이상시청가</string>
+
+ <string name="description_ustvpg_d">Suggestive dialogue (Usually means talks about sex)</string>
+ <string name="description_ustvpg_l">Coarse language</string>
+ <string name="description_ustvpg_s">Sexual content</string>
+ <string name="description_ustvpg_v">Violence</string>
+ <string name="description_ustvpg_fv">Fantasy violence (Children\'s programming only)</string>
+ <string name="description_ustvpg_y">This program is designed to be appropriate for all children.</string>
+ <string name="description_ustvpg_y7">This program is designed for children age 7 and above.</string>
+ <string name="description_ustvpg_g">Most parents would find this program suitable for all ages.</string>
+ <string name="description_ustvpg_pg">This program contains material that parents may find unsuitable for younger children.</string>
+ <string name="description_ustvpg_14">This program contains some material that many parents would find unsuitable for children under 14 years of age.</string>
+ <string name="description_ustvpg_ma">This program is specifically designed to be viewed by adults and therefore may be unsuitable for children under 17.</string>
+ <string name="description_krtv_all">모든 연령의 시청자가 시청하기에 부적절한 내용이 없는 등급을 말한다.</string>
+ <string name="description_krtv_7">7세미만의 어린이가 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
+ <string name="description_krtv_12">12세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
+ <string name="description_krtv_15">15세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 보호자의 시청지도가 필요한 등급을 말한다.</string>
+ <string name="description_krtv_19">19세미만의 청소년이 시청하기에 부적절한 내용이 포함되어 있어 청소년이 시청할 수 없는 등급을 말한다.</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 6e23557331be..d37e46880c25 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1259,6 +1259,7 @@
<java-symbol type="xml" name="audio_assets" />
<java-symbol type="xml" name="global_keys" />
<java-symbol type="xml" name="default_zen_mode_config" />
+ <java-symbol type="xml" name="tv_content_rating_systems" />
<java-symbol type="raw" name="accessibility_gestures" />
<java-symbol type="raw" name="incognito_mode_start_page" />
diff --git a/core/res/res/xml/tv_content_rating_systems.xml b/core/res/res/xml/tv_content_rating_systems.xml
new file mode 100644
index 000000000000..238ce13864e1
--- /dev/null
+++ b/core/res/res/xml/tv_content_rating_systems.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<rating-system-definitions>
+ <rating-system-definition id="US_TVPG"
+ displayName="@string/display_name_ustvpg"
+ description="@string/description_ustvpg"
+ country="US">
+ <sub-rating-definition id="US_TVPG_D"
+ displayName="@string/display_name_ustvpg_d"
+ description="@string/description_ustvpg_d" />
+ <sub-rating-definition id="US_TVPG_L"
+ displayName="@string/display_name_ustvpg_l"
+ description="@string/description_ustvpg_l" />
+ <sub-rating-definition id="US_TVPG_S"
+ displayName="@string/display_name_ustvpg_s"
+ description="@string/description_ustvpg_s" />
+ <sub-rating-definition id="US_TVPG_V"
+ displayName="@string/display_name_ustvpg_v"
+ description="@string/description_ustvpg_v" />
+ <sub-rating-definition id="US_TVPG_FV"
+ displayName="@string/display_name_ustvpg_fv"
+ description="@string/description_ustvpg_fv" />
+
+ <rating-definition id="US_TVPG_TV_Y"
+ displayName="@string/display_name_ustvpg_y"
+ description="@string/description_ustvpg_y"
+ ageHint="0" />
+ <rating-definition id="US_TVPG_TV_Y7"
+ displayName="@string/display_name_ustvpg_y7"
+ description="@string/description_ustvpg_y7"
+ ageHint="7">
+ <sub-rating id="US_TVPG_FV" />
+ </rating-definition>
+ <rating-definition id="US_TVPG_TV_G"
+ displayName="@string/display_name_ustvpg_g"
+ description="@string/description_ustvpg_g"
+ ageHint="0" />
+ <rating-definition id="US_TVPG_TV_PG"
+ displayName="@string/display_name_ustvpg_pg"
+ description="@string/description_ustvpg_pg"
+ ageHint="14">
+ <sub-rating id="US_TVPG_D" />
+ <sub-rating id="US_TVPG_L" />
+ <sub-rating id="US_TVPG_S" />
+ <sub-rating id="US_TVPG_V" />
+ </rating-definition>
+ <rating-definition id="US_TVPG_TV_14"
+ displayName="@string/display_name_ustvpg_14"
+ description="@string/description_ustvpg_14"
+ ageHint="14">
+ <sub-rating id="US_TVPG_D" />
+ <sub-rating id="US_TVPG_L" />
+ <sub-rating id="US_TVPG_S" />
+ <sub-rating id="US_TVPG_V" />
+ </rating-definition>
+ <rating-definition id="US_TVPG_TV_MA"
+ displayName="@string/display_name_ustvpg_ma"
+ description="@string/description_ustvpg_ma"
+ ageHint="17">
+ <sub-rating id="US_TVPG_L" />
+ <sub-rating id="US_TVPG_S" />
+ <sub-rating id="US_TVPG_V" />
+ </rating-definition>
+ <order>
+ <rating id="US_TVPG_Y" />
+ <rating id="US_TVPG_Y7" />
+ </order>
+ <order>
+ <rating id="US_TVPG_TV_G" />
+ <rating id="US_TVPG_TV_PG" />
+ <rating id="US_TVPG_TV_14" />
+ <rating id="US_TVPG_TV_MA" />
+ </order>
+ </rating-system-definition>
+
+ <rating-system-definition id="KR_TV"
+ displayName="@string/display_name_krtv"
+ country="KR">
+ <rating-definition id="KR_TV_ALL"
+ displayName="@string/display_name_krtv_all"
+ description="@string/description_krtv_all"
+ ageHint="0" />
+ <rating-definition id="KR_TV_7"
+ displayName="@string/display_name_krtv_7"
+ description="@string/description_krtv_7"
+ ageHint="7">
+ </rating-definition>
+ <rating-definition id="KR_TV_12"
+ displayName="@string/display_name_krtv_12"
+ description="@string/description_krtv_12"
+ ageHint="12">
+ </rating-definition>
+ <rating-definition id="KR_TV_15"
+ displayName="@string/display_name_krtv_15"
+ description="@string/description_krtv_15"
+ ageHint="15">
+ </rating-definition>
+ <rating-definition id="KR_TV_19"
+ displayName="@string/display_name_krtv_19"
+ description="@string/description_krtv_19"
+ ageHint="19">
+ </rating-definition>
+ <order>
+ <rating id="KR_TV_ALL" />
+ <rating id="KR_TV_7" />
+ <rating id="KR_TV_12" />
+ <rating id="KR_TV_15" />
+ <rating id="KR_TV_19" />
+ </order>
+ </rating-system-definition>
+</rating-system-definitions>
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 41c4f07186f2..8b97f328a68a 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -38,6 +38,8 @@ interface ITvInputManager {
List<TvInputInfo> getTvInputList(int userId);
TvInputInfo getTvInputInfo(in String inputId, int userId);
+ List<Uri> getTvContentRatingSystemXmls(int userId);
+
void registerCallback(in ITvInputManagerCallback callback, int userId);
void unregisterCallback(in ITvInputManagerCallback callback, int userId);
diff --git a/media/java/android/media/tv/TvContentRating.java b/media/java/android/media/tv/TvContentRating.java
index 986a7d942933..1ace7752b036 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -17,149 +17,275 @@
package android.media.tv;
import android.annotation.SystemApi;
+import android.net.Uri;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.Log;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
/**
* A class representing a TV content rating.
+ * When a TV input service provides the content rating information of a program into TV provider,
+ * TvContentRating class will be used for generating the value of {@link
+ * TvContract.Programs#COLUMN_CONTENT_RATING}. To create an object of {@link TvContentRating}, use
+ * the {@link #createRating} method with valid arguments. The arguments could be a system defined
+ * strings, or a TV input service defined strings.
+ * TV input service defined strings are in an xml file defined in <code>&lt;{@link
+ * android.R.styleable#TvInputService tv-input}&gt;</code> with the {@link
+ * android.R.attr#contentRatingSystemXml contentRatingSystemXml} attribute by the TV input service.
+ *
+ * <h3> Content Rating System XML format </h3>
+ * The XML file for publishing content rating system should follow the DTD bellow:
+ * <p><pre class="prettyprint">
+ * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
+ * &lt;!DOCTYPE rating-systems [
+ * &lt;!ELEMENT rating-system-definitions (rating-system-definition+)&gt;
+ * &lt;!ELEMENT rating-system-definition (
+ * (sub-rating-definition*, rating-definition, sub-rating-definition*)+, order*)&gt;
+ * &lt;!ATTLIST rating-system-definition
+ * id ID #REQUIRED
+ * displayName CDATA #IMPLIED
+ * description CDATA #IMPLIED
+ * country CDATA #IMPLIED&gt;
+ * &lt;!ELEMENT sub-rating-definition EMPTY&gt;
+ * &lt;!ATTLIST sub-rating-definition
+ * id ID #REQUIRED
+ * displayName CDATA #IMPLIED
+ * icon CDATA #IMPLIED
+ * description CDATA #IMPLIED&gt;
+ * &lt;!ELEMENT rating-definition (sub-rating*))&gt;
+ * &lt;!ATTLIST rating-definition
+ * id ID #REQUIRED
+ * displayName CDATA #IMPLIED
+ * icon CDATA #IMPLIED
+ * description CDATA #IMPLIED&gt;
+ * &lt;!ELEMENT sub-rating EMPTY&gt;
+ * &lt;!ATTLIST sub-rating id IDREF #REQUIRED&gt;
+ * &lt;!ELEMENT order (rating, rating+)&gt;
+ * &lt;!ELEMENT rating EMPTY&gt;
+ * &lt;!ATTLIST rating id IDREF #REQUIRED&gt;
+ * ]&gt;
+ * </pre></p>
+ *
+ * <h3>System defined rating strings</h3>
+ *
+ * <u>System defined string for {@code domain}</u>
+ * <table border="0" cellspacing="0" cellpadding="0">
+ * <tr>
+ * <td>String value</td>
+ * <td>Comments</td>
+ * </tr>
+ * <tr>
+ * <td>android.media.tv</td>
+ * <td>Used for creating system defined content ratings</td>
+ * </tr>
+ * </table>
+ * <u>System defined string for {@code ratingSystem}</u>
+ * <table border="0" cellspacing="0" cellpadding="0">
+ * <tr>
+ * <td>String value</td>
+ * <td>Comments</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG</td>
+ * <td>The TV Parental Guidelines for US TV content ratings</td>
+ * </tr>
+ * <tr>
+ * <td>KR_TV</td>
+ * <td>The South Korean television rating system</td>
+ * </tr>
+ * </table>
+ *
+ * <u>System defined string for {@code rating}</u>
+ * <table border="0" cellspacing="0" cellpadding="0">
+ * <tr>
+ * <td>String value</td>
+ * <td>Comments</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_TV_Y</td>
+ * <td>A rating string for the US_TVPG domain. Programs rated this are designed to be
+ * appropriate for all children. Whether animated or live-action, the themes and elements
+ * in this program are specifically designed for a very young audience, including children
+ * from ages 2-6. This program is not expected to frighten younger children.</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_TV_Y7</td>
+ * <td>A rating string for the US_TVPG domain. Programs rated this are designed for children
+ * age 7 and above. It may be more appropriate for children who have acquired the
+ * developmental skills needed to distinguish between make-believe and reality. Themes and
+ * elements in this program may include mild fantasy violence or comedic violence, or may
+ * frighten children under the age of 7. Therefore, parents may wish to consider the
+ * suitability of this program for their very young children. This rating may contain
+ * fantasy violence (US_TVPG_FV) when programs are generally more intense or more combative
+ * than other programs in this category.</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_TV_G</td>
+ * <td>A rating string for the US_TVPG domain. Most parents would find this program suitable
+ * for all ages. Although this rating does not signify a program designed specifically for
+ * children, most parents may let younger children watch this program unattended. It
+ * contains little or no violence, no strong language and little or no sexual dialogue or
+ * situations.</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_TV_PG</td>
+ * <td>A rating string for the US_TVPG domain. Programs rated this contain material that
+ * parents may find unsuitable for younger children. Many parents may want to watch it with
+ * their younger children. The theme itself may call for parental guidance and/or the
+ * program may contain one or more of the following: some suggestive dialogue (US_TVPG_D),
+ * infrequent coarse language (US_TVPG_L), some sexual situations (US_TVPG_S), or moderate
+ * violence (US_TVPG_V).</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_TV_14</td>
+ * <td>A rating string for the US_TVPG domain. Programs rated this contains some material
+ * that many parents would find unsuitable for children under 14 years of age. Parents are
+ * strongly urged to exercise greater care in monitoring this program and are cautioned
+ * against letting children under the age of 14 watch unattended. This program may contain
+ * one or more of the following: intensely suggestive dialogue (US_TVPG_D), strong coarse
+ * language (US_TVPG_L), intense sexual situations (US_TVPG_S), or intense violence
+ * (US_TVPG_V).</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_TV_MA</td>
+ * <td>A rating string for the US_TVPG domain. Programs rated TV-MA are specifically
+ * designed to be viewed by adults and therefore may be unsuitable for children under 17.
+ * This program may contain one or more of the following: crude indecent language
+ * (US_TVPG_L), explicit sexual activity (US_TVPG_S), or graphic violence (US_TVPG_V).</td>
+ * </tr>
+ * <tr>
+ * <td>KR_TV_ALL</td>
+ * <td>A rating string for the KR_TV domain. This rating is for programs that are
+ * appropriate for all ages. This program usually involves programs designed for children or
+ * families. This rating does not have an icon.</td>
+ * </tr>
+ * <tr>
+ * <td>KR_TV_7</td>
+ * <td>A rating string for the KR_TV domain. This rating is for programs that may contain
+ * material inappropriate for children younger than 7, and parental discretion should be
+ * used. Some cartoon programs not deemed strictly as "educational", and films rated "G" or
+ * "PG" in North America may fall into the 7 category.</td>
+ * </tr>
+ * <tr>
+ * <td>KR_TV_12</td>
+ * <td>A rating string for the KR_TV domain. This rating is for programs that may deemed
+ * inappropriate for those younger than 12, and parental discretion should be used. Usually
+ * used for animations that have stronger themes or violence then those designed for
+ * children, or for reality shows that have mild violence, themes, or language.</td>
+ * </tr>
+ * <tr>
+ * <td>KR_TV_15</td>
+ * <td>A rating string for the KR_TV domain. This rating is for programs that contain
+ * material that may be inappropriate for children under 15, and that parental discretion
+ * should be used. Examples include most dramas, and talk shows on OTA (over-the-air) TV
+ * (KBS, MBC, SBS), and many American TV shows/dramas on Cable TV channels like OCN and
+ * OnStyle. The programs that have this rating may include moderate or strong adult themes,
+ * language, sexual inference, and violence. As with the TV-14 rating in North America, this
+ * rating is commonly applied to live events where the occurrence of inappropriate dialogue
+ * is unpredictable. Since 2007, this rating is the most used rating for TV.</td>
+ * </tr>
+ * <tr>
+ * <td>KR_TV_19</td>
+ * <td>A rating string for the KR_TV domain. This rating is for programs that are intended
+ * for adults only. 19-rated programs cannot air during the hours of 7:00AM to 9:00AM, and
+ * 1:00PM to 10:00PM. Programs that receive this rating will almost certainly have adult
+ * themes, sexual situations, frequent use of strong language and disturbing scenes of
+ * violence.</td>
+ * </tr>
+ * </table>
+ *
+ * <u>System defined string for {@code subRating}</u>
+ * <table border="0" cellspacing="0" cellpadding="0">
+ * <tr>
+ * <td>String value</td>
+ * <td>Comments</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_D</td>
+ * <td>Suggestive dialogue (Not used with US_TVPG_TV_MA)</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_L</td>
+ * <td>Coarse language</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_S</td>
+ * <td>Sexual content</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_V</td>
+ * <td>Violence</td>
+ * </tr>
+ * <tr>
+ * <td>US_TVPG_FV</td>
+ * <td>Fantasy violence (exclusive to US_TVPG_TV_Y7)</td>
+ * </tr>
+ * </table>
*/
public final class TvContentRating {
private static final String TAG = "TvContentRating";
- private static final int RATING_PREFIX_LENGTH = 10;
- private static final String PREFIX_RATING_US = "RATING_US_";
- private static final String PREFIX_SUBRATING_US = "SUBRATING_US_";
+ /** @hide */
+ public static final Uri SYSTEM_CONTENT_RATING_SYSTEM_XML = Uri.parse(
+ "android.resource://system/" + com.android.internal.R.xml.tv_content_rating_systems);
- /**
- * Rating constant for TV-Y from the TV Parental Guidelines system in US. This program is
- * designed to be appropriate for all children.
- */
- public static final String RATING_US_TV_Y = PREFIX_RATING_US + "TV_Y";
- /**
- * Rating constant for TV-Y7 from the TV Parental Guidelines system in US. This program is
- * designed for children age 7 and above.
- */
- public static final String RATING_US_TV_Y7 = PREFIX_RATING_US + "TV_Y7";
- /**
- * Rating constant for TV-G from the TV Parental Guidelines system in US. Most parents would
- * find this program suitable for all ages.
- */
- public static final String RATING_US_TV_G = PREFIX_RATING_US + "TV_G";
- /**
- * Rating constant for TV-PG from the TV Parental Guidelines system in US. This program contains
- * material that parents may find unsuitable for younger children.
- */
- public static final String RATING_US_TV_PG = PREFIX_RATING_US + "TV_PG";
- /**
- * Rating constant for TV-14 from the TV Parental Guidelines system in US. This program contains
- * some material that many parents would find unsuitable for children under 14 years of age.
- */
- public static final String RATING_US_TV_14 = PREFIX_RATING_US + "TV_14";
- /**
- * Rating constant for TV-MA from the TV Parental Guidelines system in US. This program is
- * specifically designed to be viewed by adults and therefore may be unsuitable for children
- * under 17.
- */
- public static final String RATING_US_TV_MA = PREFIX_RATING_US + "TV_MA";
-
- /**
- * Sub-rating constant for D (Suggestive dialogue) from the TV Parental Guidelines system in US.
- */
- public static final String SUBRATING_US_D = PREFIX_SUBRATING_US + "D";
- /**
- * Sub-rating constant for L (Coarse language) from the TV Parental Guidelines system in US.
- */
- public static final String SUBRATING_US_L = PREFIX_SUBRATING_US + "L";
- /**
- * Sub-rating constant for S (Sexual content) from the TV Parental Guidelines system in US.
- */
- public static final String SUBRATING_US_S = PREFIX_SUBRATING_US + "S";
- /**
- * Sub-rating constant for V (Violence) from the TV Parental Guidelines system in US.
- */
- public static final String SUBRATING_US_V = PREFIX_SUBRATING_US + "V";
- /**
- * Sub-rating constant for FV (Fantasy violence) from the TV Parental Guidelines system in US.
- */
- public static final String SUBRATING_US_FV = PREFIX_SUBRATING_US + "FV";
+ // TODO: Consider to use other DELIMITER. In some countries such as India may use this delimiter
+ // in the main ratings.
+ private static final String DELIMITER = "/";
- private static final String PREFIX_RATING_KR = "RATING_KR_";
+ private final String mDomain;
+ private final String mCountryCode;
+ private final String mRatingSystem;
+ private final String mRating;
+ private final String[] mSubRatings;
/**
- * Rating constant for 'ALL' from the South Korean television rating system. This rating is for
- * programming that is appropriate for all ages.
- */
- public static final String RATING_KR_ALL = PREFIX_RATING_KR + "ALL";
- /**
- * Rating constant for '7' from the South Korean television rating system. This rating is for
- * programming that may contain material inappropriate for children younger than 7, and parental
- * discretion should be used.
- */
- public static final String RATING_KR_7 = PREFIX_RATING_KR + "7";
- /**
- * Rating constant for '12' from the South Korean television rating system. This rating is for
- * programs that may deemed inappropriate for those younger than 12, and parental discretion
- * should be used.
- */
- public static final String RATING_KR_12 = PREFIX_RATING_KR + "12";
- /**
- * Rating constant for '15' from the South Korean television rating system. This rating is for
- * programs that contain material that may be inappropriate for children under 15, and that
- * parental discretion should be used.
- */
- public static final String RATING_KR_15 = PREFIX_RATING_KR + "15";
- /**
- * Rating constant for '19' from the South Korean television rating system. This rating is for
- * programs that are intended for adults only. 19-rated programming cannot air during the hours
- * of 7:00AM to 9:00AM, and 1:00PM to 10:00PM.
+ * Creates a TvContentRating object.
+ *
+ * @param domain The domain name.
+ * @param countryCode The country code in ISO 3166-2 format or {@code null}.
+ * @param ratingSystem The rating system id.
+ * @param rating The content rating string.
+ * @param subRatings The string array of sub-ratings.
+ * @return A TvContentRating object, or null if creation failed.
*/
- public static final String RATING_KR_19 = PREFIX_RATING_KR + "19";
-
- private static final String DELIMITER = "/";
-
- // A mapping from two-letter country code (ISO 3166-1 alpha-2) to its rating-to-sub-ratings map.
- // This is used for validating the builder parameters.
- private static final Map<String, Map<String, String[]>> sRatings
- = new ArrayMap<String, Map<String, String[]>>();
-
- static {
- Map<String, String[]> usRatings = new ArrayMap<String, String[]>();
- usRatings.put(RATING_US_TV_Y, null);
- usRatings.put(RATING_US_TV_Y7, new String[] { SUBRATING_US_FV });
- usRatings.put(RATING_US_TV_G, null);
- usRatings.put(RATING_US_TV_PG, new String[] {
- SUBRATING_US_D, SUBRATING_US_L, SUBRATING_US_S, SUBRATING_US_V });
- usRatings.put(RATING_US_TV_14, new String[] {
- SUBRATING_US_D, SUBRATING_US_L, SUBRATING_US_S, SUBRATING_US_V });
- usRatings.put(RATING_US_TV_MA, new String[] {
- SUBRATING_US_L, SUBRATING_US_S, SUBRATING_US_V });
- sRatings.put(PREFIX_RATING_US, usRatings);
-
- Map<String, String[]> krRatings = new ArrayMap<String, String[]>();
- krRatings.put(RATING_KR_ALL, null);
- krRatings.put(RATING_KR_7, null);
- krRatings.put(RATING_KR_12, null);
- krRatings.put(RATING_KR_15, null);
- krRatings.put(RATING_KR_19, null);
- sRatings.put(PREFIX_RATING_KR, krRatings);
+ public static TvContentRating createRating(String domain, String countryCode,
+ String ratingSystem, String rating, String... subRatings) {
+ if (TextUtils.isEmpty(domain)) {
+ throw new IllegalArgumentException("domain cannot be empty");
+ }
+ if (TextUtils.isEmpty(rating)) {
+ throw new IllegalArgumentException("rating cannot be empty");
+ }
+ return new TvContentRating(domain, countryCode, ratingSystem, rating, subRatings);
}
- private final String mRating;
- private final String[] mSubRatings;
-
/**
- * Constructs a TvContentRating object from a given rating constant.
+ * Recovers a TvContentRating from a String that was previously created with
+ * {@link #flattenToString}.
*
- * @param rating The rating constant defined in this class.
+ * @param ratingString The String that was returned by flattenToString().
+ * @return a new TvContentRating containing the domain, countryCode, rating system, rating and
+ * sub-ratings information was encoded in {@code ratingString}.
+ * @see #flattenToString
*/
- public TvContentRating(String rating) {
- this(rating, null);
+ public static TvContentRating unflattenFromString(String ratingString) {
+ if (TextUtils.isEmpty(ratingString)) {
+ throw new IllegalArgumentException("ratingString cannot be empty");
+ }
+ String[] strs = ratingString.split(DELIMITER);
+ if (strs.length < 4) {
+ throw new IllegalArgumentException("Invalid rating string: " + ratingString);
+ }
+ if (strs.length > 4) {
+ String[] subRatings = new String[strs.length - 4];
+ System.arraycopy(strs, 4, subRatings, 0, subRatings.length);
+ return new TvContentRating(strs[0], strs[1], strs[2], strs[3], subRatings);
+ }
+ return new TvContentRating(strs[0], strs[1], strs[2], strs[3], null);
}
/**
@@ -168,57 +294,45 @@ public final class TvContentRating {
* @param rating The rating constant defined in this class.
* @param subRatings The String array of sub-rating constants defined in this class.
*/
- public TvContentRating(String rating, String[] subRatings) {
- if (TextUtils.isEmpty(rating)) {
- throw new IllegalArgumentException("rating cannot be null");
- }
+ private TvContentRating(String domain, String countryCode,
+ String ratingSystem, String rating, String[] subRatings) {
+ mDomain = domain;
+ mCountryCode = countryCode;
+ mRatingSystem = ratingSystem;
mRating = rating;
mSubRatings = subRatings;
- String prefix = "";
- if (mRating.length() > RATING_PREFIX_LENGTH) {
- prefix = mRating.substring(0, RATING_PREFIX_LENGTH);
- }
- Map<String, String[]> ratings = sRatings.get(prefix);
- if (ratings != null) {
- if (!ratings.keySet().contains(mRating)) {
- Log.w(TAG, "Unknown rating: " + mRating);
- } else if (mSubRatings != null) {
- String[] validSubRatings = ratings.get(mRating);
- if (validSubRatings == null) {
- Log.w(TAG, "Invalid subratings: " + mSubRatings);
- } else {
- List<String> validSubRatingList = Arrays.asList(subRatings);
- for (String sr : mSubRatings) {
- if (TextUtils.isEmpty(sr)) {
- throw new IllegalArgumentException(
- "subRatings cannot contain empty elements");
- }
- if (!validSubRatingList.contains(sr)) {
- Log.w(TAG, "Invalid subrating: " + sr);
- break;
- }
- }
- }
- }
- } else {
- Log.w(TAG, "Rating undefined for " + mRating);
- }
}
/**
- * Returns the main rating constant.
- *
- * @return the rating string that starts with "RATING_" prefix as defined in this class.
+ * Returns the domain.
+ */
+ public String getDomain() {
+ return mDomain;
+ }
+
+ /**
+ * Returns the country code in ISO 3166-2 format or {@code null}.
+ */
+ public String getCountry() {
+ return mCountryCode;
+ }
+
+ /**
+ * Returns the rating system id.
+ */
+ public String getRatingSystem() {
+ return mRatingSystem;
+ }
+
+ /**
+ * Returns the main rating.
*/
public String getMainRating() {
return mRating;
}
/**
- * Returns the list of sub-rating constants.
- *
- * @return the unmodifiable {@code List} of sub-rating strings that start with "SUBRATING_"
- * prefix as defined in this class.
+ * Returns the unmodifiable {@code List} of sub-rating strings.
*/
public List<String> getSubRatings() {
if (mSubRatings == null) {
@@ -238,10 +352,14 @@ public final class TvContentRating {
* @see #unflattenFromString
*/
public String flattenToString() {
- // TODO: Consider removing all obvious/redundant sub-strings including "RATING" and
- // "SUBRATING" and find out a storage-efficient string format such as:
- // <country>-<primary>/<sub1>/<sub2>/<sub3>
- StringBuilder builder = new StringBuilder(mRating);
+ StringBuilder builder = new StringBuilder();
+ builder.append(mDomain);
+ builder.append(DELIMITER);
+ builder.append(mCountryCode);
+ builder.append(DELIMITER);
+ builder.append(mRatingSystem);
+ builder.append(DELIMITER);
+ builder.append(mRating);
if (mSubRatings != null) {
for (String subRating : mSubRatings) {
builder.append(DELIMITER);
@@ -252,31 +370,6 @@ public final class TvContentRating {
}
/**
- * Recovers a TvContentRating from a String that was previously created with
- * {@link #flattenToString}.
- *
- * @param ratingString The String that was returned by flattenToString().
- * @return a new TvContentRating containing the rating and sub-ratings information was encoded
- * in {@code ratingString}.
- * @see #flattenToString
- */
- public static TvContentRating unflattenFromString(String ratingString) {
- if (TextUtils.isEmpty(ratingString)) {
- throw new IllegalArgumentException("Empty rating string");
- }
- String[] strs = ratingString.split(DELIMITER);
- if (strs.length < 1) {
- throw new IllegalArgumentException("Invalid rating string: " + ratingString);
- }
- if (strs.length > 1) {
- String[] subRatings = new String[strs.length - 1];
- System.arraycopy(strs, 1, subRatings, 0, subRatings.length);
- return new TvContentRating(strs[0], subRatings);
- }
- return new TvContentRating(strs[0]);
- }
-
- /**
* Returns true if this rating has the same main rating as the specified rating and when this
* rating's sub-ratings contain the other's.
* <p>
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index e48b805ad301..bc0538c3b034 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -18,6 +18,7 @@ package android.media.tv;
import android.annotation.SystemApi;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -118,6 +119,7 @@ public final class TvInputInfo implements Parcelable {
private String mLabel;
private Uri mIconUri;
private boolean mIsConnectedToHdmiSwitch;
+ private Uri mRatingSystemXmlUri;
static {
sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_OTHER_HARDWARE,
@@ -237,6 +239,19 @@ public final class TvInputInfo implements Parcelable {
Log.d(TAG, "Settings activity loaded. [" + input.mSettingsActivity + "] for "
+ si.name);
}
+ int contentRatingSystemXml = sa.getResourceId(
+ com.android.internal.R.styleable.TvInputService_contentRatingSystemXml, -1);
+ if (contentRatingSystemXml != -1) {
+ input.mRatingSystemXmlUri = new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+ .authority(si.packageName)
+ .appendPath(Integer.toString(contentRatingSystemXml))
+ .build();
+ if (DEBUG) {
+ Log.d(TAG, "Content rating xml loaded. [" + contentRatingSystemXml + "] for "
+ + si.name);
+ }
+ }
sa.recycle();
input.mLabel = label;
@@ -346,6 +361,15 @@ public final class TvInputInfo implements Parcelable {
}
/**
+ * Returns the resource uri for the rating system xml of this TV input service.
+ * @hide
+ */
+ @SystemApi
+ public Uri getRatingSystemXmlUri() {
+ return mRatingSystemXmlUri;
+ }
+
+ /**
* Returns {@code true} if this TV input is pass-though which does not have any real channels
* in TvProvider. {@code false} otherwise.
*
@@ -449,9 +473,10 @@ public final class TvInputInfo implements Parcelable {
dest.writeString(mSetupActivity);
dest.writeString(mSettingsActivity);
dest.writeInt(mType);
- dest.writeString(mIconUri == null ? null : mIconUri.toString());
+ dest.writeParcelable(mIconUri, flags);
dest.writeString(mLabel);
dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
+ dest.writeParcelable(mRatingSystemXmlUri, flags);
}
private Drawable loadDefaultIcon(Context context) {
@@ -521,11 +546,9 @@ public final class TvInputInfo implements Parcelable {
mSetupActivity = in.readString();
mSettingsActivity = in.readString();
mType = in.readInt();
- String mIconUriString = in.readString();
- if (mIconUriString != null) {
- mIconUri = Uri.parse(mIconUriString);
- }
+ mIconUri = in.readParcelable(null);
mLabel = in.readString();
mIsConnectedToHdmiSwitch = in.readByte() == 1 ? true : false;
+ mRatingSystemXmlUri = in.readParcelable(null);
}
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 49b224048978..1c83e9408ae4 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -800,6 +800,19 @@ public final class TvInputManager {
}
/**
+ * Returns the list of xml resource uris for TV content rating systems.
+ * @hide
+ */
+ @SystemApi
+ public List<Uri> getTvContentRatingSystemXmls() {
+ try {
+ return mService.getTvContentRatingSystemXmls(mUserId);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
* Creates a {@link Session} for a given TV input.
* <p>
* The number of sessions that can be created at the same time is limited by the capability of
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 16597c05b8f4..d59c883cb65b 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -35,6 +35,7 @@ import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Rect;
import android.hardware.hdmi.HdmiCecDeviceInfo;
@@ -281,6 +282,18 @@ public final class TvInputManagerService extends SystemService {
userState.inputMap.clear();
userState.inputMap = inputMap;
+
+ Resources r = Resources.getSystem();
+ userState.ratingSystemXmlUriSet.clear();
+ userState.ratingSystemXmlUriSet.add(TvContentRating.SYSTEM_CONTENT_RATING_SYSTEM_XML);
+ for (TvInputState state : userState.inputMap.values()) {
+ Uri ratingSystemXmlUri = state.mInfo.getRatingSystemXmlUri();
+ if (ratingSystemXmlUri != null) {
+ // TODO: need to check the validation of xml format and the duplication of rating
+ // systems.
+ userState.ratingSystemXmlUriSet.add(state.mInfo.getRatingSystemXmlUri());
+ }
+ }
}
private void switchUser(int userId) {
@@ -814,6 +827,23 @@ public final class TvInputManagerService extends SystemService {
}
@Override
+ public List<Uri> getTvContentRatingSystemXmls(int userId) {
+ final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, "getTvContentRatingSystemXmls");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ UserState userState = getUserStateLocked(resolvedUserId);
+ List<Uri> ratingSystemXmlUriList = new ArrayList<Uri>();
+ ratingSystemXmlUriList.addAll(userState.ratingSystemXmlUriSet);
+ return ratingSystemXmlUriList;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
public void registerCallback(final ITvInputManagerCallback callback, int userId) {
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
Binder.getCallingUid(), userId, "registerCallback");
@@ -1604,6 +1634,9 @@ public final class TvInputManagerService extends SystemService {
// A set of all TV input packages.
private final Set<String> packageSet = new HashSet<String>();
+ // A set of all TV content rating system xml uris.
+ private final Set<Uri> ratingSystemXmlUriSet = new HashSet<Uri>();
+
// A mapping from the token of a client to its state.
private final Map<IBinder, ClientState> clientStateMap =
new HashMap<IBinder, ClientState>();