1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.content.pm; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.annotation.SystemApi; 22 import android.content.IntentFilter; 23 import android.content.pm.InstantAppResolveInfo.InstantAppDigest; 24 import android.net.Uri; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 28 import java.security.MessageDigest; 29 import java.security.NoSuchAlgorithmException; 30 import java.util.ArrayList; 31 import java.util.List; 32 import java.util.Locale; 33 34 /** 35 * Information about an ephemeral application. 36 * @hide 37 */ 38 @Deprecated 39 @SystemApi 40 public final class EphemeralResolveInfo implements Parcelable { 41 /** Algorithm that will be used to generate the domain digest */ 42 public static final String SHA_ALGORITHM = "SHA-256"; 43 44 private final InstantAppResolveInfo mInstantAppResolveInfo; 45 @Deprecated 46 private final List<IntentFilter> mLegacyFilters; 47 48 @Deprecated EphemeralResolveInfo(@onNull Uri uri, @NonNull String packageName, @NonNull List<IntentFilter> filters)49 public EphemeralResolveInfo(@NonNull Uri uri, @NonNull String packageName, 50 @NonNull List<IntentFilter> filters) { 51 if (uri == null || packageName == null || filters == null || filters.isEmpty()) { 52 throw new IllegalArgumentException(); 53 } 54 final List<EphemeralIntentFilter> ephemeralFilters = new ArrayList<>(1); 55 ephemeralFilters.add(new EphemeralIntentFilter(packageName, filters)); 56 mInstantAppResolveInfo = new InstantAppResolveInfo(uri.getHost(), packageName, 57 createInstantAppIntentFilterList(ephemeralFilters)); 58 mLegacyFilters = new ArrayList<IntentFilter>(filters.size()); 59 mLegacyFilters.addAll(filters); 60 } 61 62 @Deprecated EphemeralResolveInfo(@onNull EphemeralDigest digest, @Nullable String packageName, @Nullable List<EphemeralIntentFilter> filters)63 public EphemeralResolveInfo(@NonNull EphemeralDigest digest, @Nullable String packageName, 64 @Nullable List<EphemeralIntentFilter> filters) { 65 this(digest, packageName, filters, -1 /*versionCode*/); 66 } 67 EphemeralResolveInfo(@onNull EphemeralDigest digest, @Nullable String packageName, @Nullable List<EphemeralIntentFilter> filters, int versionCode)68 public EphemeralResolveInfo(@NonNull EphemeralDigest digest, @Nullable String packageName, 69 @Nullable List<EphemeralIntentFilter> filters, int versionCode) { 70 mInstantAppResolveInfo = new InstantAppResolveInfo( 71 digest.getInstantAppDigest(), packageName, 72 createInstantAppIntentFilterList(filters), versionCode); 73 mLegacyFilters = null; 74 } 75 EphemeralResolveInfo(@onNull String hostName, @Nullable String packageName, @Nullable List<EphemeralIntentFilter> filters)76 public EphemeralResolveInfo(@NonNull String hostName, @Nullable String packageName, 77 @Nullable List<EphemeralIntentFilter> filters) { 78 this(new EphemeralDigest(hostName), packageName, filters); 79 } 80 EphemeralResolveInfo(Parcel in)81 EphemeralResolveInfo(Parcel in) { 82 mInstantAppResolveInfo = in.readParcelable(null /*loader*/); 83 mLegacyFilters = new ArrayList<IntentFilter>(); 84 in.readList(mLegacyFilters, null /*loader*/); 85 } 86 87 /** @hide */ getInstantAppResolveInfo()88 public InstantAppResolveInfo getInstantAppResolveInfo() { 89 return mInstantAppResolveInfo; 90 } 91 createInstantAppIntentFilterList( List<EphemeralIntentFilter> filters)92 private static List<InstantAppIntentFilter> createInstantAppIntentFilterList( 93 List<EphemeralIntentFilter> filters) { 94 if (filters == null) { 95 return null; 96 } 97 final int filterCount = filters.size(); 98 final List<InstantAppIntentFilter> returnList = new ArrayList<>(filterCount); 99 for (int i = 0; i < filterCount; i++) { 100 returnList.add(filters.get(i).getInstantAppIntentFilter()); 101 } 102 return returnList; 103 } 104 getDigestBytes()105 public byte[] getDigestBytes() { 106 return mInstantAppResolveInfo.getDigestBytes(); 107 } 108 getDigestPrefix()109 public int getDigestPrefix() { 110 return mInstantAppResolveInfo.getDigestPrefix(); 111 } 112 getPackageName()113 public String getPackageName() { 114 return mInstantAppResolveInfo.getPackageName(); 115 } 116 getIntentFilters()117 public List<EphemeralIntentFilter> getIntentFilters() { 118 final List<InstantAppIntentFilter> filters = mInstantAppResolveInfo.getIntentFilters(); 119 final int filterCount = filters.size(); 120 final List<EphemeralIntentFilter> returnList = new ArrayList<>(filterCount); 121 for (int i = 0; i < filterCount; i++) { 122 returnList.add(new EphemeralIntentFilter(filters.get(i))); 123 } 124 return returnList; 125 } 126 getVersionCode()127 public int getVersionCode() { 128 return mInstantAppResolveInfo.getVersionCode(); 129 } 130 131 @Deprecated getFilters()132 public List<IntentFilter> getFilters() { 133 return mLegacyFilters; 134 } 135 136 @Override describeContents()137 public int describeContents() { 138 return 0; 139 } 140 141 @Override writeToParcel(Parcel out, int flags)142 public void writeToParcel(Parcel out, int flags) { 143 out.writeParcelable(mInstantAppResolveInfo, flags); 144 out.writeList(mLegacyFilters); 145 } 146 147 public static final Parcelable.Creator<EphemeralResolveInfo> CREATOR 148 = new Parcelable.Creator<EphemeralResolveInfo>() { 149 @Override 150 public EphemeralResolveInfo createFromParcel(Parcel in) { 151 return new EphemeralResolveInfo(in); 152 } 153 @Override 154 public EphemeralResolveInfo[] newArray(int size) { 155 return new EphemeralResolveInfo[size]; 156 } 157 }; 158 159 /** 160 * Helper class to generate and store each of the digests and prefixes 161 * sent to the Ephemeral Resolver. 162 * <p> 163 * Since intent filters may want to handle multiple hosts within a 164 * domain [eg “*.google.com”], the resolver is presented with multiple 165 * hash prefixes. For example, "a.b.c.d.e" generates digests for 166 * "d.e", "c.d.e", "b.c.d.e" and "a.b.c.d.e". 167 * 168 * @hide 169 */ 170 @SystemApi 171 public static final class EphemeralDigest implements Parcelable { 172 private final InstantAppDigest mInstantAppDigest; 173 EphemeralDigest(@onNull String hostName)174 public EphemeralDigest(@NonNull String hostName) { 175 this(hostName, -1 /*maxDigests*/); 176 } 177 178 /** @hide */ EphemeralDigest(@onNull String hostName, int maxDigests)179 public EphemeralDigest(@NonNull String hostName, int maxDigests) { 180 mInstantAppDigest = new InstantAppDigest(hostName, maxDigests); 181 } 182 EphemeralDigest(Parcel in)183 EphemeralDigest(Parcel in) { 184 mInstantAppDigest = in.readParcelable(null /*loader*/); 185 } 186 187 /** @hide */ getInstantAppDigest()188 InstantAppDigest getInstantAppDigest() { 189 return mInstantAppDigest; 190 } 191 getDigestBytes()192 public byte[][] getDigestBytes() { 193 return mInstantAppDigest.getDigestBytes(); 194 } 195 getDigestPrefix()196 public int[] getDigestPrefix() { 197 return mInstantAppDigest.getDigestPrefix(); 198 } 199 200 @Override describeContents()201 public int describeContents() { 202 return 0; 203 } 204 205 @Override writeToParcel(Parcel out, int flags)206 public void writeToParcel(Parcel out, int flags) { 207 out.writeParcelable(mInstantAppDigest, flags); 208 } 209 210 @SuppressWarnings("hiding") 211 public static final Parcelable.Creator<EphemeralDigest> CREATOR = 212 new Parcelable.Creator<EphemeralDigest>() { 213 @Override 214 public EphemeralDigest createFromParcel(Parcel in) { 215 return new EphemeralDigest(in); 216 } 217 @Override 218 public EphemeralDigest[] newArray(int size) { 219 return new EphemeralDigest[size]; 220 } 221 }; 222 } 223 } 224