1 /* 2 * Copyright 2014, 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 com.android.server.pm; 18 19 import com.android.internal.util.XmlUtils; 20 import org.xmlpull.v1.XmlPullParser; 21 import org.xmlpull.v1.XmlPullParserException; 22 import org.xmlpull.v1.XmlSerializer; 23 import android.content.IntentFilter; 24 import android.util.Log; 25 import java.io.IOException; 26 import android.os.UserHandle; 27 28 /** 29 * The {@link PackageManagerService} maintains some {@link CrossProfileIntentFilter}s for each user. 30 * If an {@link Intent} matches the {@link CrossProfileIntentFilter}, then activities in the user 31 * {@link #mTargetUserId} can access it. 32 */ 33 class CrossProfileIntentFilter extends IntentFilter { 34 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 35 private static final String ATTR_FLAGS = "flags"; 36 private static final String ATTR_OWNER_PACKAGE = "ownerPackage"; 37 private static final String ATTR_FILTER = "filter"; 38 39 private static final String TAG = "CrossProfileIntentFilter"; 40 41 // If the intent matches the IntentFilter, then it can be forwarded to this userId. 42 final int mTargetUserId; 43 final String mOwnerPackage; // packageName of the app. 44 final int mFlags; 45 46 CrossProfileIntentFilter(IntentFilter filter, String ownerPackage, int targetUserId, 47 int flags) { 48 super(filter); 49 mTargetUserId = targetUserId; 50 mOwnerPackage = ownerPackage; 51 mFlags = flags; 52 } 53 54 public int getTargetUserId() { 55 return mTargetUserId; 56 } 57 58 public int getFlags() { 59 return mFlags; 60 } 61 62 public String getOwnerPackage() { 63 return mOwnerPackage; 64 } 65 66 CrossProfileIntentFilter(XmlPullParser parser) throws XmlPullParserException, IOException { 67 mTargetUserId = getIntFromXml(parser, ATTR_TARGET_USER_ID, UserHandle.USER_NULL); 68 mOwnerPackage = getStringFromXml(parser, ATTR_OWNER_PACKAGE, ""); 69 mFlags = getIntFromXml(parser, ATTR_FLAGS, 0); 70 71 int outerDepth = parser.getDepth(); 72 String tagName = parser.getName(); 73 int type; 74 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 75 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 76 tagName = parser.getName(); 77 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 78 continue; 79 } else if (type == XmlPullParser.START_TAG) { 80 if (tagName.equals(ATTR_FILTER)) { 81 break; 82 } else { 83 String msg = "Unknown element under " 84 + Settings.TAG_CROSS_PROFILE_INTENT_FILTERS + ": " + tagName + " at " 85 + parser.getPositionDescription(); 86 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 87 XmlUtils.skipCurrentTag(parser); 88 } 89 } 90 } 91 if (tagName.equals(ATTR_FILTER)) { 92 readFromXml(parser); 93 } else { 94 String msg = "Missing element under " + TAG + ": " + ATTR_FILTER + 95 " at " + parser.getPositionDescription(); 96 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 97 XmlUtils.skipCurrentTag(parser); 98 } 99 } 100 101 String getStringFromXml(XmlPullParser parser, String attribute, String defaultValue) { 102 String value = parser.getAttributeValue(null, attribute); 103 if (value == null) { 104 String msg = "Missing element under " + TAG +": " + attribute + " at " + 105 parser.getPositionDescription(); 106 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 107 return defaultValue; 108 } else { 109 return value; 110 } 111 } 112 113 int getIntFromXml(XmlPullParser parser, String attribute, int defaultValue) { 114 String stringValue = getStringFromXml(parser, attribute, null); 115 if (stringValue != null) { 116 return Integer.parseInt(stringValue); 117 } 118 return defaultValue; 119 } 120 121 public void writeToXml(XmlSerializer serializer) throws IOException { 122 serializer.attribute(null, ATTR_TARGET_USER_ID, Integer.toString(mTargetUserId)); 123 serializer.attribute(null, ATTR_FLAGS, Integer.toString(mFlags)); 124 serializer.attribute(null, ATTR_OWNER_PACKAGE, mOwnerPackage); 125 serializer.startTag(null, ATTR_FILTER); 126 super.writeToXml(serializer); 127 serializer.endTag(null, ATTR_FILTER); 128 } 129 130 @Override 131 public String toString() { 132 return "CrossProfileIntentFilter{0x" + Integer.toHexString(System.identityHashCode(this)) 133 + " " + Integer.toString(mTargetUserId) + "}"; 134 } 135 136 boolean equalsIgnoreFilter(CrossProfileIntentFilter other) { 137 return mTargetUserId == other.mTargetUserId 138 && mOwnerPackage.equals(other.mOwnerPackage) 139 && mFlags == other.mFlags; 140 } 141 } 142