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_USER_ID = "ownerUserId"; 37 private static final String ATTR_OWNER_PACKAGE = "ownerPackage"; 38 private static final String ATTR_FILTER = "filter"; 39 40 private static final String TAG = "CrossProfileIntentFilter"; 41 42 // If the intent matches the IntentFilter, then it can be forwarded to this userId. 43 final int mTargetUserId; 44 final int mOwnerUserId; // userId of the app which has set this CrossProfileIntentFilter. 45 final String mOwnerPackage; // packageName of the app. 46 final int mFlags; 47 CrossProfileIntentFilter(IntentFilter filter, String ownerPackage, int ownerUserId, int targetUserId, int flags)48 CrossProfileIntentFilter(IntentFilter filter, String ownerPackage, int ownerUserId, 49 int targetUserId, int flags) { 50 super(filter); 51 mTargetUserId = targetUserId; 52 mOwnerUserId = ownerUserId; 53 mOwnerPackage = ownerPackage; 54 mFlags = flags; 55 } 56 getTargetUserId()57 public int getTargetUserId() { 58 return mTargetUserId; 59 } 60 getFlags()61 public int getFlags() { 62 return mFlags; 63 } 64 getOwnerUserId()65 public int getOwnerUserId() { 66 return mOwnerUserId; 67 } 68 getOwnerPackage()69 public String getOwnerPackage() { 70 return mOwnerPackage; 71 } 72 CrossProfileIntentFilter(XmlPullParser parser)73 CrossProfileIntentFilter(XmlPullParser parser) throws XmlPullParserException, IOException { 74 mTargetUserId = getIntFromXml(parser, ATTR_TARGET_USER_ID, UserHandle.USER_NULL); 75 mOwnerUserId = getIntFromXml(parser, ATTR_OWNER_USER_ID, UserHandle.USER_NULL); 76 mOwnerPackage = getStringFromXml(parser, ATTR_OWNER_PACKAGE, ""); 77 mFlags = getIntFromXml(parser, ATTR_FLAGS, 0); 78 79 int outerDepth = parser.getDepth(); 80 String tagName = parser.getName(); 81 int type; 82 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 83 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 84 tagName = parser.getName(); 85 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 86 continue; 87 } else if (type == XmlPullParser.START_TAG) { 88 if (tagName.equals(ATTR_FILTER)) { 89 break; 90 } else { 91 String msg = "Unknown element under " 92 + Settings.TAG_CROSS_PROFILE_INTENT_FILTERS + ": " + tagName + " at " 93 + parser.getPositionDescription(); 94 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 95 XmlUtils.skipCurrentTag(parser); 96 } 97 } 98 } 99 if (tagName.equals(ATTR_FILTER)) { 100 readFromXml(parser); 101 } else { 102 String msg = "Missing element under " + TAG + ": " + ATTR_FILTER + 103 " at " + parser.getPositionDescription(); 104 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 105 XmlUtils.skipCurrentTag(parser); 106 } 107 } 108 getStringFromXml(XmlPullParser parser, String attribute, String defaultValue)109 String getStringFromXml(XmlPullParser parser, String attribute, String defaultValue) { 110 String value = parser.getAttributeValue(null, attribute); 111 if (value == null) { 112 String msg = "Missing element under " + TAG +": " + attribute + " at " + 113 parser.getPositionDescription(); 114 PackageManagerService.reportSettingsProblem(Log.WARN, msg); 115 return defaultValue; 116 } else { 117 return value; 118 } 119 } 120 getIntFromXml(XmlPullParser parser, String attribute, int defaultValue)121 int getIntFromXml(XmlPullParser parser, String attribute, int defaultValue) { 122 String stringValue = getStringFromXml(parser, attribute, null); 123 if (stringValue != null) { 124 return Integer.parseInt(stringValue); 125 } 126 return defaultValue; 127 } 128 writeToXml(XmlSerializer serializer)129 public void writeToXml(XmlSerializer serializer) throws IOException { 130 serializer.attribute(null, ATTR_TARGET_USER_ID, Integer.toString(mTargetUserId)); 131 serializer.attribute(null, ATTR_FLAGS, Integer.toString(mFlags)); 132 serializer.attribute(null, ATTR_OWNER_USER_ID, Integer.toString(mOwnerUserId)); 133 serializer.attribute(null, ATTR_OWNER_PACKAGE, mOwnerPackage); 134 serializer.startTag(null, ATTR_FILTER); 135 super.writeToXml(serializer); 136 serializer.endTag(null, ATTR_FILTER); 137 } 138 139 @Override toString()140 public String toString() { 141 return "CrossProfileIntentFilter{0x" + Integer.toHexString(System.identityHashCode(this)) 142 + " " + Integer.toString(mTargetUserId) + "}"; 143 } 144 equalsIgnoreFilter(CrossProfileIntentFilter other)145 boolean equalsIgnoreFilter(CrossProfileIntentFilter other) { 146 return mTargetUserId == other.mTargetUserId 147 && mOwnerUserId == other.mOwnerUserId 148 && mOwnerPackage.equals(other.mOwnerPackage) 149 && mFlags == other.mFlags; 150 } 151 } 152