summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/app/SystemServiceRegistry.java12
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/content/Intent.java28
-rw-r--r--core/java/android/content/pm/PackageInstaller.java10
-rw-r--r--core/java/android/content/pm/PackageManager.java11
-rw-r--r--core/java/android/content/pm/PackageManagerInternal.java44
-rw-r--r--core/java/android/content/rollback/IRollbackManager.aidl41
-rw-r--r--core/java/android/content/rollback/PackageRollbackInfo.aidl18
-rw-r--r--core/java/android/content/rollback/PackageRollbackInfo.java109
-rw-r--r--core/java/android/content/rollback/RollbackInfo.aidl18
-rw-r--r--core/java/android/content/rollback/RollbackInfo.java70
-rw-r--r--core/java/android/content/rollback/RollbackManager.java174
12 files changed, 547 insertions, 0 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index fb72f06e541f..3f6ebc8e63e9 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -49,6 +49,8 @@ import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutManager;
import android.content.res.Resources;
+import android.content.rollback.IRollbackManager;
+import android.content.rollback.RollbackManager;
import android.debug.AdbManager;
import android.debug.IAdbManager;
import android.hardware.ConsumerIrManager;
@@ -1169,6 +1171,16 @@ final class SystemServiceRegistry {
throws ServiceNotFoundException {
return new RoleManager(ctx.getOuterContext());
}});
+
+ registerService(Context.ROLLBACK_SERVICE, RollbackManager.class,
+ new CachedServiceFetcher<RollbackManager>() {
+ @Override
+ public RollbackManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(Context.ROLLBACK_SERVICE);
+ return new RollbackManager(ctx.getOuterContext(),
+ IRollbackManager.Stub.asInterface(b));
+ }});
//CHECKSTYLE:ON IndentationCheck
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 5c9fced0f2cb..125c4c6b6503 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3123,6 +3123,7 @@ public abstract class Context {
APPWIDGET_SERVICE,
//@hide: VOICE_INTERACTION_MANAGER_SERVICE,
//@hide: BACKUP_SERVICE,
+ ROLLBACK_SERVICE,
DROPBOX_SERVICE,
//@hide: DEVICE_IDLE_CONTROLLER,
DEVICE_POLICY_SERVICE,
@@ -4003,6 +4004,17 @@ public abstract class Context {
public static final String BACKUP_SERVICE = "backup";
/**
+ * Use with {@link #getSystemService(String)} to retrieve an
+ * {@link android.content.rollback.RollbackManager} for communicating
+ * with the rollback manager
+ *
+ * @see #getSystemService(String)
+ * @hide TODO(ruhler): hidden, @TestApi until we decide on public vs. @SystemApi.
+ */
+ @TestApi
+ public static final String ROLLBACK_SERVICE = "rollback";
+
+ /**
* Use with {@link #getSystemService(String)} to retrieve a
* {@link android.os.DropBoxManager} instance for recording
* diagnostic logs.
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d5c6c63243f6..1e3908c556af 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -27,6 +27,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -2248,6 +2249,32 @@ public class Intent implements Parcelable, Cloneable {
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
/**
+ * Broadcast Action: Sent to the system rollback manager when a package
+ * needs to have rollback enabled.
+ * <p class="note">
+ * This is a protected intent that can only be sent by the system.
+ * </p>
+ *
+ * @hide This broadcast is used internally by the system.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PACKAGE_ENABLE_ROLLBACK =
+ "android.intent.action.PACKAGE_ENABLE_ROLLBACK";
+ /**
+ * Broadcast Action: An existing version of an application package has been
+ * rolled back to a previous version.
+ * The data contains the name of the package.
+ *
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system.
+ *
+ * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi.
+ */
+ @TestApi
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_PACKAGE_ROLLBACK_EXECUTED =
+ "android.intent.action.PACKAGE_ROLLBACK_EXECUTED";
+ /**
* @hide
* Broadcast Action: Ask system services if there is any reason to
* restart the given package. The data contains the name of the
@@ -10343,6 +10370,7 @@ public class Intent implements Parcelable, Cloneable {
case ACTION_MEDIA_SCANNER_SCAN_FILE:
case ACTION_PACKAGE_NEEDS_VERIFICATION:
case ACTION_PACKAGE_VERIFIED:
+ case ACTION_PACKAGE_ENABLE_ROLLBACK:
// Ignore legacy actions
break;
default:
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index f06df3d4dfba..a2fd83f9d8a0 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -24,6 +24,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.AppGlobals;
@@ -1425,6 +1426,15 @@ public class PackageInstaller {
this.grantedRuntimePermissions = permissions;
}
+ /**
+ * Request that rollbacks be enabled for the given upgrade.
+ * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi.
+ */
+ @TestApi
+ public void setEnableRollback() {
+ installFlags |= PackageManager.INSTALL_ENABLE_ROLLBACK;
+ }
+
/** {@hide} */
@SystemApi
public void setAllowDowngrade(boolean allowDowngrade) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 9d604bbd75aa..260879625b01 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -720,6 +720,9 @@ public abstract class PackageManager {
INSTALL_FORCE_SDK,
INSTALL_FULL_APP,
INSTALL_ALLOCATE_AGGRESSIVE,
+ INSTALL_VIRTUAL_PRELOAD,
+ INSTALL_APEX,
+ INSTALL_ENABLE_ROLLBACK,
})
@Retention(RetentionPolicy.SOURCE)
public @interface InstallFlags {}
@@ -857,6 +860,14 @@ public abstract class PackageManager {
*/
public static final int INSTALL_APEX = 0x00020000;
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that rollback
+ * should be enabled for this install.
+ *
+ * @hide
+ */
+ public static final int INSTALL_ENABLE_ROLLBACK = 0x00040000;
+
/** @hide */
@IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
DONT_KILL_APP
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 5db9f506e6e4..83979e925be1 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -759,4 +759,48 @@ public abstract class PackageManagerInternal {
/** Returns whether the given package is enabled for the given user */
public abstract @PackageManager.EnabledState int getApplicationEnabledState(
String packageName, int userId);
+
+ /**
+ * Extra field name for the token of a request to enable rollback for a
+ * package.
+ */
+ public static final String EXTRA_ENABLE_ROLLBACK_TOKEN =
+ "android.content.pm.extra.ENABLE_ROLLBACK_TOKEN";
+
+ /**
+ * Extra field name for the installFlags of a request to enable rollback
+ * for a package.
+ */
+ public static final String EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS =
+ "android.content.pm.extra.ENABLE_ROLLBACK_INSTALL_FLAGS";
+
+ /**
+ * Used as the {@code enableRollbackCode} argument for
+ * {@link PackageManagerInternal#setEnableRollbackCode} to indicate that
+ * enabling rollback succeeded.
+ */
+ public static final int ENABLE_ROLLBACK_SUCCEEDED = 1;
+
+ /**
+ * Used as the {@code enableRollbackCode} argument for
+ * {@link PackageManagerInternal#setEnableRollbackCode} to indicate that
+ * enabling rollback failed.
+ */
+ public static final int ENABLE_ROLLBACK_FAILED = -1;
+
+ /**
+ * Allows the rollback manager listening to the
+ * {@link Intent#ACTION_PACKAGE_ENABLE_ROLLBACK enable rollback broadcast}
+ * to respond to the package manager. The response must include the
+ * {@code enableRollbackCode} which is one of
+ * {@link PackageManager#ENABLE_ROLLBACK_SUCCEEDED} or
+ * {@link PackageManager#ENABLE_ROLLBACK_FAILED}.
+ *
+ * @param token pending package identifier as passed via the
+ * {@link PackageManager#EXTRA_ENABLE_ROLLBACK_TOKEN} Intent extra.
+ * @param enableRollbackCode the status code result of enabling rollback
+ * @throws SecurityException if the caller does not have the
+ * PACKAGE_ROLLBACK_AGENT permission.
+ */
+ public abstract void setEnableRollbackCode(int token, int enableRollbackCode);
}
diff --git a/core/java/android/content/rollback/IRollbackManager.aidl b/core/java/android/content/rollback/IRollbackManager.aidl
new file mode 100644
index 000000000000..7f557cd8bbe8
--- /dev/null
+++ b/core/java/android/content/rollback/IRollbackManager.aidl
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2018, 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 android.content.rollback;
+
+import android.content.pm.ParceledListSlice;
+import android.content.pm.StringParceledListSlice;
+import android.content.rollback.RollbackInfo;
+import android.content.IntentSender;
+
+/** {@hide} */
+interface IRollbackManager {
+
+ RollbackInfo getAvailableRollback(String packageName);
+
+ StringParceledListSlice getPackagesWithAvailableRollbacks();
+
+ ParceledListSlice getRecentlyExecutedRollbacks();
+
+ void executeRollback(in RollbackInfo rollback, String callerPackageName,
+ in IntentSender statusReceiver);
+
+ // Exposed for test purposes only.
+ void reloadPersistedData();
+
+ // Exposed for test purposes only.
+ void expireRollbackForPackage(String packageName);
+}
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.aidl b/core/java/android/content/rollback/PackageRollbackInfo.aidl
new file mode 100644
index 000000000000..9cb52c982754
--- /dev/null
+++ b/core/java/android/content/rollback/PackageRollbackInfo.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2018 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 android.content.rollback;
+
+parcelable PackageRollbackInfo;
diff --git a/core/java/android/content/rollback/PackageRollbackInfo.java b/core/java/android/content/rollback/PackageRollbackInfo.java
new file mode 100644
index 000000000000..0c057656d59a
--- /dev/null
+++ b/core/java/android/content/rollback/PackageRollbackInfo.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2018 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 android.content.rollback;
+
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Information about a rollback available for a particular package.
+ *
+ * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi.
+ */
+@TestApi
+public final class PackageRollbackInfo implements Parcelable {
+ /**
+ * The name of a package being rolled back.
+ */
+ public final String packageName;
+
+ /**
+ * The version the package was rolled back from.
+ */
+ public final PackageVersion higherVersion;
+
+ /**
+ * The version the package was rolled back to.
+ */
+ public final PackageVersion lowerVersion;
+
+ /**
+ * Represents a version of a package.
+ */
+ public static class PackageVersion {
+ public final long versionCode;
+
+ // TODO(b/120200473): Include apk sha or some other way to distinguish
+ // between two different apks with the same version code.
+ public PackageVersion(long versionCode) {
+ this.versionCode = versionCode;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof PackageVersion) {
+ PackageVersion otherVersion = (PackageVersion) other;
+ return versionCode == otherVersion.versionCode;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(versionCode);
+ }
+ }
+
+ public PackageRollbackInfo(String packageName,
+ PackageVersion higherVersion, PackageVersion lowerVersion) {
+ this.packageName = packageName;
+ this.higherVersion = higherVersion;
+ this.lowerVersion = lowerVersion;
+ }
+
+ private PackageRollbackInfo(Parcel in) {
+ this.packageName = in.readString();
+ this.higherVersion = new PackageVersion(in.readLong());
+ this.lowerVersion = new PackageVersion(in.readLong());
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(packageName);
+ out.writeLong(higherVersion.versionCode);
+ out.writeLong(lowerVersion.versionCode);
+ }
+
+ public static final Parcelable.Creator<PackageRollbackInfo> CREATOR =
+ new Parcelable.Creator<PackageRollbackInfo>() {
+ public PackageRollbackInfo createFromParcel(Parcel in) {
+ return new PackageRollbackInfo(in);
+ }
+
+ public PackageRollbackInfo[] newArray(int size) {
+ return new PackageRollbackInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/content/rollback/RollbackInfo.aidl b/core/java/android/content/rollback/RollbackInfo.aidl
new file mode 100644
index 000000000000..a9dc5cd59cbb
--- /dev/null
+++ b/core/java/android/content/rollback/RollbackInfo.aidl
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2018 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 android.content.rollback;
+
+parcelable RollbackInfo;
diff --git a/core/java/android/content/rollback/RollbackInfo.java b/core/java/android/content/rollback/RollbackInfo.java
new file mode 100644
index 000000000000..5fa4e57e78e5
--- /dev/null
+++ b/core/java/android/content/rollback/RollbackInfo.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 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 android.content.rollback;
+
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Information about a set of packages that can be, or already have been
+ * rolled back together.
+ *
+ * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi.
+ */
+@TestApi
+public final class RollbackInfo implements Parcelable {
+
+ /**
+ * The package that needs to be rolled back.
+ */
+ public final PackageRollbackInfo targetPackage;
+
+ // TODO: Add a list of additional packages rolled back due to atomic
+ // install dependencies when rollback of atomic installs is supported.
+ // TODO: Add a flag to indicate if reboot is required, when rollback of
+ // staged installs is supported.
+
+ public RollbackInfo(PackageRollbackInfo targetPackage) {
+ this.targetPackage = targetPackage;
+ }
+
+ private RollbackInfo(Parcel in) {
+ this.targetPackage = PackageRollbackInfo.CREATOR.createFromParcel(in);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ targetPackage.writeToParcel(out, flags);
+ }
+
+ public static final Parcelable.Creator<RollbackInfo> CREATOR =
+ new Parcelable.Creator<RollbackInfo>() {
+ public RollbackInfo createFromParcel(Parcel in) {
+ return new RollbackInfo(in);
+ }
+
+ public RollbackInfo[] newArray(int size) {
+ return new RollbackInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/content/rollback/RollbackManager.java b/core/java/android/content/rollback/RollbackManager.java
new file mode 100644
index 000000000000..294151aff82c
--- /dev/null
+++ b/core/java/android/content/rollback/RollbackManager.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2018 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 android.content.rollback;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.content.IntentSender;
+import android.os.RemoteException;
+
+import java.util.List;
+
+/**
+ * Offers the ability to rollback packages after upgrade.
+ * <p>
+ * For packages installed with rollbacks enabled, the RollbackManager can be
+ * used to initiate rollback of those packages for a limited time period after
+ * upgrade.
+ *
+ * TODO: Require an appropriate permission for apps to use these APIs.
+ *
+ * @see PackageInstaller.SessionParams#setEnableRollback()
+ * @hide TODO: hidden, @TestApi until we decide on public vs. @SystemApi.
+ */
+@TestApi
+@SystemService(Context.ROLLBACK_SERVICE)
+public final class RollbackManager {
+ private final String mCallerPackageName;
+ private final IRollbackManager mBinder;
+
+ /** {@hide} */
+ public RollbackManager(Context context, IRollbackManager binder) {
+ mCallerPackageName = context.getPackageName();
+ mBinder = binder;
+ }
+
+ /**
+ * Returns the rollback currently available to be executed for the given
+ * package.
+ * <p>
+ * The returned RollbackInfo describes what packages would be rolled back,
+ * including package version codes before and after rollback. The rollback
+ * can be initiated using {@link #executeRollback(RollbackInfo,IntentSender)}.
+ * <p>
+ * TODO: What if there is no package installed on device for packageName?
+ *
+ * @param packageName name of the package to get the availble RollbackInfo for.
+ * @return the rollback available for the package, or null if no rollback
+ * is available for the package.
+ */
+ public @Nullable RollbackInfo getAvailableRollback(@NonNull String packageName) {
+ try {
+ return mBinder.getAvailableRollback(packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Gets the names of packages that are available for rollback.
+ * Call {@link #getAvailableRollback(String)} to get more information
+ * about the rollback available for a particular package.
+ *
+ * @return the names of packages that are available for rollback.
+ */
+ public @NonNull List<String> getPackagesWithAvailableRollbacks() {
+ try {
+ return mBinder.getPackagesWithAvailableRollbacks().getList();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+
+ /**
+ * Gets the list of all recently executed rollbacks.
+ * This is for the purposes of preventing re-install of a bad version of a
+ * package.
+ * <p>
+ * Returns an empty list if there are no recently executed rollbacks.
+ * <p>
+ * To avoid having to keep around complete rollback history forever on a
+ * device, the returned list of rollbacks is only guaranteed to include
+ * rollbacks that are still relevant. A rollback is no longer considered
+ * relevant if the package is subsequently uninstalled or upgraded
+ * (without the possibility of rollback) to a higher version code than was
+ * rolled back from.
+ *
+ * @return the recently executed rollbacks
+ */
+ public @NonNull List<RollbackInfo> getRecentlyExecutedRollbacks() {
+ try {
+ return mBinder.getRecentlyExecutedRollbacks().getList();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Execute the given rollback, rolling back all versions of the packages
+ * to the last good versions previously installed on the device as
+ * specified in the given rollback object. The rollback will fail if any
+ * of the installed packages or available rollbacks are inconsistent with
+ * the versions specified in the given rollback object, which can happen
+ * if a package has been updated or a rollback expired since the rollback
+ * object was retrieved from {@link #getAvailableRollback(String)}.
+ * <p>
+ * TODO: Specify the returns status codes.
+ * TODO: What happens in case reboot is required for the rollback to take
+ * effect for staged installs?
+ *
+ * @param rollback to execute
+ * @param statusReceiver where to deliver the results
+ */
+ public void executeRollback(@NonNull RollbackInfo rollback,
+ @NonNull IntentSender statusReceiver) {
+ try {
+ mBinder.executeRollback(rollback, mCallerPackageName, statusReceiver);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Reload all persisted rollback data from device storage.
+ * This API is meant to test that rollback state is properly preserved
+ * across device reboot, by simulating what happens on reboot without
+ * actually rebooting the device.
+ *
+ * @hide
+ */
+ @TestApi
+ public void reloadPersistedData() {
+ try {
+ mBinder.reloadPersistedData();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Expire the rollback data for a given package.
+ * This API is meant to facilitate testing of rollback logic for
+ * expiring rollback data.
+ *
+ * @param packageName the name of the package to expire data for.
+ *
+ * @hide
+ */
+ @TestApi
+ public void expireRollbackForPackage(@NonNull String packageName) {
+ try {
+ mBinder.expireRollbackForPackage(packageName);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+}