summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/PackageManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/PackageManagerService.java')
-rw-r--r--services/java/com/android/server/PackageManagerService.java257
1 files changed, 210 insertions, 47 deletions
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 9b8a605..94312fc 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -1050,7 +1050,7 @@ class PackageManagerService extends IPackageManager.Stub {
void cleanupInstallFailedPackage(PackageSetting ps) {
Slog.i(TAG, "Cleaning up incompletely installed app: " + ps.name);
if (mInstaller != null) {
- boolean useSecureFS = useEncryptedFilesystemForPackage(ps.pkg);
+ boolean useSecureFS = false;
int retCode = mInstaller.remove(ps.name, useSecureFS);
if (retCode < 0) {
Slog.w(TAG, "Couldn't remove app data directory for package: "
@@ -1225,6 +1225,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
+ permReader.close();
} catch (XmlPullParserException e) {
Slog.w(TAG, "Got execption parsing permissions.", e);
} catch (IOException e) {
@@ -2779,11 +2780,6 @@ class PackageManagerService extends IPackageManager.Stub {
return performed ? DEX_OPT_PERFORMED : DEX_OPT_SKIPPED;
}
- private static boolean useEncryptedFilesystemForPackage(PackageParser.Package pkg) {
- return Environment.isEncryptedFilesystemEnabled() &&
- ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_NEVER_ENCRYPT) == 0);
- }
-
private boolean verifyPackageUpdate(PackageSetting oldPkg, PackageParser.Package newPkg) {
if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
Slog.w(TAG, "Unable to update from " + oldPkg.name
@@ -2800,7 +2796,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
private File getDataPathForPackage(PackageParser.Package pkg) {
- boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
+ boolean useEncryptedFSDir = false;
File dataPath;
if (useEncryptedFSDir) {
dataPath = new File(mSecureAppDataDir, pkg.packageName);
@@ -2852,7 +2848,7 @@ class PackageManagerService extends IPackageManager.Stub {
mResolveActivity.processName = mAndroidApplication.processName;
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
- mResolveActivity.theme = com.android.internal.R.style.Theme_Dialog_Alert;
+ mResolveActivity.theme = com.android.internal.R.style.Theme_Holo_Dialog_Alert;
mResolveActivity.exported = true;
mResolveActivity.enabled = true;
mResolveInfo.activityInfo = mResolveActivity;
@@ -2926,24 +2922,23 @@ class PackageManagerService extends IPackageManager.Stub {
System.arraycopy(mTmpSharedLibraries, 0,
pkg.usesLibraryFiles, 0, num);
}
+ }
- if (pkg.reqFeatures != null) {
- N = pkg.reqFeatures.size();
- for (int i=0; i<N; i++) {
- FeatureInfo fi = pkg.reqFeatures.get(i);
- if ((fi.flags&FeatureInfo.FLAG_REQUIRED) == 0) {
- // Don't care.
- continue;
- }
+ if (pkg.reqFeatures != null) {
+ int N = pkg.reqFeatures.size();
+ for (int i = 0; i < N; i++) {
+ FeatureInfo fi = pkg.reqFeatures.get(i);
+ if ((fi.flags & FeatureInfo.FLAG_REQUIRED) == 0) {
+ // Don't care.
+ continue;
+ }
- if (fi.name != null) {
- if (mAvailableFeatures.get(fi.name) == null) {
- Slog.e(TAG, "Package " + pkg.packageName
- + " requires unavailable feature "
- + fi.name + "; failing!");
- mLastScanError = PackageManager.INSTALL_FAILED_MISSING_FEATURE;
- return null;
- }
+ if (fi.name != null) {
+ if (mAvailableFeatures.get(fi.name) == null) {
+ Slog.e(TAG, "Package " + pkg.packageName
+ + " requires unavailable feature " + fi.name + "; failing!");
+ mLastScanError = PackageManager.INSTALL_FAILED_MISSING_FEATURE;
+ return null;
}
}
}
@@ -3157,7 +3152,7 @@ class PackageManagerService extends IPackageManager.Stub {
pkg.applicationInfo.dataDir = dataPath.getPath();
} else {
// This is a normal package, need to make its data directory.
- boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(pkg);
+ boolean useEncryptedFSDir = false;
dataPath = getDataPathForPackage(pkg);
boolean uidError = false;
@@ -4412,10 +4407,19 @@ class PackageManagerService extends IPackageManager.Stub {
}
}
}
-
+
+ /**
+ * Check if the external storage media is available. This is true if there
+ * is a mounted external storage medium or if the external storage is
+ * emulated.
+ */
+ private boolean isExternalMediaAvailable() {
+ return mMediaMounted || Environment.isExternalStorageEmulated();
+ }
+
public String nextPackageToClean(String lastPackage) {
synchronized (mPackages) {
- if (!mMediaMounted) {
+ if (!isExternalMediaAvailable()) {
// If the external storage is no longer mounted at this point,
// the caller may not have been able to delete all of this
// packages files and can not delete any more. Bail.
@@ -4435,7 +4439,7 @@ class PackageManagerService extends IPackageManager.Stub {
void startCleaningPackages() {
synchronized (mPackages) {
- if (!mMediaMounted) {
+ if (!isExternalMediaAvailable()) {
return;
}
if (mSettings.mPackagesToBeCleaned.size() <= 0) {
@@ -4570,6 +4574,80 @@ class PackageManagerService extends IPackageManager.Stub {
mHandler.sendMessage(msg);
}
+ public void setInstallerPackageName(String targetPackage,
+ String installerPackageName) {
+ PackageSetting pkgSetting;
+ final int uid = Binder.getCallingUid();
+ final int permission = mContext.checkCallingPermission(
+ android.Manifest.permission.INSTALL_PACKAGES);
+ final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
+ synchronized (mPackages) {
+ PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
+ if (targetPackageSetting == null) {
+ throw new IllegalArgumentException("Unknown target package: " + targetPackage);
+ }
+
+ PackageSetting installerPackageSetting;
+ if (installerPackageName != null) {
+ installerPackageSetting = mSettings.mPackages.get(installerPackageName);
+ if (installerPackageSetting == null) {
+ throw new IllegalArgumentException("Unknown installer package: "
+ + installerPackageName);
+ }
+ } else {
+ installerPackageSetting = null;
+ }
+
+ Signature[] callerSignature;
+ Object obj = mSettings.getUserIdLP(uid);
+ if (obj != null) {
+ if (obj instanceof SharedUserSetting) {
+ callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
+ } else if (obj instanceof PackageSetting) {
+ callerSignature = ((PackageSetting)obj).signatures.mSignatures;
+ } else {
+ throw new SecurityException("Bad object " + obj + " for uid " + uid);
+ }
+ } else {
+ throw new SecurityException("Unknown calling uid " + uid);
+ }
+
+ // Verify: can't set installerPackageName to a package that is
+ // not signed with the same cert as the caller.
+ if (installerPackageSetting != null) {
+ if (checkSignaturesLP(callerSignature,
+ installerPackageSetting.signatures.mSignatures)
+ != PackageManager.SIGNATURE_MATCH) {
+ throw new SecurityException(
+ "Caller does not have same cert as new installer package "
+ + installerPackageName);
+ }
+ }
+
+ // Verify: if target already has an installer package, it must
+ // be signed with the same cert as the caller.
+ if (targetPackageSetting.installerPackageName != null) {
+ PackageSetting setting = mSettings.mPackages.get(
+ targetPackageSetting.installerPackageName);
+ // If the currently set package isn't valid, then it's always
+ // okay to change it.
+ if (setting != null) {
+ if (checkSignaturesLP(callerSignature,
+ setting.signatures.mSignatures)
+ != PackageManager.SIGNATURE_MATCH) {
+ throw new SecurityException(
+ "Caller does not have same cert as old installer package "
+ + targetPackageSetting.installerPackageName);
+ }
+ }
+ }
+
+ // Okay!
+ targetPackageSetting.installerPackageName = installerPackageName;
+ scheduleWriteSettingsLocked();
+ }
+ }
+
private void processPendingInstall(final InstallArgs args, final int currentStatus) {
// Queue up an async operation since the package installation may take a little while.
mHandler.post(new Runnable() {
@@ -4677,6 +4755,79 @@ class PackageManagerService extends IPackageManager.Stub {
abstract void handleReturnCode();
}
+ class MeasureParams extends HandlerParams {
+ private final PackageStats mStats;
+ private boolean mSuccess;
+
+ private final IPackageStatsObserver mObserver;
+
+ public MeasureParams(PackageStats stats, boolean success,
+ IPackageStatsObserver observer) {
+ mObserver = observer;
+ mStats = stats;
+ mSuccess = success;
+ }
+
+ @Override
+ void handleStartCopy() throws RemoteException {
+ final boolean mounted;
+
+ if (Environment.isExternalStorageEmulated()) {
+ mounted = true;
+ } else {
+ final String status = Environment.getExternalStorageState();
+
+ mounted = status.equals(Environment.MEDIA_MOUNTED)
+ || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
+ }
+
+ if (mounted) {
+ final File externalCacheDir = Environment
+ .getExternalStorageAppCacheDirectory(mStats.packageName);
+ final long externalCacheSize = mContainerService
+ .calculateDirectorySize(externalCacheDir.getPath());
+ mStats.externalCacheSize = externalCacheSize;
+
+ final File externalDataDir = Environment
+ .getExternalStorageAppDataDirectory(mStats.packageName);
+ long externalDataSize = mContainerService.calculateDirectorySize(externalDataDir
+ .getPath());
+
+ if (externalCacheDir.getParentFile().equals(externalDataDir)) {
+ externalDataSize -= externalCacheSize;
+ }
+ mStats.externalDataSize = externalDataSize;
+
+ final File externalMediaDir = Environment
+ .getExternalStorageAppMediaDirectory(mStats.packageName);
+ mStats.externalMediaSize = mContainerService
+ .calculateDirectorySize(externalCacheDir.getPath());
+
+ final File externalObbDir = Environment
+ .getExternalStorageAppObbDirectory(mStats.packageName);
+ mStats.externalObbSize = mContainerService.calculateDirectorySize(externalObbDir
+ .getPath());
+ }
+ }
+
+ @Override
+ void handleReturnCode() {
+ if (mObserver != null) {
+ try {
+ mObserver.onGetStatsCompleted(mStats, mSuccess);
+ } catch (RemoteException e) {
+ Slog.i(TAG, "Observer no longer exists.");
+ }
+ }
+ }
+
+ @Override
+ void handleServiceError() {
+ Slog.e(TAG, "Could not measure application " + mStats.packageName
+ + " external storage");
+ }
+ }
+
class InstallParams extends HandlerParams {
final IPackageInstallObserver observer;
int flags;
@@ -6162,7 +6313,7 @@ class PackageManagerService extends IPackageManager.Stub {
deletedPs = mSettings.mPackages.get(packageName);
}
if ((flags&PackageManager.DONT_DELETE_DATA) == 0) {
- boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
+ boolean useEncryptedFSDir = false;
if (mInstaller != null) {
int retCode = mInstaller.remove(packageName, useEncryptedFSDir);
if (retCode < 0) {
@@ -6406,7 +6557,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
boolean useEncryptedFSDir = false;
- if(!dataOnly) {
+ if (!dataOnly) {
//need to check this only for fully installed applications
if (p == null) {
Slog.w(TAG, "Package named '" + packageName +"' doesn't exist.");
@@ -6417,7 +6568,6 @@ class PackageManagerService extends IPackageManager.Stub {
Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
- useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
}
if (mInstaller != null) {
int retCode = mInstaller.clearUserData(packageName, useEncryptedFSDir);
@@ -6471,7 +6621,7 @@ class PackageManagerService extends IPackageManager.Stub {
Slog.w(TAG, "Package " + packageName + " has no applicationInfo.");
return false;
}
- boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
+ boolean useEncryptedFSDir = false;
if (mInstaller != null) {
int retCode = mInstaller.deleteCacheFiles(packageName, useEncryptedFSDir);
if (retCode < 0) {
@@ -6491,18 +6641,16 @@ class PackageManagerService extends IPackageManager.Stub {
mHandler.post(new Runnable() {
public void run() {
mHandler.removeCallbacks(this);
- PackageStats lStats = new PackageStats(packageName);
- final boolean succeded;
+ PackageStats stats = new PackageStats(packageName);
+
+ final boolean success;
synchronized (mInstallLock) {
- succeded = getPackageSizeInfoLI(packageName, lStats);
+ success = getPackageSizeInfoLI(packageName, stats);
}
- if(observer != null) {
- try {
- observer.onGetStatsCompleted(lStats, succeded);
- } catch (RemoteException e) {
- Log.i(TAG, "Observer no longer exists.");
- }
- } //end if observer
+
+ Message msg = mHandler.obtainMessage(INIT_COPY);
+ msg.obj = new MeasureParams(stats, success, observer);
+ mHandler.sendMessage(msg);
} //end run
});
}
@@ -6535,7 +6683,7 @@ class PackageManagerService extends IPackageManager.Stub {
}
publicSrcDir = isForwardLocked(p) ? applicationInfo.publicSourceDir : null;
}
- boolean useEncryptedFSDir = useEncryptedFilesystemForPackage(p);
+ boolean useEncryptedFSDir = false;
if (mInstaller != null) {
int res = mInstaller.getSizeInfo(packageName, p.mPath,
publicSrcDir, pStats, useEncryptedFSDir);
@@ -7299,7 +7447,7 @@ class PackageManagerService extends IPackageManager.Stub {
pw.println(" ");
pw.println("Package warning messages:");
File fname = getSettingsProblemFile();
- FileInputStream in;
+ FileInputStream in = null;
try {
in = new FileInputStream(fname);
int avail = in.available();
@@ -7308,6 +7456,13 @@ class PackageManagerService extends IPackageManager.Stub {
pw.print(new String(data));
} catch (FileNotFoundException e) {
} catch (IOException e) {
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ }
+ }
}
}
}
@@ -7700,8 +7855,7 @@ class PackageManagerService extends IPackageManager.Stub {
this.pkgFlags = pkgFlags & (
ApplicationInfo.FLAG_SYSTEM |
ApplicationInfo.FLAG_FORWARD_LOCK |
- ApplicationInfo.FLAG_EXTERNAL_STORAGE |
- ApplicationInfo.FLAG_NEVER_ENCRYPT);
+ ApplicationInfo.FLAG_EXTERNAL_STORAGE);
}
}
@@ -7889,6 +8043,14 @@ class PackageManagerService extends IPackageManager.Stub {
sharedUser = orig.sharedUser;
}
+ public void copyFrom(PackageSetting base) {
+ super.copyFrom((PackageSettingBase) base);
+
+ userId = base.userId;
+ sharedUser = base.sharedUser;
+ pkg = base.pkg;
+ }
+
@Override
public String toString() {
return "PackageSetting{"
@@ -9736,7 +9898,8 @@ class PackageManagerService extends IPackageManager.Stub {
* Update media status on PackageManager.
*/
public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
- if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ int callingUid = Binder.getCallingUid();
+ if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
throw new SecurityException("Media status can only be updated by the system");
}
synchronized (mPackages) {