diff options
| author | 2023-11-08 16:34:32 -0800 | |
|---|---|---|
| committer | 2023-11-10 10:56:22 -0800 | |
| commit | 032a57a7d630a96bb6301f7b852b3f9365743d7e (patch) | |
| tree | 32a8723d4b5c5b04d5c08e2912d7cd7234471d39 | |
| parent | 10614f6487059a631cda474e820a6e6ff33e208d (diff) | |
CSAI: add TvAdServiceInfo
Bug: 309866029
Test: mmm
Change-Id: Ibf49a99604d499a7d34df63841fb878be3b33801
| -rw-r--r-- | media/java/android/media/tv/ad/TvAdServiceInfo.aidl | 19 | ||||
| -rw-r--r-- | media/java/android/media/tv/ad/TvAdServiceInfo.java | 194 |
2 files changed, 213 insertions, 0 deletions
diff --git a/media/java/android/media/tv/ad/TvAdServiceInfo.aidl b/media/java/android/media/tv/ad/TvAdServiceInfo.aidl new file mode 100644 index 000000000000..a5e631fc8426 --- /dev/null +++ b/media/java/android/media/tv/ad/TvAdServiceInfo.aidl @@ -0,0 +1,19 @@ +/* + * Copyright 2023 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.ad; + +parcelable TvAdServiceInfo; diff --git a/media/java/android/media/tv/ad/TvAdServiceInfo.java b/media/java/android/media/tv/ad/TvAdServiceInfo.java new file mode 100644 index 000000000000..ed04f1f9058c --- /dev/null +++ b/media/java/android/media/tv/ad/TvAdServiceInfo.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2023 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.ad; + +import android.annotation.Nullable; +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.XmlResourceParser; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.util.Xml; + +import androidx.annotation.NonNull; + +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 AD service. + * @hide + */ +public final class TvAdServiceInfo implements Parcelable { + private static final boolean DEBUG = false; + private static final String TAG = "TvAdServiceInfo"; + + private static final String XML_START_TAG_NAME = "tv-ad-service"; + + private final ResolveInfo mService; + private final String mId; + private final List<String> mTypes = new ArrayList<>(); + + /** + * Constructs a TvAdServiceInfo object. + * + * @param context the application context + * @param component the component name of the TvAdService + */ + public TvAdServiceInfo(@NonNull Context context, @NonNull ComponentName component) { + if (context == null) { + throw new IllegalArgumentException("context cannot be null."); + } + // TODO: use a constant + Intent intent = new Intent("android.media.tv.ad.TvAdService").setComponent(component); + ResolveInfo resolveInfo = context.getPackageManager().resolveService( + intent, PackageManager.GET_SERVICES | PackageManager.GET_META_DATA); + if (resolveInfo == null) { + throw new IllegalArgumentException("Invalid component. Can't find the service."); + } + + ComponentName componentName = new ComponentName(resolveInfo.serviceInfo.packageName, + resolveInfo.serviceInfo.name); + String id; + id = generateAdServiceId(componentName); + List<String> types = new ArrayList<>(); + parseServiceMetadata(resolveInfo, context, types); + + mService = resolveInfo; + mId = id; + } + + private TvAdServiceInfo(ResolveInfo service, String id, List<String> types) { + mService = service; + mId = id; + mTypes.addAll(types); + } + + private TvAdServiceInfo(@NonNull Parcel in) { + mService = ResolveInfo.CREATOR.createFromParcel(in); + mId = in.readString(); + in.readStringList(mTypes); + } + + public static final Creator<TvAdServiceInfo> CREATOR = new Creator<TvAdServiceInfo>() { + @Override + public TvAdServiceInfo createFromParcel(Parcel in) { + return new TvAdServiceInfo(in); + } + + @Override + public TvAdServiceInfo[] newArray(int size) { + return new TvAdServiceInfo[size]; + } + }; + + /** + * Returns a unique ID for this TV AD service. The ID is generated from the package and class + * name implementing the TV AD service. + */ + @NonNull + public String getId() { + return mId; + } + + /** + * Returns the component of the TV AD service. + * @hide + */ + public ComponentName getComponent() { + return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name); + } + + /** + * Returns the information of the service that implements this AD service. + */ + @Nullable + public ServiceInfo getServiceInfo() { + return mService.serviceInfo; + } + + /** + * Gets supported TV AD types. + */ + @NonNull + public List<String> getSupportedTypes() { + return mTypes; + } + + private static String generateAdServiceId(ComponentName name) { + return name.flattenToShortString(); + } + + private static void parseServiceMetadata( + ResolveInfo resolveInfo, Context context, List<String> types) { + ServiceInfo serviceInfo = resolveInfo.serviceInfo; + PackageManager pm = context.getPackageManager(); + // TODO: use constant for the metadata + try (XmlResourceParser parser = + serviceInfo.loadXmlMetaData(pm, "android.media.tv.ad.service")) { + if (parser == null) { + throw new IllegalStateException( + "No " + "android.media.tv.ad.service" + + " meta-data found for " + serviceInfo.name); + } + + Resources resources = pm.getResourcesForApplication(serviceInfo.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 " + serviceInfo.name); + } + + // TODO: parse attributes + } catch (IOException | XmlPullParserException e) { + throw new IllegalStateException( + "Failed reading meta-data for " + serviceInfo.packageName, e); + } catch (PackageManager.NameNotFoundException e) { + throw new IllegalStateException("No resources found for " + serviceInfo.packageName, e); + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(@NonNull Parcel dest, int flags) { + mService.writeToParcel(dest, flags); + dest.writeString(mId); + dest.writeStringList(mTypes); + } +} |