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

Commit 946ed215 authored by Zimuzo's avatar Zimuzo Committed by android-build-merger
Browse files

Merge "Fix device not rebooting after watchdog triggered staged rollback" into...

Merge "Fix device not rebooting after watchdog triggered staged rollback" into qt-dev am: efb46305
am: f24f0fd0

Change-Id: Idd5a2ff6f7bb5b585e762eb9020e8485eeb5632e
parents 062bd275 f24f0fd0
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());
        }
    }
}