1 /* 2 * Copyright (C) 2020 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.security; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.net.Uri; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 25 import org.xmlpull.v1.XmlPullParser; 26 import org.xmlpull.v1.XmlPullParserException; 27 import org.xmlpull.v1.XmlSerializer; 28 29 import java.io.IOException; 30 import java.util.Collections; 31 import java.util.HashMap; 32 import java.util.Map; 33 import java.util.Objects; 34 35 /** 36 * The mapping from URI to alias, which determines the alias to use when the user visits a URI. 37 * This mapping is part of the {@link AppUriAuthenticationPolicy}, which specifies which app this 38 * mapping should be used for. 39 * 40 * @hide 41 * @see AppUriAuthenticationPolicy 42 */ 43 public final class UrisToAliases implements Parcelable { 44 45 private static final String KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS = 46 "authentication_policy_uri_to_alias"; 47 private static final String KEY_AUTHENTICATION_POLICY_URI = "policy_uri"; 48 private static final String KEY_AUTHENTICATION_POLICY_ALIAS = "policy_alias"; 49 50 /** 51 * The mappings from URIs to aliases, which will be used for authentication. 52 */ 53 @NonNull 54 private final Map<Uri, String> mUrisToAliases; 55 UrisToAliases()56 public UrisToAliases() { 57 this.mUrisToAliases = new HashMap<>(); 58 } 59 UrisToAliases(@onNull Map<Uri, String> urisToAliases)60 private UrisToAliases(@NonNull Map<Uri, String> urisToAliases) { 61 this.mUrisToAliases = urisToAliases; 62 } 63 64 @NonNull 65 public static final Creator<UrisToAliases> CREATOR = new Creator<UrisToAliases>() { 66 @Override 67 public UrisToAliases createFromParcel(Parcel in) { 68 Map<Uri, String> urisToAliases = new HashMap<>(); 69 in.readMap(urisToAliases, String.class.getClassLoader()); 70 return new UrisToAliases(urisToAliases); 71 } 72 73 @Override 74 public UrisToAliases[] newArray(int size) { 75 return new UrisToAliases[size]; 76 } 77 }; 78 79 /** 80 * Returns the mapping from URIs to aliases. 81 */ 82 @NonNull getUrisToAliases()83 public Map<Uri, String> getUrisToAliases() { 84 return Collections.unmodifiableMap(mUrisToAliases); 85 } 86 87 /** 88 * Adds mapping from an URI to an alias. 89 */ addUriToAlias(@onNull Uri uri, @NonNull String alias)90 public void addUriToAlias(@NonNull Uri uri, @NonNull String alias) { 91 mUrisToAliases.put(uri, alias); 92 } 93 94 /** 95 * Restore a previously saved {@link UrisToAliases} from XML. 96 */ 97 @Nullable readFromXml(@onNull XmlPullParser parser)98 public static UrisToAliases readFromXml(@NonNull XmlPullParser parser) 99 throws IOException, XmlPullParserException { 100 Map<Uri, String> urisToAliases = new HashMap<>(); 101 int outerDepth = parser.getDepth(); 102 int type; 103 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 104 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 105 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 106 continue; 107 } 108 if (!parser.getName().equals(KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS)) { 109 continue; 110 } 111 Uri uri = Uri.parse(parser.getAttributeValue(null, KEY_AUTHENTICATION_POLICY_URI)); 112 String alias = parser.getAttributeValue(null, KEY_AUTHENTICATION_POLICY_ALIAS); 113 urisToAliases.put(uri, alias); 114 } 115 return new UrisToAliases(urisToAliases); 116 } 117 118 /** 119 * Save the {@link UrisToAliases} to XML. 120 */ writeToXml(@onNull XmlSerializer out)121 public void writeToXml(@NonNull XmlSerializer out) throws IOException { 122 for (Map.Entry<Uri, String> urisToAliases : mUrisToAliases.entrySet()) { 123 out.startTag(null, KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS); 124 out.attribute(null, KEY_AUTHENTICATION_POLICY_URI, urisToAliases.getKey().toString()); 125 out.attribute(null, KEY_AUTHENTICATION_POLICY_ALIAS, urisToAliases.getValue()); 126 out.endTag(null, KEY_AUTHENTICATION_POLICY_URI_TO_ALIAS); 127 } 128 } 129 130 @Override describeContents()131 public int describeContents() { 132 return 0; 133 } 134 135 @Override writeToParcel(@onNull Parcel dest, int flags)136 public void writeToParcel(@NonNull Parcel dest, int flags) { 137 dest.writeMap(mUrisToAliases); 138 } 139 140 @Override equals(Object obj)141 public boolean equals(Object obj) { 142 if (this == obj) { 143 return true; 144 } 145 if (!(obj instanceof UrisToAliases)) { 146 return false; 147 } 148 UrisToAliases other = (UrisToAliases) obj; 149 return Objects.equals(mUrisToAliases, other.mUrisToAliases); 150 } 151 152 @Override hashCode()153 public int hashCode() { 154 return mUrisToAliases.hashCode(); 155 } 156 } 157