diff options
author | Dianne Hackborn <hackbod@google.com> | 2011-01-09 11:38:15 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-01-09 11:38:15 -0800 |
commit | cd23823d4f533431c76baa104eb50b7803b3b391 (patch) | |
tree | cde07be9855acfa3a611cdd4f800001d52bc5052 | |
parent | 9b447d122a2f0a4798f03749e9d93b9a58834fe3 (diff) | |
parent | 690d20bb53ba2485f59d128b365eff991d5cc3e6 (diff) | |
download | frameworks_base-cd23823d4f533431c76baa104eb50b7803b3b391.zip frameworks_base-cd23823d4f533431c76baa104eb50b7803b3b391.tar.gz frameworks_base-cd23823d4f533431c76baa104eb50b7803b3b391.tar.bz2 |
Merge "Fix issue # 3227963: SecurityException: Neither user 10023 nor..." into gingerbread
-rw-r--r-- | cmds/pm/src/com/android/commands/pm/Pm.java | 59 | ||||
-rw-r--r-- | services/java/com/android/server/PackageManagerService.java | 92 |
2 files changed, 118 insertions, 33 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index 311dc38..326e2c8 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -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(""); diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index b0f3a23..cb9dfc8 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -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); |