Merge "Make Rollback fields private and add accessors."
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index 0d5746b..6769fe0 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -65,7 +65,7 @@
/**
* The directory where the rollback data is stored.
*/
- public final File backupDir;
+ private final File mBackupDir;
/**
* The time when the upgrade occurred, for purposes of expiring
@@ -74,24 +74,24 @@
* The timestamp is not applicable for all rollback states, but we make
* sure to keep it non-null to avoid potential errors there.
*/
- public @NonNull Instant timestamp;
+ private @NonNull Instant mTimestamp;
/**
* The session ID for the staged session if this rollback data represents a staged session,
* {@code -1} otherwise.
*/
- public final int stagedSessionId;
+ private final int mStagedSessionId;
/**
* The current state of the rollback.
* ENABLING, AVAILABLE, or COMMITTED.
*/
- public @RollbackState int state;
+ private @RollbackState int mState;
/**
* The id of the post-reboot apk session for a staged install, if any.
*/
- public int apkSessionId = -1;
+ private int mApkSessionId = -1;
/**
* True if we are expecting the package manager to call restoreUserData
@@ -99,7 +99,7 @@
* has not yet been fully applied.
*/
// NOTE: All accesses to this field are from the RollbackManager handler thread.
- public boolean restoreUserDataInProgress = false;
+ private boolean mRestoreUserDataInProgress = false;
/**
* Constructs a new, empty Rollback instance.
@@ -114,10 +114,10 @@
/* isStaged */ stagedSessionId != -1,
/* causePackages */ new ArrayList<>(),
/* committedSessionId */ -1);
- this.backupDir = backupDir;
- this.stagedSessionId = stagedSessionId;
- this.state = ROLLBACK_STATE_ENABLING;
- this.timestamp = Instant.now();
+ mBackupDir = backupDir;
+ mStagedSessionId = stagedSessionId;
+ mState = ROLLBACK_STATE_ENABLING;
+ mTimestamp = Instant.now();
}
/**
@@ -126,21 +126,115 @@
Rollback(RollbackInfo info, File backupDir, Instant timestamp, int stagedSessionId,
@RollbackState int state, int apkSessionId, boolean restoreUserDataInProgress) {
this.info = info;
- this.backupDir = backupDir;
- this.timestamp = timestamp;
- this.stagedSessionId = stagedSessionId;
- this.state = state;
- this.apkSessionId = apkSessionId;
- this.restoreUserDataInProgress = restoreUserDataInProgress;
+ mBackupDir = backupDir;
+ mTimestamp = timestamp;
+ mStagedSessionId = stagedSessionId;
+ mState = state;
+ mApkSessionId = apkSessionId;
+ mRestoreUserDataInProgress = restoreUserDataInProgress;
}
/**
* Whether the rollback is for rollback of a staged install.
*/
- public boolean isStaged() {
+ boolean isStaged() {
return info.isStaged();
}
+ /**
+ * Returns the directory in which rollback data should be stored.
+ */
+ File getBackupDir() {
+ return mBackupDir;
+ }
+
+ /**
+ * Returns the time when the upgrade occurred, for purposes of expiring rollback data.
+ */
+ Instant getTimestamp() {
+ return mTimestamp;
+ }
+
+ /**
+ * Sets the time at which upgrade occurred.
+ */
+ void setTimestamp(Instant timestamp) {
+ mTimestamp = timestamp;
+ }
+
+ /**
+ * Returns the session ID for the staged session if this rollback data represents a staged
+ * session, or {@code -1} otherwise.
+ */
+ int getStagedSessionId() {
+ return mStagedSessionId;
+ }
+
+ /**
+ * Returns true if the rollback is in the ENABLING state.
+ */
+ boolean isEnabling() {
+ return mState == ROLLBACK_STATE_ENABLING;
+ }
+
+ /**
+ * Returns true if the rollback is in the AVAILABLE state.
+ */
+ boolean isAvailable() {
+ return mState == ROLLBACK_STATE_AVAILABLE;
+ }
+
+ /**
+ * Returns true if the rollback is in the COMMITTED state.
+ */
+ boolean isCommitted() {
+ return mState == ROLLBACK_STATE_COMMITTED;
+ }
+
+ /**
+ * Sets the state of the rollback to AVAILABLE.
+ */
+ void setAvailable() {
+ mState = ROLLBACK_STATE_AVAILABLE;
+ }
+
+ /**
+ * Sets the state of the rollback to COMMITTED.
+ */
+ void setCommitted() {
+ mState = ROLLBACK_STATE_COMMITTED;
+ }
+
+ /**
+ * Returns the id of the post-reboot apk session for a staged install, if any.
+ */
+ int getApkSessionId() {
+ return mApkSessionId;
+ }
+
+ /**
+ * Sets the id of the post-reboot apk session for a staged install.
+ */
+ void setApkSessionId(int apkSessionId) {
+ mApkSessionId = apkSessionId;
+ }
+
+ /**
+ * Returns true if we are expecting the package manager to call restoreUserData for this
+ * rollback because it has just been committed but the rollback has not yet been fully applied.
+ */
+ boolean isRestoreUserDataInProgress() {
+ return mRestoreUserDataInProgress;
+ }
+
+ /**
+ * Sets whether we are expecting the package manager to call restoreUserData for this
+ * rollback because it has just been committed but the rollback has not yet been fully applied.
+ */
+ void setRestoreUserDataInProgress(boolean restoreUserDataInProgress) {
+ mRestoreUserDataInProgress = restoreUserDataInProgress;
+ }
+
static String rollbackStateToString(@RollbackState int state) {
switch (state) {
case Rollback.ROLLBACK_STATE_ENABLING: return "enabling";
@@ -160,7 +254,7 @@
throw new ParseException("Invalid rollback state: " + state, 0);
}
- public String getStateAsString() {
- return rollbackStateToString(state);
+ String getStateAsString() {
+ return rollbackStateToString(mState);
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index 3147bc6..96d284b 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -282,7 +282,7 @@
List<RollbackInfo> rollbacks = new ArrayList<>();
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback rollback = mRollbacks.get(i);
- if (rollback.state == Rollback.ROLLBACK_STATE_AVAILABLE) {
+ if (rollback.isAvailable()) {
rollbacks.add(rollback.info);
}
}
@@ -298,7 +298,7 @@
List<RollbackInfo> rollbacks = new ArrayList<>();
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback rollback = mRollbacks.get(i);
- if (rollback.state == Rollback.ROLLBACK_STATE_COMMITTED) {
+ if (rollback.isCommitted()) {
rollbacks.add(rollback.info);
}
}
@@ -332,7 +332,7 @@
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
- rollback.timestamp = rollback.timestamp.plusMillis(timeDifference);
+ rollback.setTimestamp(rollback.getTimestamp().plusMillis(timeDifference));
saveRollback(rollback);
}
}
@@ -358,7 +358,7 @@
Slog.i(TAG, "Initiating rollback");
Rollback rollback = getRollbackForId(rollbackId);
- if (rollback == null || rollback.state != Rollback.ROLLBACK_STATE_AVAILABLE) {
+ if (rollback == null || !rollback.isAvailable()) {
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_ROLLBACK_UNAVAILABLE,
"Rollback unavailable");
return;
@@ -454,8 +454,8 @@
// TODO: Could this cause a rollback to be
// resurrected if it should otherwise have
// expired by now?
- rollback.state = Rollback.ROLLBACK_STATE_AVAILABLE;
- rollback.restoreUserDataInProgress = false;
+ rollback.setAvailable();
+ rollback.setRestoreUserDataInProgress(false);
}
sendFailure(statusReceiver, RollbackManager.STATUS_FAILURE_INSTALL,
"Rollback downgrade install failed: "
@@ -468,7 +468,7 @@
if (!rollback.isStaged()) {
// All calls to restoreUserData should have
// completed by now for a non-staged install.
- rollback.restoreUserDataInProgress = false;
+ rollback.setRestoreUserDataInProgress(false);
}
rollback.info.setCommittedSessionId(parentSessionId);
@@ -490,8 +490,8 @@
);
synchronized (mLock) {
- rollback.state = Rollback.ROLLBACK_STATE_COMMITTED;
- rollback.restoreUserDataInProgress = true;
+ rollback.setCommitted();
+ rollback.setRestoreUserDataInProgress(true);
}
parentSession.commit(receiver.getIntentSender());
} catch (IOException e) {
@@ -618,9 +618,9 @@
synchronized (mLock) {
for (Rollback rollback : mRollbacks) {
if (rollback.isStaged()) {
- if (rollback.state == Rollback.ROLLBACK_STATE_ENABLING) {
+ if (rollback.isEnabling()) {
enabling.add(rollback);
- } else if (rollback.restoreUserDataInProgress) {
+ } else if (rollback.isRestoreUserDataInProgress()) {
restoreInProgress.add(rollback);
}
@@ -635,8 +635,8 @@
for (Rollback rollback : enabling) {
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
- PackageInstaller.SessionInfo session = installer.getSessionInfo(
- rollback.stagedSessionId);
+ PackageInstaller.SessionInfo session =
+ installer.getSessionInfo(rollback.getStagedSessionId());
if (session == null || session.isStagedSessionFailed()) {
// TODO: Do we need to remove this from
// mRollbacks, or is it okay to leave as
@@ -650,13 +650,13 @@
for (Rollback rollback : restoreInProgress) {
PackageInstaller installer = mContext.getPackageManager().getPackageInstaller();
- PackageInstaller.SessionInfo session = installer.getSessionInfo(
- rollback.stagedSessionId);
+ PackageInstaller.SessionInfo session =
+ installer.getSessionInfo(rollback.getStagedSessionId());
// TODO: What if session is null?
if (session != null) {
if (session.isStagedSessionApplied() || session.isStagedSessionFailed()) {
synchronized (mLock) {
- rollback.restoreUserDataInProgress = false;
+ rollback.setRestoreUserDataInProgress(false);
}
saveRollback(rollback);
}
@@ -694,8 +694,7 @@
while (iter.hasNext()) {
Rollback rollback = iter.next();
// TODO: Should we remove rollbacks in the ENABLING state here?
- if (rollback.state == Rollback.ROLLBACK_STATE_AVAILABLE
- || rollback.state == Rollback.ROLLBACK_STATE_ENABLING) {
+ if (rollback.isEnabling() || rollback.isAvailable()) {
for (PackageRollbackInfo info : rollback.info.getPackages()) {
if (info.getPackageName().equals(packageName)
&& !packageVersionsEqual(
@@ -761,15 +760,16 @@
Iterator<Rollback> iter = mRollbacks.iterator();
while (iter.hasNext()) {
Rollback rollback = iter.next();
- if (rollback.state != Rollback.ROLLBACK_STATE_AVAILABLE) {
+ if (!rollback.isAvailable()) {
continue;
}
if (!now.isBefore(
- rollback.timestamp.plusMillis(mRollbackLifetimeDurationInMillis))) {
+ rollback.getTimestamp()
+ .plusMillis(mRollbackLifetimeDurationInMillis))) {
iter.remove();
deleteRollback(rollback);
- } else if (oldest == null || oldest.isAfter(rollback.timestamp)) {
- oldest = rollback.timestamp;
+ } else if (oldest == null || oldest.isAfter(rollback.getTimestamp())) {
+ oldest = rollback.getTimestamp();
}
}
}
@@ -877,7 +877,7 @@
synchronized (mLock) {
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback rollback = mRollbacks.get(i);
- if (rollback.apkSessionId == parentSession.getSessionId()) {
+ if (rollback.getApkSessionId() == parentSession.getSessionId()) {
// This is the apk session for a staged session with rollback enabled. We do not
// need to create a new rollback for this session.
return true;
@@ -1020,7 +1020,7 @@
// staged installs
for (int i = 0; i < mRollbacks.size(); i++) {
Rollback rollback = mRollbacks.get(i);
- if (rollback.state != Rollback.ROLLBACK_STATE_ENABLING) {
+ if (!rollback.isEnabling()) {
continue;
}
@@ -1053,7 +1053,7 @@
synchronized (mLock) {
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback candidate = mRollbacks.get(i);
- if (candidate.restoreUserDataInProgress) {
+ if (candidate.isRestoreUserDataInProgress()) {
info = getPackageRollbackInfo(candidate, packageName);
if (info != null) {
rollback = candidate;
@@ -1146,8 +1146,8 @@
synchronized (mLock) {
for (int i = 0; i < mRollbacks.size(); ++i) {
Rollback candidate = mRollbacks.get(i);
- if (candidate.stagedSessionId == originalSessionId) {
- candidate.apkSessionId = apkSessionId;
+ if (candidate.getStagedSessionId() == originalSessionId) {
+ candidate.setApkSessionId(apkSessionId);
rollback = candidate;
break;
}
@@ -1333,8 +1333,8 @@
// to a new package being installed. Won't this revive an expired
// rollback? Consider adding a ROLLBACK_STATE_EXPIRED to address this.
synchronized (mLock) {
- rollback.state = Rollback.ROLLBACK_STATE_AVAILABLE;
- rollback.timestamp = Instant.now();
+ rollback.setAvailable();
+ rollback.setTimestamp(Instant.now());
}
saveRollback(rollback);
@@ -1434,9 +1434,9 @@
ipw.println(info.getRollbackId() + ":");
ipw.increaseIndent();
ipw.println("-state: " + rollback.getStateAsString());
- ipw.println("-timestamp: " + rollback.timestamp);
- if (rollback.stagedSessionId != -1) {
- ipw.println("-stagedSessionId: " + rollback.stagedSessionId);
+ ipw.println("-timestamp: " + rollback.getTimestamp());
+ if (rollback.getStagedSessionId() != -1) {
+ ipw.println("-stagedSessionId: " + rollback.getStagedSessionId());
}
ipw.println("-packages:");
ipw.increaseIndent();
@@ -1446,7 +1446,7 @@
+ " -> " + pkg.getVersionRolledBackTo().getLongVersionCode());
}
ipw.decreaseIndent();
- if (rollback.state == Rollback.ROLLBACK_STATE_COMMITTED) {
+ if (rollback.isCommitted()) {
ipw.println("-causePackages:");
ipw.increaseIndent();
for (VersionedPackage cPkg : info.getCausePackages()) {
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index b2448f6..772c53f 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -17,7 +17,6 @@
package com.android.server.rollback;
import static com.android.server.rollback.Rollback.rollbackStateFromString;
-import static com.android.server.rollback.Rollback.rollbackStateToString;
import android.annotation.NonNull;
import android.content.pm.VersionedPackage;
@@ -216,7 +215,7 @@
static void backupPackageCodePath(Rollback rollback, String packageName, String codePath)
throws IOException {
File sourceFile = new File(codePath);
- File targetDir = new File(rollback.backupDir, packageName);
+ File targetDir = new File(rollback.getBackupDir(), packageName);
targetDir.mkdirs();
File targetFile = new File(targetDir, sourceFile.getName());
@@ -229,7 +228,7 @@
* Includes the base apk and any splits. Returns null if none found.
*/
static File[] getPackageCodePaths(Rollback rollback, String packageName) {
- File targetDir = new File(rollback.backupDir, packageName);
+ File targetDir = new File(rollback.getBackupDir(), packageName);
File[] files = targetDir.listFiles();
if (files == null || files.length == 0) {
return null;
@@ -243,7 +242,7 @@
*/
static void deletePackageCodePaths(Rollback rollback) {
for (PackageRollbackInfo info : rollback.info.getPackages()) {
- File targetDir = new File(rollback.backupDir, info.getPackageName());
+ File targetDir = new File(rollback.getBackupDir(), info.getPackageName());
removeFile(targetDir);
}
}
@@ -255,13 +254,13 @@
try {
JSONObject dataJson = new JSONObject();
dataJson.put("info", rollbackInfoToJson(rollback.info));
- dataJson.put("timestamp", rollback.timestamp.toString());
- dataJson.put("stagedSessionId", rollback.stagedSessionId);
- dataJson.put("state", rollbackStateToString(rollback.state));
- dataJson.put("apkSessionId", rollback.apkSessionId);
- dataJson.put("restoreUserDataInProgress", rollback.restoreUserDataInProgress);
+ dataJson.put("timestamp", rollback.getTimestamp().toString());
+ dataJson.put("stagedSessionId", rollback.getStagedSessionId());
+ dataJson.put("state", rollback.getStateAsString());
+ dataJson.put("apkSessionId", rollback.getApkSessionId());
+ dataJson.put("restoreUserDataInProgress", rollback.isRestoreUserDataInProgress());
- PrintWriter pw = new PrintWriter(new File(rollback.backupDir, "rollback.json"));
+ PrintWriter pw = new PrintWriter(new File(rollback.getBackupDir(), "rollback.json"));
pw.println(dataJson.toString());
pw.close();
} catch (JSONException e) {
@@ -273,7 +272,7 @@
* Removes all persistent storage associated with the given rollback.
*/
void deleteRollback(Rollback rollback) {
- removeFile(rollback.backupDir);
+ removeFile(rollback.getBackupDir());
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
new file mode 100644
index 0000000..d27f1c7
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackUnitTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.rollback;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+
+@RunWith(JUnit4.class)
+public class RollbackUnitTest {
+
+ @Test
+ public void newEmptyStagedRollbackDefaults() {
+ int rollbackId = 123;
+ int sessionId = 567;
+ File file = new File("/test/testing");
+
+ Rollback rollback = new Rollback(rollbackId, file, sessionId);
+
+ assertThat(rollback.isEnabling()).isTrue();
+ assertThat(rollback.getBackupDir().getAbsolutePath()).isEqualTo("/test/testing");
+ assertThat(rollback.isStaged()).isTrue();
+ assertThat(rollback.getStagedSessionId()).isEqualTo(567);
+ }
+
+ @Test
+ public void newEmptyNonStagedRollbackDefaults() {
+ int rollbackId = 123;
+ File file = new File("/test/testing");
+
+ Rollback rollback = new Rollback(rollbackId, file, -1);
+
+ assertThat(rollback.isEnabling()).isTrue();
+ assertThat(rollback.getBackupDir().getAbsolutePath()).isEqualTo("/test/testing");
+ assertThat(rollback.isStaged()).isFalse();
+ }
+
+ @Test
+ public void rollbackStateChanges() {
+ Rollback rollback = new Rollback(123, new File("/test/testing"), -1);
+
+ assertThat(rollback.isEnabling()).isTrue();
+ assertThat(rollback.isAvailable()).isFalse();
+ assertThat(rollback.isCommitted()).isFalse();
+
+ rollback.setAvailable();
+
+ assertThat(rollback.isEnabling()).isFalse();
+ assertThat(rollback.isAvailable()).isTrue();
+ assertThat(rollback.isCommitted()).isFalse();
+
+ rollback.setCommitted();
+
+ assertThat(rollback.isEnabling()).isFalse();
+ assertThat(rollback.isAvailable()).isFalse();
+ assertThat(rollback.isCommitted()).isTrue();
+ }
+
+}