TvContentRating.java revision 1fd38bd99610d7dc2a9c335ae2af4089fe1006a1
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.media.tv;
18
19import android.annotation.SystemApi;
20import android.net.Uri;
21import android.text.TextUtils;
22import android.util.Log;
23
24import java.util.Arrays;
25import java.util.Collections;
26import java.util.List;
27
28/**
29 * A class representing a TV content rating.
30 * When a TV input service provides the content rating information of a program into TV provider,
31 * TvContentRating class will be used for generating the value of {@link
32 * TvContract.Programs#COLUMN_CONTENT_RATING}. To create an object of {@link TvContentRating}, use
33 * the {@link #createRating} method with valid arguments. The arguments could be a system defined
34 * strings, or a TV input service defined strings.
35 * TV input service defined strings are in an xml file defined in <code>&lt;{@link
36 * android.R.styleable#TvInputService tv-input}&gt;</code> with the {@link
37 * android.R.attr#contentRatingSystemXml contentRatingSystemXml} attribute by the TV input service.
38 *
39 * <h3> Content Rating System XML format </h3>
40 * The XML file for publishing content rating system should follow the DTD bellow:
41 * <p><pre class="prettyprint">
42 * &lt;?xml version="1.0" encoding="UTF-8"?&gt;
43 * &lt;!DOCTYPE rating-systems [
44 *     &lt;!ELEMENT rating-system-definitions (rating-system-definition+)&gt;
45 *     &lt;!ELEMENT rating-system-definition (
46 *         (sub-rating-definition*, rating-definition, sub-rating-definition*)+, order*)&gt;
47 *     &lt;!ATTLIST rating-system-definition
48 *         id          ID    #REQUIRED
49 *         displayName CDATA #IMPLIED
50 *         description CDATA #IMPLIED
51 *         country     CDATA #IMPLIED&gt;
52 *     &lt;!ELEMENT sub-rating-definition EMPTY&gt;
53 *     &lt;!ATTLIST sub-rating-definition
54 *         id          ID    #REQUIRED
55 *         displayName CDATA #IMPLIED
56 *         icon        CDATA #IMPLIED
57 *         description CDATA #IMPLIED&gt;
58 *     &lt;!ELEMENT rating-definition (sub-rating*))&gt;
59 *     &lt;!ATTLIST rating-definition
60 *         id          ID    #REQUIRED
61 *         displayName CDATA #IMPLIED
62 *         icon        CDATA #IMPLIED
63 *         description CDATA #IMPLIED&gt;
64 *     &lt;!ELEMENT sub-rating EMPTY&gt;
65 *     &lt;!ATTLIST sub-rating id IDREF #REQUIRED&gt;
66 *     &lt;!ELEMENT order (rating, rating+)&gt;
67 *     &lt;!ELEMENT rating EMPTY&gt;
68 *     &lt;!ATTLIST rating id IDREF #REQUIRED&gt;
69 * ]&gt;
70 * </pre></p>
71 *
72 * <h3>System defined rating strings</h3>
73 *
74 * <u>System defined string for {@code domain}</u>
75 * <table border="0" cellspacing="0" cellpadding="0">
76 *     <tr>
77 *         <td>String value</td>
78 *         <td>Comments</td>
79 *     </tr>
80 *     <tr>
81 *         <td>android.media.tv</td>
82 *         <td>Used for creating system defined content ratings</td>
83 *     </tr>
84 * </table>
85 * <u>System defined string for {@code ratingSystem}</u>
86 * <table border="0" cellspacing="0" cellpadding="0">
87 *     <tr>
88 *         <td>String value</td>
89 *         <td>Comments</td>
90 *     </tr>
91 *     <!--tr>
92 *         <td>AM_TV</td>
93 *         <td></td>
94 *     </tr-->
95 *     <!--tr>
96 *         <td>AR_TV</td>
97 *         <td></td>
98 *     </tr-->
99 *     <tr>
100 *         <td>AU_TV</td>
101 *         <td>Australian TV Classification</td>
102 *     </tr>
103 *     <!--tr>
104 *         <td>BG_TV</td>
105 *         <td></td>
106 *     </tr-->
107 *     <!--tr>
108 *         <td>BR_TV</td>
109 *         <td></td>
110 *     </tr-->
111 *     <!--tr>
112 *         <td>CA_TV</td>
113 *         <td></td>
114 *     </tr-->
115 *     <!--tr>
116 *         <td>CH_TV</td>
117 *         <td></td>
118 *     </tr-->
119 *     <!--tr>
120 *         <td>CL_TV</td>
121 *         <td></td>
122 *     </tr-->
123 *     <!--tr>
124 *         <td>CO_TV</td>
125 *         <td></td>
126 *     </tr-->
127 *     <tr>
128 *         <td>DE_TV</td>
129 *         <td>The Germany television rating system</td>
130 *     </tr>
131 *     <!--tr>
132 *         <td>DK_TV</td>
133 *         <td></td>
134 *     </tr-->
135 *     <tr>
136 *         <td>ES_TV</td>
137 *         <td>The Spanish rating system for television programs</td>
138 *     </tr>
139 *     <!--tr>
140 *         <td>FI_TV</td>
141 *         <td></td>
142 *     </tr-->
143 *     <tr>
144 *         <td>FR_TV</td>
145 *         <td>The content rating system in French</td>
146 *     </tr>
147 *     <!--tr>
148 *         <td>GR_TV</td>
149 *         <td></td>
150 *     </tr-->
151 *     <!--tr>
152 *         <td>HK_TV</td>
153 *         <td></td>
154 *     </tr-->
155 *     <!--tr>
156 *         <td>HU_TV</td>
157 *         <td></td>
158 *     </tr-->
159 *     <!--tr>
160 *         <td>ID_TV</td>
161 *         <td></td>
162 *     </tr-->
163 *     <!--tr>
164 *         <td>IE_TV</td>
165 *         <td></td>
166 *     </tr-->
167 *     <!--tr>
168 *         <td>IL_TV</td>
169 *         <td></td>
170 *     </tr-->
171 *     <!--tr>
172 *         <td>IN_TV</td>
173 *         <td></td>
174 *     </tr-->
175 *     <!--tr>
176 *         <td>IS_TV</td>
177 *         <td></td>
178 *     </tr-->
179 *     <!--tr>
180 *         <td>IT_TV</td>
181 *         <td></td>
182 *     </tr-->
183 *     <!--tr>
184 *         <td>KH_TV</td>
185 *         <td></td>
186 *     </tr-->
187 *     <tr>
188 *         <td>KR_TV</td>
189 *         <td>The South Korean television rating system</td>
190 *     </tr>
191 *     <!--tr>
192 *         <td>MV_TV</td>
193 *         <td></td>
194 *     </tr-->
195 *     <!--tr>
196 *         <td>MX_TV</td>
197 *         <td></td>
198 *     </tr-->
199 *     <!--tr>
200 *         <td>MY_TV</td>
201 *         <td></td>
202 *     </tr-->
203 *     <tr>
204 *         <td>NL_TV</td>
205 *         <td>The television rating system in the Netherlands</td>
206 *     </tr>
207 *     <!--tr>
208 *         <td>NZ_TV</td>
209 *         <td></td>
210 *     </tr-->
211 *     <!--tr>
212 *         <td>PE_TV</td>
213 *         <td></td>
214 *     </tr-->
215 *     <!--tr>
216 *         <td>PH_TV</td>
217 *         <td></td>
218 *     </tr-->
219 *     <!--tr>
220 *         <td>PL_TV</td>
221 *         <td></td>
222 *     </tr-->
223 *     <!--tr>
224 *         <td>PT_TV</td>
225 *         <td></td>
226 *     </tr-->
227 *     <!--tr>
228 *         <td>RO_TV</td>
229 *         <td></td>
230 *     </tr-->
231 *     <!--tr>
232 *         <td>RU_TV</td>
233 *         <td></td>
234 *     </tr-->
235 *     <!--tr>
236 *         <td>RS_TV</td>
237 *         <td></td>
238 *     </tr-->
239 *     <!--tr>
240 *         <td>SG_TV</td>
241 *         <td></td>
242 *     </tr-->
243 *     <!--tr>
244 *         <td>SI_TV</td>
245 *         <td></td>
246 *     </tr-->
247 *     <!--tr>
248 *         <td>TH_TV</td>
249 *         <td></td>
250 *     </tr-->
251 *     <!--tr>
252 *         <td>TR_TV</td>
253 *         <td></td>
254 *     </tr-->
255 *     <!--tr>
256 *         <td>TW_TV</td>
257 *         <td></td>
258 *     </tr-->
259 *     <!--tr>
260 *         <td>UA_TV</td>
261 *         <td></td>
262 *     </tr-->
263 *     <tr>
264 *         <td>US_TVPG</td>
265 *         <td>The TV Parental Guidelines for US TV content ratings</td>
266 *     </tr>
267 *     <!--tr>
268 *         <td>VE_TV</td>
269 *         <td></td>
270 *     </tr-->
271 *     <!--tr>
272 *         <td>ZA_TV</td>
273 *         <td></td>
274 *     </tr-->
275 * </table>
276 *
277 * <u>System defined string for {@code rating}</u>
278 * <table border="0" cellspacing="0" cellpadding="0">
279 *     <tr>
280 *         <td>String value</td>
281 *         <td>Comments</td>
282 *     </tr>
283 *     <!--tr>
284 *         <td>AM_TV_ALL</td>
285 *         <td></td>
286 *     </tr-->
287 *     <!--tr>
288 *         <td>AR_TV_ALL</td>
289 *         <td></td>
290 *     </tr-->
291 *     <tr>
292 *         <td>AU_TV_CTC</td>
293 *         <td>A rating string for {@code AU_TV}. The content has been assessed and approved for
294 *         advertising unclassified films. Any advertising of unclassified films must display the
295 *         CTC message.</td>
296 *     </tr>
297 *     <tr>
298 *         <td>AU_TV_G</td>
299 *         <td>A rating string for {@code AU_TV}. The content is very mild in impact. The G
300 *         classification is suitable for everyone. G products may contain classifiable elements
301 *         such as language and themes that are very mild in impact. However, some G-classified
302 *         films may contain content that is not of interest to children.</td>
303 *     </tr>
304 *     <tr>
305 *         <td>AU_TV_PG</td>
306 *         <td>A rating string for {@code AU_TV}. The content is mild in impact. The impact of PG
307 *         (Parental Guidance) classified films should be no higher than mild, but they may contain
308 *         content that children find confusing or upsetting and may require the guidance or parents
309 *         and guardians. They may, for example, contain classifiable elements such as language and
310 *         themes that are mild in impact. It is not recommended for viewing or playing by persons
311 *         under 15 without guidance from parents or guardians.</td>
312 *     </tr>
313 *     <tr>
314 *         <td>AU_TV_M</td>
315 *         <td>A rating string for {@code AU_TV}. The content is moderate in impact. Films
316 *         classified M (Mature) contain content of a moderate impact and are recommended for
317 *         teenagers aged 15 years and over. Children under 15 may legally access this material
318 *         because it is an advisory category. However, M classified films may include classifiable
319 *         elements such as violence and nudity of moderate impact that are not recommended for
320 *         children under 15 years. Parents and guardians may need to find out more about the film’s
321 *         specific content, before deciding whether the material is suitable for their child.</td>
322 *     </tr>
323 *     <tr>
324 *         <td>AU_TV_MA16</td>
325 *         <td>A rating string for {@code AU_TV}. The content is strong in impact. MA 15+ classified
326 *         material contains strong content and is legally restricted to persons 15 years and over.
327 *         It may contain classifiable elements such as sex scenes and drug use that are strong in
328 *         impact. A person may be asked to show proof of their age before hiring or purchasing an
329 *         MA 15+ film. Cinema staff may also request that the person show proof of their age before
330 *         allowing them to watch an MA 15+ film. Children under the age of 15 may not legally
331 *         watch, buy or hire MA 15+ classified material unless they are in the company of a parent
332 *         or adult guardian. Children under 15 who go to the cinema to see an MA 15+ film must be
333 *         accompanied by a parent or adult guardian for the duration of the film. The parent or
334 *         adult guardian must also purchase the movie ticket for the child. The guardian must be
335 *         an adult exercising parental control over the person under 15 years of age. The guardian
336 *         needs to be 18 years or older.</td>
337 *     </tr>
338 *     <tr>
339 *         <td>AU_TV_R18</td>
340 *         <td>A rating string for {@code AU_TV}. The content is high in impact. R 18+ classified
341 *         material is restricted to adults. Such material may contain classifiable elements such as
342 *         sex scenes and drug use that are high in impact. Some material classified R18+ may be
343 *         offensive to sections of the adult community. A person may be asked for proof of their
344 *         age before purchasing, hiring or viewing R18+ films at a retail store or cinema.</td>
345 *     </tr>
346 *     <tr>
347 *         <td>AU_TV_X18</td>
348 *         <td>A rating string for {@code AU_TV}. X 18+ films are restricted to adults. This
349 *         classification is a special and legally restricted category which contains only sexually
350 *         explicit content. That is, material which shows actual sexual intercourse and other
351 *         sexual activity between consenting adults. X18+ films are only available for sale or hire
352 *         in the ACT and the NT.</td>
353 *     </tr>
354 *     <!--tr>
355 *         <td>BG_TV_ALL</td>
356 *         <td></td>
357 *     </tr-->
358 *     <!--tr>
359 *         <td>BR_TV_ALL</td>
360 *         <td></td>
361 *     </tr-->
362 *     <!--tr>
363 *         <td>CA_TV_ALL</td>
364 *         <td></td>
365 *     </tr-->
366 *     <!--tr>
367 *         <td>CH_TV_ALL</td>
368 *         <td></td>
369 *     </tr-->
370 *     <!--tr>
371 *         <td>CL_TV_ALL</td>
372 *         <td></td>
373 *     </tr-->
374 *     <!--tr>
375 *         <td>CO_TV_ALL</td>
376 *         <td></td>
377 *     </tr-->
378 *     <tr>
379 *         <td>DE_TV_ALL</td>
380 *         <td>Without restriction. There are time schedules and certain age groups which have to be
381 *         considered. {@code DE_TV_ALL} is scheduled in daytime (6:00AM – 8:00PM). However, cinema
382 *         films classified with "12" may be shown during the daytime, if they are not considered
383 *         harmful to younger children.</td>
384 *     </tr>
385 *     <tr>
386 *         <td>DE_TV_12</td>
387 *         <td>Suitable for 12 years and above. There are time schedules and certain age groups
388 *         which have to be considered. {@code DE_TV_12} is scheduled in primetime (from 8:00PM
389 *         – 10.00 p.m.).</td>
390 *     </tr>
391 *     <tr>
392 *         <td>DE_TV_16</td>
393 *         <td>Suitable for 16 years and above. There are time schedules and certain age groups
394 *         which have to be considered. {@code DE_TV_16} is scheduled in late evening (from 10:00PM
395 *         - 11:00PM). </td>
396 *     </tr>
397 *     <tr>
398 *         <td>DE_TV_18</td>
399 *         <td>Suitable for 18 years and above. There are time schedules and certain age groups
400 *         which have to be considered. {@code DE_TV_18} is scheduled in late night (from 11:00PM
401 *         - 6:00AM). </td>
402 *     </tr>
403 *     <!--tr>
404 *         <td>DK_TV_ALL</td>
405 *         <td></td>
406 *     </tr-->
407 *     <tr>
408 *         <td>ES_TV_ALL</td>
409 *         <td>A rating string for {@code ES_TV}. This rating is for programs for all ages.</td>
410 *     </tr>
411 *     <tr>
412 *         <td>ES_TV_I</td>
413 *         <td>A rating string for {@code ES_TV}. This rating is for the recommended programs
414 *         especially for children.</td>
415 *     </tr>
416 *     <tr>
417 *         <td>ES_TV_7</td>
418 *         <td>A rating string for {@code ES_TV}. This rating is for programs not recommended for
419 *         children under 7.</td>
420 *     </tr>
421 *     <tr>
422 *         <td>ES_TV_13</td>
423 *         <td>A rating string for {@code ES_TV}. This rating is for programs not recommended for
424 *         children under 13.</td>
425 *     </tr>
426 *     <tr>
427 *         <td>ES_TV_18</td>
428 *         <td>A rating string for {@code ES_TV}. This rating is for programs not recommended for
429 *         children under 18.</td>
430 *     </tr>
431 *     <!--tr>
432 *         <td>FI_TV_ALL</td>
433 *         <td></td>
434 *     </tr-->
435 *     <tr>
436 *         <td>FR_TV_ALL</td>
437 *         <td>A rating string for {@code FR_TV}. According to CSA in France, if no rating appears,
438 *         the program is most likely appropriate for all ages. In Android TV, however,
439 *         {@code RATING_FR_ALL} is used for handling that case.</td>
440 *     </tr>
441 *     <tr>
442 *         <td>FR_TV_10</td>
443 *         <td>A rating string for {@code FR_TV}. This rating is for programs that are not
444 *         recommended for children under 10.</td>
445 *     </tr>
446 *     <tr>
447 *         <td>FR_TV_12</td>
448 *         <td>A rating string for {@code FR_TV}. This rating is for programs that are not
449 *         recommended for children under 12. Programs rated this are not allowed to air before
450 *         10:00 pm (Some channels and programs are subject to exception). </td>
451 *     </tr>
452 *     <tr>
453 *         <td>FR_TV_16</td>
454 *         <td>A rating string for {@code FR_TV}. This rating is for programs that are not
455 *         recommended for children under 16. Programs rated this are not allowed to air before
456 *         10:30 pm (Some channels and programs are subject to exception). </td>
457 *     </tr>
458 *     <tr>
459 *         <td>FR_TV_18</td>
460 *         <td>A rating string for {@code FR_TV}.  This rating is for programs that are not
461 *         recommended for persons under 18. Programs rated this are allowed between midnight and
462 *         5 am and only on some channels. The access to these programs is locked by a personal
463 *         password.</td>
464 *     </tr>
465 *     <!--tr>
466 *         <td>GR_TV_ALL</td>
467 *         <td></td>
468 *     </tr-->
469 *     <!--tr>
470 *         <td>HK_TV_ALL</td>
471 *         <td></td>
472 *     </tr-->
473 *     <!--tr>
474 *         <td>HU_TV_ALL</td>
475 *         <td></td>
476 *     </tr-->
477 *     <!--tr>
478 *         <td>ID_TV_ALL</td>
479 *         <td></td>
480 *     </tr-->
481 *     <!--tr>
482 *         <td>IE_TV_ALL</td>
483 *         <td></td>
484 *     </tr-->
485 *     <!--tr>
486 *         <td>IL_TV_ALL</td>
487 *         <td></td>
488 *     </tr-->
489 *     <!--tr>
490 *         <td>IN_TV_ALL</td>
491 *         <td></td>
492 *     </tr-->
493 *     <!--tr>
494 *         <td>IS_TV_ALL</td>
495 *         <td></td>
496 *     </tr-->
497 *     <!--tr>
498 *         <td>IT_TV_ALL</td>
499 *         <td></td>
500 *     </tr-->
501 *     <!--tr>
502 *         <td>KH_TV_ALL</td>
503 *         <td></td>
504 *     </tr-->
505 *     <tr>
506 *         <td>KR_TV_ALL</td>
507 *         <td>A rating string for {@code KR_TV}. This rating is for programs that are appropriate
508 *         for all ages. This program usually involves programs designed for children or families.
509 *         </td>
510 *     </tr>
511 *     <tr>
512 *         <td>KR_TV_7</td>
513 *         <td>A rating string for {@code KR_TV}. This rating is for programs that may contain
514 *         material inappropriate for children younger than 7, and parental guidance is required.
515 *         </td>
516 *     </tr>
517 *     <tr>
518 *         <td>KR_TV_12</td>
519 *         <td>A rating string for {@code KR_TV}. This rating is for programs that may contain
520 *         material inappropriate for children younger than 12, and parental guidance is required.
521 *         </td>
522 *     </tr>
523 *     <tr>
524 *         <td>KR_TV_15</td>
525 *         <td>A rating string for {@code KR_TV}. This rating is for programs that may contain
526 *         material inappropriate for children younger than 15, and parental guidance is required.
527 *     </tr>
528 *     <tr>
529 *         <td>KR_TV_19</td>
530 *         <td>A rating string for {@code KR_TV}. This rating is for programs designed for adults
531 *         only.</td>
532 *     </tr>
533 *     <!--tr>
534 *         <td>MV_TV_ALL</td>
535 *         <td></td>
536 *     </tr-->
537 *     <!--tr>
538 *         <td>MX_TV_ALL</td>
539 *         <td></td>
540 *     </tr-->
541 *     <!--tr>
542 *         <td>MY_TV_ALL</td>
543 *         <td></td>
544 *     </tr-->
545 *     <tr>
546 *         <td>NL_TV_AL</td>
547 *         <td>A rating string for {@code NL_TV}. This rating is for programs that are appropriate
548 *         for all ages.</td>
549 *     </tr>
550 *     <tr>
551 *         <td>NL_TV_6</td>
552 *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
553 *         advisory for children under 6.</td>
554 *     </tr>
555 *     <tr>
556 *         <td>NL_TV_9</td>
557 *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
558 *         advisory for children under 9.</td>
559 *     </tr>
560 *     <tr>
561 *         <td>NL_TV_12</td>
562 *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
563 *         advisory for children under 12.</td>
564 *     </tr>
565 *     <tr>
566 *         <td>NL_TV_16</td>
567 *         <td>A rating string for {@code NL_TV}. This rating is for programs that require parental
568 *         advisory for children under 16.</td>
569 *     </tr>
570 *     <!--tr>
571 *         <td>NZ_TV_ALL</td>
572 *         <td></td>
573 *     </tr-->
574 *     <!--tr>
575 *         <td>PE_TV_ALL</td>
576 *         <td></td>
577 *     </tr-->
578 *     <!--tr>
579 *         <td>PH_TV_ALL</td>
580 *         <td></td>
581 *     </tr-->
582 *     <!--tr>
583 *         <td>PL_TV_ALL</td>
584 *         <td></td>
585 *     </tr-->
586 *     <!--tr>
587 *         <td>PT_TV_ALL</td>
588 *         <td></td>
589 *     </tr-->
590 *     <!--tr>
591 *         <td>RO_TV_ALL</td>
592 *         <td></td>
593 *     </tr-->
594 *     <!--tr>
595 *         <td>RU_TV_ALL</td>
596 *         <td></td>
597 *     </tr-->
598 *     <!--tr>
599 *         <td>RS_TV_ALL</td>
600 *         <td></td>
601 *     </tr-->
602 *     <!--tr>
603 *         <td>SG_TV_ALL</td>
604 *         <td></td>
605 *     </tr-->
606 *     <!--tr>
607 *         <td>SI_TV_ALL</td>
608 *         <td></td>
609 *     </tr-->
610 *     <!--tr>
611 *         <td>TH_TV_ALL</td>
612 *         <td></td>
613 *     </tr-->
614 *     <!--tr>
615 *         <td>TR_TV_ALL</td>
616 *         <td></td>
617 *     </tr-->
618 *     <!--tr>
619 *         <td>TW_TV_ALL</td>
620 *         <td></td>
621 *     </tr-->
622 *     <!--tr>
623 *         <td>UA_TV_ALL</td>
624 *         <td></td>
625 *     </tr-->
626 *     <tr>
627 *         <td>US_TVPG_TV_Y</td>
628 *         <td>A rating string for {@code US_TVPG}. Programs rated this are designed to be
629 *         appropriate for all children. Whether animated or live-action, the themes and elements
630 *         in this program are specifically designed for a very young audience, including children
631 *         from ages 2-6. This program is not expected to frighten younger children.</td>
632 *     </tr>
633 *     <tr>
634 *         <td>US_TVPG_TV_Y7</td>
635 *         <td>A rating string for {@code US_TVPG}. Programs rated this are designed for children
636 *         age 7 and above. It may be more appropriate for children who have acquired the
637 *         developmental skills needed to distinguish between make-believe and reality. Themes and
638 *         elements in this program may include mild fantasy violence or comedic violence, or may
639 *         frighten children under the age of 7. Therefore, parents may wish to consider the
640 *         suitability of this program for their very young children. This rating may contain
641 *         fantasy violence (US_TVPG_FV) when programs are generally more intense or more combative
642 *         than other programs in this category.</td>
643 *     </tr>
644 *     <tr>
645 *         <td>US_TVPG_TV_G</td>
646 *         <td>A rating string for {@code US_TVPG}. Most parents would find this program suitable
647 *         for all ages. Although this rating does not signify a program designed specifically for
648 *         children, most parents may let younger children watch this program unattended. It
649 *         contains little or no violence, no strong language and little or no sexual dialogue or
650 *         situations.</td>
651 *     </tr>
652 *     <tr>
653 *         <td>US_TVPG_TV_PG</td>
654 *         <td>A rating string for {@code US_TVPG}. Programs rated this contain material that
655 *         parents may find unsuitable for younger children. Many parents may want to watch it with
656 *         their younger children. The theme itself may call for parental guidance and/or the
657 *         program may contain one or more of the following: some suggestive dialogue (
658 *         {@code US_TVPG_D}), infrequent coarse language ({@code US_TVPG_L}), some sexual
659 *         situations ({@code US_TVPG_S}), or moderate violence ({@code US_TVPG_V}).</td>
660 *     </tr>
661 *     <tr>
662 *         <td>US_TVPG_TV_14</td>
663 *         <td>A rating string for {@code US_TVPG}. Programs rated this contains some material
664 *         that many parents would find unsuitable for children under 14 years of age. Parents are
665 *         strongly urged to exercise greater care in monitoring this program and are cautioned
666 *         against letting children under the age of 14 watch unattended. This program may contain
667 *         one or more of the following: intensely suggestive dialogue ({@code US_TVPG_D}), strong
668 *         coarse language ({@code US_TVPG_L}), intense sexual situations ({@code US_TVPG_S}), or
669 *         intense violence ({@code US_TVPG_V}).</td>
670 *     </tr>
671 *     <tr>
672 *         <td>US_TVPG_TV_MA</td>
673 *         <td>A rating string for {@code US_TVPG}. Programs rated TV-MA are specifically
674 *         designed to be viewed by adults and therefore may be unsuitable for children under 17.
675 *         This program may contain one or more of the following: crude indecent language
676 *         ({@code US_TVPG_L}), explicit sexual activity ({@code US_TVPG_S}), or graphic violence
677 *         ({@code US_TVPG_V}).</td>
678 *     </tr>
679 *     <!--tr>
680 *         <td>VE_TV_ALL</td>
681 *         <td></td>
682 *     </tr-->
683 *     <!--tr>
684 *         <td>ZA_TV_ALL</td>
685 *         <td></td>
686 *     </tr-->
687 * </table>
688 *
689 * <u>System defined string for {@code subRating}</u>
690 * <table border="0" cellspacing="0" cellpadding="0">
691 *     <tr>
692 *         <td>String value</td>
693 *         <td>Comments</td>
694 *     </tr>
695 *     <!--tr>
696 *         <td>AM_TV_</td>
697 *         <td></td>
698 *     </tr-->
699 *     <!--tr>
700 *         <td>AR_TV_</td>
701 *         <td></td>
702 *     </tr-->
703 *     <!--tr>
704 *         <td>BG_TV_</td>
705 *         <td></td>
706 *     </tr-->
707 *     <!--tr>
708 *         <td>BR_TV_</td>
709 *         <td></td>
710 *     </tr-->
711 *     <!--tr>
712 *         <td>CA_TV_</td>
713 *         <td></td>
714 *     </tr-->
715 *     <!--tr>
716 *         <td>CH_TV_</td>
717 *         <td></td>
718 *     </tr-->
719 *     <!--tr>
720 *         <td>CL_TV_</td>
721 *         <td></td>
722 *     </tr-->
723 *     <!--tr>
724 *         <td>CO_TV_</td>
725 *         <td></td>
726 *     </tr-->
727 *     <!--tr>
728 *         <td>DK_TV_</td>
729 *         <td></td>
730 *     </tr-->
731 *     <!--tr>
732 *         <td>FI_TV_</td>
733 *         <td></td>
734 *     </tr-->
735 *     <!--tr>
736 *         <td>GR_TV_</td>
737 *         <td></td>
738 *     </tr-->
739 *     <!--tr>
740 *         <td>HK_TV_</td>
741 *         <td></td>
742 *     </tr-->
743 *     <!--tr>
744 *         <td>HU_TV_</td>
745 *         <td></td>
746 *     </tr-->
747 *     <!--tr>
748 *         <td>ID_TV_</td>
749 *         <td></td>
750 *     </tr-->
751 *     <!--tr>
752 *         <td>IE_TV_</td>
753 *         <td></td>
754 *     </tr-->
755 *     <!--tr>
756 *         <td>IL_TV_</td>
757 *         <td></td>
758 *     </tr-->
759 *     <!--tr>
760 *         <td>IN_TV_</td>
761 *         <td></td>
762 *     </tr-->
763 *     <!--tr>
764 *         <td>IS_TV_</td>
765 *         <td></td>
766 *     </tr-->
767 *     <!--tr>
768 *         <td>IT_TV_</td>
769 *         <td></td>
770 *     </tr-->
771 *     <!--tr>
772 *         <td>KH_TV_</td>
773 *         <td></td>
774 *     </tr-->
775 *     <!--tr>
776 *         <td>MV_TV_</td>
777 *         <td></td>
778 *     </tr-->
779 *     <!--tr>
780 *         <td>MX_TV_</td>
781 *         <td></td>
782 *     </tr-->
783 *     <!--tr>
784 *         <td>MY_TV_</td>
785 *         <td></td>
786 *     </tr-->
787 *     <tr>
788 *         <td>NL_TV_V</td>
789 *         <td>Violence</td>
790 *     </tr>
791 *     <tr>
792 *         <td>NL_TV_F</td>
793 *         <td>Fear</td>
794 *     </tr>
795 *     <tr>
796 *         <td>NL_TV_S</td>
797 *         <td>Sex</td>
798 *     </tr>
799 *     <tr>
800 *         <td>NL_TV_D</td>
801 *         <td>Discrimination</td>
802 *     </tr>
803 *     <tr>
804 *         <td>NL_TV_DA</td>
805 *         <td>Drugs- and alcoholabuse</td>
806 *     </tr>
807 *     <tr>
808 *         <td>NL_TV_L</td>
809 *         <td>Coarse Language</td>
810 *     </tr>
811 *     <!--tr>
812 *         <td>NZ_TV_</td>
813 *         <td></td>
814 *     </tr-->
815 *     <!--tr>
816 *         <td>PE_TV_</td>
817 *         <td></td>
818 *     </tr-->
819 *     <!--tr>
820 *         <td>PH_TV_</td>
821 *         <td></td>
822 *     </tr-->
823 *     <!--tr>
824 *         <td>PL_TV_</td>
825 *         <td></td>
826 *     </tr-->
827 *     <!--tr>
828 *         <td>PT_TV_</td>
829 *         <td></td>
830 *     </tr-->
831 *     <!--tr>
832 *         <td>RO_TV_</td>
833 *         <td></td>
834 *     </tr-->
835 *     <!--tr>
836 *         <td>RU_TV_</td>
837 *         <td></td>
838 *     </tr-->
839 *     <!--tr>
840 *         <td>RS_TV_</td>
841 *         <td></td>
842 *     </tr-->
843 *     <!--tr>
844 *         <td>SG_TV_</td>
845 *         <td></td>
846 *     </tr-->
847 *     <!--tr>
848 *         <td>SI_TV_</td>
849 *         <td></td>
850 *     </tr-->
851 *     <!--tr>
852 *         <td>TH_TV_</td>
853 *         <td></td>
854 *     </tr-->
855 *     <!--tr>
856 *         <td>TR_TV_</td>
857 *         <td></td>
858 *     </tr-->
859 *     <!--tr>
860 *         <td>TW_TV_</td>
861 *         <td></td>
862 *     </tr-->
863 *     <!--tr>
864 *         <td>UA_TV_</td>
865 *         <td></td>
866 *     </tr-->
867 *     <tr>
868 *         <td>US_TVPG_D</td>
869 *         <td>Suggestive dialogue (Not used with US_TVPG_TV_MA)</td>
870 *     </tr>
871 *     <tr>
872 *         <td>US_TVPG_L</td>
873 *         <td>Coarse language</td>
874 *     </tr>
875 *     <tr>
876 *         <td>US_TVPG_S</td>
877 *         <td>Sexual content</td>
878 *     </tr>
879 *     <tr>
880 *         <td>US_TVPG_V</td>
881 *         <td>Violence</td>
882 *     </tr>
883 *     <tr>
884 *         <td>US_TVPG_FV</td>
885 *         <td>Fantasy violence (exclusive to US_TVPG_TV_Y7)</td>
886 *     </tr>
887 *     <!--tr>
888 *         <td>VE_TV_</td>
889 *         <td></td>
890 *     </tr-->
891 *     <!--tr>
892 *         <td>ZA_TV_</td>
893 *         <td></td>
894 *     </tr-->
895 * </table>
896 */
897public final class TvContentRating {
898    private static final String TAG = "TvContentRating";
899
900    /** @hide */
901    public static final Uri SYSTEM_CONTENT_RATING_SYSTEM_XML = Uri.parse(
902            "android.resource://system/" + com.android.internal.R.xml.tv_content_rating_systems);
903
904    // TODO: Consider to use other DELIMITER. In some countries such as India may use this delimiter
905    // in the main ratings.
906    private static final String DELIMITER = "/";
907
908    private final String mDomain;
909    private final String mRatingSystem;
910    private final String mRating;
911    private final String[] mSubRatings;
912
913    /**
914     * Creates a TvContentRating object.
915     *
916     * @param domain The domain name.
917     * @param ratingSystem The rating system id.
918     * @param rating The content rating string.
919     * @param subRatings The string array of sub-ratings.
920     * @return A TvContentRating object, or null if creation failed.
921     */
922    public static TvContentRating createRating(String domain, String ratingSystem,
923            String rating, String... subRatings) {
924        if (TextUtils.isEmpty(domain)) {
925            throw new IllegalArgumentException("domain cannot be empty");
926        }
927        if (TextUtils.isEmpty(rating)) {
928            throw new IllegalArgumentException("rating cannot be empty");
929        }
930        return new TvContentRating(domain, ratingSystem, rating, subRatings);
931    }
932
933    /**
934     * Recovers a TvContentRating from a String that was previously created with
935     * {@link #flattenToString}.
936     *
937     * @param ratingString The String that was returned by flattenToString().
938     * @return a new TvContentRating containing the domain, rating system, rating and
939     *         sub-ratings information was encoded in {@code ratingString}.
940     * @see #flattenToString
941     */
942    public static TvContentRating unflattenFromString(String ratingString) {
943        if (TextUtils.isEmpty(ratingString)) {
944            throw new IllegalArgumentException("ratingString cannot be empty");
945        }
946        String[] strs = ratingString.split(DELIMITER);
947        if (strs.length < 3) {
948            throw new IllegalArgumentException("Invalid rating string: " + ratingString);
949        }
950        if (strs.length > 3) {
951            String[] subRatings = new String[strs.length - 3];
952            System.arraycopy(strs, 3, subRatings, 0, subRatings.length);
953            return new TvContentRating(strs[0], strs[1], strs[2], subRatings);
954        }
955        return new TvContentRating(strs[0], strs[1], strs[2], null);
956    }
957
958    /**
959     * Constructs a TvContentRating object from a given rating and sub-rating constants.
960     *
961     * @param domain The domain name.
962     * @param ratingSystem The rating system id.
963     * @param rating The content rating string.
964     * @param subRatings The String array of sub-rating constants defined in this class.
965     */
966    private TvContentRating(
967            String domain, String ratingSystem, String rating, String[] subRatings) {
968        mDomain = domain;
969        mRatingSystem = ratingSystem;
970        mRating = rating;
971        mSubRatings = subRatings;
972    }
973
974    /**
975     * Returns the domain.
976     */
977    public String getDomain() {
978        return mDomain;
979    }
980
981    /**
982     * Returns the rating system id.
983     */
984    public String getRatingSystem() {
985        return mRatingSystem;
986    }
987
988    /**
989     * Returns the main rating.
990     */
991    public String getMainRating() {
992        return mRating;
993    }
994
995    /**
996     * Returns the unmodifiable {@code List} of sub-rating strings.
997     */
998    public List<String> getSubRatings() {
999        if (mSubRatings == null) {
1000            return null;
1001        }
1002        return Collections.unmodifiableList(Arrays.asList(mSubRatings));
1003    }
1004
1005    /**
1006     * Returns a String that unambiguously describes both the rating and sub-rating information
1007     * contained in the TvContentRating. You can later recover the TvContentRating from this string
1008     * through {@link #unflattenFromString}.
1009     *
1010     * @return a new String holding rating/sub-rating information, which can later be stored in the
1011     *         database and settings.
1012     * @see #unflattenFromString
1013     */
1014    public String flattenToString() {
1015        StringBuilder builder = new StringBuilder();
1016        builder.append(mDomain);
1017        builder.append(DELIMITER);
1018        builder.append(mRatingSystem);
1019        builder.append(DELIMITER);
1020        builder.append(mRating);
1021        if (mSubRatings != null) {
1022            for (String subRating : mSubRatings) {
1023                builder.append(DELIMITER);
1024                builder.append(subRating);
1025            }
1026        }
1027        return builder.toString();
1028    }
1029
1030    /**
1031     * Returns true if this rating has the same main rating as the specified rating and when this
1032     * rating's sub-ratings contain the other's.
1033     * <p>
1034     * For example, a TvContentRating object that represents TV-PG with S(Sexual content) and
1035     * V(Violence) contains TV-PG, TV-PG/S, TV-PG/V and itself.
1036     * </p>
1037     *
1038     * @param rating The {@link TvContentRating} to check.
1039     * @return {@code true} if this object contains {@code rating}, {@code false} otherwise.
1040     * @hide
1041     */
1042    @SystemApi
1043    public final boolean contains(TvContentRating rating) {
1044        if (rating == null) {
1045            throw new IllegalArgumentException("rating cannot be null");
1046        }
1047        if (!rating.getMainRating().equals(mRating)) {
1048            return false;
1049        }
1050        List<String> subRatings = getSubRatings();
1051        List<String> subRatingsOther = rating.getSubRatings();
1052        if (subRatings == null && subRatingsOther == null) {
1053            return true;
1054        } else if (subRatings == null && subRatingsOther != null) {
1055            return false;
1056        } else if (subRatings != null && subRatingsOther == null) {
1057            return true;
1058        } else {
1059            return subRatings.containsAll(subRatingsOther);
1060        }
1061    }
1062}
1063