Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package com.android.server.rollback; |
| 18 | |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 19 | import android.content.BroadcastReceiver; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 20 | import android.content.Context; |
| 21 | import android.content.Intent; |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 22 | import android.content.IntentFilter; |
| 23 | import android.content.pm.PackageInstaller; |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 24 | import android.content.pm.PackageManager; |
Zimuzo | c119780 | 2019-01-30 12:05:41 +0000 | [diff] [blame] | 25 | import android.content.pm.VersionedPackage; |
Richard Uhler | 0e96192 | 2019-01-25 13:07:08 +0000 | [diff] [blame] | 26 | import android.content.rollback.PackageRollbackInfo; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 27 | import android.content.rollback.RollbackInfo; |
| 28 | import android.content.rollback.RollbackManager; |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 29 | import android.os.Environment; |
| 30 | import android.os.FileUtils; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 31 | import android.os.Handler; |
| 32 | import android.os.HandlerThread; |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 33 | import android.os.PowerManager; |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 34 | import android.text.TextUtils; |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 35 | import android.util.Pair; |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 36 | import android.util.Slog; |
| 37 | import android.util.StatsLog; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 38 | |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 39 | import com.android.internal.R; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 40 | import com.android.server.PackageWatchdog; |
| 41 | import com.android.server.PackageWatchdog.PackageHealthObserver; |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 42 | import com.android.server.PackageWatchdog.PackageHealthObserverImpact; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 43 | |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 44 | import libcore.io.IoUtils; |
| 45 | |
| 46 | import java.io.File; |
| 47 | import java.io.FileOutputStream; |
| 48 | import java.io.IOException; |
| 49 | import java.io.PrintWriter; |
Richard Uhler | bf5b5c4 | 2019-01-28 15:26:37 +0000 | [diff] [blame] | 50 | import java.util.Collections; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 51 | import java.util.List; |
| 52 | |
| 53 | /** |
| 54 | * {@code PackageHealthObserver} for {@code RollbackManagerService}. |
| 55 | * |
| 56 | * @hide |
| 57 | */ |
| 58 | public final class RollbackPackageHealthObserver implements PackageHealthObserver { |
| 59 | private static final String TAG = "RollbackPackageHealthObserver"; |
| 60 | private static final String NAME = "rollback-observer"; |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 61 | private static final int INVALID_ROLLBACK_ID = -1; |
| 62 | private final Context mContext; |
| 63 | private final Handler mHandler; |
| 64 | private final File mLastStagedRollbackIdFile; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 65 | |
| 66 | RollbackPackageHealthObserver(Context context) { |
| 67 | mContext = context; |
| 68 | HandlerThread handlerThread = new HandlerThread("RollbackPackageHealthObserver"); |
| 69 | handlerThread.start(); |
| 70 | mHandler = handlerThread.getThreadHandler(); |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 71 | File dataDir = new File(Environment.getDataDirectory(), "rollback-observer"); |
| 72 | dataDir.mkdirs(); |
| 73 | mLastStagedRollbackIdFile = new File(dataDir, "last-staged-rollback-id"); |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 74 | PackageWatchdog.getInstance(mContext).registerHealthObserver(this); |
| 75 | } |
| 76 | |
| 77 | @Override |
Zimuzo | 71d931e | 2019-02-01 13:08:16 +0000 | [diff] [blame] | 78 | public int onHealthCheckFailed(VersionedPackage failedPackage) { |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 79 | VersionedPackage moduleMetadataPackage = getModuleMetadataPackage(); |
| 80 | if (moduleMetadataPackage == null) { |
| 81 | // Ignore failure, no mainline update available |
| 82 | return PackageHealthObserverImpact.USER_IMPACT_NONE; |
| 83 | } |
| 84 | |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 85 | if (getAvailableRollback(mContext.getSystemService(RollbackManager.class), |
| 86 | failedPackage, moduleMetadataPackage) == null) { |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 87 | // Don't handle the notification, no rollbacks available for the package |
| 88 | return PackageHealthObserverImpact.USER_IMPACT_NONE; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 89 | } |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 90 | // Rollback is available, we may get a callback into #execute |
| 91 | return PackageHealthObserverImpact.USER_IMPACT_MEDIUM; |
| 92 | } |
| 93 | |
| 94 | @Override |
Zimuzo | 71d931e | 2019-02-01 13:08:16 +0000 | [diff] [blame] | 95 | public boolean execute(VersionedPackage failedPackage) { |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 96 | VersionedPackage moduleMetadataPackage = getModuleMetadataPackage(); |
| 97 | if (moduleMetadataPackage == null) { |
| 98 | // Ignore failure, no mainline update available |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 99 | return false; |
| 100 | } |
| 101 | |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 102 | RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class); |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 103 | Pair<RollbackInfo, Boolean> rollbackPair = getAvailableRollback(rollbackManager, |
Zimuzo | 71d931e | 2019-02-01 13:08:16 +0000 | [diff] [blame] | 104 | failedPackage, moduleMetadataPackage); |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 105 | if (rollbackPair == null) { |
| 106 | Slog.w(TAG, "Expected rollback but no valid rollback found for package: [ " |
Zimuzo | 71d931e | 2019-02-01 13:08:16 +0000 | [diff] [blame] | 107 | + failedPackage.getPackageName() + "] with versionCode: [" |
| 108 | + failedPackage.getVersionCode() + "]"); |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 109 | return false; |
| 110 | } |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 111 | |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 112 | RollbackInfo rollback = rollbackPair.first; |
| 113 | // We only log mainline package rollbacks, so check if rollback contains the |
| 114 | // module metadata provider, if it does, the rollback is a mainline rollback |
| 115 | boolean hasModuleMetadataPackage = rollbackPair.second; |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 116 | |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 117 | if (hasModuleMetadataPackage) { |
| 118 | StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, |
| 119 | StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE, |
| 120 | moduleMetadataPackage.getPackageName(), |
| 121 | moduleMetadataPackage.getVersionCode()); |
| 122 | } |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 123 | LocalIntentReceiver rollbackReceiver = new LocalIntentReceiver((Intent result) -> { |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 124 | if (hasModuleMetadataPackage) { |
| 125 | int status = result.getIntExtra(RollbackManager.EXTRA_STATUS, |
| 126 | RollbackManager.STATUS_FAILURE); |
| 127 | if (status == RollbackManager.STATUS_SUCCESS) { |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 128 | if (rollback.isStaged()) { |
| 129 | int rollbackId = rollback.getRollbackId(); |
| 130 | BroadcastReceiver listener = |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 131 | listenForStagedSessionReady(rollbackManager, rollbackId, |
| 132 | moduleMetadataPackage); |
| 133 | handleStagedSessionChange(rollbackManager, rollbackId, listener, |
| 134 | moduleMetadataPackage); |
| 135 | } else { |
| 136 | StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, |
| 137 | StatsLog |
| 138 | .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS, |
| 139 | moduleMetadataPackage.getPackageName(), |
| 140 | moduleMetadataPackage.getVersionCode()); |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 141 | } |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 142 | } else { |
| 143 | StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, |
| 144 | StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, |
| 145 | moduleMetadataPackage.getPackageName(), |
| 146 | moduleMetadataPackage.getVersionCode()); |
| 147 | } |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 148 | } |
| 149 | }); |
| 150 | |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 151 | mHandler.post(() -> |
Zimuzo | c119780 | 2019-01-30 12:05:41 +0000 | [diff] [blame] | 152 | rollbackManager.commitRollback(rollback.getRollbackId(), |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 153 | Collections.singletonList(failedPackage), |
Richard Uhler | e87368e | 2019-01-24 16:34:14 +0000 | [diff] [blame] | 154 | rollbackReceiver.getIntentSender())); |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 155 | // Assume rollback executed successfully |
| 156 | return true; |
| 157 | } |
| 158 | |
| 159 | @Override |
| 160 | public String getName() { |
| 161 | return NAME; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 162 | } |
| 163 | |
| 164 | /** |
| 165 | * Start observing health of {@code packages} for {@code durationMs}. |
| 166 | * This may cause {@code packages} to be rolled back if they crash too freqeuntly. |
| 167 | */ |
| 168 | public void startObservingHealth(List<String> packages, long durationMs) { |
Zimuzo | 9284e74 | 2019-02-22 12:09:28 +0000 | [diff] [blame] | 169 | PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs, |
| 170 | false /* withExplicitHealthCheck */); |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 171 | } |
| 172 | |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 173 | /** Verifies the rollback state after a reboot. */ |
| 174 | public void onBootCompleted() { |
| 175 | int rollbackId = popLastStagedRollbackId(); |
| 176 | if (rollbackId == INVALID_ROLLBACK_ID) { |
| 177 | // No staged rollback before reboot |
| 178 | return; |
| 179 | } |
| 180 | |
| 181 | RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class); |
| 182 | PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller(); |
| 183 | RollbackInfo rollback = null; |
| 184 | for (RollbackInfo info : rollbackManager.getRecentlyCommittedRollbacks()) { |
| 185 | if (rollbackId == info.getRollbackId()) { |
| 186 | rollback = info; |
| 187 | break; |
| 188 | } |
| 189 | } |
| 190 | |
| 191 | if (rollback == null) { |
| 192 | Slog.e(TAG, "rollback info not found for last staged rollback: " + rollbackId); |
| 193 | return; |
| 194 | } |
| 195 | |
| 196 | String moduleMetadataPackageName = getModuleMetadataPackageName(); |
| 197 | if (moduleMetadataPackageName == null) { |
| 198 | // Only log mainline staged rollbacks |
| 199 | return; |
| 200 | } |
| 201 | |
| 202 | // Use the version of the metadata package that was installed before |
| 203 | // we rolled back for logging purposes. |
| 204 | VersionedPackage moduleMetadataPackage = null; |
| 205 | for (PackageRollbackInfo packageRollback : rollback.getPackages()) { |
| 206 | if (moduleMetadataPackageName.equals(packageRollback.getPackageName())) { |
| 207 | moduleMetadataPackage = packageRollback.getVersionRolledBackFrom(); |
| 208 | break; |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | if (moduleMetadataPackage == null) { |
| 213 | // Only log mainline staged rollbacks |
| 214 | return; |
| 215 | } |
| 216 | |
| 217 | int sessionId = rollback.getCommittedSessionId(); |
| 218 | PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId); |
| 219 | if (sessionInfo == null) { |
| 220 | Slog.e(TAG, "On boot completed, could not load session id " + sessionId); |
| 221 | return; |
| 222 | } |
| 223 | if (sessionInfo.isStagedSessionApplied()) { |
| 224 | StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, |
| 225 | StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS, |
| 226 | moduleMetadataPackage.getPackageName(), |
| 227 | moduleMetadataPackage.getVersionCode()); |
| 228 | } else if (sessionInfo.isStagedSessionReady()) { |
| 229 | // TODO: What do for staged session ready but not applied |
| 230 | } else { |
| 231 | StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, |
| 232 | StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, |
| 233 | moduleMetadataPackage.getPackageName(), |
| 234 | moduleMetadataPackage.getVersionCode()); |
| 235 | } |
| 236 | } |
| 237 | |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 238 | private Pair<RollbackInfo, Boolean> getAvailableRollback(RollbackManager rollbackManager, |
Zimuzo | 71d931e | 2019-02-01 13:08:16 +0000 | [diff] [blame] | 239 | VersionedPackage failedPackage, VersionedPackage moduleMetadataPackage) { |
Zimuzo | c119780 | 2019-01-30 12:05:41 +0000 | [diff] [blame] | 240 | for (RollbackInfo rollback : rollbackManager.getAvailableRollbacks()) { |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 241 | // We only rollback mainline packages, so check if rollback contains the |
| 242 | // module metadata provider, if it does, the rollback is a mainline rollback |
| 243 | boolean hasModuleMetadataPackage = false; |
| 244 | boolean hasFailedPackage = false; |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 245 | for (PackageRollbackInfo packageRollback : rollback.getPackages()) { |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 246 | hasModuleMetadataPackage |= packageRollback.getPackageName().equals( |
Zimuzo | 71d931e | 2019-02-01 13:08:16 +0000 | [diff] [blame] | 247 | moduleMetadataPackage.getPackageName()); |
| 248 | hasFailedPackage |= packageRollback.getPackageName().equals( |
| 249 | failedPackage.getPackageName()) |
Zimuzo | 972e1cd | 2019-01-28 16:30:01 +0000 | [diff] [blame] | 250 | && packageRollback.getVersionRolledBackFrom().getVersionCode() |
Zimuzo | 71d931e | 2019-02-01 13:08:16 +0000 | [diff] [blame] | 251 | == failedPackage.getVersionCode(); |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 252 | } |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 253 | if (hasFailedPackage) { |
| 254 | return new Pair<RollbackInfo, Boolean>(rollback, hasModuleMetadataPackage); |
Zimuzo | e5009cd | 2019-01-23 18:11:58 +0000 | [diff] [blame] | 255 | } |
| 256 | } |
| 257 | return null; |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 258 | } |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 259 | |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 260 | private String getModuleMetadataPackageName() { |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 261 | String packageName = mContext.getResources().getString( |
| 262 | R.string.config_defaultModuleMetadataProvider); |
Zimuzo | 9e57ecb | 2019-02-04 15:34:08 +0000 | [diff] [blame] | 263 | if (TextUtils.isEmpty(packageName)) { |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 264 | return null; |
| 265 | } |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 266 | return packageName; |
| 267 | } |
| 268 | |
| 269 | private VersionedPackage getModuleMetadataPackage() { |
| 270 | String packageName = getModuleMetadataPackageName(); |
| 271 | if (packageName == null) { |
| 272 | return null; |
| 273 | } |
Zimuzo | 03eeb13 | 2019-01-30 15:13:56 +0000 | [diff] [blame] | 274 | |
| 275 | try { |
| 276 | return new VersionedPackage(packageName, mContext.getPackageManager().getPackageInfo( |
| 277 | packageName, 0 /* flags */).getLongVersionCode()); |
| 278 | } catch (PackageManager.NameNotFoundException e) { |
| 279 | Slog.w(TAG, "Module metadata provider not found"); |
| 280 | return null; |
| 281 | } |
| 282 | } |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 283 | |
| 284 | private BroadcastReceiver listenForStagedSessionReady(RollbackManager rollbackManager, |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 285 | int rollbackId, VersionedPackage moduleMetadataPackage) { |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 286 | BroadcastReceiver sessionUpdatedReceiver = new BroadcastReceiver() { |
| 287 | @Override |
| 288 | public void onReceive(Context context, Intent intent) { |
| 289 | handleStagedSessionChange(rollbackManager, |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 290 | rollbackId, this /* BroadcastReceiver */, moduleMetadataPackage); |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 291 | } |
| 292 | }; |
| 293 | IntentFilter sessionUpdatedFilter = |
| 294 | new IntentFilter(PackageInstaller.ACTION_SESSION_UPDATED); |
| 295 | mContext.registerReceiver(sessionUpdatedReceiver, sessionUpdatedFilter); |
| 296 | return sessionUpdatedReceiver; |
| 297 | } |
| 298 | |
| 299 | private void handleStagedSessionChange(RollbackManager rollbackManager, int rollbackId, |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 300 | BroadcastReceiver listener, VersionedPackage moduleMetadataPackage) { |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 301 | PackageInstaller packageInstaller = |
| 302 | mContext.getPackageManager().getPackageInstaller(); |
| 303 | List<RollbackInfo> recentRollbacks = |
| 304 | rollbackManager.getRecentlyCommittedRollbacks(); |
| 305 | for (int i = 0; i < recentRollbacks.size(); i++) { |
| 306 | RollbackInfo recentRollback = recentRollbacks.get(i); |
| 307 | int sessionId = recentRollback.getCommittedSessionId(); |
| 308 | if ((rollbackId == recentRollback.getRollbackId()) |
| 309 | && (sessionId != PackageInstaller.SessionInfo.INVALID_ID)) { |
| 310 | PackageInstaller.SessionInfo sessionInfo = |
| 311 | packageInstaller.getSessionInfo(sessionId); |
Dario Freni | 60a96c1 | 2019-02-24 21:01:29 +0000 | [diff] [blame] | 312 | if (sessionInfo.isStagedSessionReady()) { |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 313 | mContext.unregisterReceiver(listener); |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 314 | saveLastStagedRollbackId(rollbackId); |
| 315 | StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, |
| 316 | StatsLog |
| 317 | .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED, |
| 318 | moduleMetadataPackage.getPackageName(), |
| 319 | moduleMetadataPackage.getVersionCode()); |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 320 | mContext.getSystemService(PowerManager.class).reboot("Rollback staged install"); |
Dario Freni | 60a96c1 | 2019-02-24 21:01:29 +0000 | [diff] [blame] | 321 | } else if (sessionInfo.isStagedSessionFailed()) { |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 322 | StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, |
| 323 | StatsLog |
| 324 | .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE, |
| 325 | moduleMetadataPackage.getPackageName(), |
| 326 | moduleMetadataPackage.getVersionCode()); |
Zimuzo | ff99176 | 2019-02-01 19:25:44 +0000 | [diff] [blame] | 327 | mContext.unregisterReceiver(listener); |
| 328 | } |
| 329 | } |
| 330 | } |
| 331 | } |
Zimuzo | 841c494 | 2019-03-04 12:31:48 +0000 | [diff] [blame] | 332 | |
| 333 | private void saveLastStagedRollbackId(int stagedRollbackId) { |
| 334 | try { |
| 335 | FileOutputStream fos = new FileOutputStream(mLastStagedRollbackIdFile); |
| 336 | PrintWriter pw = new PrintWriter(fos); |
| 337 | pw.println(stagedRollbackId); |
| 338 | pw.flush(); |
| 339 | FileUtils.sync(fos); |
| 340 | pw.close(); |
| 341 | } catch (IOException e) { |
| 342 | Slog.e(TAG, "Failed to save last staged rollback id", e); |
| 343 | mLastStagedRollbackIdFile.delete(); |
| 344 | } |
| 345 | } |
| 346 | |
| 347 | private int popLastStagedRollbackId() { |
| 348 | int rollbackId = INVALID_ROLLBACK_ID; |
| 349 | if (!mLastStagedRollbackIdFile.exists()) { |
| 350 | return rollbackId; |
| 351 | } |
| 352 | |
| 353 | try { |
| 354 | rollbackId = Integer.parseInt( |
| 355 | IoUtils.readFileAsString(mLastStagedRollbackIdFile.getAbsolutePath()).trim()); |
| 356 | } catch (IOException | NumberFormatException e) { |
| 357 | Slog.e(TAG, "Failed to retrieve last staged rollback id", e); |
| 358 | } |
| 359 | mLastStagedRollbackIdFile.delete(); |
| 360 | return rollbackId; |
| 361 | } |
Zimuzo | c4073cc | 2019-01-18 18:39:18 +0000 | [diff] [blame] | 362 | } |