Notify StagedApexObservers when there is a change in set of staged APEX

The set of staged APEX is changed whenever:
- a session containing APEX succesfully passes pre-reboot verification
  and gets marked ready
- a staged session gets abandoned

(Note: Unit tests have been removed to resolve cherry-pick conflict)

Bug: 187444679
Test: atest StagedInstallInternalTests
Change-Id: I5c5bb4523cdab46e22fe3c8e2373289d8619c10e
Merged-In: I5c5bb4523cdab46e22fe3c8e2373289d8619c10e
This commit is contained in:
Samiul Islam
2021-08-04 13:12:57 +01:00
parent 9a68bedca7
commit 7675b5c154

View File

@@ -29,7 +29,9 @@ import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ApexStagedEvent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IStagedApexObserver;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
@@ -108,7 +110,8 @@ public class StagingManager {
private final ApexManager mApexManager;
private final PowerManager mPowerManager;
private final Context mContext;
private final PreRebootVerificationHandler mPreRebootVerificationHandler;
@VisibleForTesting
final PreRebootVerificationHandler mPreRebootVerificationHandler;
private final Supplier<PackageParser2> mPackageParserSupplier;
private final File mFailureReasonFile = new File("/metadata/staged-install/failure_reason.txt");
@@ -127,6 +130,9 @@ public class StagingManager {
@GuardedBy("mSuccessfulStagedSessionIds")
private final List<Integer> mSuccessfulStagedSessionIds = new ArrayList<>();
@GuardedBy("mStagedApexObservers")
private final List<IStagedApexObserver> mStagedApexObservers = new ArrayList<>();
StagingManager(PackageInstallerService pi, Context context,
Supplier<PackageParser2> packageParserSupplier) {
mPi = pi;
@@ -189,6 +195,18 @@ public class StagingManager {
mApexManager.markBootCompleted();
}
void registerStagedApexObserver(IStagedApexObserver observer) {
synchronized (mStagedApexObservers) {
mStagedApexObservers.add(observer);
}
}
void unregisterStagedApexObserver(IStagedApexObserver observer) {
synchronized (mStagedApexObservers) {
mStagedApexObservers.remove(observer);
}
}
/**
* Validates the signature used to sign the container of the new apex package
*
@@ -1080,6 +1098,9 @@ public class StagingManager {
Slog.w(TAG, "Could not contact apexd to abort staged session " + sessionId);
}
}
if (sessionContainsApex(session)) {
notifyStagedApexObservers();
}
}
// Session was successfully aborted from apexd (if required) and pre-reboot verification
@@ -1384,7 +1405,22 @@ public class StagingManager {
return null;
}
private final class PreRebootVerificationHandler extends Handler {
private void notifyStagedApexObservers() {
synchronized (mStagedApexObservers) {
for (IStagedApexObserver observer : mStagedApexObservers) {
ApexStagedEvent event = new ApexStagedEvent();
event.stagedApexModuleNames = getStagedApexModuleNames().toArray(new String[0]);
try {
observer.onApexStaged(event);
} catch (RemoteException re) {
Slog.w(TAG, "Failed to contact the observer " + re.getMessage());
}
}
}
}
@VisibleForTesting
final class PreRebootVerificationHandler extends Handler {
// Hold session ids before handler gets ready to do the verification.
private IntArray mPendingSessionIds;
private boolean mIsReady;
@@ -1412,7 +1448,8 @@ public class StagingManager {
private static final int MSG_PRE_REBOOT_VERIFICATION_START = 1;
private static final int MSG_PRE_REBOOT_VERIFICATION_APEX = 2;
private static final int MSG_PRE_REBOOT_VERIFICATION_APK = 3;
private static final int MSG_PRE_REBOOT_VERIFICATION_END = 4;
@VisibleForTesting
static final int MSG_PRE_REBOOT_VERIFICATION_END = 4;
@Override
public void handleMessage(Message msg) {
@@ -1664,6 +1701,7 @@ public class StagingManager {
if (hasApex) {
try {
mApexManager.markStagedSessionReady(session.sessionId);
notifyStagedApexObservers();
} catch (PackageManagerException e) {
session.setStagedSessionFailed(e.error, e.getMessage());
return;