TIF: Enable applications to register custom content rating systems

A recent change that moved the string resource for the system supported
content ratings from the framework to the TV app led to a need for
allowing the TV app to publish its own content rating systems. This
change added an intent action and a metadata key to be used by the TV
input manager service for querying available content rating systems,
similarly to the way InputManager defined ACTION_QUERY_KEYBOARD_LAYOUTS
and META_DATA_KEYBOARD_LAYOUTS for custom keyboard layouts. Applications
now can register their own rating systems simply by declaring a
broadcast receiver in their manifests.

Bug: 17167287, Bug: 17114406
Change-Id: I1808c624014b603ea709714737c2a880714bdc0a
diff --git a/api/current.txt b/api/current.txt
index 45c9afa..d83fede 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1360,7 +1360,6 @@
     field public static final int trimPathEnd = 16843811; // 0x1010423
     field public static final int trimPathOffset = 16843812; // 0x1010424
     field public static final int trimPathStart = 16843810; // 0x1010422
-    field public static final int tvContentRatingDescription = 16843955; // 0x10104b3
     field public static final int type = 16843169; // 0x10101a1
     field public static final int typeface = 16842902; // 0x1010096
     field public static final int uiOptions = 16843672; // 0x1010398
@@ -16780,11 +16779,13 @@
     method public boolean isRatingBlocked(android.media.tv.TvContentRating);
     method public void registerListener(android.media.tv.TvInputManager.TvInputListener, android.os.Handler);
     method public void unregisterListener(android.media.tv.TvInputManager.TvInputListener);
-    field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
-    field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
+    field public static final java.lang.String ACTION_BLOCKED_RATINGS_CHANGED = "android.media.tv.TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED";
+    field public static final java.lang.String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED = "android.media.tv.TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED";
+    field public static final java.lang.String ACTION_QUERY_CONTENT_RATING_SYSTEMS = "android.media.tv.TvInputManager.ACTION_QUERY_CONTENT_RATING_SYSTEMS";
     field public static final int INPUT_STATE_CONNECTED = 0; // 0x0
     field public static final int INPUT_STATE_CONNECTED_STANDBY = 1; // 0x1
     field public static final int INPUT_STATE_DISCONNECTED = 2; // 0x2
+    field public static final java.lang.String META_DATA_CONTENT_RATING_SYSTEMS = "android.media.tv.TvInputManager.META_DATA_CONTENT_RATING_SYSTEMS";
     field public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3; // 0x3
     field public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1; // 0x1
     field public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = 0; // 0x0
