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 static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 20 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK; 21 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS; 22 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK; 23 import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER; 24 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.text.TextUtils; 28 import android.util.ArraySet; 29 import android.util.Log; 30 31 import com.android.internal.util.XmlUtils; 32 33 import org.xmlpull.v1.XmlPullParser; 34 import org.xmlpull.v1.XmlPullParserException; 35 import org.xmlpull.v1.XmlSerializer; 36 37 import java.io.IOException; 38 import java.util.ArrayList; 39 40 /** 41 * The {@link com.android.server.pm.PackageManagerService} maintains some 42 * {@link IntentFilterVerificationInfo}s for each domain / package name. 43 * 44 * @hide 45 */ 46 public final class IntentFilterVerificationInfo implements Parcelable { 47 private static final String TAG = IntentFilterVerificationInfo.class.getName(); 48 49 private static final String TAG_DOMAIN = "domain"; 50 private static final String ATTR_DOMAIN_NAME = "name"; 51 private static final String ATTR_PACKAGE_NAME = "packageName"; 52 private static final String ATTR_STATUS = "status"; 53 54 private ArraySet<String> mDomains = new ArraySet<>(); 55 private String mPackageName; 56 private int mMainStatus; 57 IntentFilterVerificationInfo()58 public IntentFilterVerificationInfo() { 59 mPackageName = null; 60 mMainStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 61 } 62 IntentFilterVerificationInfo(String packageName, ArrayList<String> domains)63 public IntentFilterVerificationInfo(String packageName, ArrayList<String> domains) { 64 mPackageName = packageName; 65 mDomains.addAll(domains); 66 mMainStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; 67 } 68 IntentFilterVerificationInfo(XmlPullParser parser)69 public IntentFilterVerificationInfo(XmlPullParser parser) 70 throws IOException, XmlPullParserException { 71 readFromXml(parser); 72 } 73 IntentFilterVerificationInfo(Parcel source)74 public IntentFilterVerificationInfo(Parcel source) { 75 readFromParcel(source); 76 } 77 getPackageName()78 public String getPackageName() { 79 return mPackageName; 80 } 81 getStatus()82 public int getStatus() { 83 return mMainStatus; 84 } 85 setStatus(int s)86 public void setStatus(int s) { 87 if (s >= INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED && 88 s <= INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) { 89 mMainStatus = s; 90 } else { 91 Log.w(TAG, "Trying to set a non supported status: " + s); 92 } 93 } 94 getDomains()95 public ArraySet<String> getDomains() { 96 return mDomains; 97 } 98 setDomains(ArrayList<String> list)99 public void setDomains(ArrayList<String> list) { 100 mDomains = new ArraySet<>(list); 101 } 102 getDomainsString()103 public String getDomainsString() { 104 StringBuilder sb = new StringBuilder(); 105 for (String str : mDomains) { 106 if (sb.length() > 0) { 107 sb.append(" "); 108 } 109 sb.append(str); 110 } 111 return sb.toString(); 112 } 113 getStringFromXml(XmlPullParser parser, String attribute, String defaultValue)114 String getStringFromXml(XmlPullParser parser, String attribute, String defaultValue) { 115 String value = parser.getAttributeValue(null, attribute); 116 if (value == null) { 117 String msg = "Missing element under " + TAG +": " + attribute + " at " + 118 parser.getPositionDescription(); 119 Log.w(TAG, msg); 120 return defaultValue; 121 } else { 122 return value; 123 } 124 } 125 getIntFromXml(XmlPullParser parser, String attribute, int defaultValue)126 int getIntFromXml(XmlPullParser parser, String attribute, int defaultValue) { 127 String value = parser.getAttributeValue(null, attribute); 128 if (TextUtils.isEmpty(value)) { 129 String msg = "Missing element under " + TAG +": " + attribute + " at " + 130 parser.getPositionDescription(); 131 Log.w(TAG, msg); 132 return defaultValue; 133 } else { 134 return Integer.parseInt(value); 135 } 136 } 137 readFromXml(XmlPullParser parser)138 public void readFromXml(XmlPullParser parser) throws XmlPullParserException, 139 IOException { 140 mPackageName = getStringFromXml(parser, ATTR_PACKAGE_NAME, null); 141 if (mPackageName == null) { 142 Log.e(TAG, "Package name cannot be null!"); 143 } 144 int status = getIntFromXml(parser, ATTR_STATUS, -1); 145 if (status == -1) { 146 Log.e(TAG, "Unknown status value: " + status); 147 } 148 mMainStatus = status; 149 150 int outerDepth = parser.getDepth(); 151 int type; 152 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 153 && (type != XmlPullParser.END_TAG 154 || parser.getDepth() > outerDepth)) { 155 if (type == XmlPullParser.END_TAG 156 || type == XmlPullParser.TEXT) { 157 continue; 158 } 159 160 String tagName = parser.getName(); 161 if (tagName.equals(TAG_DOMAIN)) { 162 String name = getStringFromXml(parser, ATTR_DOMAIN_NAME, null); 163 if (!TextUtils.isEmpty(name)) { 164 mDomains.add(name); 165 } 166 } else { 167 Log.w(TAG, "Unknown tag parsing IntentFilter: " + tagName); 168 } 169 XmlUtils.skipCurrentTag(parser); 170 } 171 } 172 writeToXml(XmlSerializer serializer)173 public void writeToXml(XmlSerializer serializer) throws IOException { 174 serializer.attribute(null, ATTR_PACKAGE_NAME, mPackageName); 175 serializer.attribute(null, ATTR_STATUS, String.valueOf(mMainStatus)); 176 for (String str : mDomains) { 177 serializer.startTag(null, TAG_DOMAIN); 178 serializer.attribute(null, ATTR_DOMAIN_NAME, str); 179 serializer.endTag(null, TAG_DOMAIN); 180 } 181 } 182 getStatusString()183 public String getStatusString() { 184 return getStatusStringFromValue(mMainStatus); 185 } 186 getStatusStringFromValue(long val)187 public static String getStatusStringFromValue(long val) { 188 StringBuilder sb = new StringBuilder(); 189 switch ((int)(val >> 32)) { 190 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS: 191 sb.append("always : "); 192 sb.append(Long.toHexString(val & 0x00000000FFFFFFFF)); 193 break; 194 195 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK: 196 sb.append("ask"); 197 break; 198 199 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER: 200 sb.append("never"); 201 break; 202 203 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK: 204 sb.append("always-ask"); 205 break; 206 207 case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED: 208 default: 209 sb.append("undefined"); 210 break; 211 } 212 return sb.toString(); 213 } 214 215 @Override describeContents()216 public int describeContents() { 217 return 0; 218 } 219 readFromParcel(Parcel source)220 private void readFromParcel(Parcel source) { 221 mPackageName = source.readString(); 222 mMainStatus = source.readInt(); 223 ArrayList<String> list = new ArrayList<>(); 224 source.readStringList(list); 225 mDomains.addAll(list); 226 } 227 228 @Override writeToParcel(Parcel dest, int flags)229 public void writeToParcel(Parcel dest, int flags) { 230 dest.writeString(mPackageName); 231 dest.writeInt(mMainStatus); 232 dest.writeStringList(new ArrayList<>(mDomains)); 233 } 234 235 public static final Creator<IntentFilterVerificationInfo> CREATOR = 236 new Creator<IntentFilterVerificationInfo>() { 237 public IntentFilterVerificationInfo createFromParcel(Parcel source) { 238 return new IntentFilterVerificationInfo(source); 239 } 240 public IntentFilterVerificationInfo[] newArray(int size) { 241 return new IntentFilterVerificationInfo[size]; 242 } 243 }; 244 } 245