Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bd23fa0b authored by Jae Seo's avatar Jae Seo
Browse files

TvContract: Address the feedback from the API review

This change addresses the following comments from the council:
- Provider authority should be "android.media.tv"
- Rename COLUMN_DATA to COLUMN_INTERNAL_PROVIDER_DATA and add comment to
  indicate data is internal to the provider that inserted it, and should
  not be decoded by other apps. It would be nice to restrict read access
  to this column, but not essential.
- Hide COLUMN_LOCKED since implementation isn't defined yet, also
  questions about how it interacts with Unicorn.
- Fix typo in ORIGINAL_NETWORK documentation.
- All provider MIME types need to be changed to follow platform
  conventions: "vnd.android.cursor.dir/channel",
  "vnd.android.cursor.dir/program", etc. (Notice singular tense and no
  package prefixes since they're part of the platform API.)
- Rename Programs.COLUMN_DATA to COLUMN_INTERNAL_PROVIDER_DATA, along
  with docs update, for the same reasons as above.
- Rename COLUMN_DESCRIPTION to COLUMN_SHORT_DESCRIPTION and update docs
  to indicate it's a recommended maximum length, not a hard cap.
- COLUMN_GENRE should be split into two columns: COLUMN_BROADCAST_GENRE
  (from broadcast standard) and COLUMN_CANONICAL_GENRE (from an Android
  standard). Define a subclass with the Android canonical genres, which
  are simple strings that are comma-separated when inserted into
  COLUMN_CANONICAL_GENRE.

Bug: 15345342
Change-Id: I7f8e70aef617475a59d096fd73a551e7df8a1d3a
parent 0bec6388
Loading
Loading
Loading
Loading
+28 −12
Original line number Diff line number Diff line
@@ -15862,7 +15862,7 @@ package android.media.tv {
    method public static final android.net.Uri buildProgramUri(long);
    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
    method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
    field public static final java.lang.String AUTHORITY = "com.android.tv";
    field public static final java.lang.String AUTHORITY = "android.media.tv";
  }
  public static abstract interface TvContract.BaseTvColumns implements android.provider.BaseColumns {
@@ -15871,11 +15871,10 @@ package android.media.tv {
  public static final class TvContract.Channels implements android.media.tv.TvContract.BaseTvColumns {
    field public static final java.lang.String COLUMN_BROWSABLE = "browsable";
    field public static final java.lang.String COLUMN_DATA = "data";
    field public static final java.lang.String COLUMN_DESCRIPTION = "description";
    field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
    field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
    field public static final java.lang.String COLUMN_LOCKED = "locked";
    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
    field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
    field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
    field public static final java.lang.String COLUMN_SERVICE_ID = "service_id";
@@ -15884,12 +15883,12 @@ package android.media.tv {
    field public static final java.lang.String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
    field public static final java.lang.String COLUMN_TYPE = "type";
    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.android.tv.channels";
    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.android.tv.channels";
    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
    field public static final android.net.Uri CONTENT_URI;
    field public static final int SERVICE_TYPE_AUDIO = 2; // 0x2
    field public static final int SERVICE_TYPE_AUDIO_VIDEO = 1; // 0x1
    field public static final int SERVICE_TYPE_OTHER = 0; // 0x0
    field public static final int SERVICE_TYPE_RADIO = 2; // 0x2
    field public static final int SERVICE_TYPE_TV = 1; // 0x1
    field public static final int TYPE_1SEG = 263168; // 0x40400
    field public static final int TYPE_ATSC_C = 197120; // 0x30200
    field public static final int TYPE_ATSC_M_H = 197120; // 0x30200
@@ -15916,20 +15915,37 @@ package android.media.tv {
  public static final class TvContract.Programs implements android.media.tv.TvContract.BaseTvColumns {
    field public static final java.lang.String COLUMN_AUDIO_LANGUAGE = "audio_language";
    field public static final java.lang.String COLUMN_BROADCAST_GENRE = "broadcast_genre";
    field public static final java.lang.String COLUMN_CANONICAL_GENRE = "canonical_genre";
    field public static final java.lang.String COLUMN_CHANNEL_ID = "channel_id";
    field public static final java.lang.String COLUMN_DATA = "data";
    field public static final java.lang.String COLUMN_DESCRIPTION = "description";
    field public static final java.lang.String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
    field public static final java.lang.String COLUMN_GENRE = "genre";
    field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
    field public static final java.lang.String COLUMN_LONG_DESCRIPTION = "long_description";
    field public static final java.lang.String COLUMN_SHORT_DESCRIPTION = "short_description";
    field public static final java.lang.String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
    field public static final java.lang.String COLUMN_TITLE = "title";
    field public static final java.lang.String COLUMN_VERSION_NUMBER = "version_number";
    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.android.tv.programs";
    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.android.tv.programs";
    field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
    field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/program";
    field public static final android.net.Uri CONTENT_URI;
  }
  public static final class TvContract.Programs.Genres {
    method public static java.lang.String[] decode(java.lang.String);
    method public static java.lang.String encode(java.lang.String...);
    field public static final java.lang.String ANIMAL_WILDLIFE = "Animal/Wildlife";
    field public static final java.lang.String COMEDY = "Comedy";
    field public static final java.lang.String DRAMA = "Drama";
    field public static final java.lang.String EDUCATION = "Education";
    field public static final java.lang.String FAMILY_KIDS = "Family/Kids";
    field public static final java.lang.String GAMING = "Gaming";
    field public static final java.lang.String MOVIES = "Movies";
    field public static final java.lang.String NEWS = "News";
    field public static final java.lang.String SHOPPING = "Shopping";
    field public static final java.lang.String SPORTS = "Sports";
    field public static final java.lang.String TRAVEL = "Travel";
  }
  public final class TvInputInfo implements android.os.Parcelable {
    method public int describeContents();
    method public android.content.ComponentName getComponent();
+110 −46
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ import java.util.List;
 */
public final class TvContract {
    /** The authority for the TV provider. */
    public static final String AUTHORITY = "com.android.tv";
    public static final String AUTHORITY = "android.media.tv";

    private static final String PATH_CHANNEL = "channel";
    private static final String PATH_PROGRAM = "program";
@@ -243,12 +243,10 @@ public final class TvContract {
                + PATH_CHANNEL);

        /** The MIME type of a directory of TV channels. */
        public static final String CONTENT_TYPE =
                "vnd.android.cursor.dir/vnd.com.android.tv.channels";
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel";

        /** The MIME type of a single TV channel. */
        public static final String CONTENT_ITEM_TYPE =
                "vnd.android.cursor.item/vnd.com.android.tv.channels";
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";

        /** A generic channel type. */
        public static final int TYPE_OTHER = 0x0;
@@ -319,11 +317,11 @@ public final class TvContract {
        /** A generic service type. */
        public static final int SERVICE_TYPE_OTHER = 0x0;

        /** The service type for regular TV channels. */
        public static final int SERVICE_TYPE_TV = 0x1;
        /** The service type for regular TV channels that have both audio and video. */
        public static final int SERVICE_TYPE_AUDIO_VIDEO = 0x1;

        /** The service type for radio channels. */
        public static final int SERVICE_TYPE_RADIO = 0x2;
        /** The service type for radio channels that have audio only. */
        public static final int SERVICE_TYPE_AUDIO = 0x2;

        /**
         * The name of the {@link TvInputService} subclass that provides this TV channel. This
@@ -363,7 +361,7 @@ public final class TvContract {
         * a radio-like channel. Use the same coding for {@code service_type} in the underlying
         * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB
         * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER},
         * {@link #SERVICE_TYPE_TV}, {@link #SERVICE_TYPE_RADIO}
         * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO}
         * </p><p>
         * This is a required field.
         * </p><p>
@@ -376,7 +374,7 @@ public final class TvContract {
         * The original network ID of this TV channel.
         * <p>
         * This is used to identify the originating delivery system, if applicable. Use the same
         * coding for {@code origianal_network_id} in the underlying broadcast standard if it is
         * coding for {@code original_network_id} in the underlying broadcast standard if it is
         * defined there (e.g. ETSI EN 300 468/TR 101 211 and ARIB STD-B10). If channels cannot be
         * globally identified by 2-tuple {{@link #COLUMN_TRANSPORT_STREAM_ID},
         * {@link #COLUMN_SERVICE_ID}}, one must carefully assign a value to this field to form a
@@ -496,17 +494,20 @@ public final class TvContract {
         * </p><p>
         * Type: INTEGER (boolean)
         * </p>
         * @hide
         */
        public static final String COLUMN_LOCKED = "locked";

        /**
         * Generic data used by individual TV input services.
         * Internal data used by individual TV input services.
         * <p>
         * This is internal to the provider that inserted it, and should not be decoded by other
         * apps.
         * </p><p>
         * Type: BLOB
         * </p>
         */
        public static final String COLUMN_DATA = "data";

        public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";

        /**
         * The version number of this row entry used by TV input services.
@@ -532,12 +533,10 @@ public final class TvContract {
                + PATH_PROGRAM);

        /** The MIME type of a directory of TV programs. */
        public static final String CONTENT_TYPE =
                "vnd.android.cursor.dir/vnd.com.android.tv.programs";
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program";

        /** The MIME type of a single TV program. */
        public static final String CONTENT_ITEM_TYPE =
                "vnd.android.cursor.item/vnd.com.android.tv.programs";
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";

        /**
         * The ID of the TV channel that contains this TV program.
@@ -578,44 +577,42 @@ public final class TvContract {
         * <p>
         * Use the same language appeared in the underlying broadcast standard, if applicable. (For
         * example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, use one of the
         * following genres:
         * <ul>
         *     <li>Family/Kids</li>
         *     <li>Sports</li>
         *     <li>Shopping</li>
         *     <li>Movies</li>
         *     <li>Comedy</li>
         *     <li>Travel</li>
         *     <li>Drama</li>
         *     <li>Education</li>
         *     <li>Animal/Wildlife</li>
         *     <li>News</li>
         *     <li>Gaming</li>
         *     <li>Others</li>
         * </ul>
         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty.
         * </p><p>
         * Type: TEXT
         * </p>
         */
        public static final String COLUMN_GENRE = "genre";
        public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre";

        /**
         * The description of this TV program that is displayed to the user by default.
         * The comma-separated canonical genre string of this TV program.
         * <p>
         * The maximum length of this field is 256 characters.
         * Canonical genres are defined in {@link Genres}. Use {@link Genres#encode Genres.encode()}
         * to create a text that can be stored in this column. Use {@link Genres#decode
         * Genres.decode()} to get the canonical genre strings from the text stored in this column.
         * </p><p>
         * Type: TEXT
         * </p>
         * @see Genres
         */
        public static final String COLUMN_DESCRIPTION = "description";
        public static final String COLUMN_CANONICAL_GENRE = "canonical_genre";

        /**
         * The short description of this TV program that is displayed to the user by default.
         * <p>
         * It is recommended to limit the length of the descriptions to 256 characters.
         * </p><p>
         * Type: TEXT
         * </p>
         */
        public static final String COLUMN_SHORT_DESCRIPTION = "short_description";

        /**
         * The detailed, lengthy description of this TV program that is displayed only when the user
         * wants to see more information.
         * <p>
         * TV input services should leave this field empty if they have no additional
         * details beyond {@link #COLUMN_DESCRIPTION}.
         * TV input services should leave this field empty if they have no additional details beyond
         * {@link #COLUMN_SHORT_DESCRIPTION}.
         * </p><p>
         * Type: TEXT
         * </p>
@@ -634,12 +631,15 @@ public final class TvContract {
        public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";

        /**
         * Generic data used by TV input services.
         * Internal data used by individual TV input services.
         * <p>
         * This is internal to the provider that inserted it, and should not be decoded by other
         * apps.
         * </p><p>
         * Type: BLOB
         * </p>
         */
        public static final String COLUMN_DATA = "data";
        public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";

        /**
         * The version number of this row entry used by TV input services.
@@ -655,6 +655,72 @@ public final class TvContract {
        public static final String COLUMN_VERSION_NUMBER = "version_number";

        private Programs() {}

        /** Canonical genres for TV programs. */
        public static final class Genres {
            /** The genre for Family/Kids. */
            public static final String FAMILY_KIDS = "Family/Kids";

            /** The genre for Sports. */
            public static final String SPORTS = "Sports";

            /** The genre for Shopping. */
            public static final String SHOPPING = "Shopping";

            /** The genre for Movies. */
            public static final String MOVIES = "Movies";

            /** The genre for Comedy. */
            public static final String COMEDY = "Comedy";

            /** The genre for Travel. */
            public static final String TRAVEL = "Travel";

            /** The genre for Drama. */
            public static final String DRAMA = "Drama";

            /** The genre for Education. */
            public static final String EDUCATION = "Education";

            /** The genre for Animal/Wildlife. */
            public static final String ANIMAL_WILDLIFE = "Animal/Wildlife";

            /** The genre for News. */
            public static final String NEWS = "News";

            /** The genre for Gaming. */
            public static final String GAMING = "Gaming";

            private Genres() {}

            /**
             * Encodes canonical genre strings to a text that can be put into the database.
             *
             * @param genres Canonical genre strings. Use the strings defined in this class.
             * @return an encoded genre string that can be inserted into the
             *         {@link #COLUMN_CANONICAL_GENRE} column.
             */
            public static String encode(String... genres) {
                StringBuilder sb = new StringBuilder();
                String separator = "";
                for (String genre : genres) {
                    sb.append(separator).append(genre);
                    separator = ",";
                }
                return sb.toString();
            }

            /**
             * Decodes the canonical genre strings from the text stored in the database.
             *
             * @param genres The encoded genre string retrieved from the
             *            {@link #COLUMN_CANONICAL_GENRE} column.
             * @return canonical genre strings.
             */
            public static String[] decode(String genres) {
                return genres.split("\\s*,\\s*");
            }
        }
    }

    /**
@@ -670,12 +736,10 @@ public final class TvContract {
                Uri.parse("content://" + AUTHORITY + "/watched_program");

        /** The MIME type of a directory of watched programs. */
        public static final String CONTENT_TYPE =
                "vnd.android.cursor.dir/vnd.com.android.tv.watched_programs";
        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program";

        /** The MIME type of a single item in this table. */
        public static final String CONTENT_ITEM_TYPE =
                "vnd.android.cursor.item/vnd.com.android.tv.watched_programs";
        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program";

        /**
         * The UTC time that the user started watching this TV program, in milliseconds since the
+1 −1
Original line number Diff line number Diff line
@@ -1046,7 +1046,7 @@ public final class TvInputManagerService extends SystemService {
                    TvContract.Programs.COLUMN_TITLE,
                    TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS,
                    TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS,
                    TvContract.Programs.COLUMN_DESCRIPTION
                    TvContract.Programs.COLUMN_SHORT_DESCRIPTION
            };
            String selection = TvContract.Programs.COLUMN_CHANNEL_ID + "=? AND "
                    + TvContract.Programs.COLUMN_START_TIME_UTC_MILLIS + "<=? AND "