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

Commit 51693ff8 authored by Shubang Lu's avatar Shubang Lu Committed by Android (Google) Code Review
Browse files

Merge changes from topic "TIAF_attrs"

* changes:
  TIAF: handle TIAS XML and build TIAS info
  TIAF: Add attr for TV interactive app service
parents ae90b555 9736c2eb
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
@@ -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 {
+12 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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">
+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);
            }
        }
    }
}
+26 −8
Original line number Diff line number Diff line
@@ -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>&lt;{@link android.R.styleable#TvIAppService tv-iapp}&gt;</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() {
@@ -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();
@@ -113,6 +128,7 @@ public abstract class TvIAppService extends Service {

        /**
         * Starts TvIAppService session.
         * @hide
         */
        public void onStartIApp() {
        }
@@ -144,6 +160,7 @@ public abstract class TvIAppService extends Service {

        /**
         * Releases TvIAppService session.
         * @hide
         */
        public void onRelease() {
        }
@@ -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