Merge "Store "block uninstall" flag separately from the rest of package state." into oc-dev

This commit is contained in:
Vladislav Kuzkokov
2017-05-05 09:36:45 +00:00
committed by Android (Google) Code Review
6 changed files with 84 additions and 45 deletions

View File

@@ -44,7 +44,6 @@ public class PackageUserState {
public boolean notLaunched; public boolean notLaunched;
public boolean hidden; // Is the app restricted by owner / admin public boolean hidden; // Is the app restricted by owner / admin
public boolean suspended; public boolean suspended;
public boolean blockUninstall;
public boolean instantApp; public boolean instantApp;
public int enabled; public int enabled;
public String lastDisableAppCaller; public String lastDisableAppCaller;
@@ -75,7 +74,6 @@ public class PackageUserState {
notLaunched = o.notLaunched; notLaunched = o.notLaunched;
hidden = o.hidden; hidden = o.hidden;
suspended = o.suspended; suspended = o.suspended;
blockUninstall = o.blockUninstall;
instantApp = o.instantApp; instantApp = o.instantApp;
enabled = o.enabled; enabled = o.enabled;
lastDisableAppCaller = o.lastDisableAppCaller; lastDisableAppCaller = o.lastDisableAppCaller;
@@ -193,9 +191,6 @@ public class PackageUserState {
if (suspended != oldState.suspended) { if (suspended != oldState.suspended) {
return false; return false;
} }
if (blockUninstall != oldState.blockUninstall) {
return false;
}
if (instantApp != oldState.instantApp) { if (instantApp != oldState.instantApp) {
return false; return false;
} }

View File

@@ -18514,11 +18514,6 @@ public class PackageManagerService extends IPackageManager.Stub
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DELETE_PACKAGES, null); android.Manifest.permission.DELETE_PACKAGES, null);
synchronized (mPackages) { synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps == null) {
Log.i(TAG, "Package doesn't exist in set block uninstall " + packageName);
return false;
}
// Cannot block uninstall of static shared libs as they are // Cannot block uninstall of static shared libs as they are
// considered a part of the using app (emulating static linking). // considered a part of the using app (emulating static linking).
// Also static libs are installed always on internal storage. // Also static libs are installed always on internal storage.
@@ -18528,12 +18523,7 @@ public class PackageManagerService extends IPackageManager.Stub
+ " providing static shared library: " + pkg.staticSharedLibName); + " providing static shared library: " + pkg.staticSharedLibName);
return false; return false;
} }
if (!ps.getInstalled(userId)) { mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
// Can't block uninstall for an app that is not installed or enabled.
Log.i(TAG, "Package not installed in set block uninstall " + packageName);
return false;
}
ps.setBlockUninstall(blockUninstall, userId);
mSettings.writePackageRestrictionsLPr(userId); mSettings.writePackageRestrictionsLPr(userId);
} }
return true; return true;
@@ -18542,12 +18532,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override @Override
public boolean getBlockUninstallForUser(String packageName, int userId) { public boolean getBlockUninstallForUser(String packageName, int userId) {
synchronized (mPackages) { synchronized (mPackages) {
PackageSetting ps = mSettings.mPackages.get(packageName); return mSettings.getBlockUninstallLPr(userId, packageName);
if (ps == null) {
Log.i(TAG, "Package doesn't exist in get block uninstall " + packageName);
return false;
}
return ps.getBlockUninstall(userId);
} }
} }
@@ -18754,7 +18739,6 @@ public class PackageManagerService extends IPackageManager.Stub
null /*lastDisableAppCaller*/, null /*lastDisableAppCaller*/,
null /*enabledComponents*/, null /*enabledComponents*/,
null /*disabledComponents*/, null /*disabledComponents*/,
false /*blockUninstall*/,
ps.readUserState(nextUserId).domainVerificationStatus, ps.readUserState(nextUserId).domainVerificationStatus,
0, PackageManager.INSTALL_REASON_UNKNOWN); 0, PackageManager.INSTALL_REASON_UNKNOWN);
} }

View File

