Merge "Fix issue # 3227963: SecurityException: Neither user 10023 nor..." into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
cd23823d4f
@ -18,9 +18,11 @@ package com.android.commands.pm;
|
||||
|
||||
import com.android.internal.content.PackageHelper;
|
||||
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.FeatureInfo;
|
||||
import android.content.pm.IPackageDataObserver;
|
||||
import android.content.pm.IPackageDeleteObserver;
|
||||
import android.content.pm.IPackageInstallObserver;
|
||||
import android.content.pm.IPackageManager;
|
||||
@ -100,6 +102,11 @@ public final class Pm {
|
||||
return;
|
||||
}
|
||||
|
||||
if ("clear".equals(op)) {
|
||||
runClear();
|
||||
return;
|
||||
}
|
||||
|
||||
if ("enable".equals(op)) {
|
||||
runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
|
||||
return;
|
||||
@ -809,6 +816,55 @@ public final class Pm {
|
||||
return obs.result;
|
||||
}
|
||||
|
||||
class ClearDataObserver extends IPackageDataObserver.Stub {
|
||||
boolean finished;
|
||||
boolean result;
|
||||
|
||||
@Override
|
||||
public void onRemoveCompleted(String packageName, boolean succeeded) throws RemoteException {
|
||||
synchronized (this) {
|
||||
finished = true;
|
||||
result = succeeded;
|
||||
notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void runClear() {
|
||||
String pkg = nextArg();
|
||||
if (pkg == null) {
|
||||
System.err.println("Error: no package specified");
|
||||
showUsage();
|
||||
return;
|
||||
}
|
||||
|
||||
ClearDataObserver obs = new ClearDataObserver();
|
||||
try {
|
||||
if (!ActivityManagerNative.getDefault().clearApplicationUserData(pkg, obs)) {
|
||||
System.err.println("Failed");
|
||||
}
|
||||
|
||||
synchronized (obs) {
|
||||
while (!obs.finished) {
|
||||
try {
|
||||
obs.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obs.result) {
|
||||
System.err.println("Success");
|
||||
} else {
|
||||
System.err.println("Failed");
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
System.err.println(e.toString());
|
||||
System.err.println(PM_NOT_RUNNING_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
private static String enabledSettingToString(int state) {
|
||||
switch (state) {
|
||||
case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT:
|
||||
@ -944,6 +1000,7 @@ public final class Pm {
|
||||
System.err.println(" pm path PACKAGE");
|
||||
System.err.println(" pm install [-l] [-r] [-t] [-i INSTALLER_PACKAGE_NAME] [-s] [-f] PATH");
|
||||
System.err.println(" pm uninstall [-k] PACKAGE");
|
||||
System.err.println(" pm clear PACKAGE");
|
||||
System.err.println(" pm enable PACKAGE_OR_COMPONENT");
|
||||
System.err.println(" pm disable PACKAGE_OR_COMPONENT");
|
||||
System.err.println(" pm setInstallLocation [0/auto] [1/internal] [2/external]");
|
||||
@ -986,6 +1043,8 @@ public final class Pm {
|
||||
System.err.println(" -k: keep the data and cache directories around.");
|
||||
System.err.println("after the package removal.");
|
||||
System.err.println("");
|
||||
System.err.println("The clear command deletes all data associated with a package.");
|
||||
System.err.println("");
|
||||
System.err.println("The enable and disable commands change the enabled state of");
|
||||
System.err.println("a given package or component (written as \"package/class\").");
|
||||
System.err.println("");
|
||||
|
@ -3663,17 +3663,6 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
mAppDirs.remove(pkg.mPath);
|
||||
}
|
||||
|
||||
PackageSetting ps = (PackageSetting)pkg.mExtras;
|
||||
if (ps != null && ps.sharedUser != null) {
|
||||
// XXX don't do this until the data is removed.
|
||||
if (false) {
|
||||
ps.sharedUser.packages.remove(ps);
|
||||
if (ps.sharedUser.packages.size() == 0) {
|
||||
// Remove.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int N = pkg.providers.size();
|
||||
StringBuilder r = null;
|
||||
int i;
|
||||
@ -5695,12 +5684,26 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
killApplication(packageName, oldPkg.applicationInfo.uid);
|
||||
|
||||
res.removedInfo.uid = oldPkg.applicationInfo.uid;
|
||||
res.removedInfo.removedPackage = packageName;
|
||||
// Remove existing system package
|
||||
removePackageLI(oldPkg, true);
|
||||
synchronized (mPackages) {
|
||||
mSettings.disableSystemPackageLP(packageName);
|
||||
if (!mSettings.disableSystemPackageLP(packageName) && deletedPackage != null) {
|
||||
// We didn't need to disable the .apk as a current system package,
|
||||
// which means we are replacing another update that is already
|
||||
// installed. We need to make sure to delete the older one's .apk.
|
||||
res.removedInfo.args = createInstallArgs(isExternal(pkg)
|
||||
? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL,
|
||||
deletedPackage.applicationInfo.sourceDir,
|
||||
deletedPackage.applicationInfo.publicSourceDir,
|
||||
deletedPackage.applicationInfo.nativeLibraryDir);
|
||||
} else {
|
||||
res.removedInfo.args = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Successfully disabled the old package. Now proceed with re-installation
|
||||
@ -5739,17 +5742,6 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
mSettings.writeLP();
|
||||
}
|
||||
} else {
|
||||
// If this is an update to an existing update, setup
|
||||
// to remove the existing update.
|
||||
synchronized (mPackages) {
|
||||
PackageSetting ps = mSettings.getDisabledSystemPkg(packageName);
|
||||
if (ps != null && ps.codePathString != null &&
|
||||
!ps.codePathString.equals(oldPkgSetting.codePathString)) {
|
||||
res.removedInfo.args = createInstallArgs(0, oldPkgSetting.codePathString,
|
||||
oldPkgSetting.resourcePathString, oldPkgSetting.nativeLibraryPathString);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6252,24 +6244,21 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
ps = mSettings.getDisabledSystemPkg(p.packageName);
|
||||
}
|
||||
if (ps == null) {
|
||||
Slog.w(TAG, "Attempt to delete system package "+ p.packageName);
|
||||
Slog.w(TAG, "Attempt to delete unknown system package "+ p.packageName);
|
||||
return false;
|
||||
} else {
|
||||
Log.i(TAG, "Deleting system pkg from data partition");
|
||||
}
|
||||
// Delete the updated package
|
||||
outInfo.isRemovedPackageSystemUpdate = true;
|
||||
final boolean deleteCodeAndResources;
|
||||
if (ps.versionCode < p.mVersionCode) {
|
||||
// Delete code and resources for downgrades
|
||||
deleteCodeAndResources = true;
|
||||
// Delete data for downgrades
|
||||
flags &= ~PackageManager.DONT_DELETE_DATA;
|
||||
} else {
|
||||
// Preserve data by setting flag
|
||||
deleteCodeAndResources = false;
|
||||
flags |= PackageManager.DONT_DELETE_DATA;
|
||||
}
|
||||
boolean ret = deleteInstalledPackageLI(p, deleteCodeAndResources, flags, outInfo,
|
||||
boolean ret = deleteInstalledPackageLI(p, true, flags, outInfo,
|
||||
writeSettings);
|
||||
if (!ret) {
|
||||
return false;
|
||||
@ -7850,6 +7839,12 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
pkgFlags);
|
||||
}
|
||||
|
||||
PackageSetting(PackageSetting orig) {
|
||||
super(orig.name, orig.realName, orig.codePath, orig.resourcePath,
|
||||
orig.nativeLibraryPathString, orig.versionCode, orig.pkgFlags);
|
||||
copyFrom(orig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PackageSetting{"
|
||||
@ -8062,21 +8057,29 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
return s;
|
||||
}
|
||||
|
||||
int disableSystemPackageLP(String name) {
|
||||
boolean disableSystemPackageLP(String name) {
|
||||
PackageSetting p = mPackages.get(name);
|
||||
if(p == null) {
|
||||
Log.w(TAG, "Package:"+name+" is not an installed package");
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
PackageSetting dp = mDisabledSysPackages.get(name);
|
||||
// always make sure the system package code and resource paths dont change
|
||||
if(dp == null) {
|
||||
if (dp == null) {
|
||||
if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
|
||||
p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
|
||||
}
|
||||
mDisabledSysPackages.put(name, p);
|
||||
|
||||
// a little trick... when we install the new package, we don't
|
||||
// want to modify the existing PackageSetting for the built-in
|
||||
// version. so at this point we need a new PackageSetting that
|
||||
// is okay to much with.
|
||||
PackageSetting newp = new PackageSetting(p);
|
||||
replacePackageLP(name, newp);
|
||||
return true;
|
||||
}
|
||||
return removePackageLP(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
PackageSetting enableSystemPackageLP(String name) {
|
||||
@ -8410,6 +8413,19 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void replacePackageLP(String name, PackageSetting newp) {
|
||||
PackageSetting p = mPackages.get(name);
|
||||
if (p != null) {
|
||||
if (p.sharedUser != null) {
|
||||
p.sharedUser.packages.remove(p);
|
||||
p.sharedUser.packages.add(newp);
|
||||
} else {
|
||||
replaceUserIdLP(p.userId, newp);
|
||||
}
|
||||
}
|
||||
mPackages.put(name, newp);
|
||||
}
|
||||
|
||||
private boolean addUserIdLP(int uid, Object obj, Object name) {
|
||||
if (uid >= FIRST_APPLICATION_UID + MAX_APPLICATION_UIDS) {
|
||||
return false;
|
||||
@ -8472,6 +8488,16 @@ class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private void replaceUserIdLP(int uid, Object obj) {
|
||||
if (uid >= FIRST_APPLICATION_UID) {
|
||||
int N = mUserIds.size();
|
||||
final int index = uid - FIRST_APPLICATION_UID;
|
||||
if (index < N) mUserIds.set(index, obj);
|
||||
} else {
|
||||
mOtherUserIds.put(uid, obj);
|
||||
}
|
||||
}
|
||||
|
||||
void writeLP() {
|
||||
//Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
|
||||
|
||||
|
Reference in New Issue
Block a user