Loading core/java/android/app/ApplicationPackageManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -1466,6 +1466,18 @@ final class ApplicationPackageManager extends PackageManager { } } /** * @hide */ public void addCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId) { try { mPM.addCrossProfileIntentsForPackage(packageName, sourceUserId, targetUserId); } catch (RemoteException e) { // Should never happen! } } /** * @hide */ Loading core/java/android/content/pm/IPackageManager.aidl +4 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,9 @@ interface IPackageManager { void addCrossProfileIntentFilter(in IntentFilter intentFilter, int sourceUserId, int targetUserId, int flags); void addCrossProfileIntentsForPackage(in String packageName, int sourceUserId, int targetUserId); void clearCrossProfileIntentFilters(int sourceUserId); /** Loading core/java/android/content/pm/PackageManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -3610,4 +3610,12 @@ public abstract class PackageManager { * @hide */ public abstract void clearCrossProfileIntentFilters(int sourceUserId); /** * Forwards all intents for {@link packageName} for user {@link sourceUserId} to user * {@link targetUserId}. * @hide */ public abstract void addCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId); } services/core/java/com/android/server/pm/PackageManagerService.java +106 −7 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ import com.android.server.ServiceThread; import com.android.server.Watchdog; import com.android.server.pm.Settings.DatabaseVersion; import com.android.server.storage.DeviceStorageMonitorInternal; import com.android.server.storage.DeviceStorageMonitorInternal; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -91,7 +90,6 @@ import android.content.pm.ManifestDigest; import android.content.pm.PackageCleanItem; import android.content.pm.PackageInfo; import android.content.pm.PackageInfoLite; import android.content.pm.PackageInstallerParams; import android.content.pm.PackageManager; import android.content.pm.PackageParser.ActivityIntentInfo; import android.content.pm.PackageParser.PackageParserException; Loading Loading @@ -3363,6 +3361,26 @@ public class PackageManagerService extends IPackageManager.Stub { if (matches.get(i).getTargetUserId() == targetUserId) return true; } } ArrayList<String> packageNames = null; SparseArray<ArrayList<String>> fromSource = mSettings.mCrossProfilePackageInfo.get(sourceUserId); if (fromSource != null) { packageNames = fromSource.get(targetUserId); } if (packageNames.contains(intent.getPackage())) { return true; } // We need the package name, so we try to resolve with the loosest flags possible List<ResolveInfo> resolveInfos = mActivities.queryIntent( intent, resolvedType, PackageManager.GET_UNINSTALLED_PACKAGES, targetUserId); int count = resolveInfos.size(); for (int i = 0; i < count; i++) { ResolveInfo resolveInfo = resolveInfos.get(i); if (packageNames.contains(resolveInfo.activityInfo.packageName)) { return true; } } return false; } Loading Loading @@ -3403,6 +3421,14 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { final String pkgName = intent.getPackage(); if (pkgName == null) { //Check if the intent needs to be forwarded to another user for this package ArrayList<ResolveInfo> crossProfileResult = queryIntentActivitiesCrossProfilePackage( intent, resolvedType, flags, userId); if (!crossProfileResult.isEmpty()) { // Skip the current profile return crossProfileResult; } List<ResolveInfo> result; List<CrossProfileIntentFilter> matchingFilters = getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); Loading @@ -3426,6 +3452,13 @@ public class PackageManagerService extends IPackageManager.Stub { } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { ArrayList<ResolveInfo> crossProfileResult = queryIntentActivitiesCrossProfilePackage( intent, resolvedType, flags, userId, pkg, pkgName); if (!crossProfileResult.isEmpty()) { // Skip the current profile return crossProfileResult; } return mActivities.queryIntentForPackage(intent, resolvedType, flags, pkg.activities, userId); } Loading @@ -3446,7 +3479,8 @@ public class PackageManagerService extends IPackageManager.Stub { ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, flags, sourceUserId); if (resolveInfo != null) { return createForwardingResolveInfo(filter, sourceUserId); return createForwardingResolveInfo( filter, sourceUserId, filter.getTargetUserId()); } } } Loading @@ -3454,6 +3488,56 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( Intent intent, String resolvedType, int flags, int userId) { ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); SparseArray<ArrayList<String>> sourceForwardingInfo = mSettings.mCrossProfilePackageInfo.get(userId); if (sourceForwardingInfo != null) { int NI = sourceForwardingInfo.size(); for (int i = 0; i < NI; i++) { int targetUserId = sourceForwardingInfo.keyAt(i); ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i); List<ResolveInfo> resolveInfos = mActivities.queryIntent( intent, resolvedType, flags, targetUserId); int NJ = resolveInfos.size(); for (int j = 0; j < NJ; j++) { ResolveInfo resolveInfo = resolveInfos.get(j); if (packageNames.contains(resolveInfo.activityInfo.packageName)) { matchingResolveInfos.add(createForwardingResolveInfo( resolveInfo.filter, userId, targetUserId)); } } } } return matchingResolveInfos; } private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( Intent intent, String resolvedType, int flags, int userId, PackageParser.Package pkg, String packageName) { ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); SparseArray<ArrayList<String>> sourceForwardingInfo = mSettings.mCrossProfilePackageInfo.get(userId); if (sourceForwardingInfo != null) { int NI = sourceForwardingInfo.size(); for (int i = 0; i < NI; i++) { int targetUserId = sourceForwardingInfo.keyAt(i); if (sourceForwardingInfo.valueAt(i).contains(packageName)) { List<ResolveInfo> resolveInfos = mActivities.queryIntentForPackage( intent, resolvedType, flags, pkg.activities, targetUserId); int NJ = resolveInfos.size(); for (int j = 0; j < NJ; j++) { ResolveInfo resolveInfo = resolveInfos.get(j); matchingResolveInfos.add(createForwardingResolveInfo( resolveInfo.filter, userId, targetUserId)); } } } } return matchingResolveInfos; } // Return matching ResolveInfo if any for skip current profile intent filters. private ResolveInfo queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, Loading Loading @@ -3486,15 +3570,14 @@ public class PackageManagerService extends IPackageManager.Stub { List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, resolvedType, flags, filter.getTargetUserId()); if (resultTargetUser != null) { return createForwardingResolveInfo(filter, sourceUserId); return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); } return null; } private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, int sourceUserId) { private ResolveInfo createForwardingResolveInfo(IntentFilter filter, int sourceUserId, int targetUserId) { String className; int targetUserId = filter.getTargetUserId(); if (targetUserId == UserHandle.USER_OWNER) { className = FORWARD_INTENT_TO_USER_OWNER; } else { Loading Loading @@ -11604,6 +11687,22 @@ public class PackageManagerService extends IPackageManager.Stub { } } public void addCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); mSettings.addCrossProfilePackage(packageName, sourceUserId, targetUserId); mSettings.writePackageRestrictionsLPr(sourceUserId); } public void removeCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); mSettings.removeCrossProfilePackage(packageName, sourceUserId, targetUserId); mSettings.writePackageRestrictionsLPr(sourceUserId); } @Override public void clearCrossProfileIntentFilters(int sourceUserId) { mContext.enforceCallingOrSelfPermission( Loading services/core/java/com/android/server/pm/Settings.java +144 −0 Original line number Diff line number Diff line Loading @@ -31,12 +31,14 @@ import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.PatternMatcher; import android.util.LogPrinter; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.JournaledFile; import com.android.internal.util.XmlUtils; import com.android.server.pm.PackageManagerService.DumpState; import java.util.Collection; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; Loading Loading @@ -134,6 +136,10 @@ final class Settings { "persistent-preferred-activities"; static final String TAG_CROSS_PROFILE_INTENT_FILTERS = "crossProfile-intent-filters"; private static final String TAG_CROSS_PROFILE_PACKAGE_INFO = "cross-profile-package-info"; private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID = "target-user-id"; private static final String CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME = "package-name"; private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME = "value"; //Old name. Kept for compatibility static final String TAG_FORWARDING_INTENT_FILTERS = "forwarding-intent-filters"; Loading Loading @@ -240,6 +246,11 @@ final class Settings { public final KeySetManager mKeySetManager = new KeySetManager(mPackages); // A mapping of (sourceUserId, targetUserId, packageNames) for forwarding the intents of a // package. final SparseArray<SparseArray<ArrayList<String>>> mCrossProfilePackageInfo = new SparseArray<SparseArray<ArrayList<String>>>(); Settings(Context context) { this(context, Environment.getDataDirectory()); } Loading @@ -262,6 +273,47 @@ final class Settings { mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); } public void addCrossProfilePackage( String packageName, int sourceUserId, int targetUserId) { synchronized(mCrossProfilePackageInfo) { SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(sourceUserId); if (sourceForwardingInfo == null) { sourceForwardingInfo = new SparseArray<ArrayList<String>>(); mCrossProfilePackageInfo.put(sourceUserId, sourceForwardingInfo); } ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId); if (packageNames == null) { packageNames = new ArrayList<String>(); sourceForwardingInfo.put(targetUserId, packageNames); } if (!packageNames.contains(packageName)) { packageNames.add(packageName); } } } public void removeCrossProfilePackage( String packageName, int sourceUserId, int targetUserId) { synchronized(mCrossProfilePackageInfo) { SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(sourceUserId); if (sourceForwardingInfo == null) { return; } ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId); if (packageNames != null && packageNames.contains(packageName)) { packageNames.remove(packageName); if (packageNames.isEmpty()) { sourceForwardingInfo.remove(targetUserId); if (sourceForwardingInfo.size() == 0) { mCrossProfilePackageInfo.remove(sourceUserId); } } } } } PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String nativeLibraryPathString, String cpuAbiString, int pkgFlags, UserHandle user, boolean add) { Loading Loading @@ -1005,6 +1057,68 @@ final class Settings { } } private void readCrossProfilePackageInfoLPw(XmlPullParser parser, int userId) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName.equals(TAG_ITEM)) { String targetUserIdString = parser.getAttributeValue(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID); if (targetUserIdString == null) { String msg = "Missing element under " + TAG +": " + CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID + " at " + parser.getPositionDescription(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); continue; } int targetUserId = Integer.parseInt(targetUserIdString); readCrossProfilePackageInfoForTargetLPw(parser, userId, targetUserId); } else { String msg = "Unknown element under " + TAG_CROSS_PROFILE_PACKAGE_INFO + ": " + parser.getName(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); XmlUtils.skipCurrentTag(parser); } } } private void readCrossProfilePackageInfoForTargetLPw( XmlPullParser parser, int sourceUserId, int targetUserId) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName.equals(CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME)) { String packageName = parser.getAttributeValue( null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME); if (packageName == null) { String msg = "Missing element under " + TAG +": " + CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME + " at " + parser.getPositionDescription(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); continue; } addCrossProfilePackage(packageName, sourceUserId, targetUserId); } else { String msg = "Unknown element under " + TAG_ITEM + ": " + parser.getName(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); XmlUtils.skipCurrentTag(parser); } } } void readPackageRestrictionsLPr(int userId) { if (DEBUG_MU) { Log.i(TAG, "Reading package restrictions for user=" + userId); Loading Loading @@ -1136,6 +1250,8 @@ final class Settings { } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS) || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) { readCrossProfileIntentFiltersLPw(parser, userId); } else if (tagName.equals(TAG_CROSS_PROFILE_PACKAGE_INFO)){ readCrossProfilePackageInfoLPw(parser, userId); } else { Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " + parser.getName()); Loading Loading @@ -1227,6 +1343,32 @@ final class Settings { serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS); } void writeCrossProfilePackageInfoLPr(XmlSerializer serializer, int userId) throws IllegalArgumentException, IllegalStateException, IOException { SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(userId); if (sourceForwardingInfo == null) { return; } serializer.startTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO); int NI = sourceForwardingInfo.size(); for (int i = 0; i < NI; i++) { int targetUserId = sourceForwardingInfo.keyAt(i); ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i); serializer.startTag(null, TAG_ITEM); serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID, Integer.toString(targetUserId)); int NJ = packageNames.size(); for (int j = 0; j < NJ; j++) { serializer.startTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME); serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME, packageNames.get(j)); serializer.endTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME); } serializer.endTag(null, TAG_ITEM); } serializer.endTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO); } void writePackageRestrictionsLPr(int userId) { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); Loading Loading @@ -1327,6 +1469,8 @@ final class Settings { writeCrossProfileIntentFiltersLPr(serializer, userId); writeCrossProfilePackageInfoLPr(serializer, userId); serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endDocument(); Loading Loading
core/java/android/app/ApplicationPackageManager.java +12 −0 Original line number Diff line number Diff line Loading @@ -1466,6 +1466,18 @@ final class ApplicationPackageManager extends PackageManager { } } /** * @hide */ public void addCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId) { try { mPM.addCrossProfileIntentsForPackage(packageName, sourceUserId, targetUserId); } catch (RemoteException e) { // Should never happen! } } /** * @hide */ Loading
core/java/android/content/pm/IPackageManager.aidl +4 −1 Original line number Diff line number Diff line Loading @@ -251,6 +251,9 @@ interface IPackageManager { void addCrossProfileIntentFilter(in IntentFilter intentFilter, int sourceUserId, int targetUserId, int flags); void addCrossProfileIntentsForPackage(in String packageName, int sourceUserId, int targetUserId); void clearCrossProfileIntentFilters(int sourceUserId); /** Loading
core/java/android/content/pm/PackageManager.java +8 −0 Original line number Diff line number Diff line Loading @@ -3610,4 +3610,12 @@ public abstract class PackageManager { * @hide */ public abstract void clearCrossProfileIntentFilters(int sourceUserId); /** * Forwards all intents for {@link packageName} for user {@link sourceUserId} to user * {@link targetUserId}. * @hide */ public abstract void addCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId); }
services/core/java/com/android/server/pm/PackageManagerService.java +106 −7 Original line number Diff line number Diff line Loading @@ -53,7 +53,6 @@ import com.android.server.ServiceThread; import com.android.server.Watchdog; import com.android.server.pm.Settings.DatabaseVersion; import com.android.server.storage.DeviceStorageMonitorInternal; import com.android.server.storage.DeviceStorageMonitorInternal; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -91,7 +90,6 @@ import android.content.pm.ManifestDigest; import android.content.pm.PackageCleanItem; import android.content.pm.PackageInfo; import android.content.pm.PackageInfoLite; import android.content.pm.PackageInstallerParams; import android.content.pm.PackageManager; import android.content.pm.PackageParser.ActivityIntentInfo; import android.content.pm.PackageParser.PackageParserException; Loading Loading @@ -3363,6 +3361,26 @@ public class PackageManagerService extends IPackageManager.Stub { if (matches.get(i).getTargetUserId() == targetUserId) return true; } } ArrayList<String> packageNames = null; SparseArray<ArrayList<String>> fromSource = mSettings.mCrossProfilePackageInfo.get(sourceUserId); if (fromSource != null) { packageNames = fromSource.get(targetUserId); } if (packageNames.contains(intent.getPackage())) { return true; } // We need the package name, so we try to resolve with the loosest flags possible List<ResolveInfo> resolveInfos = mActivities.queryIntent( intent, resolvedType, PackageManager.GET_UNINSTALLED_PACKAGES, targetUserId); int count = resolveInfos.size(); for (int i = 0; i < count; i++) { ResolveInfo resolveInfo = resolveInfos.get(i); if (packageNames.contains(resolveInfo.activityInfo.packageName)) { return true; } } return false; } Loading Loading @@ -3403,6 +3421,14 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { final String pkgName = intent.getPackage(); if (pkgName == null) { //Check if the intent needs to be forwarded to another user for this package ArrayList<ResolveInfo> crossProfileResult = queryIntentActivitiesCrossProfilePackage( intent, resolvedType, flags, userId); if (!crossProfileResult.isEmpty()) { // Skip the current profile return crossProfileResult; } List<ResolveInfo> result; List<CrossProfileIntentFilter> matchingFilters = getMatchingCrossProfileIntentFilters(intent, resolvedType, userId); Loading @@ -3426,6 +3452,13 @@ public class PackageManagerService extends IPackageManager.Stub { } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { ArrayList<ResolveInfo> crossProfileResult = queryIntentActivitiesCrossProfilePackage( intent, resolvedType, flags, userId, pkg, pkgName); if (!crossProfileResult.isEmpty()) { // Skip the current profile return crossProfileResult; } return mActivities.queryIntentForPackage(intent, resolvedType, flags, pkg.activities, userId); } Loading @@ -3446,7 +3479,8 @@ public class PackageManagerService extends IPackageManager.Stub { ResolveInfo resolveInfo = checkTargetCanHandle(filter, intent, resolvedType, flags, sourceUserId); if (resolveInfo != null) { return createForwardingResolveInfo(filter, sourceUserId); return createForwardingResolveInfo( filter, sourceUserId, filter.getTargetUserId()); } } } Loading @@ -3454,6 +3488,56 @@ public class PackageManagerService extends IPackageManager.Stub { return null; } private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( Intent intent, String resolvedType, int flags, int userId) { ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); SparseArray<ArrayList<String>> sourceForwardingInfo = mSettings.mCrossProfilePackageInfo.get(userId); if (sourceForwardingInfo != null) { int NI = sourceForwardingInfo.size(); for (int i = 0; i < NI; i++) { int targetUserId = sourceForwardingInfo.keyAt(i); ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i); List<ResolveInfo> resolveInfos = mActivities.queryIntent( intent, resolvedType, flags, targetUserId); int NJ = resolveInfos.size(); for (int j = 0; j < NJ; j++) { ResolveInfo resolveInfo = resolveInfos.get(j); if (packageNames.contains(resolveInfo.activityInfo.packageName)) { matchingResolveInfos.add(createForwardingResolveInfo( resolveInfo.filter, userId, targetUserId)); } } } } return matchingResolveInfos; } private ArrayList<ResolveInfo> queryIntentActivitiesCrossProfilePackage( Intent intent, String resolvedType, int flags, int userId, PackageParser.Package pkg, String packageName) { ArrayList<ResolveInfo> matchingResolveInfos = new ArrayList<ResolveInfo>(); SparseArray<ArrayList<String>> sourceForwardingInfo = mSettings.mCrossProfilePackageInfo.get(userId); if (sourceForwardingInfo != null) { int NI = sourceForwardingInfo.size(); for (int i = 0; i < NI; i++) { int targetUserId = sourceForwardingInfo.keyAt(i); if (sourceForwardingInfo.valueAt(i).contains(packageName)) { List<ResolveInfo> resolveInfos = mActivities.queryIntentForPackage( intent, resolvedType, flags, pkg.activities, targetUserId); int NJ = resolveInfos.size(); for (int j = 0; j < NJ; j++) { ResolveInfo resolveInfo = resolveInfos.get(j); matchingResolveInfos.add(createForwardingResolveInfo( resolveInfo.filter, userId, targetUserId)); } } } } return matchingResolveInfos; } // Return matching ResolveInfo if any for skip current profile intent filters. private ResolveInfo queryCrossProfileIntents( List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType, Loading Loading @@ -3486,15 +3570,14 @@ public class PackageManagerService extends IPackageManager.Stub { List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent, resolvedType, flags, filter.getTargetUserId()); if (resultTargetUser != null) { return createForwardingResolveInfo(filter, sourceUserId); return createForwardingResolveInfo(filter, sourceUserId, filter.getTargetUserId()); } return null; } private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, int sourceUserId) { private ResolveInfo createForwardingResolveInfo(IntentFilter filter, int sourceUserId, int targetUserId) { String className; int targetUserId = filter.getTargetUserId(); if (targetUserId == UserHandle.USER_OWNER) { className = FORWARD_INTENT_TO_USER_OWNER; } else { Loading Loading @@ -11604,6 +11687,22 @@ public class PackageManagerService extends IPackageManager.Stub { } } public void addCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); mSettings.addCrossProfilePackage(packageName, sourceUserId, targetUserId); mSettings.writePackageRestrictionsLPr(sourceUserId); } public void removeCrossProfileIntentsForPackage(String packageName, int sourceUserId, int targetUserId) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null); mSettings.removeCrossProfilePackage(packageName, sourceUserId, targetUserId); mSettings.writePackageRestrictionsLPr(sourceUserId); } @Override public void clearCrossProfileIntentFilters(int sourceUserId) { mContext.enforceCallingOrSelfPermission( Loading
services/core/java/com/android/server/pm/Settings.java +144 −0 Original line number Diff line number Diff line Loading @@ -31,12 +31,14 @@ import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.PatternMatcher; import android.util.LogPrinter; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.JournaledFile; import com.android.internal.util.XmlUtils; import com.android.server.pm.PackageManagerService.DumpState; import java.util.Collection; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; Loading Loading @@ -134,6 +136,10 @@ final class Settings { "persistent-preferred-activities"; static final String TAG_CROSS_PROFILE_INTENT_FILTERS = "crossProfile-intent-filters"; private static final String TAG_CROSS_PROFILE_PACKAGE_INFO = "cross-profile-package-info"; private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID = "target-user-id"; private static final String CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME = "package-name"; private static final String CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME = "value"; //Old name. Kept for compatibility static final String TAG_FORWARDING_INTENT_FILTERS = "forwarding-intent-filters"; Loading Loading @@ -240,6 +246,11 @@ final class Settings { public final KeySetManager mKeySetManager = new KeySetManager(mPackages); // A mapping of (sourceUserId, targetUserId, packageNames) for forwarding the intents of a // package. final SparseArray<SparseArray<ArrayList<String>>> mCrossProfilePackageInfo = new SparseArray<SparseArray<ArrayList<String>>>(); Settings(Context context) { this(context, Environment.getDataDirectory()); } Loading @@ -262,6 +273,47 @@ final class Settings { mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml"); } public void addCrossProfilePackage( String packageName, int sourceUserId, int targetUserId) { synchronized(mCrossProfilePackageInfo) { SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(sourceUserId); if (sourceForwardingInfo == null) { sourceForwardingInfo = new SparseArray<ArrayList<String>>(); mCrossProfilePackageInfo.put(sourceUserId, sourceForwardingInfo); } ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId); if (packageNames == null) { packageNames = new ArrayList<String>(); sourceForwardingInfo.put(targetUserId, packageNames); } if (!packageNames.contains(packageName)) { packageNames.add(packageName); } } } public void removeCrossProfilePackage( String packageName, int sourceUserId, int targetUserId) { synchronized(mCrossProfilePackageInfo) { SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(sourceUserId); if (sourceForwardingInfo == null) { return; } ArrayList<String> packageNames = sourceForwardingInfo.get(targetUserId); if (packageNames != null && packageNames.contains(packageName)) { packageNames.remove(packageName); if (packageNames.isEmpty()) { sourceForwardingInfo.remove(targetUserId); if (sourceForwardingInfo.size() == 0) { mCrossProfilePackageInfo.remove(sourceUserId); } } } } } PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage, String realName, SharedUserSetting sharedUser, File codePath, File resourcePath, String nativeLibraryPathString, String cpuAbiString, int pkgFlags, UserHandle user, boolean add) { Loading Loading @@ -1005,6 +1057,68 @@ final class Settings { } } private void readCrossProfilePackageInfoLPw(XmlPullParser parser, int userId) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName.equals(TAG_ITEM)) { String targetUserIdString = parser.getAttributeValue(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID); if (targetUserIdString == null) { String msg = "Missing element under " + TAG +": " + CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID + " at " + parser.getPositionDescription(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); continue; } int targetUserId = Integer.parseInt(targetUserIdString); readCrossProfilePackageInfoForTargetLPw(parser, userId, targetUserId); } else { String msg = "Unknown element under " + TAG_CROSS_PROFILE_PACKAGE_INFO + ": " + parser.getName(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); XmlUtils.skipCurrentTag(parser); } } } private void readCrossProfilePackageInfoForTargetLPw( XmlPullParser parser, int sourceUserId, int targetUserId) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName.equals(CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME)) { String packageName = parser.getAttributeValue( null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME); if (packageName == null) { String msg = "Missing element under " + TAG +": " + CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME + " at " + parser.getPositionDescription(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); continue; } addCrossProfilePackage(packageName, sourceUserId, targetUserId); } else { String msg = "Unknown element under " + TAG_ITEM + ": " + parser.getName(); PackageManagerService.reportSettingsProblem(Log.WARN, msg); XmlUtils.skipCurrentTag(parser); } } } void readPackageRestrictionsLPr(int userId) { if (DEBUG_MU) { Log.i(TAG, "Reading package restrictions for user=" + userId); Loading Loading @@ -1136,6 +1250,8 @@ final class Settings { } else if (tagName.equals(TAG_FORWARDING_INTENT_FILTERS) || tagName.equals(TAG_CROSS_PROFILE_INTENT_FILTERS)) { readCrossProfileIntentFiltersLPw(parser, userId); } else if (tagName.equals(TAG_CROSS_PROFILE_PACKAGE_INFO)){ readCrossProfilePackageInfoLPw(parser, userId); } else { Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " + parser.getName()); Loading Loading @@ -1227,6 +1343,32 @@ final class Settings { serializer.endTag(null, TAG_CROSS_PROFILE_INTENT_FILTERS); } void writeCrossProfilePackageInfoLPr(XmlSerializer serializer, int userId) throws IllegalArgumentException, IllegalStateException, IOException { SparseArray<ArrayList<String>> sourceForwardingInfo = mCrossProfilePackageInfo.get(userId); if (sourceForwardingInfo == null) { return; } serializer.startTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO); int NI = sourceForwardingInfo.size(); for (int i = 0; i < NI; i++) { int targetUserId = sourceForwardingInfo.keyAt(i); ArrayList<String> packageNames = sourceForwardingInfo.valueAt(i); serializer.startTag(null, TAG_ITEM); serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_TARGET_USER_ID, Integer.toString(targetUserId)); int NJ = packageNames.size(); for (int j = 0; j < NJ; j++) { serializer.startTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME); serializer.attribute(null, CROSS_PROFILE_PACKAGE_INFO_ATTR_PACKAGE_NAME, packageNames.get(j)); serializer.endTag(null, CROSS_PROFILE_PACKAGE_INFO_TAG_PACKAGE_NAME); } serializer.endTag(null, TAG_ITEM); } serializer.endTag(null, TAG_CROSS_PROFILE_PACKAGE_INFO); } void writePackageRestrictionsLPr(int userId) { if (DEBUG_MU) { Log.i(TAG, "Writing package restrictions for user=" + userId); Loading Loading @@ -1327,6 +1469,8 @@ final class Settings { writeCrossProfileIntentFiltersLPr(serializer, userId); writeCrossProfilePackageInfoLPr(serializer, userId); serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endDocument(); Loading