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.SystemApi;
21 import android.content.IntentFilter;
22 import android.net.Uri;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.security.MessageDigest;
27 import java.security.NoSuchAlgorithmException;
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 /**
32  * Information about an ephemeral application.
33  * @hide
34  */
35 @SystemApi
36 public final class EphemeralResolveInfo implements Parcelable {
37     /** Algorithm that will be used to generate the domain digest */
38     public static final String SHA_ALGORITHM = "SHA-256";
39 
40     /** Full digest of the domain hash */
41     private final byte[] mDigestBytes;
42     /** The first 4 bytes of the domain hash */
43     private final int mDigestPrefix;
44     private final String mPackageName;
45     /** The filters used to match domain */
46     private final List<IntentFilter> mFilters = new ArrayList<IntentFilter>();
47 
EphemeralResolveInfo(@onNull Uri uri, @NonNull String packageName, @NonNull List<IntentFilter> filters)48     public EphemeralResolveInfo(@NonNull Uri uri, @NonNull String packageName,
49             @NonNull List<IntentFilter> filters) {
50         // validate arguments
51         if (uri == null
52                 || packageName == null
53                 || filters == null
54                 || filters.size() == 0) {
55             throw new IllegalArgumentException();
56         }
57 
58         mDigestBytes = generateDigest(uri);
59         mDigestPrefix =
60                 mDigestBytes[0] << 24
61                 | mDigestBytes[1] << 16
62                 | mDigestBytes[2] << 8
63                 | mDigestBytes[3] << 0;
64         mFilters.addAll(filters);
65         mPackageName = packageName;
66     }
67 
EphemeralResolveInfo(Parcel in)68     EphemeralResolveInfo(Parcel in) {
69         mDigestBytes = in.createByteArray();
70         mDigestPrefix = in.readInt();
71         mPackageName = in.readString();
72         in.readList(mFilters, null /*loader*/);
73     }
74 
getDigestBytes()75     public byte[] getDigestBytes() {
76         return mDigestBytes;
77     }
78 
getDigestPrefix()79     public int getDigestPrefix() {
80         return mDigestPrefix;
81     }
82 
getPackageName()83     public String getPackageName() {
84         return mPackageName;
85     }
86 
getFilters()87     public List<IntentFilter> getFilters() {
88         return mFilters;
89     }
90 
generateDigest(Uri uri)91     private static byte[] generateDigest(Uri uri) {
92         try {
93             final MessageDigest digest = MessageDigest.getInstance(SHA_ALGORITHM);
94             final byte[] hostBytes = uri.getHost().getBytes();
95             return digest.digest(hostBytes);
96         } catch (NoSuchAlgorithmException e) {
97             throw new IllegalStateException("could not find digest algorithm");
98         }
99     }
100 
101     @Override
describeContents()102     public int describeContents() {
103         return 0;
104     }
105 
106     @Override
writeToParcel(Parcel out, int flags)107     public void writeToParcel(Parcel out, int flags) {
108         out.writeByteArray(mDigestBytes);
109         out.writeInt(mDigestPrefix);
110         out.writeString(mPackageName);
111         out.writeList(mFilters);
112     }
113 
114     public static final Parcelable.Creator<EphemeralResolveInfo> CREATOR
115             = new Parcelable.Creator<EphemeralResolveInfo>() {
116         public EphemeralResolveInfo createFromParcel(Parcel in) {
117             return new EphemeralResolveInfo(in);
118         }
119 
120         public EphemeralResolveInfo[] newArray(int size) {
121             return new EphemeralResolveInfo[size];
122         }
123     };
124 
125     /** @hide */
126     public static final class EphemeralResolveIntentInfo extends IntentFilter {
127         private final EphemeralResolveInfo mResolveInfo;
128 
EphemeralResolveIntentInfo(@onNull IntentFilter orig, @NonNull EphemeralResolveInfo resolveInfo)129         public EphemeralResolveIntentInfo(@NonNull IntentFilter orig,
130                 @NonNull EphemeralResolveInfo resolveInfo) {
131             super(orig);
132             this.mResolveInfo = resolveInfo;
133         }
134 
getEphemeralResolveInfo()135         public EphemeralResolveInfo getEphemeralResolveInfo() {
136             return mResolveInfo;
137         }
138     }
139 }
140