diff options
author | Jeff Sharkey <jsharkey@android.com> | 2014-07-08 11:28:00 -0700 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2014-07-09 16:55:56 -0700 |
commit | ec55ef0934b8e0d1bb705434947de817f7be57f1 (patch) | |
tree | 4855af37aa2c312bc2a645f5d94c463a2859d516 /services | |
parent | 2cfc8482267707a671cbe4275ea8927c1aef991a (diff) | |
download | frameworks_base-ec55ef0934b8e0d1bb705434947de817f7be57f1.zip frameworks_base-ec55ef0934b8e0d1bb705434947de817f7be57f1.tar.gz frameworks_base-ec55ef0934b8e0d1bb705434947de817f7be57f1.tar.bz2 |
Extend pm to support sessions and split APKs.
Separate commands to create an install session, stream files into the
staging area, and then commit the install. Streaming can accept data
from stdin across adb, avoiding extra copy from push.
Extend FileBridge to support blocking close(). Always destroy
session regardless of result.
Bug: 14975160
Change-Id: Ic3f462e7d1901079b785e210228950cdfa676466
Diffstat (limited to 'services')
3 files changed, 171 insertions, 155 deletions
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index 5fdfce4..682a38d 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -30,8 +30,11 @@ import android.os.Binder; import android.os.FileUtils; import android.os.HandlerThread; import android.os.Process; +import android.os.SELinux; import android.os.UserHandle; import android.os.UserManager; +import android.system.ErrnoException; +import android.system.Os; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; @@ -42,6 +45,8 @@ import com.android.server.IoThread; import com.google.android.collect.Sets; import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; public class PackageInstallerService extends IPackageInstaller.Stub { private static final String TAG = "PackageInstaller"; @@ -54,8 +59,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub { private final AppOpsManager mAppOps; private final File mStagingDir; + private final HandlerThread mInstallThread; - private final HandlerThread mInstallThread = new HandlerThread(TAG); private final Callback mCallback = new Callback(); @GuardedBy("mSessions") @@ -63,27 +68,50 @@ public class PackageInstallerService extends IPackageInstaller.Stub { @GuardedBy("mSessions") private final SparseArray<PackageInstallerSession> mSessions = new SparseArray<>(); + private static final FilenameFilter sStageFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return name.startsWith("vmdl") && name.endsWith(".tmp"); + } + }; + public PackageInstallerService(Context context, PackageManagerService pm, File stagingDir) { mContext = context; mPm = pm; mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); mStagingDir = stagingDir; - mStagingDir.mkdirs(); + + mInstallThread = new HandlerThread(TAG); + mInstallThread.start(); synchronized (mSessions) { readSessionsLocked(); // Clean up orphaned staging directories - final ArraySet<String> dirs = Sets.newArraySet(mStagingDir.list()); + final ArraySet<File> stages = Sets.newArraySet(mStagingDir.listFiles(sStageFilter)); for (int i = 0; i < mSessions.size(); i++) { - dirs.remove(Integer.toString(mSessions.keyAt(i))); + final PackageInstallerSession session = mSessions.valueAt(i); + stages.remove(session.sessionStageDir); + } + for (File stage : stages) { + Slog.w(TAG, "Deleting orphan stage " + stage); + if (stage.isDirectory()) { + FileUtils.deleteContents(stage); + } + stage.delete(); } - for (String dirName : dirs) { - Slog.w(TAG, "Deleting orphan session " + dirName); - final File dir = new File(mStagingDir, dirName); - FileUtils.deleteContents(dir); - dir.delete(); + } + } + + @Deprecated + public File allocateSessionDir() throws IOException { + synchronized (mSessions) { + try { + final int sessionId = allocateSessionIdLocked(); + return prepareSessionStageDir(sessionId); + } catch (IllegalStateException e) { + throw new IOException(e); } } } @@ -110,11 +138,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } @Override - public int createSession(int userId, String installerPackageName, - PackageInstallerParams params) { + public int createSession(String installerPackageName, PackageInstallerParams params, + int userId) { final int callingUid = Binder.getCallingUid(); mPm.enforceCrossUserPermission(callingUid, userId, false, TAG); - mAppOps.checkPackage(callingUid, installerPackageName); if (mPm.isUserRestricted(UserHandle.getUserId(callingUid), UserManager.DISALLOW_INSTALL_APPS)) { @@ -124,20 +151,21 @@ public class PackageInstallerService extends IPackageInstaller.Stub { if ((callingUid == Process.SHELL_UID) || (callingUid == 0)) { params.installFlags |= INSTALL_FROM_ADB; } else { + mAppOps.checkPackage(callingUid, installerPackageName); + params.installFlags &= ~INSTALL_FROM_ADB; params.installFlags &= ~INSTALL_ALL_USERS; params.installFlags |= INSTALL_REPLACE_EXISTING; } synchronized (mSessions) { - final int sessionId = allocateSessionIdLocked(); final long createdMillis = System.currentTimeMillis(); - final File sessionDir = new File(mStagingDir, Integer.toString(sessionId)); - sessionDir.mkdirs(); + final int sessionId = allocateSessionIdLocked(); + final File sessionStageDir = prepareSessionStageDir(sessionId); final PackageInstallerSession session = new PackageInstallerSession(mCallback, mPm, sessionId, userId, installerPackageName, callingUid, params, createdMillis, - sessionDir, mInstallThread.getLooper()); + sessionStageDir, mInstallThread.getLooper()); mSessions.put(sessionId, session); writeSessionsAsync(); @@ -166,8 +194,30 @@ public class PackageInstallerService extends IPackageInstaller.Stub { return mNextSessionId++; } + private File prepareSessionStageDir(int sessionId) { + final File file = new File(mStagingDir, "vmdl" + sessionId + ".tmp"); + + if (file.exists()) { + throw new IllegalStateException(); + } + + try { + Os.mkdir(file.getAbsolutePath(), 0755); + Os.chmod(file.getAbsolutePath(), 0755); + } catch (ErrnoException e) { + // This purposefully throws if directory already exists + throw new IllegalStateException("Failed to prepare session dir", e); + } + + if (!SELinux.restorecon(file)) { + throw new IllegalStateException("Failed to prepare session dir"); + } + + return file; + } + @Override - public int[] getSessions(int userId, String installerPackageName) { + public int[] getSessions(String installerPackageName, int userId) { final int callingUid = Binder.getCallingUid(); mPm.enforceCrossUserPermission(callingUid, userId, false, TAG); mAppOps.checkPackage(callingUid, installerPackageName); @@ -187,13 +237,14 @@ public class PackageInstallerService extends IPackageInstaller.Stub { } @Override - public void uninstall(int userId, String basePackageName, IPackageDeleteObserver observer) { - mPm.deletePackageAsUser(basePackageName, observer, userId, 0); + public void uninstall(String basePackageName, int flags, IPackageDeleteObserver observer, + int userId) { + mPm.deletePackageAsUser(basePackageName, observer, userId, flags); } @Override - public void uninstallSplit(int userId, String basePackageName, String overlayName, - IPackageDeleteObserver observer) { + public void uninstallSplit(String basePackageName, String overlayName, int flags, + IPackageDeleteObserver observer, int userId) { // TODO: flesh out once PM has split support throw new UnsupportedOperationException(); } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 8067bd9..3448803 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -20,6 +20,8 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED; +import static android.system.OsConstants.O_CREAT; +import static android.system.OsConstants.O_WRONLY; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageInstallObserver2; @@ -37,9 +39,11 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.ParcelFileDescriptor; +import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; import android.system.ErrnoException; +import android.system.Os; import android.system.OsConstants; import android.system.StructStat; import android.util.ArraySet; @@ -58,6 +62,10 @@ import java.util.ArrayList; public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final String TAG = "PackageInstaller"; + // TODO: enforce INSTALL_ALLOW_TEST + // TODO: enforce INSTALL_ALLOW_DOWNGRADE + // TODO: handle INSTALL_EXTERNAL, INSTALL_INTERNAL + private final PackageInstallerService.Callback mCallback; private final PackageManagerService mPm; private final Handler mHandler; @@ -69,7 +77,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { public final int installerUid; public final PackageInstallerParams params; public final long createdMillis; - public final File sessionDir; + public final File sessionStageDir; private static final int MSG_INSTALL = 0; @@ -85,6 +93,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { installLocked(); } catch (InstallFailedException e) { Slog.e(TAG, "Install failed: " + e); + destroy(); try { mRemoteObserver.packageInstalled(mPackageName, null, e.error); } catch (RemoteException ignored) { @@ -114,7 +123,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { public PackageInstallerSession(PackageInstallerService.Callback callback, PackageManagerService pm, int sessionId, int userId, String installerPackageName, - int installerUid, PackageInstallerParams params, long createdMillis, File sessionDir, + int installerUid, PackageInstallerParams params, long createdMillis, File sessionStageDir, Looper looper) { mCallback = callback; mPm = pm; @@ -126,7 +135,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { this.installerUid = installerUid; this.params = params; this.createdMillis = createdMillis; - this.sessionDir = sessionDir; + this.sessionStageDir = sessionStageDir; // Check against any explicitly provided signatures mSignatures = params.signatures; @@ -138,6 +147,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { == PackageManager.PERMISSION_GRANTED) { mPermissionsConfirmed = true; } + if (installerUid == Process.SHELL_UID || installerUid == 0) { + mPermissionsConfirmed = true; + } } @Override @@ -168,10 +180,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (!FileUtils.isValidExtFilename(name)) { throw new IllegalArgumentException("Invalid name: " + name); } - final File target = new File(sessionDir, name); + final File target = new File(sessionStageDir, name); final FileDescriptor targetFd = Libcore.os.open(target.getAbsolutePath(), - OsConstants.O_CREAT | OsConstants.O_WRONLY, 00700); + O_CREAT | O_WRONLY, 0644); + Os.chmod(target.getAbsolutePath(), 0644); // If caller specified a total length, allocate it for them. Free up // cache space to grow, if needed. @@ -235,7 +248,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { if (!mPermissionsConfirmed) { // TODO: async confirm permissions with user // when they confirm, we'll kick off another install() pass - mPermissionsConfirmed = true; + throw new SecurityException("Caller must hold INSTALL permission"); } // Inherit any packages and native libraries from existing install that @@ -258,7 +271,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } }; - mPm.installStage(mPackageName, this.sessionDir, localObserver, params, installerPackageName, + mPm.installStage(mPackageName, this.sessionStageDir, localObserver, params, installerPackageName, installerUid, new UserHandle(userId)); } @@ -271,9 +284,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private void validateInstallLocked() throws InstallFailedException { mPackageName = null; mVersionCode = -1; - mSignatures = null; - final File[] files = sessionDir.listFiles(); + final File[] files = sessionStageDir.listFiles(); if (ArrayUtils.isEmpty(files)) { throw new InstallFailedException(INSTALL_FAILED_INVALID_APK, "No packages staged"); } @@ -296,11 +308,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } // Use first package to define unknown values - if (mPackageName != null) { + if (mPackageName == null) { mPackageName = info.packageName; mVersionCode = info.versionCode; } - if (mSignatures != null) { + if (mSignatures == null) { mSignatures = info.signatures; } @@ -310,9 +322,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // Take this opportunity to enforce uniform naming final String name; if (info.splitName == null) { - name = info.packageName + ".apk"; + name = "base.apk"; } else { - name = info.packageName + "-" + info.splitName + ".apk"; + name = "split_" + info.splitName + ".apk"; } if (!FileUtils.isValidExtFilename(name)) { throw new InstallFailedException(INSTALL_FAILED_INVALID_APK, @@ -382,7 +394,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final File existingDir = new File(app.getBaseCodePath()); try { - linkTreeIgnoringExisting(existingDir, sessionDir); + linkTreeIgnoringExisting(existingDir, sessionStageDir); } catch (ErrnoException e) { throw new InstallFailedException(INSTALL_FAILED_INTERNAL_ERROR, "Failed to splice into stage"); @@ -416,8 +428,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { synchronized (mLock) { mInvalid = true; } - FileUtils.deleteContents(sessionDir); - sessionDir.delete(); + FileUtils.deleteContents(sessionStageDir); + sessionStageDir.delete(); } finally { mCallback.onSessionInvalid(this); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 0a201f9..fe9ce8f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -377,11 +377,6 @@ public class PackageManagerService extends IPackageManager.Stub { // apps. final File mDrmAppPrivateInstallDir; - /** Directory where third-party apps are staged before install */ - final File mAppStagingDir; - - private final Random mTempFileRandom = new Random(); - // ---------------------------------------------------------------- // Lock for state used when installing and doing other long running @@ -1363,7 +1358,6 @@ public class PackageManagerService extends IPackageManager.Stub { mAsecInternalPath = new File(dataDir, "app-asec").getPath(); mUserAppDataDir = new File(dataDir, "user"); mDrmAppPrivateInstallDir = new File(dataDir, "app-private"); - mAppStagingDir = new File(dataDir, "app-staging"); sUserManager = new UserManagerService(context, this, mInstallLock, mPackages); @@ -1767,7 +1761,7 @@ public class PackageManagerService extends IPackageManager.Stub { } // synchronized (mPackages) } // synchronized (mInstallLock) - mInstallerService = new PackageInstallerService(context, this, mAppStagingDir); + mInstallerService = new PackageInstallerService(context, this, mAppInstallDir); // Now after opening every single application zip, make sure they // are all flushed. Not really needed, but keeps things nice and @@ -4172,6 +4166,7 @@ public class PackageManagerService extends IPackageManager.Stub { pp.collectCertificates(pkg, parseFlags); pp.collectManifestDigest(pkg); } catch (PackageParserException e) { + Slog.e(TAG, "Failed during collect: " + e); mLastScanError = e.error; return false; } @@ -4200,6 +4195,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { pkg = pp.parsePackage(scanFile, parseFlags); } catch (PackageParserException e) { + Slog.e(TAG, "Failed during scan: " + e); mLastScanError = e.error; return null; } @@ -7652,8 +7648,20 @@ public class PackageManagerService extends IPackageManager.Stub { verificationParams.setInstallerUid(uid); final Message msg = mHandler.obtainMessage(INIT_COPY); - msg.obj = new InstallParams(originFile, observer, filteredFlags, installerPackageName, - verificationParams, user, packageAbiOverride); + msg.obj = new InstallParams(originFile, false, observer, filteredFlags, + installerPackageName, verificationParams, user, packageAbiOverride); + mHandler.sendMessage(msg); + } + + void installStage(String packageName, File stageDir, IPackageInstallObserver2 observer, + PackageInstallerParams params, String installerPackageName, int installerUid, + UserHandle user) { + final VerificationParams verifParams = new VerificationParams(null, params.originatingUri, + params.referrerUri, installerUid, null); + + final Message msg = mHandler.obtainMessage(INIT_COPY); + msg.obj = new InstallParams(stageDir, true, observer, params.installFlags, + installerPackageName, verifParams, user, params.abiOverride); mHandler.sendMessage(msg); } @@ -7769,17 +7777,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } - void installStage(String packageName, File stageDir, IPackageInstallObserver2 observer2, - PackageInstallerParams params, String installerPackageName, int installerUid, - UserHandle user) { - Slog.e(TAG, "TODO: install stage!"); - try { - observer2.packageInstalled(packageName, null, - PackageManager.INSTALL_FAILED_INTERNAL_ERROR); - } catch (RemoteException ignored) { - } - } - /** * @hide */ @@ -8365,10 +8362,10 @@ public class PackageManagerService extends IPackageManager.Stub { final File originFile; /** - * Flag indicating that {@link #originFile} lives in a trusted location, + * Flag indicating that {@link #originFile} has already been staged, * meaning downstream users don't need to defensively copy the contents. */ - boolean originTrusted; + boolean originStaged; final IPackageInstallObserver2 observer; int flags; @@ -8379,12 +8376,12 @@ public class PackageManagerService extends IPackageManager.Stub { final String packageAbiOverride; final String packageInstructionSetOverride; - InstallParams(File originFile, IPackageInstallObserver2 observer, int flags, - String installerPackageName, VerificationParams verificationParams, UserHandle user, - String packageAbiOverride) { + InstallParams(File originFile, boolean originStaged, IPackageInstallObserver2 observer, + int flags, String installerPackageName, VerificationParams verificationParams, + UserHandle user, String packageAbiOverride) { super(user); this.originFile = Preconditions.checkNotNull(originFile); - this.originTrusted = false; + this.originStaged = originStaged; this.observer = observer; this.flags = flags; this.installerPackageName = installerPackageName; @@ -8912,8 +8909,8 @@ public class PackageManagerService extends IPackageManager.Stub { static abstract class InstallArgs { /** @see InstallParams#originFile */ final File originFile; - /** @see InstallParams#originTrusted */ - final boolean originTrusted; + /** @see InstallParams#originStaged */ + final boolean originStaged; // TODO: define inherit location @@ -8926,11 +8923,11 @@ public class PackageManagerService extends IPackageManager.Stub { final String instructionSet; final String abiOverride; - InstallArgs(File originFile, boolean originTrusted, IPackageInstallObserver2 observer, + InstallArgs(File originFile, boolean originStaged, IPackageInstallObserver2 observer, int flags, String installerPackageName, ManifestDigest manifestDigest, UserHandle user, String instructionSet, String abiOverride) { this.originFile = originFile; - this.originTrusted = originTrusted; + this.originStaged = originStaged; this.flags = flags; this.observer = observer; this.installerPackageName = installerPackageName; @@ -9009,7 +9006,7 @@ public class PackageManagerService extends IPackageManager.Stub { /** New install */ FileInstallArgs(InstallParams params) { - super(params.originFile, params.originTrusted, params.observer, params.flags, + super(params.originFile, params.originStaged, params.observer, params.flags, params.installerPackageName, params.getManifestDigest(), params.getUser(), params.packageInstructionSetOverride, params.packageAbiOverride); if (isFwdLocked()) { @@ -9028,7 +9025,7 @@ public class PackageManagerService extends IPackageManager.Stub { /** New install from existing */ FileInstallArgs(File originFile, String instructionSet) { - super(originFile, true, null, 0, null, null, null, instructionSet, null); + super(originFile, false, null, 0, null, null, null, instructionSet, null); } boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException { @@ -9053,37 +9050,45 @@ public class PackageManagerService extends IPackageManager.Stub { } int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { - try { - final File tempDir = createTempPackageDir(mAppInstallDir); - codeFile = tempDir; - resourceFile = tempDir; - } catch (IOException e) { - Slog.w(TAG, "Failed to create copy file: " + e); - return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; - } + int ret = PackageManager.INSTALL_SUCCEEDED; - final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { - @Override - public ParcelFileDescriptor open(String name, int mode) throws RemoteException { - if (!FileUtils.isValidExtFilename(name)) { - throw new IllegalArgumentException("Invalid filename: " + name); - } - try { - final File file = new File(codeFile, name); - final FileDescriptor fd = Os.open(file.getAbsolutePath(), - O_RDWR | O_CREAT, 0644); - Os.chmod(file.getAbsolutePath(), 0644); - return new ParcelFileDescriptor(fd); - } catch (ErrnoException e) { - throw new RemoteException("Failed to open: " + e.getMessage()); - } + if (originStaged) { + Slog.d(TAG, originFile + " already staged; skipping copy"); + codeFile = originFile; + resourceFile = originFile; + } else { + try { + final File tempDir = mInstallerService.allocateSessionDir(); + codeFile = tempDir; + resourceFile = tempDir; + } catch (IOException e) { + Slog.w(TAG, "Failed to create copy file: " + e); + return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; } - }; - int ret = imcs.copyPackage(originFile.getAbsolutePath(), target); - if (ret != PackageManager.INSTALL_SUCCEEDED) { - Slog.e(TAG, "Failed to copy package"); - return ret; + final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() { + @Override + public ParcelFileDescriptor open(String name, int mode) throws RemoteException { + if (!FileUtils.isValidExtFilename(name)) { + throw new IllegalArgumentException("Invalid filename: " + name); + } + try { + final File file = new File(codeFile, name); + final FileDescriptor fd = Os.open(file.getAbsolutePath(), + O_RDWR | O_CREAT, 0644); + Os.chmod(file.getAbsolutePath(), 0644); + return new ParcelFileDescriptor(fd); + } catch (ErrnoException e) { + throw new RemoteException("Failed to open: " + e.getMessage()); + } + } + }; + + ret = imcs.copyPackage(originFile.getAbsolutePath(), target); + if (ret != PackageManager.INSTALL_SUCCEEDED) { + Slog.e(TAG, "Failed to copy package"); + return ret; + } } String[] abiList = (abiOverride != null) ? @@ -9288,7 +9293,7 @@ public class PackageManagerService extends IPackageManager.Stub { /** New install */ AsecInstallArgs(InstallParams params) { - super(params.originFile, params.originTrusted, params.observer, params.flags, + super(params.originFile, params.originStaged, params.observer, params.flags, params.installerPackageName, params.getManifestDigest(), params.getUser(), params.packageInstructionSetOverride, params.packageAbiOverride); } @@ -9318,7 +9323,7 @@ public class PackageManagerService extends IPackageManager.Stub { /** New install from existing */ AsecInstallArgs(File originPackageFile, String cid, String instructionSet, boolean isExternal, boolean isForwardLocked) { - super(originPackageFile, true, null, (isExternal ? INSTALL_EXTERNAL : 0) + super(originPackageFile, false, null, (isExternal ? INSTALL_EXTERNAL : 0) | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null, instructionSet, null); this.cid = cid; @@ -10082,6 +10087,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { pkg = pp.parsePackage(tmpPackageFile, parseFlags); } catch (PackageParserException e) { + Slog.e(TAG, "Failed during install: " + e); res.returnCode = e.error; return; } @@ -10098,6 +10104,7 @@ public class PackageManagerService extends IPackageManager.Stub { pp.collectCertificates(pkg, parseFlags); pp.collectManifestDigest(pkg); } catch (PackageParserException e) { + Slog.e(TAG, "Failed during install: " + e); res.returnCode = e.error; return; } @@ -10276,63 +10283,9 @@ public class PackageManagerService extends IPackageManager.Stub { return name.startsWith("vmdl") && name.endsWith(".tmp"); } }; - deleteTempPackageFilesInDirectory(mAppInstallDir, filter); - deleteTempPackageFilesInDirectory(mDrmAppPrivateInstallDir, filter); - } - - private static final void deleteTempPackageFilesInDirectory(File directory, - FilenameFilter filter) { - final File[] files = directory.listFiles(filter); - if (!ArrayUtils.isEmpty(files)) { - for (File file : files) { - if (file.isDirectory()) { - FileUtils.deleteContents(file); - file.delete(); - } else if (file.isFile()) { - file.delete(); - } - } - } - } - - private File createTempPackageDir(File installDir) throws IOException { - int n = 0; - while (n++ < 32) { - final File file = new File(installDir, "vmdl" + mTempFileRandom.nextInt() + ".tmp"); - try { - Os.mkdir(file.getAbsolutePath(), 0755); - Os.chmod(file.getAbsolutePath(), 0755); - if (!SELinux.restorecon(file)) { - throw new IOException("Failed to restorecon"); - } - return file; - } catch (ErrnoException e) { - if (e.errno == EEXIST) continue; - throw e.rethrowAsIOException(); - } - } - throw new IOException("Failed to create temp directory"); - } - - private File createTempPackageFile(File installDir) throws IOException { - int n = 0; - while (n++ < 32) { - final File file = new File(installDir, "vmdl" + mTempFileRandom.nextInt() + ".tmp"); - try { - final FileDescriptor fd = Os.open(file.getAbsolutePath(), - O_RDWR | O_CREAT | O_EXCL, 0644); - IoUtils.closeQuietly(fd); - Os.chmod(file.getAbsolutePath(), 0644); - if (!SELinux.restorecon(file)) { - throw new IOException("Failed to restorecon"); - } - return file; - } catch (ErrnoException e) { - if (e.errno == EEXIST) continue; - throw e.rethrowAsIOException(); - } + for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) { + file.delete(); } - throw new IOException("Failed to create temp file"); } @Override |