Move some fields/methods into StagedSession (2/n)
These members are staged session exclusive and should be moved into the class. Bug: 166694095 Test: atest StagedInstallTest Change-Id: I7e80c13f14a6fc70054ac79ac37857f1a7914e87
This commit is contained in:
@@ -429,22 +429,45 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
@GuardedBy("mLock")
|
||||
private ArrayMap<String, List<CertifiedChecksum>> mChecksums = new ArrayMap<>();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mStagedSessionApplied;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mStagedSessionReady;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mStagedSessionFailed;
|
||||
@GuardedBy("mLock")
|
||||
private int mStagedSessionErrorCode = SessionInfo.STAGED_SESSION_NO_ERROR;
|
||||
@GuardedBy("mLock")
|
||||
private String mStagedSessionErrorMessage;
|
||||
|
||||
@Nullable
|
||||
final StagedSession mStagedSession;
|
||||
|
||||
@VisibleForTesting
|
||||
public class StagedSession implements StagingManager.StagedSession {
|
||||
@GuardedBy("mLock")
|
||||
private boolean mSessionApplied;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mSessionReady;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mSessionFailed;
|
||||
@GuardedBy("mLock")
|
||||
private int mSessionErrorCode = SessionInfo.STAGED_SESSION_NO_ERROR;
|
||||
@GuardedBy("mLock")
|
||||
private String mSessionErrorMessage;
|
||||
|
||||
/**
|
||||
* The callback to run when pre-reboot verification has ended. Used by {@link #abandon()}
|
||||
* to delay session clean-up until it is safe to do so.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private Runnable mPendingAbandonCallback;
|
||||
/**
|
||||
* {@code true} if pre-reboot verification is ongoing which means it is not safe for
|
||||
* {@link #abandon()} to clean up staging directories.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private boolean mInPreRebootVerification;
|
||||
|
||||
StagedSession(boolean isReady, boolean isApplied, boolean isFailed, int errorCode,
|
||||
String errorMessage) {
|
||||
mSessionReady = isReady;
|
||||
mSessionApplied = isApplied;
|
||||
mSessionFailed = isFailed;
|
||||
mSessionErrorCode = errorCode;
|
||||
mSessionErrorMessage = errorMessage != null ? errorMessage : "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StagingManager.StagedSession> getChildSessions() {
|
||||
if (!params.isMultiPackage) {
|
||||
@@ -482,7 +505,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
@Override
|
||||
public boolean containsApexSession() {
|
||||
return PackageInstallerSession.this.containsApexSession();
|
||||
return sessionContains((s) -> s.isApexSession());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -492,17 +515,52 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
@Override
|
||||
public void setSessionReady() {
|
||||
setStagedSessionReady();
|
||||
synchronized (mLock) {
|
||||
// Do not allow destroyed/failed staged session to change state
|
||||
if (mDestroyed || mSessionFailed) return;
|
||||
mSessionReady = true;
|
||||
mSessionApplied = false;
|
||||
mSessionFailed = false;
|
||||
mSessionErrorCode = SessionInfo.STAGED_SESSION_NO_ERROR;
|
||||
mSessionErrorMessage = "";
|
||||
}
|
||||
mCallback.onStagedSessionChanged(PackageInstallerSession.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionFailed(int errorCode, String errorMessage) {
|
||||
setStagedSessionFailed(errorCode, errorMessage);
|
||||
List<PackageInstallerSession> childSessions;
|
||||
synchronized (mLock) {
|
||||
// Do not allow destroyed/failed staged session to change state
|
||||
if (mDestroyed || mSessionFailed) return;
|
||||
mSessionReady = false;
|
||||
mSessionApplied = false;
|
||||
mSessionFailed = true;
|
||||
mSessionErrorCode = errorCode;
|
||||
mSessionErrorMessage = errorMessage;
|
||||
Slog.d(TAG, "Marking session " + sessionId + " as failed: " + errorMessage);
|
||||
childSessions = getChildSessionsLocked();
|
||||
}
|
||||
cleanStageDir(childSessions);
|
||||
mCallback.onStagedSessionChanged(PackageInstallerSession.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionApplied() {
|
||||
setStagedSessionApplied();
|
||||
List<PackageInstallerSession> childSessions;
|
||||
synchronized (mLock) {
|
||||
// Do not allow destroyed/failed staged session to change state
|
||||
if (mDestroyed || mSessionFailed) return;
|
||||
mSessionReady = false;
|
||||
mSessionApplied = true;
|
||||
mSessionFailed = false;
|
||||
mSessionErrorCode = SessionInfo.STAGED_SESSION_NO_ERROR;
|
||||
mSessionErrorMessage = "";
|
||||
Slog.d(TAG, "Marking session " + sessionId + " as applied");
|
||||
childSessions = getChildSessionsLocked();
|
||||
}
|
||||
cleanStageDir(childSessions);
|
||||
mCallback.onStagedSessionChanged(PackageInstallerSession.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -510,10 +568,35 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
return PackageInstallerSession.this.containsApkSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs apks of staged session while skipping the verification process for a committed
|
||||
* and ready session.
|
||||
*/
|
||||
@Override
|
||||
public void installSession(IntentSender statusReceiver) {
|
||||
installStagedSession(statusReceiver);
|
||||
assertCallerIsOwnerOrRootOrSystemLocked();
|
||||
Preconditions.checkArgument(!hasParentSessionId()); // Don't allow installing child
|
||||
// sessions
|
||||
Preconditions.checkArgument(isCommitted() && isSessionReady());
|
||||
|
||||
// Since staged sessions are installed during boot, the original reference to status
|
||||
// receiver from the owner has already been lost. We can safely replace it with a
|
||||
// status receiver from the system without effecting the flow.
|
||||
updateRemoteStatusReceiver(statusReceiver);
|
||||
install();
|
||||
}
|
||||
|
||||
private void updateRemoteStatusReceiver(IntentSender remoteStatusReceiver) {
|
||||
synchronized (mLock) {
|
||||
mRemoteStatusReceiver = remoteStatusReceiver;
|
||||
if (isMultiPackage()) {
|
||||
final IntentSender childIntentSender = new ChildStatusIntentReceiver(
|
||||
mChildSessions.clone(), remoteStatusReceiver).getIntentSender();
|
||||
for (int i = mChildSessions.size() - 1; i >= 0; --i) {
|
||||
mChildSessions.valueAt(i).mRemoteStatusReceiver = childIntentSender;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -533,7 +616,9 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
@Override
|
||||
public boolean isInTerminalState() {
|
||||
return isStagedAndInTerminalState();
|
||||
synchronized (mLock) {
|
||||
return mSessionApplied || mSessionFailed;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -553,54 +638,135 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
@Override
|
||||
public boolean isSessionReady() {
|
||||
return isStagedSessionReady();
|
||||
synchronized (mLock) {
|
||||
return mSessionReady;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSessionApplied() {
|
||||
return isStagedSessionApplied();
|
||||
synchronized (mLock) {
|
||||
return mSessionApplied;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSessionFailed() {
|
||||
return isStagedSessionFailed();
|
||||
synchronized (mLock) {
|
||||
return mSessionFailed;
|
||||
}
|
||||
}
|
||||
|
||||
@StagedSessionErrorCode int getSessionErrorCode() {
|
||||
synchronized (mLock) {
|
||||
return mSessionErrorCode;
|
||||
}
|
||||
}
|
||||
|
||||
String getSessionErrorMessage() {
|
||||
synchronized (mLock) {
|
||||
return mSessionErrorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abandon() {
|
||||
PackageInstallerSession.this.abandon();
|
||||
final Runnable r;
|
||||
synchronized (mLock) {
|
||||
assertNotChildLocked("StagedSession#abandon");
|
||||
assertCallerIsOwnerOrRootLocked();
|
||||
if (isInTerminalState()) {
|
||||
// We keep the session in the database if it's in a finalized state. It will be
|
||||
// removed by PackageInstallerService when the last update time is old enough.
|
||||
// Also, in such cases cleanStageDir() has already been executed so no need to
|
||||
// do it now.
|
||||
return;
|
||||
}
|
||||
mDestroyed = true;
|
||||
boolean isCommitted = mCommitted;
|
||||
List<PackageInstallerSession> childSessions = getChildSessionsLocked();
|
||||
r = () -> {
|
||||
assertNotLocked("abandonStaged");
|
||||
if (isCommitted) {
|
||||
mStagingManager.abortCommittedSession(this);
|
||||
}
|
||||
cleanStageDir(childSessions);
|
||||
destroyInternal();
|
||||
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
|
||||
maybeCleanUpChildSessions();
|
||||
};
|
||||
if (mInPreRebootVerification) {
|
||||
// Pre-reboot verification is ongoing, not safe to clean up the session yet.
|
||||
mPendingAbandonCallback = r;
|
||||
mCallback.onStagedSessionChanged(PackageInstallerSession.this);
|
||||
return;
|
||||
}
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notified by the staging manager that pre-reboot verification is about to start. The
|
||||
* return value should be checked to decide whether it is OK to start pre-reboot
|
||||
* verification. In the case of a destroyed session, {@code false} is returned and there is
|
||||
* no need to start pre-reboot verification.
|
||||
*/
|
||||
@Override
|
||||
public boolean notifyStartPreRebootVerification() {
|
||||
return notifyStagedStartPreRebootVerification();
|
||||
synchronized (mLock) {
|
||||
if (mInPreRebootVerification) {
|
||||
throw new IllegalStateException("Pre-reboot verification has started");
|
||||
}
|
||||
if (mDestroyed) {
|
||||
return false;
|
||||
}
|
||||
mInPreRebootVerification = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notified by the staging manager that pre-reboot verification has ended. Now it is safe to
|
||||
* clean up the session if {@link #abandon()} has been called previously.
|
||||
*/
|
||||
@Override
|
||||
public void notifyEndPreRebootVerification() {
|
||||
notifyStagedEndPreRebootVerification();
|
||||
synchronized (mLock) {
|
||||
if (!mInPreRebootVerification) {
|
||||
throw new IllegalStateException("Pre-reboot verification not started");
|
||||
}
|
||||
mInPreRebootVerification = false;
|
||||
}
|
||||
dispatchPendingAbandonCallback();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes verification process for non-final committed staged session.
|
||||
*
|
||||
* Useful if a device gets rebooted before verification is complete and we need to restart
|
||||
* the verification.
|
||||
*/
|
||||
@Override
|
||||
public void verifySession() {
|
||||
verifyStagedSession();
|
||||
assertCallerIsOwnerOrRootOrSystemLocked();
|
||||
Preconditions.checkArgument(isCommitted());
|
||||
Preconditions.checkArgument(isStaged());
|
||||
Preconditions.checkArgument(!mSessionApplied && !mSessionFailed);
|
||||
verify();
|
||||
}
|
||||
|
||||
private void dispatchPendingAbandonCallback() {
|
||||
final Runnable callback;
|
||||
synchronized (mLock) {
|
||||
callback = mPendingAbandonCallback;
|
||||
mPendingAbandonCallback = null;
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The callback to run when pre-reboot verification has ended. Used by {@link #abandonStaged()}
|
||||
* to delay session clean-up until it is safe to do so.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
@Nullable
|
||||
private Runnable mPendingAbandonCallback;
|
||||
/**
|
||||
* {@code true} if pre-reboot verification is ongoing which means it is not safe for
|
||||
* {@link #abandon()} to clean up staging directories.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private boolean mInPreRebootVerification;
|
||||
|
||||
/**
|
||||
* Path to the validated base APK for this session, which may point at an
|
||||
* APK inside the session (when the session defines the base), or it may
|
||||
@@ -838,13 +1004,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
mPrepared = prepared;
|
||||
mCommitted = committed;
|
||||
mDestroyed = destroyed;
|
||||
mStagedSessionReady = isReady;
|
||||
mStagedSessionFailed = isFailed;
|
||||
mStagedSessionApplied = isApplied;
|
||||
mStagedSessionErrorCode = stagedSessionErrorCode;
|
||||
mStagedSessionErrorMessage =
|
||||
stagedSessionErrorMessage != null ? stagedSessionErrorMessage : "";
|
||||
mStagedSession = params.isStaged ? new StagedSession() : null;
|
||||
mStagedSession = params.isStaged ? new StagedSession(isReady, isApplied, isFailed,
|
||||
stagedSessionErrorCode, stagedSessionErrorMessage) : null;
|
||||
|
||||
if (isDataLoaderInstallation()) {
|
||||
if (isApexSession()) {
|
||||
@@ -937,10 +1098,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
info.rollbackDataPolicy = params.rollbackDataPolicy;
|
||||
info.parentSessionId = mParentSessionId;
|
||||
info.childSessionIds = getChildSessionIdsLocked();
|
||||
info.isStagedSessionApplied = mStagedSessionApplied;
|
||||
info.isStagedSessionReady = mStagedSessionReady;
|
||||
info.isStagedSessionFailed = mStagedSessionFailed;
|
||||
info.setStagedSessionErrorCode(mStagedSessionErrorCode, mStagedSessionErrorMessage);
|
||||
info.isStagedSessionApplied = isStagedSessionApplied();
|
||||
info.isStagedSessionReady = isStagedSessionReady();
|
||||
info.isStagedSessionFailed = isStagedSessionFailed();
|
||||
info.setStagedSessionErrorCode(getStagedSessionErrorCode(),
|
||||
getStagedSessionErrorMessage());
|
||||
info.createdMillis = createdMillis;
|
||||
info.updatedMillis = updatedMillis;
|
||||
}
|
||||
@@ -975,9 +1137,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
/** Returns true if a staged session has reached a final state and can be forgotten about */
|
||||
public boolean isStagedAndInTerminalState() {
|
||||
synchronized (mLock) {
|
||||
return params.isStaged && (mStagedSessionApplied || mStagedSessionFailed);
|
||||
}
|
||||
return params.isStaged && mStagedSession.isInTerminalState();
|
||||
}
|
||||
|
||||
private void assertNotLocked(String cookie) {
|
||||
@@ -1872,7 +2032,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
// Session is sealed and committed but could not be verified, we need to destroy it.
|
||||
destroyInternal();
|
||||
if (isStaged()) {
|
||||
setStagedSessionFailed(
|
||||
mStagedSession.setSessionFailed(
|
||||
SessionInfo.STAGED_SESSION_VERIFICATION_FAILED, msgWithErrorCode);
|
||||
// TODO(b/136257624): Remove this once all verification logic has been transferred out
|
||||
// of StagingManager.
|
||||
@@ -2011,21 +2171,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
verify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes verification process for non-final committed staged session.
|
||||
*
|
||||
* Useful if a device gets rebooted before verification is complete and we need to restart the
|
||||
* verification.
|
||||
*/
|
||||
void verifyStagedSession() {
|
||||
assertCallerIsOwnerOrRootOrSystemLocked();
|
||||
Preconditions.checkArgument(isCommitted());
|
||||
Preconditions.checkArgument(isStaged());
|
||||
Preconditions.checkArgument(!mStagedSessionApplied && !mStagedSessionFailed);
|
||||
|
||||
verify();
|
||||
}
|
||||
|
||||
private void verify() {
|
||||
try {
|
||||
verifyNonStaged();
|
||||
@@ -2080,36 +2225,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs apks of staged session while skipping the verification process for a committed and
|
||||
* ready session.
|
||||
*/
|
||||
void installStagedSession(IntentSender statusReceiver) {
|
||||
assertCallerIsOwnerOrRootOrSystemLocked();
|
||||
Preconditions.checkArgument(!hasParentSessionId()); // Don't allow installing child sessions
|
||||
Preconditions.checkArgument(isCommitted() && isStagedSessionReady());
|
||||
|
||||
// Since staged sessions are installed during boot, the original reference to status
|
||||
// receiver from the owner has already been lost. We can safely replace it with a
|
||||
// status receiver from the system without effecting the flow.
|
||||
updateRemoteStatusReceiver(statusReceiver);
|
||||
install();
|
||||
}
|
||||
|
||||
private void updateRemoteStatusReceiver(IntentSender remoteStatusReceiver) {
|
||||
synchronized (mLock) {
|
||||
mRemoteStatusReceiver = remoteStatusReceiver;
|
||||
if (isMultiPackage()) {
|
||||
final IntentSender childIntentSender =
|
||||
new ChildStatusIntentReceiver(mChildSessions.clone(), remoteStatusReceiver)
|
||||
.getIntentSender();
|
||||
for (int i = mChildSessions.size() - 1; i >= 0; --i) {
|
||||
mChildSessions.valueAt(i).mRemoteStatusReceiver = childIntentSender;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void install() {
|
||||
try {
|
||||
installNonStaged();
|
||||
@@ -2518,10 +2633,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean containsApexSession() {
|
||||
return sessionContains((s) -> s.isApexSession());
|
||||
}
|
||||
|
||||
boolean containsApkSession() {
|
||||
return sessionContains((s) -> !s.isApexSession());
|
||||
}
|
||||
@@ -3343,6 +3454,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
private void abandonNonStaged() {
|
||||
synchronized (mLock) {
|
||||
assertNotChildLocked("abandonNonStaged");
|
||||
assertCallerIsOwnerOrRootLocked();
|
||||
if (mRelinquished) {
|
||||
if (LOGD) Slog.d(TAG, "Ignoring abandon after commit relinquished control");
|
||||
@@ -3354,98 +3466,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
maybeCleanUpChildSessions();
|
||||
}
|
||||
|
||||
private void abandonStaged() {
|
||||
final Runnable r;
|
||||
synchronized (mLock) {
|
||||
assertCallerIsOwnerOrRootLocked();
|
||||
if (isStagedAndInTerminalState()) {
|
||||
// We keep the session in the database if it's in a finalized state. It will be
|
||||
// removed by PackageInstallerService when the last update time is old enough.
|
||||
// Also, in such cases cleanStageDir() has already been executed so no need to
|
||||
// do it now.
|
||||
return;
|
||||
}
|
||||
mDestroyed = true;
|
||||
boolean isCommitted = mCommitted;
|
||||
List<PackageInstallerSession> childSessions = getChildSessionsLocked();
|
||||
r = () -> {
|
||||
assertNotLocked("abandonStaged");
|
||||
if (isCommitted) {
|
||||
mStagingManager.abortCommittedSession(mStagedSession);
|
||||
}
|
||||
cleanStageDir(childSessions);
|
||||
destroyInternal();
|
||||
dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null);
|
||||
maybeCleanUpChildSessions();
|
||||
};
|
||||
if (mInPreRebootVerification) {
|
||||
// Pre-reboot verification is ongoing. It is not safe to clean up the session yet.
|
||||
mPendingAbandonCallback = r;
|
||||
mCallback.onStagedSessionChanged(this);
|
||||
return;
|
||||
}
|
||||
@GuardedBy("mLock")
|
||||
private void assertNotChildLocked(String cookie) {
|
||||
if (hasParentSessionId()) {
|
||||
throw new IllegalStateException(cookie + " can't be called on a child session, id="
|
||||
+ sessionId + " parentId=" + getParentSessionId());
|
||||
}
|
||||
r.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abandon() {
|
||||
if (hasParentSessionId()) {
|
||||
throw new IllegalStateException(
|
||||
"Session " + sessionId + " is a child of multi-package session "
|
||||
+ getParentSessionId() + " and may not be abandoned directly.");
|
||||
}
|
||||
if (params.isStaged) {
|
||||
abandonStaged();
|
||||
mStagedSession.abandon();
|
||||
} else {
|
||||
abandonNonStaged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notified by the staging manager that pre-reboot verification is about to start. The return
|
||||
* value should be checked to decide whether it is OK to start pre-reboot verification. In
|
||||
* the case of a destroyed session, {@code false} is returned and there is no need to start
|
||||
* pre-reboot verification.
|
||||
*/
|
||||
boolean notifyStagedStartPreRebootVerification() {
|
||||
synchronized (mLock) {
|
||||
if (mInPreRebootVerification) {
|
||||
throw new IllegalStateException("Pre-reboot verification has started");
|
||||
}
|
||||
if (mDestroyed) {
|
||||
return false;
|
||||
}
|
||||
mInPreRebootVerification = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchPendingAbandonCallback() {
|
||||
final Runnable callback;
|
||||
synchronized (mLock) {
|
||||
callback = mPendingAbandonCallback;
|
||||
mPendingAbandonCallback = null;
|
||||
}
|
||||
if (callback != null) {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Notified by the staging manager that pre-reboot verification has ended. Now it is safe to
|
||||
* clean up the session if {@link #abandon()} has been called previously.
|
||||
*/
|
||||
void notifyStagedEndPreRebootVerification() {
|
||||
synchronized (mLock) {
|
||||
if (!mInPreRebootVerification) {
|
||||
throw new IllegalStateException("Pre-reboot verification not started");
|
||||
}
|
||||
mInPreRebootVerification = false;
|
||||
}
|
||||
dispatchPendingAbandonCallback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultiPackage() {
|
||||
return params.isMultiPackage;
|
||||
@@ -3930,89 +3967,30 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
void setStagedSessionReady() {
|
||||
synchronized (mLock) {
|
||||
// Do not allow destroyed/failed staged session to change state
|
||||
if (mDestroyed || mStagedSessionFailed) return;
|
||||
mStagedSessionReady = true;
|
||||
mStagedSessionApplied = false;
|
||||
mStagedSessionFailed = false;
|
||||
mStagedSessionErrorCode = SessionInfo.STAGED_SESSION_NO_ERROR;
|
||||
mStagedSessionErrorMessage = "";
|
||||
}
|
||||
mCallback.onStagedSessionChanged(this);
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
void setStagedSessionFailed(@StagedSessionErrorCode int errorCode, String errorMessage) {
|
||||
List<PackageInstallerSession> childSessions;
|
||||
synchronized (mLock) {
|
||||
// Do not allow destroyed/failed staged session to change state
|
||||
if (mDestroyed || mStagedSessionFailed) return;
|
||||
mStagedSessionReady = false;
|
||||
mStagedSessionApplied = false;
|
||||
mStagedSessionFailed = true;
|
||||
mStagedSessionErrorCode = errorCode;
|
||||
mStagedSessionErrorMessage = errorMessage;
|
||||
Slog.d(TAG, "Marking session " + sessionId + " as failed: " + errorMessage);
|
||||
childSessions = getChildSessionsLocked();
|
||||
}
|
||||
cleanStageDir(childSessions);
|
||||
mCallback.onStagedSessionChanged(this);
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
void setStagedSessionApplied() {
|
||||
List<PackageInstallerSession> childSessions;
|
||||
synchronized (mLock) {
|
||||
// Do not allow destroyed/failed staged session to change state
|
||||
if (mDestroyed || mStagedSessionFailed) return;
|
||||
mStagedSessionReady = false;
|
||||
mStagedSessionApplied = true;
|
||||
mStagedSessionFailed = false;
|
||||
mStagedSessionErrorCode = SessionInfo.STAGED_SESSION_NO_ERROR;
|
||||
mStagedSessionErrorMessage = "";
|
||||
Slog.d(TAG, "Marking session " + sessionId + " as applied");
|
||||
childSessions = getChildSessionsLocked();
|
||||
}
|
||||
cleanStageDir(childSessions);
|
||||
mCallback.onStagedSessionChanged(this);
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
boolean isStagedSessionReady() {
|
||||
synchronized (mLock) {
|
||||
return mStagedSessionReady;
|
||||
}
|
||||
return params.isStaged && mStagedSession.isSessionReady();
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
boolean isStagedSessionApplied() {
|
||||
synchronized (mLock) {
|
||||
return mStagedSessionApplied;
|
||||
}
|
||||
return params.isStaged && mStagedSession.isSessionApplied();
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
boolean isStagedSessionFailed() {
|
||||
synchronized (mLock) {
|
||||
return mStagedSessionFailed;
|
||||
}
|
||||
return params.isStaged && mStagedSession.isSessionFailed();
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@StagedSessionErrorCode int getStagedSessionErrorCode() {
|
||||
synchronized (mLock) {
|
||||
return mStagedSessionErrorCode;
|
||||
}
|
||||
return params.isStaged ? mStagedSession.getSessionErrorCode()
|
||||
: SessionInfo.STAGED_SESSION_NO_ERROR;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
String getStagedSessionErrorMessage() {
|
||||
synchronized (mLock) {
|
||||
return mStagedSessionErrorMessage;
|
||||
}
|
||||
return params.isStaged ? mStagedSession.getSessionErrorMessage() : "";
|
||||
}
|
||||
|
||||
private void destroyInternal() {
|
||||
@@ -4109,11 +4087,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
pw.printPair("params.isStaged", params.isStaged);
|
||||
pw.printPair("mParentSessionId", mParentSessionId);
|
||||
pw.printPair("mChildSessionIds", getChildSessionIdsLocked());
|
||||
pw.printPair("mStagedSessionApplied", mStagedSessionApplied);
|
||||
pw.printPair("mStagedSessionFailed", mStagedSessionFailed);
|
||||
pw.printPair("mStagedSessionReady", mStagedSessionReady);
|
||||
pw.printPair("mStagedSessionErrorCode", mStagedSessionErrorCode);
|
||||
pw.printPair("mStagedSessionErrorMessage", mStagedSessionErrorMessage);
|
||||
pw.printPair("mStagedSessionApplied", isStagedSessionApplied());
|
||||
pw.printPair("mStagedSessionFailed", isStagedSessionFailed());
|
||||
pw.printPair("mStagedSessionReady", isStagedSessionReady());
|
||||
pw.printPair("mStagedSessionErrorCode", getStagedSessionErrorCode());
|
||||
pw.printPair("mStagedSessionErrorMessage", getStagedSessionErrorMessage());
|
||||
pw.println();
|
||||
|
||||
pw.decreaseIndent();
|
||||
@@ -4279,12 +4257,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
|
||||
writeBooleanAttribute(out, ATTR_MULTI_PACKAGE, params.isMultiPackage);
|
||||
writeBooleanAttribute(out, ATTR_STAGED_SESSION, params.isStaged);
|
||||
writeBooleanAttribute(out, ATTR_IS_READY, mStagedSessionReady);
|
||||
writeBooleanAttribute(out, ATTR_IS_FAILED, mStagedSessionFailed);
|
||||
writeBooleanAttribute(out, ATTR_IS_APPLIED, mStagedSessionApplied);
|
||||
out.attributeInt(null, ATTR_STAGED_SESSION_ERROR_CODE, mStagedSessionErrorCode);
|
||||
writeBooleanAttribute(out, ATTR_IS_READY, isStagedSessionReady());
|
||||
writeBooleanAttribute(out, ATTR_IS_FAILED, isStagedSessionFailed());
|
||||
writeBooleanAttribute(out, ATTR_IS_APPLIED, isStagedSessionApplied());
|
||||
out.attributeInt(null, ATTR_STAGED_SESSION_ERROR_CODE, getStagedSessionErrorCode());
|
||||
writeStringAttribute(out, ATTR_STAGED_SESSION_ERROR_MESSAGE,
|
||||
mStagedSessionErrorMessage);
|
||||
getStagedSessionErrorMessage());
|
||||
// TODO(patb,109941548): avoid writing to xml and instead infer / validate this after
|
||||
// we've read all sessions.
|
||||
out.attributeInt(null, ATTR_PARENT_SESSION_ID, mParentSessionId);
|
||||
|
||||
Reference in New Issue
Block a user