diff options
author | Raj Yengisetty <rajesh@cyngn.com> | 2014-11-14 09:44:50 -0800 |
---|---|---|
committer | Steve Kondik <steve@cyngn.com> | 2015-10-23 14:33:01 -0500 |
commit | 86c3e388dc1a483111af610d237204f4b575993d (patch) | |
tree | 32c24bac226944ed4d34dea98d4a3e410ecff684 | |
parent | d8826da4a586c643715594a31b6eecd6a5667b5a (diff) | |
download | frameworks_base-86c3e388dc1a483111af610d237204f4b575993d.zip frameworks_base-86c3e388dc1a483111af610d237204f4b575993d.tar.gz frameworks_base-86c3e388dc1a483111af610d237204f4b575993d.tar.bz2 |
Protected apps
Fix up protected apps filter.
Move filtering to correct place (when querying providers,
ResolveInfo.activityInfo is null), and port over commit
4dad4a4e84ec385a80ebfae91c4dcd03ec30c9d0 from cm-11.0.
Protected Apps: do not filter components from the same UID
pm: Use ArraySet instead of HashSet
packagemanager: Use ArrayMap/ArraySet as per AOSP
* To reduce memory consumption
Change-Id: Ic690387cd21fdfa09ef5fb19bd3de9305050cf6e
-rw-r--r-- | core/java/android/app/ApplicationPackageManager.java | 9 | ||||
-rw-r--r-- | core/java/android/content/pm/ApplicationInfo.java | 10 | ||||
-rw-r--r-- | core/java/android/content/pm/IPackageManager.aidl | 4 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageManager.java | 20 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageParser.java | 9 | ||||
-rw-r--r-- | core/java/android/content/pm/PackageUserState.java | 6 | ||||
-rw-r--r-- | core/java/android/provider/Settings.java | 5 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 83 | ||||
-rw-r--r-- | services/core/java/com/android/server/pm/PackageSettingBase.java | 38 | ||||
-rwxr-xr-x[-rw-r--r--] | services/core/java/com/android/server/pm/Settings.java | 49 | ||||
-rw-r--r-- | test-runner/src/android/test/mock/MockPackageManager.java | 7 |
11 files changed, 232 insertions, 8 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 0adce5d..18619d3 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1992,6 +1992,15 @@ final class ApplicationPackageManager extends PackageManager { } @Override + public void setComponentProtectedSetting(ComponentName componentName, boolean newState) { + try { + mPM.setComponentProtectedSetting(componentName, newState, mContext.getUserId()); + } catch (RemoteException re) { + Log.e(TAG, "Failed to set component protected setting", re); + } + } + + @Override public PackageInstaller getPackageInstaller() { synchronized (mLock) { if (mInstaller == null) { diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 41f5233..d3d4443 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -661,6 +661,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { */ public int installLocation = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; + /** + * When true, indicates that any one component within this application is + * protected. + * @hide + */ + public boolean protect = false; + public void dump(Printer pw, String prefix) { super.dumpFront(pw, prefix); if (className != null) { @@ -793,6 +800,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { uiOptions = orig.uiOptions; backupAgentName = orig.backupAgentName; fullBackupContent = orig.fullBackupContent; + protect = orig.protect; } @@ -847,6 +855,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeInt(descriptionRes); dest.writeInt(uiOptions); dest.writeInt(fullBackupContent); + dest.writeInt(protect ? 1 : 0); } public static final Parcelable.Creator<ApplicationInfo> CREATOR @@ -900,6 +909,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { descriptionRes = source.readInt(); uiOptions = source.readInt(); fullBackupContent = source.readInt(); + protect = source.readInt() != 0; } /** diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index a5e9faf..a0bd10c 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -507,4 +507,8 @@ interface IPackageManager { boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId); String getPermissionControllerPackageName(); + + /** Protected Apps */ + void setComponentProtectedSetting(in ComponentName componentName, + in boolean newState, int userId); } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index c8e9402..53587fd 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1912,6 +1912,20 @@ public abstract class PackageManager { = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS"; /** + * Flag for {@link #setComponentProtectedSetting(android.content.ComponentName, boolean)}: + * This component or application has set to protected status + * @hide + */ + public static final boolean COMPONENT_PROTECTED_STATUS = false; + + /** + * Flag for {@link #setComponentProtectedSetting(android.content.ComponentName, boolean)}: + * This component or application has been explicitly set to visible status + * @hide + */ + public static final boolean COMPONENT_VISIBLE_STATUS = true; + + /** * String extra for {@link PackageInstallObserver} in the 'extras' Bundle in case of * {@link #INSTALL_FAILED_DUPLICATE_PERMISSION}. This extra names the package which provides * the existing definition for the permission. @@ -4484,6 +4498,12 @@ public abstract class PackageManager { public abstract @NonNull PackageInstaller getPackageInstaller(); /** + * Update Component protection state + * @hide + */ + public abstract void setComponentProtectedSetting(ComponentName componentName, boolean newState); + + /** * Adds a {@link CrossProfileIntentFilter}. After calling this method all intents sent from the * user with id sourceUserId can also be be resolved by activities in the user with id * targetUserId if they match the specified intent filter. diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 4f965f9..0edf9c1 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -4731,6 +4731,12 @@ public class PackageParser { && p.usesLibraryFiles != null) { return true; } + if (state.protectedComponents != null) { + boolean protect = state.protectedComponents.size() > 0; + if (p.applicationInfo.protect != protect) { + return true; + } + } return false; } @@ -4764,6 +4770,9 @@ public class PackageParser { ai.enabled = false; } ai.enabledSetting = state.enabled; + if (state.protectedComponents != null) { + ai.protect = state.protectedComponents.size() > 0; + } } public static ApplicationInfo generateApplicationInfo(Package p, int flags, diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index 9b28401..7b6d188 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -36,6 +36,8 @@ public class PackageUserState { public ArraySet<String> disabledComponents; public ArraySet<String> enabledComponents; + public ArraySet<String> protectedComponents; + public ArraySet<String> visibleComponents; public int domainVerificationStatus; public int appLinkGeneration; @@ -62,5 +64,9 @@ public class PackageUserState { blockUninstall = o.blockUninstall; domainVerificationStatus = o.domainVerificationStatus; appLinkGeneration = o.appLinkGeneration; + protectedComponents = o.protectedComponents != null + ? new ArraySet<String>(o.protectedComponents) : null; + visibleComponents = o.visibleComponents != null + ? new ArraySet<String>(o.visibleComponents) : null; } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 483c263..ec7f6d2 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -6092,6 +6092,11 @@ public final class Settings { */ public static final String SLEEP_TIMEOUT = "sleep_timeout"; + /** Protected Components + * @hide + */ + public static final String PROTECTED_COMPONENTS = "protected_components"; + /** * Controls whether double tap to wake is enabled. * @hide diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index c941721..a8ca40e 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -8736,8 +8736,23 @@ public class PackageManagerService extends IPackageManager.Stub { int userId) { if (!sUserManager.exists(userId)) return null; mFlags = flags; - return super.queryIntent(intent, resolvedType, + List<ResolveInfo> list = super.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId); + // Remove protected Application components + int callingUid = Binder.getCallingUid(); + List<String> packages = Arrays.asList(getPackagesForUid(callingUid)); + if (callingUid != Process.SYSTEM_UID && + (getFlagsForUid(callingUid) & ApplicationInfo.FLAG_SYSTEM) == 0) { + Iterator<ResolveInfo> itr = list.iterator(); + while (itr.hasNext()) { + ActivityInfo activityInfo = itr.next().activityInfo; + if (activityInfo.applicationInfo.protect && (packages == null + || !packages.contains(activityInfo.packageName))) { + itr.remove(); + } + } + } + return list; } public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, @@ -13150,7 +13165,8 @@ public class PackageManagerService extends IPackageManager.Stub { false, //hidden null, null, null, false, // blockUninstall - ps.readUserState(userId).domainVerificationStatus, 0); + ps.readUserState(userId).domainVerificationStatus, 0, + null, null); if (!isSystemApp(ps)) { if (ps.isAnyInstalled(sUserManager.getUserIds())) { // Other user still have this package installed, so all @@ -16310,6 +16326,69 @@ public class PackageManagerService extends IPackageManager.Stub { } @Override + public void setComponentProtectedSetting(ComponentName componentName, boolean newState, + int userId) { + enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "set protected"); + + String packageName = componentName.getPackageName(); + String className = componentName.getClassName(); + + PackageSetting pkgSetting; + ArrayList<String> components; + + synchronized (mPackages) { + pkgSetting = mSettings.mPackages.get(packageName); + + if (pkgSetting == null) { + if (className == null) { + throw new IllegalArgumentException( + "Unknown package: " + packageName); + } + throw new IllegalArgumentException( + "Unknown component: " + packageName + + "/" + className); + } + + //Protection levels must be applied at the Component Level! + if (className == null) { + throw new IllegalArgumentException( + "Must specify Component Class name." + ); + } else { + PackageParser.Package pkg = pkgSetting.pkg; + if (pkg == null || !pkg.hasComponentClassName(className)) { + if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.JELLY_BEAN) { + throw new IllegalArgumentException("Component class " + className + + " does not exist in " + packageName); + } else { + Slog.w(TAG, "Failed setComponentProtectedSetting: component class " + + className + " does not exist in " + packageName); + } + } + + pkgSetting.protectComponentLPw(className, newState, userId); + mSettings.writePackageRestrictionsLPr(userId); + + components = mPendingBroadcasts.get(userId, packageName); + final boolean newPackage = components == null; + if (newPackage) { + components = new ArrayList<String>(); + } + if (!components.contains(className)) { + components.add(className); + } + } + } + + long callingId = Binder.clearCallingIdentity(); + try { + int packageUid = UserHandle.getUid(userId, pkgSetting.appId); + } finally { + Binder.restoreCallingIdentity(callingId); + } + } + + @Override public boolean isStorageLow() { final long token = Binder.clearCallingIdentity(); try { diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index bbdfe31..e02e4da 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -19,6 +19,7 @@ package com.android.server.pm; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; +import static android.content.pm.PackageManager.COMPONENT_VISIBLE_STATUS; import android.content.pm.IntentFilterVerificationInfo; import android.content.pm.PackageManager; @@ -343,7 +344,8 @@ abstract class PackageSettingBase extends SettingBase { boolean notLaunched, boolean hidden, String lastDisableAppCaller, ArraySet<String> enabledComponents, ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState, - int linkGeneration) { + int linkGeneration, + ArraySet<String> protectedComponents, ArraySet<String> visibleComponents) { PackageUserState state = modifyUserState(userId); state.enabled = enabled; state.installed = installed; @@ -356,6 +358,8 @@ abstract class PackageSettingBase extends SettingBase { state.blockUninstall = blockUninstall; state.domainVerificationStatus = domainVerifState; state.appLinkGeneration = linkGeneration; + state.protectedComponents = protectedComponents; + state.visibleComponents = visibleComponents; } ArraySet<String> getEnabledComponents(int userId) { @@ -395,6 +399,17 @@ abstract class PackageSettingBase extends SettingBase { return state; } + PackageUserState modifyUserStateComponents(int userId) { + PackageUserState state = modifyUserState(userId); + if (state.protectedComponents == null) { + state.protectedComponents = new ArraySet<String>(1); + } + if (state.visibleComponents == null) { + state.visibleComponents = new ArraySet<String>(1); + } + return state; + } + void addDisabledComponent(String componentClassName, int userId) { modifyUserStateComponents(userId, true, false).disabledComponents.add(componentClassName); } @@ -440,6 +455,27 @@ abstract class PackageSettingBase extends SettingBase { } } + boolean protectComponentLPw(String componentClassName, boolean protect, int userId) { + PackageUserState state = modifyUserStateComponents(userId); + boolean changed = false; + if (protect == COMPONENT_VISIBLE_STATUS) { + changed = state.protectedComponents != null + ? state.protectedComponents.remove(componentClassName) : false; + changed |= state.visibleComponents.add(componentClassName); + } else { + changed = state.visibleComponents != null + ? state.visibleComponents.remove(componentClassName) : false; + changed |= state.protectedComponents.add(componentClassName); + } + + return changed; + } + + ArraySet<String> getProtectedComponents(int userId) { + PackageUserState state = modifyUserStateComponents(userId); + return state.protectedComponents; + } + void removeUser(int userId) { userState.delete(userId); } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 46f9f16..844d5cd 100644..100755 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -182,6 +182,9 @@ final class Settings { private static final String TAG_DEFAULT_BROWSER = "default-browser"; private static final String TAG_VERSION = "version"; + private static final String TAG_PROTECTED_COMPONENTS = "protected-components"; + private static final String TAG_VISIBLE_COMPONENTS = "visible-components"; + private static final String ATTR_NAME = "name"; private static final String ATTR_USER = "user"; private static final String ATTR_CODE = "code"; @@ -652,7 +655,10 @@ final class Settings { false, // hidden null, null, null, false, // blockUninstall - INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0); + INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0, + null, + null + ); writePackageRestrictionsLPr(user.id); } } @@ -1414,7 +1420,10 @@ final class Settings { false, // hidden null, null, null, false, // blockUninstall - INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0); + INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0, + null, + null + ); } return; } @@ -1499,6 +1508,8 @@ final class Settings { ArraySet<String> enabledComponents = null; ArraySet<String> disabledComponents = null; + ArraySet<String> protectedComponents = null; + ArraySet<String> visibleComponents = null; int packageDepth = parser.getDepth(); while ((type=parser.next()) != XmlPullParser.END_DOCUMENT @@ -1513,12 +1524,17 @@ final class Settings { enabledComponents = readComponentsLPr(parser); } else if (tagName.equals(TAG_DISABLED_COMPONENTS)) { disabledComponents = readComponentsLPr(parser); + } else if (tagName.equals(TAG_PROTECTED_COMPONENTS)) { + protectedComponents = readComponentsLPr(parser); + } else if (tagName.equals(TAG_VISIBLE_COMPONENTS)) { + visibleComponents = readComponentsLPr(parser); } } ps.setUserState(userId, enabled, installed, stopped, notLaunched, hidden, enabledCaller, enabledComponents, disabledComponents, blockUninstall, - verifState, linkGeneration); + verifState, linkGeneration, + protectedComponents, visibleComponents); } else if (tagName.equals("preferred-activities")) { readPreferredActivitiesLPw(parser, userId); } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) { @@ -1758,7 +1774,11 @@ final class Settings { && ustate.disabledComponents.size() > 0) || ustate.blockUninstall || (ustate.domainVerificationStatus != - PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED)) { + PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) + || (ustate.protectedComponents != null + && ustate.protectedComponents.size() > 0) + || (ustate.visibleComponents != null + && ustate.visibleComponents.size() > 0)) { serializer.startTag(null, TAG_PACKAGE); serializer.attribute(null, ATTR_NAME, pkg.name); if (DEBUG_MU) Log.i(TAG, " pkg=" + pkg.name + ", state=" + ustate.enabled); @@ -1815,7 +1835,26 @@ final class Settings { } serializer.endTag(null, TAG_DISABLED_COMPONENTS); } - + if (ustate.protectedComponents != null + && ustate.protectedComponents.size() > 0) { + serializer.startTag(null, TAG_PROTECTED_COMPONENTS); + for (final String name : ustate.protectedComponents) { + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, name); + serializer.endTag(null, TAG_ITEM); + } + serializer.endTag(null, TAG_PROTECTED_COMPONENTS); + } + if (ustate.visibleComponents != null + && ustate.visibleComponents.size() > 0) { + serializer.startTag(null, TAG_VISIBLE_COMPONENTS); + for (final String name : ustate.visibleComponents) { + serializer.startTag(null, TAG_ITEM); + serializer.attribute(null, ATTR_NAME, name); + serializer.endTag(null, TAG_ITEM); + } + serializer.endTag(null, TAG_VISIBLE_COMPONENTS); + } serializer.endTag(null, TAG_PACKAGE); } } diff --git a/test-runner/src/android/test/mock/MockPackageManager.java b/test-runner/src/android/test/mock/MockPackageManager.java index 1ff621a..808498b 100644 --- a/test-runner/src/android/test/mock/MockPackageManager.java +++ b/test-runner/src/android/test/mock/MockPackageManager.java @@ -870,6 +870,13 @@ public class MockPackageManager extends PackageManager { public boolean isUpgrade() { throw new UnsupportedOperationException(); } + /** + * @hide + */ + @Override + public void setComponentProtectedSetting(ComponentName componentName, boolean newState) { + throw new UnsupportedOperationException(); + } /** * @hide |