@@ -402,14 +402,6 @@ abstract class PackageSettingBase extends SettingBase {
modifyUserState(userId).suspended = suspended; modifyUserState(userId).suspended = suspended;
} }
boolean getBlockUninstall(int userId) {
return readUserState(userId).blockUninstall;
}
void setBlockUninstall(boolean blockUninstall, int userId) {
modifyUserState(userId).blockUninstall = blockUninstall;
}
boolean getInstantApp(int userId) { boolean getInstantApp(int userId) {
return readUserState(userId).instantApp; return readUserState(userId).instantApp;
} }
@@ -421,8 +413,8 @@ abstract class PackageSettingBase extends SettingBase {
void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp, boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
String lastDisableAppCaller, ArraySet<String> enabledComponents, String lastDisableAppCaller, ArraySet<String> enabledComponents,
ArraySet<String> disabledComponents, boolean blockUninstall, ArraySet<String> disabledComponents, int domainVerifState,
int domainVerifState, int linkGeneration, int installReason) { int linkGeneration, int installReason) {
PackageUserState state = modifyUserState(userId); PackageUserState state = modifyUserState(userId);
state.ceDataInode = ceDataInode; state.ceDataInode = ceDataInode;
state.enabled = enabled; state.enabled = enabled;
@@ -434,7 +426,6 @@ abstract class PackageSettingBase extends SettingBase {
state.lastDisableAppCaller = lastDisableAppCaller; state.lastDisableAppCaller = lastDisableAppCaller;
state.enabledComponents = enabledComponents; state.enabledComponents = enabledComponents;
state.disabledComponents = disabledComponents; state.disabledComponents = disabledComponents;
state.blockUninstall = blockUninstall;
state.domainVerificationStatus = domainVerifState; state.domainVerificationStatus = domainVerifState;
state.appLinkGeneration = linkGeneration; state.appLinkGeneration = linkGeneration;
state.installReason = installReason; state.installReason = installReason;

View File

@@ -186,6 +186,8 @@ final class Settings {
private static final String TAG_PERMISSIONS = "perms"; private static final String TAG_PERMISSIONS = "perms";
private static final String TAG_CHILD_PACKAGE = "child-package"; private static final String TAG_CHILD_PACKAGE = "child-package";
private static final String TAG_USES_STATIC_LIB = "uses-static-lib"; private static final String TAG_USES_STATIC_LIB = "uses-static-lib";
private static final String TAG_BLOCK_UNINSTALL_PACKAGES = "block-uninstall-packages";
private static final String TAG_BLOCK_UNINSTALL = "block-uninstall";
private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES = private static final String TAG_PERSISTENT_PREFERRED_ACTIVITIES =
"persistent-preferred-activities"; "persistent-preferred-activities";
@@ -215,6 +217,8 @@ final class Settings {
// New name for the above attribute. // New name for the above attribute.
private static final String ATTR_HIDDEN = "hidden"; private static final String ATTR_HIDDEN = "hidden";
private static final String ATTR_SUSPENDED = "suspended"; private static final String ATTR_SUSPENDED = "suspended";
// Legacy, uninstall blocks are stored separately.
@Deprecated
private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall"; private static final String ATTR_BLOCK_UNINSTALL = "blockUninstall";
private static final String ATTR_ENABLED = "enabled"; private static final String ATTR_ENABLED = "enabled";
private static final String ATTR_ENABLED_CALLER = "enabledCaller"; private static final String ATTR_ENABLED_CALLER = "enabledCaller";
@@ -271,6 +275,9 @@ final class Settings {
private final ArrayMap<String, PackageSetting> mDisabledSysPackages = private final ArrayMap<String, PackageSetting> mDisabledSysPackages =
new ArrayMap<String, PackageSetting>(); new ArrayMap<String, PackageSetting>();
/** List of packages that are blocked for uninstall for specific users */
private final SparseArray<ArraySet<String>> mBlockUninstallPackages = new SparseArray<>();
// Set of restored intent-filter verification states // Set of restored intent-filter verification states
private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications = private final ArrayMap<String, IntentFilterVerificationInfo> mRestoredIntentFilterVerifications =
new ArrayMap<String, IntentFilterVerificationInfo>(); new ArrayMap<String, IntentFilterVerificationInfo>();
@@ -756,7 +763,6 @@ final class Settings {
null /*lastDisableAppCaller*/, null /*lastDisableAppCaller*/,
null /*enabledComponents*/, null /*enabledComponents*/,
null /*disabledComponents*/, null /*disabledComponents*/,
false /*blockUninstall*/,
INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
0, PackageManager.INSTALL_REASON_UNKNOWN); 0, PackageManager.INSTALL_REASON_UNKNOWN);
} }
@@ -1614,6 +1620,34 @@ final class Settings {
} }
} }
void readBlockUninstallPackagesLPw(XmlPullParser parser, int userId)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
int type;
ArraySet<String> packages = new ArraySet<>();
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_BLOCK_UNINSTALL)) {
String packageName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
packages.add(packageName);
} else {
String msg = "Unknown element under " + TAG_BLOCK_UNINSTALL_PACKAGES + ": " +
parser.getName();
PackageManagerService.reportSettingsProblem(Log.WARN, msg);
XmlUtils.skipCurrentTag(parser);
}
}
if (packages.isEmpty()) {
mBlockUninstallPackages.remove(userId);
} else {
mBlockUninstallPackages.put(userId, packages);
}
}
void readPackageRestrictionsLPr(int userId) { void readPackageRestrictionsLPr(int userId) {
if (DEBUG_MU) { if (DEBUG_MU) {
Log.i(TAG, "Reading package restrictions for user=" + userId); Log.i(TAG, "Reading package restrictions for user=" + userId);
@@ -1662,7 +1696,6 @@ final class Settings {
null /*lastDisableAppCaller*/, null /*lastDisableAppCaller*/,
null /*enabledComponents*/, null /*enabledComponents*/,
null /*disabledComponents*/, null /*disabledComponents*/,
false /*blockUninstall*/,
INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
0, PackageManager.INSTALL_REASON_UNKNOWN); 0, PackageManager.INSTALL_REASON_UNKNOWN);
} }
@@ -1768,9 +1801,12 @@ final class Settings {
} }
} }
if (blockUninstall) {
setBlockUninstallLPw(userId, name, true);
}
ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched, ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
hidden, suspended, instantApp, enabledCaller, enabledComponents, hidden, suspended, instantApp, enabledCaller, enabledComponents,
disabledComponents, blockUninstall, verifState, linkGeneration, disabledComponents, verifState, linkGeneration,
installReason); installReason);
} else if (tagName.equals("preferred-activities")) { } else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId); readPreferredActivitiesLPw(parser, userId);
@@ -1780,6 +1816,8 @@ final class Settings {
readCrossProfileIntentFiltersLPw(parser, userId); readCrossProfileIntentFiltersLPw(parser, userId);
} else if (tagName.equals(TAG_DEFAULT_APPS)) { } else if (tagName.equals(TAG_DEFAULT_APPS)) {
readDefaultAppsLPw(parser, userId); readDefaultAppsLPw(parser, userId);
} else if (tagName.equals(TAG_BLOCK_UNINSTALL_PACKAGES)) {
readBlockUninstallPackagesLPw(parser, userId);
} else { } else {
Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: " Slog.w(PackageManagerService.TAG, "Unknown element under <stopped-packages>: "
+ parser.getName()); + parser.getName());
@@ -1806,6 +1844,30 @@ final class Settings {
} }
} }
void setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall) {
ArraySet<String> packages = mBlockUninstallPackages.get(userId);
if (blockUninstall) {
if (packages == null) {
packages = new ArraySet<String>();
mBlockUninstallPackages.put(userId, packages);
}
packages.add(packageName);
} else if (packages != null) {
packages.remove(packageName);
if (packages.isEmpty()) {
mBlockUninstallPackages.remove(userId);
}
}
}
boolean getBlockUninstallLPr(int userId, String packageName) {
ArraySet<String> packages = mBlockUninstallPackages.get(userId);
if (packages == null) {
return false;
}
return packages.contains(packageName);
}
private ArraySet<String> readComponentsLPr(XmlPullParser parser) private ArraySet<String> readComponentsLPr(XmlPullParser parser)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
ArraySet<String> components = null; ArraySet<String> components = null;
@@ -1976,6 +2038,20 @@ final class Settings {
serializer.endTag(null, TAG_DEFAULT_APPS); serializer.endTag(null, TAG_DEFAULT_APPS);
} }
void writeBlockUninstallPackagesLPr(XmlSerializer serializer, int userId)
throws IOException {
ArraySet<String> packages = mBlockUninstallPackages.get(userId);
if (packages != null) {
serializer.startTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
for (int i = 0; i < packages.size(); i++) {
serializer.startTag(null, TAG_BLOCK_UNINSTALL);
serializer.attribute(null, ATTR_PACKAGE_NAME, packages.valueAt(i));
serializer.endTag(null, TAG_BLOCK_UNINSTALL);
}
serializer.endTag(null, TAG_BLOCK_UNINSTALL_PACKAGES);
}
}
void writePackageRestrictionsLPr(int userId) { void writePackageRestrictionsLPr(int userId) {
if (DEBUG_MU) { if (DEBUG_MU) {
Log.i(TAG, "Writing package restrictions for user=" + userId); Log.i(TAG, "Writing package restrictions for user=" + userId);
@@ -2038,9 +2114,6 @@ final class Settings {
if (ustate.suspended) { if (ustate.suspended) {
serializer.attribute(null, ATTR_SUSPENDED, "true"); serializer.attribute(null, ATTR_SUSPENDED, "true");
} }
if (ustate.blockUninstall) {
serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
}
if (ustate.instantApp) { if (ustate.instantApp) {
serializer.attribute(null, ATTR_INSTANT_APP, "true"); serializer.attribute(null, ATTR_INSTANT_APP, "true");
} }
@@ -2091,6 +2164,7 @@ final class Settings {
writePersistentPreferredActivitiesLPr(serializer, userId); writePersistentPreferredActivitiesLPr(serializer, userId);
writeCrossProfileIntentFiltersLPr(serializer, userId); writeCrossProfileIntentFiltersLPr(serializer, userId);
writeDefaultAppsLPr(serializer, userId); writeDefaultAppsLPr(serializer, userId);
writeBlockUninstallPackagesLPr(serializer, userId);
serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS); serializer.endTag(null, TAG_PACKAGE_RESTRICTIONS);

View File

@@ -535,7 +535,6 @@ public class PackageManagerSettingsTests {
private void verifyUserState(PackageUserState userState, PackageUserState oldUserState, private void verifyUserState(PackageUserState userState, PackageUserState oldUserState,
boolean userStateChanged, boolean notLaunched, boolean stopped, boolean installed) { boolean userStateChanged, boolean notLaunched, boolean stopped, boolean installed) {
assertThat(userState.blockUninstall, is(false));
assertThat(userState.enabled, is(0)); assertThat(userState.enabled, is(0));
assertThat(userState.hidden, is(false)); assertThat(userState.hidden, is(false));
assertThat(userState.installed, is(installed)); assertThat(userState.installed, is(installed));

View File

@@ -48,10 +48,6 @@ public class PackageUserStateTest {
oldUserState.appLinkGeneration = 6; oldUserState.appLinkGeneration = 6;
assertThat(testUserState.equals(oldUserState), is(false)); assertThat(testUserState.equals(oldUserState), is(false));
oldUserState = new PackageUserState();
oldUserState.blockUninstall = true;
assertThat(testUserState.equals(oldUserState), is(false));
oldUserState = new PackageUserState(); oldUserState = new PackageUserState();
oldUserState.ceDataInode = 4000L; oldUserState.ceDataInode = 4000L;
assertThat(testUserState.equals(oldUserState), is(false)); assertThat(testUserState.equals(oldUserState), is(false));