| /* |
| * 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 android.media.tv; |
| |
| import android.annotation.NonNull; |
| import android.text.TextUtils; |
| |
| import com.android.internal.util.Preconditions; |
| |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Objects; |
| |
| /** |
| * A class representing a TV content rating. When a TV input service inserts the content rating |
| * information on a program into the database, this class can be used to generate the formatted |
| * string for |
| * {@link TvContract.Programs#COLUMN_CONTENT_RATING TvContract.Programs.COLUMN_CONTENT_RATING}. |
| * To create a {@code TvContentRating} object, use the |
| * {@link #createRating TvContentRating.createRating} method with valid rating system string |
| * constants. |
| * |
| * <p>It is possible for an application to define its own content rating system by supplying a |
| * content rating system definition XML resource (see example below) and declaring a broadcast |
| * receiver that filters {@link TvInputManager#ACTION_QUERY_CONTENT_RATING_SYSTEMS} in its manifest. |
| * |
| * <h3> Example: Rating system definition for the TV Parental Guidelines</h3> |
| * The following XML example shows how the TV Parental Guidelines in the United States can be |
| * defined: |
| * <p><pre class="prettyprint"> |
| * {@literal |
| * <rating-system-definitions xmlns:android="http://schemas.android.com/apk/res/android" |
| * android:versionCode="1"> |
| * <rating-system-definition android:name="US_TV" |
| * android:country="US" |
| * android:description="@string/description_us_tv"> |
| * <sub-rating-definition android:name="US_TV_D" |
| * android:title="D" |
| * android:description="@string/description_us_tv_d" /> |
| * <sub-rating-definition android:name="US_TV_L" |
| * android:title="L" |
| * android:description="@string/description_us_tv_l" /> |
| * <sub-rating-definition android:name="US_TV_S" |
| * android:title="S" |
| * android:description="@string/description_us_tv_s" /> |
| * <sub-rating-definition android:name="US_TV_V" |
| * android:title="V" |
| * android:description="@string/description_us_tv_v" /> |
| * <sub-rating-definition android:name="US_TV_FV" |
| * android:title="FV" |
| * android:description="@string/description_us_tv_fv" /> |
| * |
| * <rating-definition android:name="US_TV_Y" |
| * android:title="TV-Y" |
| * android:description="@string/description_us_tv_y" |
| * android:icon="@drawable/icon_us_tv_y" |
| * android:contentAgeHint="0" /> |
| * <rating-definition android:name="US_TV_Y7" |
| * android:title="TV-Y7" |
| * android:description="@string/description_us_tv_y7" |
| * android:icon="@drawable/icon_us_tv_y7" |
| * android:contentAgeHint="7"> |
| * <sub-rating android:name="US_TV_FV" /> |
| * </rating-definition> |
| * <rating-definition android:name="US_TV_G" |
| * android:title="TV-G" |
| * android:description="@string/description_us_tv_g" |
| * android:icon="@drawable/icon_us_tv_g" |
| * android:contentAgeHint="0" /> |
| * <rating-definition android:name="US_TV_PG" |
| * android:title="TV-PG" |
| * android:description="@string/description_us_tv_pg" |
| * android:icon="@drawable/icon_us_tv_pg" |
| * android:contentAgeHint="14"> |
| * <sub-rating android:name="US_TV_D" /> |
| * <sub-rating android:name="US_TV_L" /> |
| * <sub-rating android:name="US_TV_S" /> |
| * <sub-rating android:name="US_TV_V" /> |
| * </rating-definition> |
| * <rating-definition android:name="US_TV_14" |
| * android:title="TV-14" |
| * android:description="@string/description_us_tv_14" |
| * android:icon="@drawable/icon_us_tv_14" |
| * android:contentAgeHint="14"> |
| * <sub-rating android:name="US_TV_D" /> |
| * <sub-rating android:name="US_TV_L" /> |
| * <sub-rating android:name="US_TV_S" /> |
| * <sub-rating android:name="US_TV_V" /> |
| * </rating-definition> |
| * <rating-definition android:name="US_TV_MA" |
| * android:title="TV-MA" |
| * android:description="@string/description_us_tv_ma" |
| * android:icon="@drawable/icon_us_tv_ma" |
| * android:contentAgeHint="17"> |
| * <sub-rating android:name="US_TV_L" /> |
| * <sub-rating android:name="US_TV_S" /> |
| * <sub-rating android:name="US_TV_V" /> |
| * </rating-definition> |
| * <rating-order> |
| * <rating android:name="US_TV_Y" /> |
| * <rating android:name="US_TV_Y7" /> |
| * </rating-order> |
| * <rating-order> |
| * <rating android:name="US_TV_G" /> |
| * <rating android:name="US_TV_PG" /> |
| * <rating android:name="US_TV_14" /> |
| * <rating android:name="US_TV_MA" /> |
| * </rating-order> |
| * </rating-system-definition> |
| * </rating-system-definitions>}</pre> |
| * |
| * <h3>System defined rating strings</h3> |
| * The following strings are defined by the system to provide a standard way to create |
| * {@code TvContentRating} objects. |
| * |
| * <p>For example, to create an object that represents TV-PG rating with suggestive dialogue and |
| * coarse language from the TV Parental Guidelines in the United States, one can use the following |
| * code snippet: |
| * |
| * <pre> |
| * TvContentRating rating = TvContentRating.createRating( |
| * "com.android.tv", |
| * "US_TV", |
| * "US_TV_PG", |
| * "US_TV_D", "US_TV_L"); |
| * </pre> |
| * <h4>System defined string for domains</h4> |
| * <table> |
| * <tr> |
| * <th>Constant Value</th> |
| * <th>Description</th> |
| * </tr> |
| * <tr> |
| * <td>com.android.tv</td> |
| * <td>Used for creating system defined content ratings</td> |
| * </tr> |
| * </table> |
| * |
| * <h4>System defined strings for rating systems</h4> |
| * <table> |
| * <tr> |
| * <th>Constant Value</th> |
| * <th>Description</th> |
| * </tr> |
| * <tr> |
| * <td>AR_TV</td> |
| * <td>TV content rating system for Argentina</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV</td> |
| * <td>TV content rating system for Australia</td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV</td> |
| * <td>TV content rating system for Brazil</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_EN</td> |
| * <td>TV content rating system for Canada (English)</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_FR</td> |
| * <td>TV content rating system for Canada (French)</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB</td> |
| * <td>DTMB content rating system</td> |
| * </tr> |
| * <tr> |
| * <td>DVB</td> |
| * <td>DVB content rating system</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB</td> |
| * <td>DVB content rating system for Spain</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB</td> |
| * <td>DVB content rating system for France</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB</td> |
| * <td>ISDB content rating system</td> |
| * </tr> |
| * <tr> |
| * <td>KR_TV</td> |
| * <td>TV content rating system for South Korea</td> |
| * </tr> |
| * <tr> |
| * <td>NZ_TV</td> |
| * <td>TV content rating system for New Zealand</td> |
| * </tr> |
| * <tr> |
| * <td>SG_TV</td> |
| * <td>TV content rating system for Singapore</td> |
| * </tr> |
| * <tr> |
| * <td>TH_TV</td> |
| * <td>TV content rating system for Thailand</td> |
| * </tr> |
| * <tr> |
| * <td>US_MV</td> |
| * <td>Movie content rating system for the United States</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV</td> |
| * <td>TV content rating system for the United States</td> |
| * </tr> |
| * </table> |
| * |
| * <h4>System defined strings for ratings</h4> |
| * <table> |
| * <tr> |
| * <th>Rating System</th> |
| * <th>Constant Value</th> |
| * <th>Description</th> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="4">AR_TV</td> |
| * <td>AR_TV_ATP</td> |
| * <td>Suitable for all audiences. Programs may contain mild violence, language and mature |
| * situations</td> |
| * </tr> |
| * <tr> |
| * <td>AR_TV_SAM_13</td> |
| * <td>Suitable for ages 13 and up. Programs may contain mild to moderate language and mild |
| * violence and sexual references</td> |
| * </tr> |
| * <tr> |
| * <td>AR_TV_SAM_16</td> |
| * <td>Suitable for ages 16 and up. Programs may contain more intensive violence and coarse |
| * language, partial nudity and moderate sexual references</td> |
| * </tr> |
| * <tr> |
| * <td>AR_TV_SAM_18</td> |
| * <td>Suitable for mature audiences only. Programs contain strong violence, coarse language |
| * and explicit sexual references</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="8">AU_TV</td> |
| * <td>AU_TV_P</td> |
| * <td>Recommended for younger children aged between 2 and 11 years</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV_C</td> |
| * <td>Recommended for older children aged between 5 and 14 years</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV_G</td> |
| * <td>Recommended for all ages</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV_PG</td> |
| * <td>Parental guidance is recommended for young viewers under 15</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV_M</td> |
| * <td>Recommended for mature audiences aged 15 years and over</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV_MA</td> |
| * <td>Not suitable for children and teens under 15, due to sexual descriptions, course |
| * language, adult themes or drug use</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV_AV</td> |
| * <td>Not suitable for children and teens under 15. This category is used specifically for |
| * violent programs</td> |
| * </tr> |
| * <tr> |
| * <td>AU_TV_R</td> |
| * <td>Not for children under 18. Content may include graphic violence, sexual situations, |
| * coarse language and explicit drug use</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="6">BR_TV</td> |
| * <td>BR_TV_L</td> |
| * <td>Content is suitable for all audiences</td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV_10</td> |
| * <td>Content suitable for viewers over the age of 10</td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV_12</td> |
| * <td>Content suitable for viewers over the age of 12</td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV_14</td> |
| * <td>Content suitable for viewers over the age of 14</td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV_16</td> |
| * <td>Content suitable for viewers over the age of 16</td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV_18</td> |
| * <td>Content suitable for viewers over the age of 18</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="7">CA_TV_EN</td> |
| * <td>CA_TV_EN_EXEMPT</td> |
| * <td>Exempt from ratings</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_EN_C</td> |
| * <td>Suitable for children ages 2–7</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_EN_C8</td> |
| * <td>Suitable for children ages 8 and older</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_EN_G</td> |
| * <td>Suitable for the entire family</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_EN_PG</td> |
| * <td>May contain moderate violence, profanity, nudity, and sexual references</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_EN_14</td> |
| * <td>Intended for viewers ages 14 and older</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_EN_18</td> |
| * <td>Intended for viewers ages 18 and older</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="6">CA_TV_FR</td> |
| * <td>CA_TV_FR_E</td> |
| * <td>Exempt from ratings</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_FR_G</td> |
| * <td>Appropriate for all ages</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_FR_8</td> |
| * <td>Appropriate for children 8</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_FR_13</td> |
| * <td>Suitable for children 13</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_FR_16</td> |
| * <td>Recommended for children over the age of 16</td> |
| * </tr> |
| * <tr> |
| * <td>CA_TV_FR_18</td> |
| * <td>Only to be viewed by adults</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="15">DTMB</td> |
| * <td>DTMB_4</td> |
| * <td>Recommended for ages 4 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_5</td> |
| * <td>Recommended for ages 5 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_6</td> |
| * <td>Recommended for ages 6 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_7</td> |
| * <td>Recommended for ages 7 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_8</td> |
| * <td>Recommended for ages 8 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_9</td> |
| * <td>Recommended for ages 9 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_10</td> |
| * <td>Recommended for ages 10 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_11</td> |
| * <td>Recommended for ages 11 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_12</td> |
| * <td>Recommended for ages 12 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_13</td> |
| * <td>Recommended for ages 13 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_14</td> |
| * <td>Recommended for ages 14 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_15</td> |
| * <td>Recommended for ages 15 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_16</td> |
| * <td>Recommended for ages 16 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_17</td> |
| * <td>Recommended for ages 17 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DTMB_18</td> |
| * <td>Recommended for ages 18 and over</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="15">DVB</td> |
| * <td>DVB_4</td> |
| * <td>Recommended for ages 4 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_5</td> |
| * <td>Recommended for ages 5 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_6</td> |
| * <td>Recommended for ages 6 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_7</td> |
| * <td>Recommended for ages 7 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_8</td> |
| * <td>Recommended for ages 8 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_9</td> |
| * <td>Recommended for ages 9 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_10</td> |
| * <td>Recommended for ages 10 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_11</td> |
| * <td>Recommended for ages 11 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_12</td> |
| * <td>Recommended for ages 12 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_13</td> |
| * <td>Recommended for ages 13 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_14</td> |
| * <td>Recommended for ages 14 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_15</td> |
| * <td>Recommended for ages 15 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_16</td> |
| * <td>Recommended for ages 16 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_17</td> |
| * <td>Recommended for ages 17 and over</td> |
| * </tr> |
| * <tr> |
| * <td>DVB_18</td> |
| * <td>Recommended for ages 18 and over</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="18">ES_DVB</td> |
| * <td>ES_DVB_ALL</td> |
| * <td>Recommended for all ages</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_C</td> |
| * <td>Recommended for children</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_X</td> |
| * <td>Recommended for adults</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_4</td> |
| * <td>Recommended for ages 4 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_5</td> |
| * <td>Recommended for ages 5 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_6</td> |
| * <td>Recommended for ages 6 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_7</td> |
| * <td>Recommended for ages 7 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_8</td> |
| * <td>Recommended for ages 8 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_9</td> |
| * <td>Recommended for ages 9 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_10</td> |
| * <td>Recommended for ages 10 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_11</td> |
| * <td>Recommended for ages 11 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_12</td> |
| * <td>Recommended for ages 12 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_13</td> |
| * <td>Recommended for ages 13 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_14</td> |
| * <td>Recommended for ages 14 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_15</td> |
| * <td>Recommended for ages 15 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_16</td> |
| * <td>Recommended for ages 16 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_17</td> |
| * <td>Recommended for ages 17 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ES_DVB_18</td> |
| * <td>Recommended for ages 18 and over</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="16">FR_DVB</td> |
| * <td>FR_DVB_U</td> |
| * <td>Recommended for all ages</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_4</td> |
| * <td>Recommended for ages 4 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_5</td> |
| * <td>Recommended for ages 5 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_6</td> |
| * <td>Recommended for ages 6 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_7</td> |
| * <td>Recommended for ages 7 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_8</td> |
| * <td>Recommended for ages 8 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_9</td> |
| * <td>Recommended for ages 9 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_10</td> |
| * <td>Recommended for ages 10 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_11</td> |
| * <td>Recommended for ages 11 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_12</td> |
| * <td>Recommended for ages 12 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_13</td> |
| * <td>Recommended for ages 13 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_14</td> |
| * <td>Recommended for ages 14 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_15</td> |
| * <td>Recommended for ages 15 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_16</td> |
| * <td>Recommended for ages 16 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_17</td> |
| * <td>Recommended for ages 17 and over</td> |
| * </tr> |
| * <tr> |
| * <td>FR_DVB_18</td> |
| * <td>Recommended for ages 18 and over</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="17">ISDB</td> |
| * <td>ISDB_4</td> |
| * <td>Recommended for ages 4 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_5</td> |
| * <td>Recommended for ages 5 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_6</td> |
| * <td>Recommended for ages 6 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_7</td> |
| * <td>Recommended for ages 7 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_8</td> |
| * <td>Recommended for ages 8 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_9</td> |
| * <td>Recommended for ages 9 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_10</td> |
| * <td>Recommended for ages 10 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_11</td> |
| * <td>Recommended for ages 11 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_12</td> |
| * <td>Recommended for ages 12 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_13</td> |
| * <td>Recommended for ages 13 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_14</td> |
| * <td>Recommended for ages 14 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_15</td> |
| * <td>Recommended for ages 15 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_16</td> |
| * <td>Recommended for ages 16 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_17</td> |
| * <td>Recommended for ages 17 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_18</td> |
| * <td>Recommended for ages 18 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_19</td> |
| * <td>Recommended for ages 19 and over</td> |
| * </tr> |
| * <tr> |
| * <td>ISDB_20</td> |
| * <td>Recommended for ages 20 and over</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="5">KR_TV</td> |
| * <td>KR_TV_ALL</td> |
| * <td>Appropriate for all ages</td> |
| * </tr> |
| * <tr> |
| * <td>KR_TV_7</td> |
| * <td>May contain material inappropriate for children younger than 7, and parental |
| * discretion should be used</td> |
| * </tr> |
| * <tr> |
| * <td>KR_TV_12</td> |
| * <td>May deemed inappropriate for those younger than 12, and parental discretion should be |
| * used</td> |
| * </tr> |
| * <tr> |
| * <td>KR_TV_15</td> |
| * <td>May be inappropriate for children under 15, and that parental discretion should be |
| * used</td> |
| * </tr> |
| * <tr> |
| * <td>KR_TV_19</td> |
| * <td>For adults only</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="3">NZ_TV</td> |
| * <td>NZ_TV_G</td> |
| * <td>Programmes which exclude material likely to be unsuitable for children. Programmes |
| * may not necessarily be designed for child viewers but should not contain material likely |
| * to alarm or distress them</td> |
| * </tr> |
| * <tr> |
| * <td>NZ_TV_PGR</td> |
| * <td>Programmes containing material more suited for mature audiences but not necessarily |
| * unsuitable for child viewers when subject to the guidance of a parent or an adult</td> |
| * </tr> |
| * <tr> |
| * <td>NZ_TV_AO</td> |
| * <td>Programmes containing adult themes and directed primarily at mature audiences</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="6">SG_TV</td> |
| * <td>SG_TV_G</td> |
| * <td>Suitable for all ages</td> |
| * </tr> |
| * <tr> |
| * <td>SG_TV_PG</td> |
| * <td>Suitable for all but parents should guide their young</td> |
| * </tr> |
| * <tr> |
| * <td>SG_TV_PG13</td> |
| * <td>Suitable for persons aged 13 and above but parental guidance is advised for children |
| * below 13</td> |
| * </tr> |
| * <tr> |
| * <td>SG_TV_NC16</td> |
| * <td>Suitable for persons aged 16 and above</td> |
| * </tr> |
| * <tr> |
| * <td>SG_TV_M18</td> |
| * <td>Suitable for persons aged 18 and above</td> |
| * </tr> |
| * <tr> |
| * <td>SG_TV_R21</td> |
| * <td>Suitable for adults aged 21 and above</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="6">TH_TV</td> |
| * <td>TH_TV_4</td> |
| * <td>Suitable for audiences 3 to 5 years of age</td> |
| * </tr> |
| * <tr> |
| * <td>TH_TV_6</td> |
| * <td>Suitable for audiences 6 to 12 years of age</td> |
| * </tr> |
| * <tr> |
| * <td>TH_TV_10</td> |
| * <td>Suitable for all audiences</td> |
| * </tr> |
| * <tr> |
| * <td>TH_TV_13</td> |
| * <td>Parental guidance suggested for viewers age below 13</td> |
| * </tr> |
| * <tr> |
| * <td>TH_TV_18</td> |
| * <td>Parental guidance suggested for viewers age below 18</td> |
| * </tr> |
| * <tr> |
| * <td>TH_TV_19</td> |
| * <td>Not suitable for children and teenagers</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="5">US_MV</td> |
| * <td>US_MV_G</td> |
| * <td>General audiences</td> |
| * </tr> |
| * <tr> |
| * <td>US_MV_PG</td> |
| * <td>Parental guidance suggested</td> |
| * </tr> |
| * <tr> |
| * <td>US_MV_PG13</td> |
| * <td>Parents strongly cautioned</td> |
| * </tr> |
| * <tr> |
| * <td>US_MV_R</td> |
| * <td>Restricted, under 17 requires accompanying parent or adult guardian</td> |
| * </tr> |
| * <tr> |
| * <td>US_MV_NC17</td> |
| * <td>No one 17 and under admitted</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="6">US_TV</td> |
| * <td>US_TV_Y</td> |
| * <td>This program is designed to be appropriate for all children</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_Y7</td> |
| * <td>This program is designed for children age 7 and above</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_G</td> |
| * <td>Most parents would find this program suitable for all ages</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_PG</td> |
| * <td>This program contains material that parents may find unsuitable for younger children |
| * </td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_14</td> |
| * <td>This program contains some material that many parents would find unsuitable for |
| * children under 14 years of age</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_MA</td> |
| * <td>This program is specifically designed to be viewed by adults and therefore may be |
| * unsuitable for children under 17</td> |
| * </tr> |
| * </table> |
| * |
| * <h4>System defined strings for sub-ratings</h4> |
| * <table> |
| * <tr> |
| * <th>Rating System</th> |
| * <th>Constant Value</th> |
| * <th>Description</th> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="3">BR_TV</td> |
| * <td>BR_TV_D</td> |
| * <td>Drugs<br/>Applicable to BR_TV_L, BR_TV_10, BR_TV_12, BR_TV_14, BR_TV_16, and BR_TV_18 |
| * </td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV_S</td> |
| * <td>Sex<br/>Applicable to BR_TV_L, BR_TV_10, BR_TV_12, BR_TV_14, BR_TV_16, and BR_TV_18 |
| * </td> |
| * </tr> |
| * <tr> |
| * <td>BR_TV_V</td> |
| * <td>Violence<br/>Applicable to BR_TV_L, BR_TV_10, BR_TV_12, BR_TV_14, BR_TV_16, and |
| * BR_TV_18</td> |
| * </tr> |
| * <tr> |
| * <td valign="top" rowspan="5">US_TV</td> |
| * <td>US_TV_D</td> |
| * <td>Suggestive dialogue (Usually means talks about sex)<br/>Applicable to US_TV_PG, and |
| * US_TV_14</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_L</td> |
| * <td>Coarse language<br/>Applicable to US_TV_PG, US_TV_14, and US_TV_MA</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_S</td> |
| * <td>Sexual content<br/>Applicable to US_TV_PG, US_TV_14, and US_TV_MA</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_V</td> |
| * <td>Violence<br/>Applicable to US_TV_PG, US_TV_14, and US_TV_MA</td> |
| * </tr> |
| * <tr> |
| * <td>US_TV_FV</td> |
| * <td>Fantasy violence (Children's programming only)<br/>Applicable to US_TV_Y7</td> |
| * </tr> |
| * </table> |
| */ |
| public final class TvContentRating { |
| // 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 final String mDomain; |
| private final String mRatingSystem; |
| private final String mRating; |
| private final String[] mSubRatings; |
| private final int mHashCode; |
| |
| /** |
| * Rating constant denoting unrated content. Used to handle the case where the content rating |
| * information is missing. |
| * |
| * <p>TV input services can call {@link TvInputManager#isRatingBlocked} with this constant to |
| * determine whether they should block unrated content. The subsequent call to |
| * {@link TvInputService.Session#notifyContentBlocked} with the same constant notifies |
| * applications that the current program content is blocked by parental controls. |
| */ |
| public static final TvContentRating UNRATED = new TvContentRating("null", "null", "null", null); |
| |
| /** |
| * Creates a {@code TvContentRating} object with predefined content rating strings. |
| * |
| * @param domain The domain string. For example, "com.android.tv". |
| * @param ratingSystem The rating system string. For example, "US_TV". |
| * @param rating The content rating string. For example, "US_TV_PG". |
| * @param subRatings The sub-rating strings. For example, "US_TV_D" and "US_TV_L". |
| * @return A {@code TvContentRating} object. |
| * @throws IllegalArgumentException If {@code domain}, {@code ratingSystem} or {@code rating} is |
| * {@code null}. |
| */ |
| public static TvContentRating createRating(String domain, String ratingSystem, |
| String rating, String... subRatings) { |
| if (TextUtils.isEmpty(domain)) { |
| throw new IllegalArgumentException("domain cannot be empty"); |
| } |
| if (TextUtils.isEmpty(ratingSystem)) { |
| throw new IllegalArgumentException("ratingSystem cannot be empty"); |
| } |
| if (TextUtils.isEmpty(rating)) { |
| throw new IllegalArgumentException("rating cannot be empty"); |
| } |
| return new TvContentRating(domain, ratingSystem, rating, subRatings); |
| } |
| |
| /** |
| * Recovers a {@code TvContentRating} object from the string that was previously created from |
| * {@link #flattenToString}. |
| * |
| * @param ratingString The string returned by {@link #flattenToString}. |
| * @return the {@code TvContentRating} object containing the domain, rating system, rating and |
| * sub-ratings information encoded in {@code ratingString}. |
| * @see #flattenToString |
| */ |
| 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 < 3) { |
| throw new IllegalArgumentException("Invalid rating string: " + ratingString); |
| } |
| if (strs.length > 3) { |
| String[] subRatings = new String[strs.length - 3]; |
| System.arraycopy(strs, 3, subRatings, 0, subRatings.length); |
| return new TvContentRating(strs[0], strs[1], strs[2], subRatings); |
| } |
| return new TvContentRating(strs[0], strs[1], strs[2], null); |
| } |
| |
| /** |
| * Constructs a TvContentRating object from a given rating and sub-rating constants. |
| * |
| * @param domain The string for domain of the content rating system such as "com.android.tv". |
| * @param ratingSystem The rating system string such as "US_TV". |
| * @param rating The content rating string such as "US_TV_PG". |
| * @param subRatings The sub-rating strings such as "US_TV_D" and "US_TV_L". |
| */ |
| private TvContentRating( |
| String domain, String ratingSystem, String rating, String[] subRatings) { |
| mDomain = domain; |
| mRatingSystem = ratingSystem; |
| mRating = rating; |
| if (subRatings == null || subRatings.length == 0) { |
| mSubRatings = null; |
| } else { |
| Arrays.sort(subRatings); |
| mSubRatings = subRatings; |
| } |
| mHashCode = 31 * Objects.hash(mDomain, mRating) + Arrays.hashCode(mSubRatings); |
| } |
| |
| /** |
| * Returns the domain of this {@code TvContentRating} object. |
| */ |
| public String getDomain() { |
| return mDomain; |
| } |
| |
| /** |
| * Returns the rating system of this {@code TvContentRating} object. |
| */ |
| public String getRatingSystem() { |
| return mRatingSystem; |
| } |
| |
| /** |
| * Returns the main rating of this {@code TvContentRating} object. |
| */ |
| public String getMainRating() { |
| return mRating; |
| } |
| |
| /** |
| * Returns the unmodifiable sub-rating string {@link List} of this {@code TvContentRating} |
| * object. |
| */ |
| public List<String> getSubRatings() { |
| if (mSubRatings == null) { |
| return null; |
| } |
| return Collections.unmodifiableList(Arrays.asList(mSubRatings)); |
| } |
| |
| /** |
| * Returns a string that unambiguously describes the rating information contained in a |
| * {@code TvContentRating} object. One can later recover the object from this string through |
| * {@link #unflattenFromString}. |
| * |
| * @return a string containing the rating information, which can later be stored in the |
| * database. |
| * @see #unflattenFromString |
| */ |
| public String flattenToString() { |
| StringBuilder builder = new StringBuilder(); |
| builder.append(mDomain); |
| builder.append(DELIMITER); |
| builder.append(mRatingSystem); |
| builder.append(DELIMITER); |
| builder.append(mRating); |
| if (mSubRatings != null) { |
| for (String subRating : mSubRatings) { |
| builder.append(DELIMITER); |
| builder.append(subRating); |
| } |
| } |
| return builder.toString(); |
| } |
| |
| /** |
| * Returns {@code 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>For example, a {@code TvContentRating} object that represents TV-PG with |
| * S(Sexual content) and V(Violence) contains TV-PG, TV-PG/S, TV-PG/V and itself. |
| * |
| * @param rating The {@link TvContentRating} to check. |
| * @return {@code true} if this object contains {@code rating}, {@code false} otherwise. |
| */ |
| public final boolean contains(@NonNull TvContentRating rating) { |
| Preconditions.checkNotNull(rating); |
| if (!rating.getMainRating().equals(mRating)) { |
| return false; |
| } |
| if (!rating.getDomain().equals(mDomain) || |
| !rating.getRatingSystem().equals(mRatingSystem) || |
| !rating.getMainRating().equals(mRating)) { |
| return false; |
| } |
| List<String> subRatings = getSubRatings(); |
| List<String> subRatingsOther = rating.getSubRatings(); |
| if (subRatings == null && subRatingsOther == null) { |
| return true; |
| } else if (subRatings == null && subRatingsOther != null) { |
| return false; |
| } else if (subRatings != null && subRatingsOther == null) { |
| return true; |
| } else { |
| return subRatings.containsAll(subRatingsOther); |
| } |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (!(obj instanceof TvContentRating)) { |
| return false; |
| } |
| TvContentRating other = (TvContentRating) obj; |
| if (mHashCode != other.mHashCode) { |
| return false; |
| } |
| if (!TextUtils.equals(mDomain, other.mDomain)) { |
| return false; |
| } |
| if (!TextUtils.equals(mRatingSystem, other.mRatingSystem)) { |
| return false; |
| } |
| if (!TextUtils.equals(mRating, other.mRating)) { |
| return false; |
| } |
| return Arrays.equals(mSubRatings, other.mSubRatings); |
| } |
| |
| @Override |
| public int hashCode() { |
| return mHashCode; |
| } |
| } |