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

Commit efb46305 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix device not rebooting after watchdog triggered staged rollback" into qt-dev

parents bc646622 da972362
Loading
Loading
Loading
Loading
+51 −89
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.rollback;

import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -32,7 +33,6 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.StatsLog;

@@ -77,51 +77,33 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
    @Override
    public int onHealthCheckFailed(VersionedPackage failedPackage) {
        VersionedPackage moduleMetadataPackage = getModuleMetadataPackage();
        if (moduleMetadataPackage == null) {
            // Ignore failure, no mainline update available
            return PackageHealthObserverImpact.USER_IMPACT_NONE;
        }

        if (getAvailableRollback(mContext.getSystemService(RollbackManager.class),
                        failedPackage, moduleMetadataPackage) == null) {
        if (getAvailableRollback(mContext.getSystemService(RollbackManager.class), failedPackage)
                == null) {
            // Don't handle the notification, no rollbacks available for the package
            return PackageHealthObserverImpact.USER_IMPACT_NONE;
        }
        } else {
            // Rollback is available, we may get a callback into #execute
            return PackageHealthObserverImpact.USER_IMPACT_MEDIUM;
        }
    }

    @Override
    public boolean execute(VersionedPackage failedPackage) {
        RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
        VersionedPackage moduleMetadataPackage = getModuleMetadataPackage();
        if (moduleMetadataPackage == null) {
            // Ignore failure, no mainline update available
            return false;
        }
        RollbackInfo rollback = getAvailableRollback(rollbackManager, failedPackage);

        RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
        Pair<RollbackInfo, Boolean> rollbackPair = getAvailableRollback(rollbackManager,
                failedPackage, moduleMetadataPackage);
        if (rollbackPair == null) {
        if (rollback == null) {
            Slog.w(TAG, "Expected rollback but no valid rollback found for package: [ "
                    + failedPackage.getPackageName() + "] with versionCode: ["
                    + failedPackage.getVersionCode() + "]");
            return false;
        }

        RollbackInfo rollback = rollbackPair.first;
        // We only log mainline package rollbacks, so check if rollback contains the
        // module metadata provider, if it does, the rollback is a mainline rollback
        boolean hasModuleMetadataPackage = rollbackPair.second;

        if (hasModuleMetadataPackage) {
            StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
                    StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE,
                    moduleMetadataPackage.getPackageName(),
                    moduleMetadataPackage.getVersionCode());
        }
        logEvent(moduleMetadataPackage,
                StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE);
        LocalIntentReceiver rollbackReceiver = new LocalIntentReceiver((Intent result) -> {
            if (hasModuleMetadataPackage) {
            int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
                    RollbackManager.STATUS_FAILURE);
            if (status == RollbackManager.STATUS_SUCCESS) {
@@ -133,18 +115,12 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
                    handleStagedSessionChange(rollbackManager, rollbackId, listener,
                            moduleMetadataPackage);
                } else {
                        StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
                                StatsLog
                                .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
                                moduleMetadataPackage.getPackageName(),
                                moduleMetadataPackage.getVersionCode());
                    logEvent(moduleMetadataPackage,
                            StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS);
                }
            } else {
                    StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
                            StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
                            moduleMetadataPackage.getPackageName(),
                            moduleMetadataPackage.getVersionCode());
                }
                logEvent(moduleMetadataPackage,
                        StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
            }
        });

