Add a state for Staged Sessions.
The state is only kept up-to-date for staged sessions. Clients are in charge of checking whether the session has the isStaged bit set, before considering reading the StagedSessionState associated to that session. Test: retrieved mock staged session from a small app and verified state is correctly set. Bug: 118865310 Bug: 112669193 Bug: 120487127 Change-Id: I03590476dc353fee6d6edffb7ae579a9f9664664
This commit is contained in:
@@ -11366,13 +11366,20 @@ package android.content.pm {
|
||||
method public android.net.Uri getReferrerUri();
|
||||
method public int getSessionId();
|
||||
method public long getSize();
|
||||
method public int getStagedSessionErrorCode();
|
||||
method public boolean isActive();
|
||||
method public boolean isMultiPackage();
|
||||
method public boolean isSealed();
|
||||
method public boolean isSessionApplied();
|
||||
method public boolean isSessionFailed();
|
||||
method public boolean isSessionReady();
|
||||
method public boolean isStaged();
|
||||
method public void writeToParcel(android.os.Parcel, int);
|
||||
field public static final int ACTIVATION_FAILED = 2; // 0x2
|
||||
field public static final android.os.Parcelable.Creator<android.content.pm.PackageInstaller.SessionInfo> CREATOR;
|
||||
field public static final int INVALID_ID = -1; // 0xffffffff
|
||||
field public static final int NO_ERROR = 0; // 0x0
|
||||
field public static final int VERIFICATION_FAILED = 1; // 0x1
|
||||
}
|
||||
|
||||
public static class PackageInstaller.SessionParams implements android.os.Parcelable {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package android.content.pm;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.RequiresPermission;
|
||||
@@ -54,6 +55,8 @@ import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
@@ -1594,6 +1597,29 @@ public class PackageInstaller {
|
||||
public static final int INVALID_ID = -1;
|
||||
/** {@hide} */
|
||||
private static final int[] NO_SESSIONS = {};
|
||||
|
||||
/** @hide */
|
||||
@IntDef(value = {NO_ERROR, VERIFICATION_FAILED, ACTIVATION_FAILED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface StagedSessionErrorCode{}
|
||||
/**
|
||||
* Constant indicating that no error occurred during the preparation or the activation of
|
||||
* this staged session.
|
||||
*/
|
||||
public static final int NO_ERROR = 0;
|
||||
|
||||
/**
|
||||
* Constant indicating that an error occurred during the verification phase (pre-reboot) of
|
||||
* this staged session.
|
||||
*/
|
||||
public static final int VERIFICATION_FAILED = 1;
|
||||
|
||||
/**
|
||||
* Constant indicating that an error occurred during the activation phase (post-reboot) of
|
||||
* this staged session.
|
||||
*/
|
||||
public static final int ACTIVATION_FAILED = 2;
|
||||
|
||||
/** {@hide} */
|
||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
|
||||
public int sessionId;
|
||||
@@ -1652,6 +1678,14 @@ public class PackageInstaller {
|
||||
/** {@hide} */
|
||||
public int[] childSessionIds = NO_SESSIONS;
|
||||
|
||||
/** {@hide} */
|
||||
public boolean isSessionApplied;
|
||||
/** {@hide} */
|
||||
public boolean isSessionReady;
|
||||
/** {@hide} */
|
||||
public boolean isSessionFailed;
|
||||
private int mStagedSessionErrorCode;
|
||||
|
||||
/** {@hide} */
|
||||
@UnsupportedAppUsage
|
||||
public SessionInfo() {
|
||||
@@ -1686,6 +1720,10 @@ public class PackageInstaller {
|
||||
if (childSessionIds == null) {
|
||||
childSessionIds = NO_SESSIONS;
|
||||
}
|
||||
isSessionApplied = source.readBoolean();
|
||||
isSessionReady = source.readBoolean();
|
||||
isSessionFailed = source.readBoolean();
|
||||
mStagedSessionErrorCode = source.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1970,6 +2008,44 @@ public class PackageInstaller {
|
||||
return childSessionIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the staged session has been applied successfully, meaning that all of its
|
||||
* packages have been activated and no further action is required.
|
||||
* Only meaningful if {@code isStaged} is true.
|
||||
*/
|
||||
public boolean isSessionApplied() {
|
||||
return isSessionApplied;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the staged session is ready to be applied at next reboot. Only meaningful if
|
||||
* {@code isStaged} is true.
|
||||
*/
|
||||
public boolean isSessionReady() {
|
||||
return isSessionReady;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether something went wrong and the staged session is declared as failed, meaning that
|
||||
* it will be ignored at next reboot. Only meaningful if {@code isStaged} is true.
|
||||
*/
|
||||
public boolean isSessionFailed() {
|
||||
return isSessionFailed;
|
||||
}
|
||||
|
||||
/**
|
||||
* If something went wrong with a staged session, clients can check this error code to
|
||||
* understand which kind of failure happened. Only meaningful if {@code isStaged} is true.
|
||||
*/
|
||||
public int getStagedSessionErrorCode() {
|
||||
return mStagedSessionErrorCode;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public void setStagedSessionErrorCode(@StagedSessionErrorCode int errorCode) {
|
||||
mStagedSessionErrorCode = errorCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
@@ -2001,6 +2077,10 @@ public class PackageInstaller {
|
||||
dest.writeBoolean(isStaged);
|
||||
dest.writeInt(parentSessionId);
|
||||
dest.writeIntArray(childSessionIds);
|
||||
dest.writeBoolean(isSessionApplied);
|
||||
dest.writeBoolean(isSessionReady);
|
||||
dest.writeBoolean(isSessionFailed);
|
||||
dest.writeInt(mStagedSessionErrorCode);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<SessionInfo>
|
||||
|
||||
@@ -250,6 +250,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
@GuardedBy("mLock")
|
||||
private int mParentSessionId;
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private boolean mStagedSessionApplied;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mStagedSessionReady;
|
||||
@GuardedBy("mLock")
|
||||
private boolean mStagedSessionFailed;
|
||||
@GuardedBy("mLock")
|
||||
private int mStagedSessionErrorCode = SessionInfo.NO_ERROR;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -470,6 +479,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (info.childSessionIds == null) {
|
||||
info.childSessionIds = EMPTY_CHILD_SESSION_ARRAY;
|
||||
}
|
||||
info.isSessionApplied = mStagedSessionApplied;
|
||||
info.isSessionReady = mStagedSessionReady;
|
||||
info.isSessionFailed = mStagedSessionFailed;
|
||||
info.setStagedSessionErrorCode(mStagedSessionErrorCode);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
@@ -1051,6 +1064,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
}
|
||||
if (isStaged()) {
|
||||
// STOPSHIP: implement staged sessions
|
||||
mStagedSessionReady = true;
|
||||
dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "Session staged", null);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user