blob: 67bda2ce3944dc525e37d10f3b7ce00a4784c0bd [file] [log] [blame]
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -08001/*
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 static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
20import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
21import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
Christopher Tate56f0ff32015-08-13 16:29:33 -070022import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080023import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
24
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080025import android.annotation.SystemApi;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080026import android.os.Parcel;
27import android.os.Parcelable;
28import android.text.TextUtils;
Fabrice Di Meglio07885952015-04-06 19:41:28 -070029import android.util.ArraySet;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080030import android.util.Log;
Christopher Tatef0d6cb32015-07-10 17:44:53 -070031
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080032import com.android.internal.util.XmlUtils;
Christopher Tatef0d6cb32015-07-10 17:44:53 -070033
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080034import org.xmlpull.v1.XmlPullParser;
35import org.xmlpull.v1.XmlPullParserException;
36import org.xmlpull.v1.XmlSerializer;
37
38import java.io.IOException;
39import java.util.ArrayList;
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080040import java.util.Set;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080041
42/**
43 * The {@link com.android.server.pm.PackageManagerService} maintains some
Fabrice Di Meglio7d014ce2015-04-08 16:17:46 -070044 * {@link IntentFilterVerificationInfo}s for each domain / package name.
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080045 *
46 * @hide
47 */
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080048@SystemApi
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080049public final class IntentFilterVerificationInfo implements Parcelable {
50 private static final String TAG = IntentFilterVerificationInfo.class.getName();
51
52 private static final String TAG_DOMAIN = "domain";
53 private static final String ATTR_DOMAIN_NAME = "name";
54 private static final String ATTR_PACKAGE_NAME = "packageName";
55 private static final String ATTR_STATUS = "status";
56
Fabrice Di Meglio1de3f0d2015-04-29 19:42:41 -070057 private ArraySet<String> mDomains = new ArraySet<>();
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080058 private String mPackageName;
59 private int mMainStatus;
60
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080061 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080062 public IntentFilterVerificationInfo() {
63 mPackageName = null;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080064 mMainStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
65 }
66
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080067 /** @hide */
Todd Kennedy788c8422016-08-10 10:52:34 -070068 public IntentFilterVerificationInfo(String packageName, ArraySet<String> domains) {
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080069 mPackageName = packageName;
Todd Kennedy788c8422016-08-10 10:52:34 -070070 mDomains = domains;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080071 mMainStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
72 }
73
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080074 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080075 public IntentFilterVerificationInfo(XmlPullParser parser)
76 throws IOException, XmlPullParserException {
77 readFromXml(parser);
78 }
79
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080080 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080081 public IntentFilterVerificationInfo(Parcel source) {
82 readFromParcel(source);
83 }
84
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080085 public String getPackageName() {
86 return mPackageName;
87 }
88
89 public int getStatus() {
90 return mMainStatus;
91 }
92
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -080093 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -080094 public void setStatus(int s) {
95 if (s >= INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED &&
96 s <= INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
97 mMainStatus = s;
98 } else {
99 Log.w(TAG, "Trying to set a non supported status: " + s);
100 }
101 }
102
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -0800103 public Set<String> getDomains() {
Fabrice Di Meglio1de3f0d2015-04-29 19:42:41 -0700104 return mDomains;
105 }
106
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -0800107 /** @hide */
Todd Kennedy788c8422016-08-10 10:52:34 -0700108 public void setDomains(ArraySet<String> list) {
109 mDomains = list;
Fabrice Di Meglio1de3f0d2015-04-29 19:42:41 -0700110 }
111
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -0800112 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800113 public String getDomainsString() {
114 StringBuilder sb = new StringBuilder();
115 for (String str : mDomains) {
116 if (sb.length() > 0) {
117 sb.append(" ");
118 }
119 sb.append(str);
120 }
121 return sb.toString();
122 }
123
124 String getStringFromXml(XmlPullParser parser, String attribute, String defaultValue) {
125 String value = parser.getAttributeValue(null, attribute);
126 if (value == null) {
127 String msg = "Missing element under " + TAG +": " + attribute + " at " +
128 parser.getPositionDescription();
129 Log.w(TAG, msg);
130 return defaultValue;
131 } else {
132 return value;
133 }
134 }
135
136 int getIntFromXml(XmlPullParser parser, String attribute, int defaultValue) {
137 String value = parser.getAttributeValue(null, attribute);
138 if (TextUtils.isEmpty(value)) {
139 String msg = "Missing element under " + TAG +": " + attribute + " at " +
140 parser.getPositionDescription();
141 Log.w(TAG, msg);
142 return defaultValue;
143 } else {
144 return Integer.parseInt(value);
145 }
146 }
147
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -0800148 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800149 public void readFromXml(XmlPullParser parser) throws XmlPullParserException,
150 IOException {
151 mPackageName = getStringFromXml(parser, ATTR_PACKAGE_NAME, null);
152 if (mPackageName == null) {
153 Log.e(TAG, "Package name cannot be null!");
154 }
155 int status = getIntFromXml(parser, ATTR_STATUS, -1);
156 if (status == -1) {
157 Log.e(TAG, "Unknown status value: " + status);
158 }
159 mMainStatus = status;
160
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800161 int outerDepth = parser.getDepth();
162 int type;
163 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
164 && (type != XmlPullParser.END_TAG
165 || parser.getDepth() > outerDepth)) {
166 if (type == XmlPullParser.END_TAG
167 || type == XmlPullParser.TEXT) {
168 continue;
169 }
170
171 String tagName = parser.getName();
172 if (tagName.equals(TAG_DOMAIN)) {
173 String name = getStringFromXml(parser, ATTR_DOMAIN_NAME, null);
174 if (!TextUtils.isEmpty(name)) {
Fabrice Di Meglio07885952015-04-06 19:41:28 -0700175 mDomains.add(name);
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800176 }
177 } else {
178 Log.w(TAG, "Unknown tag parsing IntentFilter: " + tagName);
179 }
180 XmlUtils.skipCurrentTag(parser);
181 }
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800182 }
183
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -0800184 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800185 public void writeToXml(XmlSerializer serializer) throws IOException {
186 serializer.attribute(null, ATTR_PACKAGE_NAME, mPackageName);
187 serializer.attribute(null, ATTR_STATUS, String.valueOf(mMainStatus));
188 for (String str : mDomains) {
189 serializer.startTag(null, TAG_DOMAIN);
190 serializer.attribute(null, ATTR_DOMAIN_NAME, str);
191 serializer.endTag(null, TAG_DOMAIN);
192 }
193 }
194
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -0800195 /** @hide */
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800196 public String getStatusString() {
Christopher Tate3decab62016-12-15 14:18:15 -0800197 return getStatusStringFromValue(((long)mMainStatus) << 32);
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800198 }
199
Jeff Schumacher6fd90ed2017-01-20 13:58:34 -0800200 /** @hide */
Christopher Tatef0d6cb32015-07-10 17:44:53 -0700201 public static String getStatusStringFromValue(long val) {
202 StringBuilder sb = new StringBuilder();
203 switch ((int)(val >> 32)) {
204 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
205 sb.append("always : ");
206 sb.append(Long.toHexString(val & 0x00000000FFFFFFFF));
207 break;
208
209 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
210 sb.append("ask");
211 break;
212
213 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER:
214 sb.append("never");
215 break;
216
Christopher Tate56f0ff32015-08-13 16:29:33 -0700217 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK:
218 sb.append("always-ask");
219 break;
220
Christopher Tatef0d6cb32015-07-10 17:44:53 -0700221 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800222 default:
Christopher Tatef0d6cb32015-07-10 17:44:53 -0700223 sb.append("undefined");
224 break;
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800225 }
Christopher Tatef0d6cb32015-07-10 17:44:53 -0700226 return sb.toString();
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800227 }
228
229 @Override
230 public int describeContents() {
231 return 0;
232 }
233
234 private void readFromParcel(Parcel source) {
235 mPackageName = source.readString();
236 mMainStatus = source.readInt();
Fabrice Di Meglio1de3f0d2015-04-29 19:42:41 -0700237 ArrayList<String> list = new ArrayList<>();
238 source.readStringList(list);
239 mDomains.addAll(list);
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800240 }
241
242 @Override
243 public void writeToParcel(Parcel dest, int flags) {
244 dest.writeString(mPackageName);
245 dest.writeInt(mMainStatus);
Fabrice Di Meglio1de3f0d2015-04-29 19:42:41 -0700246 dest.writeStringList(new ArrayList<>(mDomains));
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800247 }
248
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700249 public static final @android.annotation.NonNull Creator<IntentFilterVerificationInfo> CREATOR =
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800250 new Creator<IntentFilterVerificationInfo>() {
251 public IntentFilterVerificationInfo createFromParcel(Parcel source) {
252 return new IntentFilterVerificationInfo(source);
253 }
254 public IntentFilterVerificationInfo[] newArray(int size) {
255 return new IntentFilterVerificationInfo[size];
256 }
257 };
Fabrice Di Meglio1c1b4712014-11-19 17:12:32 -0800258}