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