Loading core/api/current.txt +8 −0 Original line number Diff line number Diff line Loading @@ -1409,6 +1409,7 @@ package android { field public static final int summaryColumn = 16843426; // 0x10102a2 field public static final int summaryOff = 16843248; // 0x10101f0 field public static final int summaryOn = 16843247; // 0x10101ef field public static final int supportedTypes; field public static final int supportsAssist = 16844016; // 0x10104f0 field public static final int supportsInlineSuggestions = 16844301; // 0x101060d field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1 Loading Loading @@ -26306,6 +26307,13 @@ package android.media.tv.interactive { public final class TvIAppManager { } public abstract class TvIAppService extends android.app.Service { ctor public TvIAppService(); method public final android.os.IBinder onBind(android.content.Intent); field public static final String SERVICE_INTERFACE = "android.media.tv.interactive.TvIAppService"; field public static final String SERVICE_META_DATA = "android.media.tv.interactive.app"; } } package android.mtp { core/res/res/values/attrs.xml +12 −0 Original line number Diff line number Diff line Loading @@ -9316,6 +9316,18 @@ <attr name="canPauseRecording" format="boolean" /> </declare-styleable> <!-- Use <code>tv-iapp</code> as the root tag of the XML resource that describes a {@link android.media.tv.interactive.TvIAppService}, which is referenced from its {@link android.media.tv.interactive.TvIAppService#SERVICE_META_DATA} meta-data entry. Described here are the attributes that can be included in that tag. --> <declare-styleable name="TvIAppService"> <!-- The interactive app types that the TV interactive app service supports. Reference to a string array resource that describes the supported types, e.g. HbbTv, Ginga. --> <attr name="supportedTypes" format="reference" /> </declare-styleable> <!-- 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 its core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -3304,6 +3304,7 @@ <public name="requiredSplitTypes" /> <public name="splitTypes" /> <public name="canDisplayOnRemoteDevices" /> <public name="supportedTypes" /> </staging-public-group> <staging-public-group type="id" first-id="0x01de0000"> Loading media/java/android/media/tv/interactive/TvIAppInfo.java 0 → 100644 +190 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.interactive; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * This class is used to specify meta information of a TV interactive app. * @hide */ public final class TvIAppInfo implements Parcelable { private static final boolean DEBUG = false; private static final String TAG = "TvIAppInfo"; private final ResolveInfo mService; private final String mId; private List<String> mTypes = new ArrayList<>(); private TvIAppInfo(ResolveInfo service, String id, List<String> types) { mService = service; mId = id; mTypes = types; } protected TvIAppInfo(Parcel in) { mService = ResolveInfo.CREATOR.createFromParcel(in); mId = in.readString(); in.readStringList(mTypes); } public static final Creator<TvIAppInfo> CREATOR = new Creator<TvIAppInfo>() { @Override public TvIAppInfo createFromParcel(Parcel in) { return new TvIAppInfo(in); } @Override public TvIAppInfo[] newArray(int size) { return new TvIAppInfo[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { mService.writeToParcel(dest, flags); dest.writeString(mId); dest.writeStringList(mTypes); } public String getId() { return mId; } /** * Returns the information of the service that implements this TV IApp service. */ public ServiceInfo getServiceInfo() { return mService.serviceInfo; } /** * A convenience builder for creating {@link TvIAppInfo} objects. */ public static final class Builder { private static final String XML_START_TAG_NAME = "tv-iapp"; private final Context mContext; private final ResolveInfo mResolveInfo; private final List<String> mTypes = new ArrayList<>(); /** * Constructs a new builder for {@link TvIAppInfo}. * * @param context A Context of the application package implementing this class. * @param component The name of the application component to be used for the * {@link TvIAppService}. */ public Builder(Context context, ComponentName component) { if (context == null) { throw new IllegalArgumentException("context cannot be null."); } Intent intent = new Intent(TvIAppService.SERVICE_INTERFACE).setComponent(component); mResolveInfo = context.getPackageManager().resolveService(intent, PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); if (mResolveInfo == null) { throw new IllegalArgumentException("Invalid component. Can't find the service."); } mContext = context; } /** * Creates a {@link TvIAppInfo} instance with the specified fields. Most of the information * is obtained by parsing the AndroidManifest and {@link TvIAppService#SERVICE_META_DATA} * for the {@link TvIAppService} this TV IApp implements. * * @return TvIAppInfo containing information about this TV IApp service. */ public TvIAppInfo build() { ComponentName componentName = new ComponentName(mResolveInfo.serviceInfo.packageName, mResolveInfo.serviceInfo.name); String id; id = generateIAppServiceId(componentName); parseServiceMetadata(); return new TvIAppInfo(mResolveInfo, id, mTypes); } private static String generateIAppServiceId(ComponentName name) { return name.flattenToShortString(); } private void parseServiceMetadata() { ServiceInfo si = mResolveInfo.serviceInfo; PackageManager pm = mContext.getPackageManager(); try (XmlResourceParser parser = si.loadXmlMetaData(pm, TvIAppService.SERVICE_META_DATA)) { if (parser == null) { throw new IllegalStateException("No " + TvIAppService.SERVICE_META_DATA + " meta-data found for " + si.name); } Resources res = pm.getResourcesForApplication(si.applicationInfo); AttributeSet attrs = Xml.asAttributeSet(parser); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { // move to the START_TAG } String nodeName = parser.getName(); if (!XML_START_TAG_NAME.equals(nodeName)) { throw new IllegalStateException("Meta-data does not start with " + XML_START_TAG_NAME + " tag for " + si.name); } TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.TvIAppService); CharSequence[] types = sa.getTextArray( com.android.internal.R.styleable.TvIAppService_supportedTypes); for (CharSequence cs : types) { mTypes.add(cs.toString()); } sa.recycle(); } catch (IOException | XmlPullParserException e) { throw new IllegalStateException( "Failed reading meta-data for " + si.packageName, e); } catch (PackageManager.NameNotFoundException e) { throw new IllegalStateException("No resources found for " + si.packageName, e); } } } } media/java/android/media/tv/interactive/TvIAppService.java +26 −8 Original line number Diff line number Diff line Loading @@ -38,22 +38,32 @@ import java.util.List; /** * The TvIAppService class represents a TV interactive applications RTE. * @hide */ public abstract class TvIAppService extends Service { private static final boolean DEBUG = false; private static final String TAG = "TvIAppService"; private final Handler mServiceHandler = new ServiceHandler(); // TODO: cleanup and unhide APIs. /** * This is the interface name that a service implementing an environment to run Tv IApp should * say that it support -- that is, this is the action it uses for its intent filter. To be * supported, the service must also require the BIND_TV_IAPP permission so that other * applications cannot abuse it. * This is the interface name that a service implementing a TV IApp service should say that it * supports -- that is, this is the action it uses for its intent filter. To be supported, the * service must also require the android.Manifest.permission#BIND_TV_IAPP permission so * that other applications cannot abuse it. */ public static final String SERVICE_INTERFACE = "android.media.tv.TvIAppService"; public static final String SERVICE_INTERFACE = "android.media.tv.interactive.TvIAppService"; /** * Name under which a TvIAppService component publishes information about itself. This meta-data * must reference an XML resource containing an * <code><{@link android.R.styleable#TvIAppService tv-iapp}></code> * tag. */ public static final String SERVICE_META_DATA = "android.media.tv.interactive.app"; private final Handler mServiceHandler = new ServiceHandler(); /** @hide */ @Override public final IBinder onBind(Intent intent) { ITvIAppService.Stub tvIAppServiceBinder = new ITvIAppService.Stub() { Loading Loading @@ -83,12 +93,17 @@ public abstract class TvIAppService extends Service { * * @param iAppServiceId The ID of the TV IApp associated with the session. * @param type The type of the TV IApp associated with the session. * @hide */ @Nullable public abstract Session onCreateSession(@NonNull String iAppServiceId, int type); public Session onCreateSession(@NonNull String iAppServiceId, int type) { // TODO: make it abstract when unhide return null; } /** * Base class for derived classes to implement to provide a TV interactive app session. * @hide */ public abstract static class Session implements KeyEvent.Callback { private final Object mLock = new Object(); Loading @@ -113,6 +128,7 @@ public abstract class TvIAppService extends Service { /** * Starts TvIAppService session. * @hide */ public void onStartIApp() { } Loading Loading @@ -144,6 +160,7 @@ public abstract class TvIAppService extends Service { /** * Releases TvIAppService session. * @hide */ public void onRelease() { } Loading Loading @@ -245,6 +262,7 @@ public abstract class TvIAppService extends Service { /** * Implements the internal ITvIAppSession interface. * @hide */ public static class ITvIAppSessionWrapper extends ITvIAppSession.Stub { private final Session mSessionImpl; Loading Loading
core/api/current.txt +8 −0 Original line number Diff line number Diff line Loading @@ -1409,6 +1409,7 @@ package android { field public static final int summaryColumn = 16843426; // 0x10102a2 field public static final int summaryOff = 16843248; // 0x10101f0 field public static final int summaryOn = 16843247; // 0x10101ef field public static final int supportedTypes; field public static final int supportsAssist = 16844016; // 0x10104f0 field public static final int supportsInlineSuggestions = 16844301; // 0x101060d field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1 Loading Loading @@ -26306,6 +26307,13 @@ package android.media.tv.interactive { public final class TvIAppManager { } public abstract class TvIAppService extends android.app.Service { ctor public TvIAppService(); method public final android.os.IBinder onBind(android.content.Intent); field public static final String SERVICE_INTERFACE = "android.media.tv.interactive.TvIAppService"; field public static final String SERVICE_META_DATA = "android.media.tv.interactive.app"; } } package android.mtp {
core/res/res/values/attrs.xml +12 −0 Original line number Diff line number Diff line Loading @@ -9316,6 +9316,18 @@ <attr name="canPauseRecording" format="boolean" /> </declare-styleable> <!-- Use <code>tv-iapp</code> as the root tag of the XML resource that describes a {@link android.media.tv.interactive.TvIAppService}, which is referenced from its {@link android.media.tv.interactive.TvIAppService#SERVICE_META_DATA} meta-data entry. Described here are the attributes that can be included in that tag. --> <declare-styleable name="TvIAppService"> <!-- The interactive app types that the TV interactive app service supports. Reference to a string array resource that describes the supported types, e.g. HbbTv, Ginga. --> <attr name="supportedTypes" format="reference" /> </declare-styleable> <!-- 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 its
core/res/res/values/public.xml +1 −0 Original line number Diff line number Diff line Loading @@ -3304,6 +3304,7 @@ <public name="requiredSplitTypes" /> <public name="splitTypes" /> <public name="canDisplayOnRemoteDevices" /> <public name="supportedTypes" /> </staging-public-group> <staging-public-group type="id" first-id="0x01de0000"> Loading
media/java/android/media/tv/interactive/TvIAppInfo.java 0 → 100644 +190 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.interactive; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * This class is used to specify meta information of a TV interactive app. * @hide */ public final class TvIAppInfo implements Parcelable { private static final boolean DEBUG = false; private static final String TAG = "TvIAppInfo"; private final ResolveInfo mService; private final String mId; private List<String> mTypes = new ArrayList<>(); private TvIAppInfo(ResolveInfo service, String id, List<String> types) { mService = service; mId = id; mTypes = types; } protected TvIAppInfo(Parcel in) { mService = ResolveInfo.CREATOR.createFromParcel(in); mId = in.readString(); in.readStringList(mTypes); } public static final Creator<TvIAppInfo> CREATOR = new Creator<TvIAppInfo>() { @Override public TvIAppInfo createFromParcel(Parcel in) { return new TvIAppInfo(in); } @Override public TvIAppInfo[] newArray(int size) { return new TvIAppInfo[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { mService.writeToParcel(dest, flags); dest.writeString(mId); dest.writeStringList(mTypes); } public String getId() { return mId; } /** * Returns the information of the service that implements this TV IApp service. */ public ServiceInfo getServiceInfo() { return mService.serviceInfo; } /** * A convenience builder for creating {@link TvIAppInfo} objects. */ public static final class Builder { private static final String XML_START_TAG_NAME = "tv-iapp"; private final Context mContext; private final ResolveInfo mResolveInfo; private final List<String> mTypes = new ArrayList<>(); /** * Constructs a new builder for {@link TvIAppInfo}. * * @param context A Context of the application package implementing this class. * @param component The name of the application component to be used for the * {@link TvIAppService}. */ public Builder(Context context, ComponentName component) { if (context == null) { throw new IllegalArgumentException("context cannot be null."); } Intent intent = new Intent(TvIAppService.SERVICE_INTERFACE).setComponent(component); mResolveInfo = context.getPackageManager().resolveService(intent, PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); if (mResolveInfo == null) { throw new IllegalArgumentException("Invalid component. Can't find the service."); } mContext = context; } /** * Creates a {@link TvIAppInfo} instance with the specified fields. Most of the information * is obtained by parsing the AndroidManifest and {@link TvIAppService#SERVICE_META_DATA} * for the {@link TvIAppService} this TV IApp implements. * * @return TvIAppInfo containing information about this TV IApp service. */ public TvIAppInfo build() { ComponentName componentName = new ComponentName(mResolveInfo.serviceInfo.packageName, mResolveInfo.serviceInfo.name); String id; id = generateIAppServiceId(componentName); parseServiceMetadata(); return new TvIAppInfo(mResolveInfo, id, mTypes); } private static String generateIAppServiceId(ComponentName name) { return name.flattenToShortString(); } private void parseServiceMetadata() { ServiceInfo si = mResolveInfo.serviceInfo; PackageManager pm = mContext.getPackageManager(); try (XmlResourceParser parser = si.loadXmlMetaData(pm, TvIAppService.SERVICE_META_DATA)) { if (parser == null) { throw new IllegalStateException("No " + TvIAppService.SERVICE_META_DATA + " meta-data found for " + si.name); } Resources res = pm.getResourcesForApplication(si.applicationInfo); AttributeSet attrs = Xml.asAttributeSet(parser); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) { // move to the START_TAG } String nodeName = parser.getName(); if (!XML_START_TAG_NAME.equals(nodeName)) { throw new IllegalStateException("Meta-data does not start with " + XML_START_TAG_NAME + " tag for " + si.name); } TypedArray sa = res.obtainAttributes(attrs, com.android.internal.R.styleable.TvIAppService); CharSequence[] types = sa.getTextArray( com.android.internal.R.styleable.TvIAppService_supportedTypes); for (CharSequence cs : types) { mTypes.add(cs.toString()); } sa.recycle(); } catch (IOException | XmlPullParserException e) { throw new IllegalStateException( "Failed reading meta-data for " + si.packageName, e); } catch (PackageManager.NameNotFoundException e) { throw new IllegalStateException("No resources found for " + si.packageName, e); } } } }
media/java/android/media/tv/interactive/TvIAppService.java +26 −8 Original line number Diff line number Diff line Loading @@ -38,22 +38,32 @@ import java.util.List; /** * The TvIAppService class represents a TV interactive applications RTE. * @hide */ public abstract class TvIAppService extends Service { private static final boolean DEBUG = false; private static final String TAG = "TvIAppService"; private final Handler mServiceHandler = new ServiceHandler(); // TODO: cleanup and unhide APIs. /** * This is the interface name that a service implementing an environment to run Tv IApp should * say that it support -- that is, this is the action it uses for its intent filter. To be * supported, the service must also require the BIND_TV_IAPP permission so that other * applications cannot abuse it. * This is the interface name that a service implementing a TV IApp service should say that it * supports -- that is, this is the action it uses for its intent filter. To be supported, the * service must also require the android.Manifest.permission#BIND_TV_IAPP permission so * that other applications cannot abuse it. */ public static final String SERVICE_INTERFACE = "android.media.tv.TvIAppService"; public static final String SERVICE_INTERFACE = "android.media.tv.interactive.TvIAppService"; /** * Name under which a TvIAppService component publishes information about itself. This meta-data * must reference an XML resource containing an * <code><{@link android.R.styleable#TvIAppService tv-iapp}></code> * tag. */ public static final String SERVICE_META_DATA = "android.media.tv.interactive.app"; private final Handler mServiceHandler = new ServiceHandler(); /** @hide */ @Override public final IBinder onBind(Intent intent) { ITvIAppService.Stub tvIAppServiceBinder = new ITvIAppService.Stub() { Loading Loading @@ -83,12 +93,17 @@ public abstract class TvIAppService extends Service { * * @param iAppServiceId The ID of the TV IApp associated with the session. * @param type The type of the TV IApp associated with the session. * @hide */ @Nullable public abstract Session onCreateSession(@NonNull String iAppServiceId, int type); public Session onCreateSession(@NonNull String iAppServiceId, int type) { // TODO: make it abstract when unhide return null; } /** * Base class for derived classes to implement to provide a TV interactive app session. * @hide */ public abstract static class Session implements KeyEvent.Callback { private final Object mLock = new Object(); Loading @@ -113,6 +128,7 @@ public abstract class TvIAppService extends Service { /** * Starts TvIAppService session. * @hide */ public void onStartIApp() { } Loading Loading @@ -144,6 +160,7 @@ public abstract class TvIAppService extends Service { /** * Releases TvIAppService session. * @hide */ public void onRelease() { } Loading Loading @@ -245,6 +262,7 @@ public abstract class TvIAppService extends Service { /** * Implements the internal ITvIAppSession interface. * @hide */ public static class ITvIAppSessionWrapper extends ITvIAppSession.Stub { private final Session mSessionImpl; Loading