Fixed NPE in package installer session.
We updated staged sessions to activation failed state when they aren't in terminal state, and device received ota and reboot. This happend before the StagingManager resumes the sessions when the whole set of parent+child sessions have been restored. A parent session probably cannot find the child session, and a null exception could happen. In this change, we do not destroy child sessions before we destroy the parent session. We only destroy a child session directly if we are sure that its parent session doesn't exist. Bug: 147651771 Test: StagedInstallTest Change-Id: Iac6489a04df35f851aa18a91e1dde2d73928b8ec
This commit is contained in:
@@ -259,11 +259,13 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
|
||||
// atomic install which needs to query sessions, which requires lock on mSessions.
|
||||
boolean isDeviceUpgrading = mPm.isDeviceUpgrading();
|
||||
for (PackageInstallerSession session : stagedSessionsToRestore) {
|
||||
if (isDeviceUpgrading && !session.isStagedAndInTerminalState()) {
|
||||
if (!session.isStagedAndInTerminalState() && session.hasParentSessionId()
|
||||
&& getSession(session.getParentSessionId()) == null) {
|
||||
session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
|
||||
"Build fingerprint has changed");
|
||||
"An orphan staged session " + session.sessionId + " is found, "
|
||||
+ "parent " + session.getParentSessionId() + " is missing");
|
||||
}
|
||||
mStagingManager.restoreSession(session);
|
||||
mStagingManager.restoreSession(session, isDeviceUpgrading);
|
||||
}
|
||||
// Broadcasts are not sent while we restore sessions on boot, since no processes would be
|
||||
// ready to listen to them. From now on, we greedily assume that broadcasts requests are
|
||||
|
||||
@@ -889,7 +889,7 @@ public class StagingManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
void restoreSession(@NonNull PackageInstallerSession session) {
|
||||
void restoreSession(@NonNull PackageInstallerSession session, boolean isDeviceUpgrading) {
|
||||
PackageInstallerSession sessionToResume = session;
|
||||
synchronized (mStagedSessions) {
|
||||
mStagedSessions.append(session.sessionId, session);
|
||||
@@ -906,6 +906,13 @@ public class StagingManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
// The preconditions used during pre-reboot verification might have changed when device
|
||||
// is upgrading. Updated staged sessions to activation failed before we resume the session.
|
||||
if (isDeviceUpgrading && !sessionToResume.isStagedAndInTerminalState()) {
|
||||
sessionToResume.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
|
||||
"Build fingerprint has changed");
|
||||
return;
|
||||
}
|
||||
checkStateAndResume(sessionToResume);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user