diff options
Diffstat (limited to 'services/java/com/android/server/PackageManagerService.java')
-rw-r--r-- | services/java/com/android/server/PackageManagerService.java | 257 |
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) { |