Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7675b5c1 authored by Samiul Islam's avatar Samiul Islam
Browse files

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
parent 9a68bedc
Loading
Loading
Loading
Loading
+41 −3
Original line number Diff line number Diff line
@@ -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;