@@ -193,26 +169,17 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
        }

        String moduleMetadataPackageName = getModuleMetadataPackageName();
        if (moduleMetadataPackageName == null) {
            // Only log mainline staged rollbacks
            return;
        }

        // Use the version of the metadata package that was installed before
        // we rolled back for logging purposes.
        VersionedPackage moduleMetadataPackage = null;
        for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
            if (moduleMetadataPackageName.equals(packageRollback.getPackageName())) {
            if (packageRollback.getPackageName().equals(moduleMetadataPackageName)) {
                moduleMetadataPackage = packageRollback.getVersionRolledBackFrom();
                break;
            }
        }

        if (moduleMetadataPackage == null) {
            // Only log mainline staged rollbacks
            return;
        }

        int sessionId = rollback.getCommittedSessionId();
        PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
        if (sessionInfo == null) {
@@ -220,42 +187,33 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
            return;
        }
        if (sessionInfo.isStagedSessionApplied()) {
            StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
                    StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
                    moduleMetadataPackage.getPackageName(),
                    moduleMetadataPackage.getVersionCode());
            logEvent(moduleMetadataPackage,
                    StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS);
        } else if (sessionInfo.isStagedSessionReady()) {
            // TODO: What do for staged session ready but not applied
        } else {
            StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
                    StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
                    moduleMetadataPackage.getPackageName(),
                    moduleMetadataPackage.getVersionCode());
            logEvent(moduleMetadataPackage,
                    StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
        }
    }

    private Pair<RollbackInfo, Boolean> getAvailableRollback(RollbackManager rollbackManager,
            VersionedPackage failedPackage, VersionedPackage moduleMetadataPackage) {
    private RollbackInfo getAvailableRollback(RollbackManager rollbackManager,
            VersionedPackage failedPackage) {
        for (RollbackInfo rollback : rollbackManager.getAvailableRollbacks()) {
            // We only rollback mainline packages, so check if rollback contains the
            // module metadata provider, if it does, the rollback is a mainline rollback
            boolean hasModuleMetadataPackage = false;
            boolean hasFailedPackage = false;
            for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
                hasModuleMetadataPackage |= packageRollback.getPackageName().equals(
                        moduleMetadataPackage.getPackageName());
                hasFailedPackage |= packageRollback.getPackageName().equals(
                boolean hasFailedPackage = packageRollback.getPackageName().equals(
                        failedPackage.getPackageName())
                        && packageRollback.getVersionRolledBackFrom().getVersionCode()
                        == failedPackage.getVersionCode();
            }
                if (hasFailedPackage) {
                return new Pair<RollbackInfo, Boolean>(rollback, hasModuleMetadataPackage);
                    return rollback;
                }
            }
        }
        return null;
    }

    @Nullable
    private String getModuleMetadataPackageName() {
        String packageName = mContext.getResources().getString(
                R.string.config_defaultModuleMetadataProvider);
@@ -265,6 +223,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
        return packageName;
    }

    @Nullable
    private VersionedPackage getModuleMetadataPackage() {
        String packageName = getModuleMetadataPackageName();
        if (packageName == null) {
@@ -311,18 +270,13 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
                if (sessionInfo.isStagedSessionReady()) {
                    mContext.unregisterReceiver(listener);
                    saveLastStagedRollbackId(rollbackId);
                    StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
                    logEvent(moduleMetadataPackage,
                            StatsLog
                            .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED,
                            moduleMetadataPackage.getPackageName(),
                            moduleMetadataPackage.getVersionCode());
                            .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED);
                    mContext.getSystemService(PowerManager.class).reboot("Rollback staged install");
                } else if (sessionInfo.isStagedSessionFailed()) {
                    StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
                            StatsLog
                            .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
                            moduleMetadataPackage.getPackageName(),
                            moduleMetadataPackage.getVersionCode());
                    logEvent(moduleMetadataPackage,
                            StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
                    mContext.unregisterReceiver(listener);
                }
            }
@@ -358,4 +312,12 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
        mLastStagedRollbackIdFile.delete();
        return rollbackId;
    }

    private static void logEvent(@Nullable VersionedPackage moduleMetadataPackage, int type) {
        Slog.i(TAG, "Watchdog event occurred of type: " + type);
        if (moduleMetadataPackage != null) {
            StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, type,
                    moduleMetadataPackage.getPackageName(), moduleMetadataPackage.getVersionCode());
        }
    }
}