Loading services/core/java/com/android/server/pm/PackageInstallerSession.java +126 −37 Original line number Diff line number Diff line Loading @@ -1746,7 +1746,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { List<PackageInstallerSession> childSessions = getChildSessionsNotLocked(); try { installNonStaged(childSessions); verifyNonStaged(childSessions); } catch (PackageManagerException e) { final String completeMsg = ExceptionUtils.getCompleteMessage(e); Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg); Loading @@ -1755,10 +1755,51 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } private void verifyNonStaged(List<PackageInstallerSession> childSessions) throws PackageManagerException { final PackageManagerService.ActiveInstallSession verifyingSession = makeSessionActiveForVerification(); if (verifyingSession == null) { return; } if (isMultiPackage()) { List<PackageManagerService.ActiveInstallSession> verifyingChildSessions = new ArrayList<>(childSessions.size()); boolean success = true; PackageManagerException failure = null; for (int i = 0; i < childSessions.size(); ++i) { final PackageInstallerSession session = childSessions.get(i); try { final PackageManagerService.ActiveInstallSession verifyingChildSession = session.makeSessionActiveForVerification(); if (verifyingChildSession != null) { verifyingChildSessions.add(verifyingChildSession); } } catch (PackageManagerException e) { failure = e; success = false; } } if (!success) { final IntentSender statusReceiver; synchronized (mLock) { statusReceiver = mRemoteStatusReceiver; } sendOnPackageInstalled(mContext, statusReceiver, sessionId, isInstallerDeviceOwnerOrAffiliatedProfileOwner(), userId, null, failure.error, failure.getLocalizedMessage(), null); return; } mPm.verifyStage(verifyingSession, verifyingChildSessions); } else { mPm.verifyStage(verifyingSession); } } private void installNonStaged(List<PackageInstallerSession> childSessions) throws PackageManagerException { final PackageManagerService.ActiveInstallSession installingSession = makeSessionActive(); makeSessionActiveForInstall(); if (installingSession == null) { return; } Loading @@ -1771,7 +1812,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final PackageInstallerSession session = childSessions.get(i); try { final PackageManagerService.ActiveInstallSession installingChildSession = session.makeSessionActive(); session.makeSessionActiveForInstall(); if (installingChildSession != null) { installingChildSessions.add(installingChildSession); } Loading @@ -1797,11 +1838,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } /** * Stages this session for install and returns a * Stages this session for verification and returns a * {@link PackageManagerService.ActiveInstallSession} representing this new staged state or null * in case permissions need to be requested before install can proceed. * in case permissions need to be requested before verification can proceed. */ private PackageManagerService.ActiveInstallSession makeSessionActive() private PackageManagerService.ActiveInstallSession makeSessionActiveForVerification() throws PackageManagerException { assertNotLocked("makeSessionActive"); Loading @@ -1820,6 +1861,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } // TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc if (!params.isMultiPackage && needToAskForPermissions()) { // User needs to confirm installation; // give installer an intent they can use to involve Loading @@ -1841,12 +1883,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } synchronized (mLock) { return makeSessionActiveLocked(); return makeSessionActiveForVerificationLocked(); } } @GuardedBy("mLock") private PackageManagerService.ActiveInstallSession makeSessionActiveLocked() private PackageManagerService.ActiveInstallSession makeSessionActiveForVerificationLocked() throws PackageManagerException { if (!params.isMultiPackage) { Objects.requireNonNull(mPackageName); Loading Loading @@ -1910,9 +1952,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs()); } // We've reached point of no return; call into PMS to install the stage. // Regardless of success or failure we always destroy session. final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() { final IPackageInstallObserver2 localObserver; if (!hasParentSessionId()) { // Avoid attaching this observer to child session since they won't use it. localObserver = new IPackageInstallObserver2.Stub() { @Override public void onUserActionRequired(Intent intent) { throw new IllegalStateException(); Loading @@ -1921,18 +1964,71 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) { if (returnCode == PackageManager.INSTALL_SUCCEEDED) { onVerificationComplete(); } else { destroyInternal(); dispatchSessionFinished(returnCode, msg, extras); } } }; } else { localObserver = null; } // An observer through which PMS returns the result of verification // TODO(samiul): We are temporarily assigning two observer to ActiveInstallSession. One for // installation and one for verification. This will be fixed within next few CLs. final IPackageInstallObserver2 sessionVerificationObserver; if (!hasParentSessionId()) { // Avoid attaching this observer to child session since they won't use it. sessionVerificationObserver = new IPackageInstallObserver2.Stub() { final UserHandle user; if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { user = UserHandle.ALL; } else { user = new UserHandle(userId); } mRelinquished = true; // TODO(159331446): create VerificationParams directly by passing information that is // required for verification only return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver, sessionId, params, mInstallerUid, mInstallSource, user, mSigningDetails); } private void onVerificationComplete() { if ((params.installFlags & PackageManager.INSTALL_DRY_RUN) != 0) { destroyInternal(); dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Dry run", new Bundle()); return; } List<PackageInstallerSession> childSessions = getChildSessionsNotLocked(); try { installNonStaged(childSessions); } catch (PackageManagerException e) { final String completeMsg = ExceptionUtils.getCompleteMessage(e); Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg); destroyInternal(); dispatchSessionFinished(e.error, completeMsg, null); } } /** * Stages this session for install and returns a * {@link PackageManagerService.ActiveInstallSession} representing this new staged state. */ private PackageManagerService.ActiveInstallSession makeSessionActiveForInstall() throws PackageManagerException { synchronized (mLock) { if (mDestroyed) { throw new PackageManagerException( INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed"); } if (!mSealed) { throw new PackageManagerException( INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed"); } } // We've reached point of no return; call into PMS to install the stage. // Regardless of success or failure we always destroy session. final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() { @Override public void onUserActionRequired(Intent intent) { throw new IllegalStateException(); Loading @@ -1941,18 +2037,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) { if (returnCode == PackageManager.INSTALL_SUCCEEDED) { // TODO(samiul): In future, packages will not be installed immediately after // verification. Package verification will return control back to here, // and we will have call into PMS again to install package. // // For now, this is a no op. } destroyInternal(); dispatchSessionFinished(returnCode, msg, extras); } }; } else { sessionVerificationObserver = null; } final UserHandle user; if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { Loading @@ -1961,11 +2049,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { user = new UserHandle(userId); } mRelinquished = true; return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver, sessionVerificationObserver, sessionId, params, mInstallerUid, mInstallSource, user, synchronized (mLock) { return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver, sessionId, params, mInstallerUid, mInstallSource, user, mSigningDetails); } } private static void maybeRenameFile(File from, File to) throws PackageManagerException { if (!from.equals(to)) { Loading services/core/java/com/android/server/pm/PackageManagerService.java +203 −100 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/pm/PackageVerificationState.java +4 −4 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.server.pm; import android.content.pm.PackageManager; import android.util.SparseBooleanArray; import com.android.server.pm.PackageManagerService.InstallParams; import com.android.server.pm.PackageManagerService.VerificationParams; /** * Tracks the package verification state for a particular package. Each package verification has a Loading @@ -28,7 +28,7 @@ import com.android.server.pm.PackageManagerService.InstallParams; * sufficient verifiers, then package verification is considered complete. */ class PackageVerificationState { private final InstallParams mParams; private final VerificationParams mParams; private final SparseBooleanArray mSufficientVerifierUids; Loading @@ -50,13 +50,13 @@ class PackageVerificationState { * Create a new package verification state where {@code requiredVerifierUid} is the user ID for * the package that must reply affirmative before things can continue. */ PackageVerificationState(InstallParams params) { PackageVerificationState(VerificationParams params) { mParams = params; mSufficientVerifierUids = new SparseBooleanArray(); mExtendedTimeout = false; } InstallParams getInstallParams() { VerificationParams getVerificationParams() { return mParams; } Loading services/core/java/com/android/server/pm/StagingManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -804,6 +804,7 @@ public class StagingManager { params.isStaged = false; if (preReboot) { params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK; params.installFlags |= PackageManager.INSTALL_DRY_RUN; } final int apkParentSessionId = mPi.createSession( params, session.getInstallerPackageName(), session.getInstallerAttributionTag(), Loading Loading
services/core/java/com/android/server/pm/PackageInstallerSession.java +126 −37 Original line number Diff line number Diff line Loading @@ -1746,7 +1746,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { List<PackageInstallerSession> childSessions = getChildSessionsNotLocked(); try { installNonStaged(childSessions); verifyNonStaged(childSessions); } catch (PackageManagerException e) { final String completeMsg = ExceptionUtils.getCompleteMessage(e); Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg); Loading @@ -1755,10 +1755,51 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } private void verifyNonStaged(List<PackageInstallerSession> childSessions) throws PackageManagerException { final PackageManagerService.ActiveInstallSession verifyingSession = makeSessionActiveForVerification(); if (verifyingSession == null) { return; } if (isMultiPackage()) { List<PackageManagerService.ActiveInstallSession> verifyingChildSessions = new ArrayList<>(childSessions.size()); boolean success = true; PackageManagerException failure = null; for (int i = 0; i < childSessions.size(); ++i) { final PackageInstallerSession session = childSessions.get(i); try { final PackageManagerService.ActiveInstallSession verifyingChildSession = session.makeSessionActiveForVerification(); if (verifyingChildSession != null) { verifyingChildSessions.add(verifyingChildSession); } } catch (PackageManagerException e) { failure = e; success = false; } } if (!success) { final IntentSender statusReceiver; synchronized (mLock) { statusReceiver = mRemoteStatusReceiver; } sendOnPackageInstalled(mContext, statusReceiver, sessionId, isInstallerDeviceOwnerOrAffiliatedProfileOwner(), userId, null, failure.error, failure.getLocalizedMessage(), null); return; } mPm.verifyStage(verifyingSession, verifyingChildSessions); } else { mPm.verifyStage(verifyingSession); } } private void installNonStaged(List<PackageInstallerSession> childSessions) throws PackageManagerException { final PackageManagerService.ActiveInstallSession installingSession = makeSessionActive(); makeSessionActiveForInstall(); if (installingSession == null) { return; } Loading @@ -1771,7 +1812,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final PackageInstallerSession session = childSessions.get(i); try { final PackageManagerService.ActiveInstallSession installingChildSession = session.makeSessionActive(); session.makeSessionActiveForInstall(); if (installingChildSession != null) { installingChildSessions.add(installingChildSession); } Loading @@ -1797,11 +1838,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } /** * Stages this session for install and returns a * Stages this session for verification and returns a * {@link PackageManagerService.ActiveInstallSession} representing this new staged state or null * in case permissions need to be requested before install can proceed. * in case permissions need to be requested before verification can proceed. */ private PackageManagerService.ActiveInstallSession makeSessionActive() private PackageManagerService.ActiveInstallSession makeSessionActiveForVerification() throws PackageManagerException { assertNotLocked("makeSessionActive"); Loading @@ -1820,6 +1861,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } // TODO(b/159331446): Move this to makeSessionActiveForInstall and update javadoc if (!params.isMultiPackage && needToAskForPermissions()) { // User needs to confirm installation; // give installer an intent they can use to involve Loading @@ -1841,12 +1883,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } synchronized (mLock) { return makeSessionActiveLocked(); return makeSessionActiveForVerificationLocked(); } } @GuardedBy("mLock") private PackageManagerService.ActiveInstallSession makeSessionActiveLocked() private PackageManagerService.ActiveInstallSession makeSessionActiveForVerificationLocked() throws PackageManagerException { if (!params.isMultiPackage) { Objects.requireNonNull(mPackageName); Loading Loading @@ -1910,9 +1952,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs()); } // We've reached point of no return; call into PMS to install the stage. // Regardless of success or failure we always destroy session. final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() { final IPackageInstallObserver2 localObserver; if (!hasParentSessionId()) { // Avoid attaching this observer to child session since they won't use it. localObserver = new IPackageInstallObserver2.Stub() { @Override public void onUserActionRequired(Intent intent) { throw new IllegalStateException(); Loading @@ -1921,18 +1964,71 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) { if (returnCode == PackageManager.INSTALL_SUCCEEDED) { onVerificationComplete(); } else { destroyInternal(); dispatchSessionFinished(returnCode, msg, extras); } } }; } else { localObserver = null; } // An observer through which PMS returns the result of verification // TODO(samiul): We are temporarily assigning two observer to ActiveInstallSession. One for // installation and one for verification. This will be fixed within next few CLs. final IPackageInstallObserver2 sessionVerificationObserver; if (!hasParentSessionId()) { // Avoid attaching this observer to child session since they won't use it. sessionVerificationObserver = new IPackageInstallObserver2.Stub() { final UserHandle user; if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { user = UserHandle.ALL; } else { user = new UserHandle(userId); } mRelinquished = true; // TODO(159331446): create VerificationParams directly by passing information that is // required for verification only return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver, sessionId, params, mInstallerUid, mInstallSource, user, mSigningDetails); } private void onVerificationComplete() { if ((params.installFlags & PackageManager.INSTALL_DRY_RUN) != 0) { destroyInternal(); dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Dry run", new Bundle()); return; } List<PackageInstallerSession> childSessions = getChildSessionsNotLocked(); try { installNonStaged(childSessions); } catch (PackageManagerException e) { final String completeMsg = ExceptionUtils.getCompleteMessage(e); Slog.e(TAG, "Commit of session " + sessionId + " failed: " + completeMsg); destroyInternal(); dispatchSessionFinished(e.error, completeMsg, null); } } /** * Stages this session for install and returns a * {@link PackageManagerService.ActiveInstallSession} representing this new staged state. */ private PackageManagerService.ActiveInstallSession makeSessionActiveForInstall() throws PackageManagerException { synchronized (mLock) { if (mDestroyed) { throw new PackageManagerException( INSTALL_FAILED_INTERNAL_ERROR, "Session destroyed"); } if (!mSealed) { throw new PackageManagerException( INSTALL_FAILED_INTERNAL_ERROR, "Session not sealed"); } } // We've reached point of no return; call into PMS to install the stage. // Regardless of success or failure we always destroy session. final IPackageInstallObserver2 localObserver = new IPackageInstallObserver2.Stub() { @Override public void onUserActionRequired(Intent intent) { throw new IllegalStateException(); Loading @@ -1941,18 +2037,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @Override public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) { if (returnCode == PackageManager.INSTALL_SUCCEEDED) { // TODO(samiul): In future, packages will not be installed immediately after // verification. Package verification will return control back to here, // and we will have call into PMS again to install package. // // For now, this is a no op. } destroyInternal(); dispatchSessionFinished(returnCode, msg, extras); } }; } else { sessionVerificationObserver = null; } final UserHandle user; if ((params.installFlags & PackageManager.INSTALL_ALL_USERS) != 0) { Loading @@ -1961,11 +2049,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { user = new UserHandle(userId); } mRelinquished = true; return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver, sessionVerificationObserver, sessionId, params, mInstallerUid, mInstallSource, user, synchronized (mLock) { return new PackageManagerService.ActiveInstallSession(mPackageName, stageDir, localObserver, sessionId, params, mInstallerUid, mInstallSource, user, mSigningDetails); } } private static void maybeRenameFile(File from, File to) throws PackageManagerException { if (!from.equals(to)) { Loading
services/core/java/com/android/server/pm/PackageManagerService.java +203 −100 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/pm/PackageVerificationState.java +4 −4 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.server.pm; import android.content.pm.PackageManager; import android.util.SparseBooleanArray; import com.android.server.pm.PackageManagerService.InstallParams; import com.android.server.pm.PackageManagerService.VerificationParams; /** * Tracks the package verification state for a particular package. Each package verification has a Loading @@ -28,7 +28,7 @@ import com.android.server.pm.PackageManagerService.InstallParams; * sufficient verifiers, then package verification is considered complete. */ class PackageVerificationState { private final InstallParams mParams; private final VerificationParams mParams; private final SparseBooleanArray mSufficientVerifierUids; Loading @@ -50,13 +50,13 @@ class PackageVerificationState { * Create a new package verification state where {@code requiredVerifierUid} is the user ID for * the package that must reply affirmative before things can continue. */ PackageVerificationState(InstallParams params) { PackageVerificationState(VerificationParams params) { mParams = params; mSufficientVerifierUids = new SparseBooleanArray(); mExtendedTimeout = false; } InstallParams getInstallParams() { VerificationParams getVerificationParams() { return mParams; } Loading
services/core/java/com/android/server/pm/StagingManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -804,6 +804,7 @@ public class StagingManager { params.isStaged = false; if (preReboot) { params.installFlags &= ~PackageManager.INSTALL_ENABLE_ROLLBACK; params.installFlags |= PackageManager.INSTALL_DRY_RUN; } final int apkParentSessionId = mPi.createSession( params, session.getInstallerPackageName(), session.getInstallerAttributionTag(), Loading