Prevent staging multiple sessions on devices not supporting checkpoint am: 8c7142a658
Change-Id: I42c180ae216777624b4ad204466f0f64fccecbb9
This commit is contained in:
committed by
Automerger Merge Worker
commit
aa0cebd8a4
@@ -36015,6 +36015,7 @@ package android.os.storage {
|
|||||||
method public boolean isAllocationSupported(@NonNull java.io.FileDescriptor);
|
method public boolean isAllocationSupported(@NonNull java.io.FileDescriptor);
|
||||||
method public boolean isCacheBehaviorGroup(java.io.File) throws java.io.IOException;
|
method public boolean isCacheBehaviorGroup(java.io.File) throws java.io.IOException;
|
||||||
method public boolean isCacheBehaviorTombstone(java.io.File) throws java.io.IOException;
|
method public boolean isCacheBehaviorTombstone(java.io.File) throws java.io.IOException;
|
||||||
|
method public boolean isCheckpointSupported();
|
||||||
method public boolean isEncrypted(java.io.File);
|
method public boolean isEncrypted(java.io.File);
|
||||||
method public boolean isObbMounted(String);
|
method public boolean isObbMounted(String);
|
||||||
method public boolean mountObb(String, String, android.os.storage.OnObbStateChangeListener);
|
method public boolean mountObb(String, String, android.os.storage.OnObbStateChangeListener);
|
||||||
|
|||||||
@@ -2304,6 +2304,19 @@ public class StorageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the device supports filesystem checkpoint.
|
||||||
|
*
|
||||||
|
* @return true if the device supports filesystem checkpoint, false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isCheckpointSupported() {
|
||||||
|
try {
|
||||||
|
return mStorageManager.supportsCheckpoint();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw e.rethrowFromSystemServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final Object mFuseAppLoopLock = new Object();
|
private final Object mFuseAppLoopLock = new Object();
|
||||||
|
|
||||||
@GuardedBy("mFuseAppLoopLock")
|
@GuardedBy("mFuseAppLoopLock")
|
||||||
|
|||||||
@@ -2648,13 +2648,6 @@ class StorageManagerService extends IStorageManager.Stub
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsCheckpoint() throws RemoteException {
|
public boolean supportsCheckpoint() throws RemoteException {
|
||||||
// Only the root, system_server and shell processes are permitted to start checkpoints
|
|
||||||
final int callingUid = Binder.getCallingUid();
|
|
||||||
if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID
|
|
||||||
&& callingUid != Process.SHELL_UID) {
|
|
||||||
throw new SecurityException("no permission to start filesystem checkpoint");
|
|
||||||
}
|
|
||||||
|
|
||||||
return mVold.supportsCheckpoint();
|
return mVold.supportsCheckpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import android.os.ParcelableException;
|
|||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ServiceManager;
|
import android.os.ServiceManager;
|
||||||
|
import android.os.storage.StorageManager;
|
||||||
import android.util.IntArray;
|
import android.util.IntArray;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
@@ -76,6 +77,7 @@ public class StagingManager {
|
|||||||
private final PackageInstallerService mPi;
|
private final PackageInstallerService mPi;
|
||||||
private final ApexManager mApexManager;
|
private final ApexManager mApexManager;
|
||||||
private final PowerManager mPowerManager;
|
private final PowerManager mPowerManager;
|
||||||
|
private final Context mContext;
|
||||||
private final PreRebootVerificationHandler mPreRebootVerificationHandler;
|
private final PreRebootVerificationHandler mPreRebootVerificationHandler;
|
||||||
|
|
||||||
@GuardedBy("mStagedSessions")
|
@GuardedBy("mStagedSessions")
|
||||||
@@ -84,6 +86,7 @@ public class StagingManager {
|
|||||||
StagingManager(PackageInstallerService pi, ApexManager am, Context context) {
|
StagingManager(PackageInstallerService pi, ApexManager am, Context context) {
|
||||||
mPi = pi;
|
mPi = pi;
|
||||||
mApexManager = am;
|
mApexManager = am;
|
||||||
|
mContext = context;
|
||||||
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
||||||
mPreRebootVerificationHandler = new PreRebootVerificationHandler(
|
mPreRebootVerificationHandler = new PreRebootVerificationHandler(
|
||||||
BackgroundThread.get().getLooper());
|
BackgroundThread.get().getLooper());
|
||||||
@@ -539,6 +542,10 @@ public class StagingManager {
|
|||||||
mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId);
|
mPreRebootVerificationHandler.startPreRebootVerification(session.sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int parentOrOwnSessionId(PackageInstallerSession session) {
|
||||||
|
return session.hasParentSessionId() ? session.getParentSessionId() : session.sessionId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Check if the session provided is non-overlapping with the active staged sessions.
|
* <p> Check if the session provided is non-overlapping with the active staged sessions.
|
||||||
*
|
*
|
||||||
@@ -561,6 +568,9 @@ public class StagingManager {
|
|||||||
"Cannot stage session " + session.sessionId + " with package name null");
|
"Cannot stage session " + session.sessionId + " with package name null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean supportsCheckpoint = ((StorageManager) mContext.getSystemService(
|
||||||
|
Context.STORAGE_SERVICE)).isCheckpointSupported();
|
||||||
|
|
||||||
synchronized (mStagedSessions) {
|
synchronized (mStagedSessions) {
|
||||||
for (int i = 0; i < mStagedSessions.size(); i++) {
|
for (int i = 0; i < mStagedSessions.size(); i++) {
|
||||||
final PackageInstallerSession stagedSession = mStagedSessions.valueAt(i);
|
final PackageInstallerSession stagedSession = mStagedSessions.valueAt(i);
|
||||||
@@ -601,7 +611,17 @@ public class StagingManager {
|
|||||||
+ stagedSession.sessionId, null);
|
+ stagedSession.sessionId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/141843321): Add support for staging multiple sessions in apexd
|
// Staging multiple root sessions is not allowed if device doesn't support
|
||||||
|
// checkpoint. If session and stagedSession do not have common ancestor, they are
|
||||||
|
// from two different root sessions.
|
||||||
|
if (!supportsCheckpoint
|
||||||
|
&& parentOrOwnSessionId(session) != parentOrOwnSessionId(stagedSession)) {
|
||||||
|
throw new PackageManagerException(
|
||||||
|
PackageManager.INSTALL_FAILED_OTHER_STAGED_SESSION_IN_PROGRESS,
|
||||||
|
"Cannot stage multiple sessions without checkpoint support", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:b/141843321 Add support for staging multiple sessions in apexd
|
||||||
// Since apexd doesn't support multiple staged sessions yet, we have to careful how
|
// Since apexd doesn't support multiple staged sessions yet, we have to careful how
|
||||||
// we handle apex sessions. We want to allow a set of apex sessions under the same
|
// we handle apex sessions. We want to allow a set of apex sessions under the same
|
||||||
// parent to be staged when there is no previously staged apex sessions.
|
// parent to be staged when there is no previously staged apex sessions.
|
||||||
|
|||||||
Reference in New Issue
Block a user