diff --git a/api/removed.txt b/api/removed.txt
index 1fde099..8915fc3 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -1,3 +1,11 @@
+package android {
+
+  public static final class R.attr {
+    field public static final int __removed1 = 16843955; // 0x10104b3
+  }
+
+}
+
 package android.app {
 
   public class KeyguardManager {
@@ -40,3 +48,11 @@
 
 }
 
+package com.android.internal {
+
+  public static final class R.attr {
+    field public static final int __removed1 = 16843955; // 0x10104b3
+  }
+
+}
+
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d8b129c..ae11eea 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7348,14 +7348,15 @@
         <!-- Component name of an activity that allows the user to modify
              the settings for this service. -->
         <attr name="settingsActivity" />
-        <!-- Reference to an XML document that describes TV content rating. -->
-        <attr name="tvContentRatingDescription" format="reference" />
     </declare-styleable>
 
+    <!-- @removed -->
+    <attr name="__removed1" format="reference" />
+
     <!-- Attributes that can be used with <code>rating-system-definition</code> tags inside of the
-         XML resource that describes TV content rating of a
-         {@link android.media.tv.TvInputService}, which is referenced from
-         {@link android.R.attr#tvContentRatingDescription}. -->
+         XML resource that describes TV content rating of a {@link android.media.tv.TvInputService},
+         which is referenced from its
+         {@link android.media.tv.TvInputManager#META_DATA_CONTENT_RATING_SYSTEMS}. -->
     <declare-styleable name="RatingSystemDefinition">
         <!-- The unique name of the content rating system. -->
         <attr name="name" />
@@ -7369,7 +7370,8 @@
 
     <!-- Attributes that can be used with <code>rating-definition</code> tags inside of the XML
          resource that describes TV content rating of a {@link android.media.tv.TvInputService},
-         which is referenced from {@link android.R.attr#tvContentRatingDescription}. -->
+         which is referenced from its
+         {@link android.media.tv.TvInputManager#META_DATA_CONTENT_RATING_SYSTEMS}. -->
     <declare-styleable name="RatingDefinition">
         <!-- The unique name of the content rating. -->
         <attr name="name" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 35658cf..c4c046c9 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2266,7 +2266,7 @@
   <public type="attr" name="windowReenterTransition" />
   <public type="attr" name="windowSharedElementReturnTransition" />
   <public type="attr" name="windowSharedElementReenterTransition" />
-  <public type="attr" name="tvContentRatingDescription"/>
+  <public type="attr" name="__removed1" />
   <public type="attr" name="datePickerMode"/>
   <public type="attr" name="timePickerMode"/>
   <public type="attr" name="inset" />
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 20b8e7c..6ca794e 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -22,6 +22,7 @@
 import android.media.tv.ITvInputHardware;
 import android.media.tv.ITvInputHardwareCallback;
 import android.media.tv.ITvInputManagerCallback;
+import android.media.tv.TvContentRatingSystemInfo;
 import android.media.tv.TvInputHardwareInfo;
 import android.media.tv.TvInputInfo;
 import android.media.tv.TvStreamConfig;
@@ -38,7 +39,7 @@
     List<TvInputInfo> getTvInputList(int userId);
     TvInputInfo getTvInputInfo(in String inputId, int userId);
 
-    List<Uri> getTvContentRatingSystemXmls(int userId);
+    List<TvContentRatingSystemInfo> getTvContentRatingSystemList(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 bbf7399..0bda2b3 100644
--- a/media/java/android/media/tv/TvContentRating.java
+++ b/media/java/android/media/tv/TvContentRating.java
@@ -33,10 +33,9 @@
  * {@link #createRating TvContentRating.createRating} method with valid rating system string
  * constants.
  * <p>
- * It is possible for a TV input to define its own content rating system by supplying a content
- * rating system definition XML resource (see example below) and having the
- * {@link android.R.attr#tvContentRatingDescription tvContentRatingDescription} attribute in
- * {@link TvInputService#SERVICE_META_DATA} of the TV input point to it.
+ * 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.
  * </p>
  * <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
diff --git a/media/java/android/media/tv/TvContentRatingSystemInfo.aidl b/media/java/android/media/tv/TvContentRatingSystemInfo.aidl
new file mode 100644
index 0000000..957be62
--- /dev/null
+++ b/media/java/android/media/tv/TvContentRatingSystemInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+parcelable TvContentRatingSystemInfo;
\ No newline at end of file
diff --git a/media/java/android/media/tv/TvContentRatingSystemInfo.java b/media/java/android/media/tv/TvContentRatingSystemInfo.java
new file mode 100644
index 0000000..f2e5b08
--- /dev/null
+++ b/media/java/android/media/tv/TvContentRatingSystemInfo.java
@@ -0,0 +1,111 @@
+/*
+ * 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.SystemApi;
+import android.content.ContentResolver;
+import android.content.pm.ApplicationInfo;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * TvContentRatingSystemInfo class provides information about a specific TV content rating system
+ * defined either by a system app or by a third-party app.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TvContentRatingSystemInfo implements Parcelable {
+    private final Uri mXmlUri;
+
+    private final ApplicationInfo mApplicationInfo;
+
+    /**
+     * Creates a TvContentRatingSystemInfo object with given resource ID and receiver info.
+     *
+     * @param xmlResourceId The ID of an XML resource whose root element is
+     *            <code> &lt;rating-system-definitions&gt;</code>
+     * @param applicationInfo Information about the application that provides the TV content rating
+     *            system definition.
+     */
+    public static final TvContentRatingSystemInfo createTvContentRatingSystemInfo(int xmlResourceId,
+            ApplicationInfo applicationInfo) {
+        Uri uri = new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+                .authority(applicationInfo.packageName)
+                .appendPath(String.valueOf(xmlResourceId))
+                .build();
+        return new TvContentRatingSystemInfo(uri, applicationInfo);
+    }
+
+    private TvContentRatingSystemInfo(Uri xmlUri, ApplicationInfo applicationInfo) {
+        mXmlUri = xmlUri;
+        mApplicationInfo = applicationInfo;
+    }
+
+    /**
+     * Returns {@code true} if the TV content rating system is defined by a system app,
+     * {@code false} otherwise.
+     */
+    public final boolean isSystemDefined() {
+        return (mApplicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
+    /**
+     * Returns the URI to the XML resource that defines the TV content rating system.
+     *
+     * TODO: Remove. Instead, parse the XML resource and provide an interface to directly access
+     * parsed information.
+     */
+    public final Uri getXmlUri() {
+        return mXmlUri;
+    }
+
+    /**
+     * Used to make this class parcelable.
+     * @hide
+     */
+    public static final Parcelable.Creator<TvContentRatingSystemInfo> CREATOR =
+            new Parcelable.Creator<TvContentRatingSystemInfo>() {
+        @Override
+        public TvContentRatingSystemInfo createFromParcel(Parcel in) {
+            return new TvContentRatingSystemInfo(in);
+        }
+
+        @Override
+        public TvContentRatingSystemInfo[] newArray(int size) {
+            return new TvContentRatingSystemInfo[size];
+        }
+    };
+
+    private TvContentRatingSystemInfo(Parcel in) {
+        mXmlUri = in.readParcelable(null);
+        mApplicationInfo = in.readParcelable(null);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mXmlUri, flags);
+        dest.writeParcelable(mApplicationInfo, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java
index 106e1dc..00183bb 100644
--- a/media/java/android/media/tv/TvInputInfo.java
+++ b/media/java/android/media/tv/TvInputInfo.java
@@ -18,7 +18,6 @@
 
 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;
@@ -125,7 +124,6 @@
     private String mLabel;
     private Uri mIconUri;
     private boolean mIsConnectedToHdmiSwitch;
-    private Uri mRatingSystemXmlUri;
 
     static {
         sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_OTHER_HARDWARE,
@@ -245,19 +243,6 @@
                 Log.d(TAG, "Settings activity loaded. [" + input.mSettingsActivity + "] for "
                         + si.name);
             }
-            int tvContentRatingDescription = sa.getResourceId(
-                    com.android.internal.R.styleable.TvInputService_tvContentRatingDescription, -1);
-            if (tvContentRatingDescription != -1) {
-                input.mRatingSystemXmlUri = new Uri.Builder()
-                        .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
-                        .authority(si.packageName)
-                        .appendPath(Integer.toString(tvContentRatingDescription))
-                        .build();
-                if (DEBUG) {
-                    Log.d(TAG, "Content rating xml loaded. [" + tvContentRatingDescription
-                            + "] for " + si.name);
-                }
-            }
             sa.recycle();
 
             input.mLabel = label;
@@ -367,15 +352,6 @@
     }
 
     /**
-     * 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.
      *
@@ -508,7 +484,6 @@
         dest.writeParcelable(mIconUri, flags);
         dest.writeString(mLabel);
         dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
-        dest.writeParcelable(mRatingSystemXmlUri, flags);
     }
 
     private Drawable loadDefaultIcon(Context context) {
@@ -581,7 +556,6 @@
         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 13937e2..6d1f0e4 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -101,14 +101,58 @@
      * {@link #isRatingBlocked}.
      */
     public static final String ACTION_BLOCKED_RATINGS_CHANGED =
-            "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
+            "android.media.tv.TvInputManager.ACTION_BLOCKED_RATINGS_CHANGED";
 
     /**
      * Broadcast intent action when the parental controls enabled state changes. For use with the
      * {@link #isParentalControlsEnabled}.
      */
     public static final String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED =
-            "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
+            "android.media.tv.TvInputManager.ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED";
+
+    /**
+     * Broadcast intent action used to query available content rating systems.
+     * <p>
+     * The TV input manager service locates available content rating systems by querying broadcast
+     * receivers that are registered for this action. An application can offer additional content
+     * rating systems to the user by declaring a suitable broadcast receiver in its manifest.
+     * </p><p>
+     * Here is an example broadcast receiver declaration that an application might include in its
+     * AndroidManifest.xml to advertise custom content rating systems. The meta-data specifies a
+     * resource that contains a description of each content rating system that is provided by the
+     * application.
+     * <p><pre class="prettyprint">
+     * {@literal
+     * <receiver android:name=".TvInputReceiver">
+     *     <intent-filter>
+     *         <action android:name=
+     *                 "android.media.tv.TvInputManager.ACTION_QUERY_CONTENT_RATING_SYSTEMS" />
+     *     </intent-filter>
+     *     <meta-data
+     *             android:name="android.media.tv.TvInputManager.META_DATA_CONTENT_RATING_SYSTEMS"
+     *             android:resource="@xml/tv_content_rating_systems" />
+     * </receiver>}</pre></p>
+     * In the above example, the <code>@xml/tv_content_rating_systems</code> resource refers to an
+     * XML resource whose root element is <code>&lt;rating-system-definitions&gt;</code> that
+     * contains zero or more <code>&lt;rating-system-definition&gt;</code> elements. Each <code>
+     * &lt;rating-system-definition&gt;</code> element specifies the ratings, sub-ratings and rating
+     * orders of a particular content rating system.
+     * </p>
+     *
+     * @see TvContentRating
+     */
+    public static final String ACTION_QUERY_CONTENT_RATING_SYSTEMS =
+            "android.media.tv.TvInputManager.ACTION_QUERY_CONTENT_RATING_SYSTEMS";
+
+    /**
+     * Content rating systems metadata associated with {@link #ACTION_QUERY_CONTENT_RATING_SYSTEMS}.
+     * <p>
+     * Specifies the resource ID of an XML resource that describes the content rating systems that
+     * are provided by the application.
+     * </p>
+     */
+    public static final String META_DATA_CONTENT_RATING_SYSTEMS =
+            "android.media.tv.TvInputManager.META_DATA_CONTENT_RATING_SYSTEMS";
 
     private final ITvInputManager mService;
 
@@ -863,13 +907,13 @@
     }
 
     /**
-     * Returns the list of xml resource uris for TV content rating systems.
+     * Returns the list of all TV content rating systems defined.
      * @hide
      */
     @SystemApi
-    public List<Uri> getTvContentRatingSystemXmls() {
+    public List<TvContentRatingSystemInfo> getTvContentRatingSystemList() {
         try {
-            return mService.getTvContentRatingSystemXmls(mUserId);
+            return mService.getTvContentRatingSystemList(mUserId);
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index fe35f95..a49d8ab 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -33,6 +33,7 @@
 import android.content.IntentFilter;
 import android.content.OperationApplicationException;
 import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
@@ -49,9 +50,11 @@
 import android.media.tv.ITvInputSession;
 import android.media.tv.ITvInputSessionCallback;
 import android.media.tv.TvContentRating;
+import android.media.tv.TvContentRatingSystemInfo;
 import android.media.tv.TvContract;
 import android.media.tv.TvInputHardwareInfo;
 import android.media.tv.TvInputInfo;
+import android.media.tv.TvInputManager;
 import android.media.tv.TvInputService;
 import android.media.tv.TvStreamConfig;
 import android.media.tv.TvTrackInfo;
@@ -137,6 +140,7 @@
         } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
             synchronized (mLock) {
                 buildTvInputListLocked(mCurrentUserId);
+                buildTvContentRatingSystemListLocked(mCurrentUserId);
             }
         }
         mTvInputHardwareManager.onBootPhase(phase);
@@ -149,6 +153,7 @@
                 if (DEBUG) Slog.d(TAG, "onSomePackagesChanged()");
                 synchronized (mLock) {
                     buildTvInputListLocked(mCurrentUserId);
+                    buildTvContentRatingSystemListLocked(mCurrentUserId);
                 }
             }
 
@@ -291,15 +296,32 @@
 
         userState.inputMap.clear();
         userState.inputMap = inputMap;
+    }
 
-        userState.ratingSystemXmlUriSet.clear();
-        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 buildTvContentRatingSystemListLocked(int userId) {
+        UserState userState = getUserStateLocked(userId);
+        userState.contentRatingSystemList.clear();
+
+        final PackageManager pm = mContext.getPackageManager();
+        Intent intent = new Intent(TvInputManager.ACTION_QUERY_CONTENT_RATING_SYSTEMS);
+        for (ResolveInfo resolveInfo :
+                pm.queryBroadcastReceivers(intent, PackageManager.GET_META_DATA)) {
+            ActivityInfo receiver = resolveInfo.activityInfo;
+            Bundle metaData = receiver.metaData;
+            if (metaData == null) {
+                continue;
             }
+
+            int xmlResId = metaData.getInt(TvInputManager.META_DATA_CONTENT_RATING_SYSTEMS);
+            if (xmlResId == 0) {
+                Slog.w(TAG, "Missing meta-data '"
+                        + TvInputManager.META_DATA_CONTENT_RATING_SYSTEMS + "' on receiver "
+                        + receiver.packageName + "/" + receiver.name);
+                continue;
+            }
+            userState.contentRatingSystemList.add(
+                    TvContentRatingSystemInfo.createTvContentRatingSystemInfo(xmlResId,
+                            receiver.applicationInfo));
         }
     }
 
@@ -318,6 +340,7 @@
             }
             mUserStates.put(userId, userState);
             buildTvInputListLocked(userId);
+            buildTvContentRatingSystemListLocked(userId);
         }
     }
 
@@ -355,7 +378,7 @@
             // Clear everything else.
             userState.inputMap.clear();
             userState.packageSet.clear();
-            userState.ratingSystemXmlUriSet.clear();
+            userState.contentRatingSystemList.clear();
             userState.clientStateMap.clear();
             userState.callbackSet.clear();
             userState.mainSessionToken = null;
@@ -903,16 +926,14 @@
         }
 
         @Override
-        public List<Uri> getTvContentRatingSystemXmls(int userId) {
+        public List<TvContentRatingSystemInfo> getTvContentRatingSystemList(int userId) {
             final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(),
-                    Binder.getCallingUid(), userId, "getTvContentRatingSystemXmls");
+                    Binder.getCallingUid(), userId, "getTvContentRatingSystemList");
             final long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mLock) {
                     UserState userState = getUserStateLocked(resolvedUserId);
-                    List<Uri> ratingSystemXmlUriList = new ArrayList<Uri>();
-                    ratingSystemXmlUriList.addAll(userState.ratingSystemXmlUriSet);
-                    return ratingSystemXmlUriList;
+                    return userState.contentRatingSystemList;
                 }
             } finally {
                 Binder.restoreCallingIdentity(identity);
@@ -1735,8 +1756,9 @@
         // 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 list of all TV content rating systems defined.
+        private final List<TvContentRatingSystemInfo>
+                contentRatingSystemList = new ArrayList<TvContentRatingSystemInfo>();
 
         // A mapping from the token of a client to its state.
         private final Map<IBinder, ClientState> clientStateMap =