blob: 4e8c254138de4c8625b73342c8e8e5fe3f56c548 [file] [log] [blame]
Richard Uhlerb29f1452018-09-12 16:38:15 +01001/*
2 * Copyright (C) 2018 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
17package android.content.rollback;
18
19import android.annotation.NonNull;
Richard Uhlerc739c8c2018-12-12 11:03:34 +000020import android.annotation.RequiresPermission;
21import android.annotation.SystemApi;
Richard Uhlerb29f1452018-09-12 16:38:15 +010022import android.annotation.SystemService;
Richard Uhlerb29f1452018-09-12 16:38:15 +010023import android.content.Context;
24import android.content.IntentSender;
Richard Uhlerbf5b5c42019-01-28 15:26:37 +000025import android.content.pm.ParceledListSlice;
26import android.content.pm.VersionedPackage;
Richard Uhlerb29f1452018-09-12 16:38:15 +010027import android.os.RemoteException;
28
29import java.util.List;
30
31/**
32 * Offers the ability to rollback packages after upgrade.
33 * <p>
34 * For packages installed with rollbacks enabled, the RollbackManager can be
35 * used to initiate rollback of those packages for a limited time period after
36 * upgrade.
37 *
Richard Uhlerb29f1452018-09-12 16:38:15 +010038 * @see PackageInstaller.SessionParams#setEnableRollback()
Richard Uhlerc739c8c2018-12-12 11:03:34 +000039 * @hide
Richard Uhlerb29f1452018-09-12 16:38:15 +010040 */
Richard Uhlerc739c8c2018-12-12 11:03:34 +000041@SystemApi
Richard Uhlerb29f1452018-09-12 16:38:15 +010042@SystemService(Context.ROLLBACK_SERVICE)
43public final class RollbackManager {
44 private final String mCallerPackageName;
45 private final IRollbackManager mBinder;
46
47 /** {@hide} */
48 public RollbackManager(Context context, IRollbackManager binder) {
49 mCallerPackageName = context.getPackageName();
50 mBinder = binder;
51 }
52
53 /**
Richard Uhler150ad982019-01-23 15:16:10 +000054 * Returns a list of all currently available rollbacks.
55 *
56 * @throws SecurityException if the caller does not have the
57 * MANAGE_ROLLBACKS permission.
58 */
59 @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
shafikfee3acf2019-03-08 15:44:26 +000060 @NonNull
Richard Uhler150ad982019-01-23 15:16:10 +000061 public List<RollbackInfo> getAvailableRollbacks() {
62 try {
63 return mBinder.getAvailableRollbacks().getList();
64 } catch (RemoteException e) {
65 throw e.rethrowFromSystemServer();
66 }
67 }
68
69 /**
Richard Uhler4b092ef2019-01-24 13:08:38 +000070 * Gets the list of all recently committed rollbacks.
Richard Uhlerb29f1452018-09-12 16:38:15 +010071 * This is for the purposes of preventing re-install of a bad version of a
Richard Uhler4b092ef2019-01-24 13:08:38 +000072 * package and monitoring the status of a staged rollback.
Richard Uhlerb29f1452018-09-12 16:38:15 +010073 * <p>
Richard Uhler4b092ef2019-01-24 13:08:38 +000074 * Returns an empty list if there are no recently committed rollbacks.
Richard Uhlerb29f1452018-09-12 16:38:15 +010075 * <p>
76 * To avoid having to keep around complete rollback history forever on a
77 * device, the returned list of rollbacks is only guaranteed to include
78 * rollbacks that are still relevant. A rollback is no longer considered
79 * relevant if the package is subsequently uninstalled or upgraded
80 * (without the possibility of rollback) to a higher version code than was
81 * rolled back from.
82 *
Richard Uhler4b092ef2019-01-24 13:08:38 +000083 * @return the recently committed rollbacks
Richard Uhlerc739c8c2018-12-12 11:03:34 +000084 * @throws SecurityException if the caller does not have the
85 * MANAGE_ROLLBACKS permission.
Richard Uhlerb29f1452018-09-12 16:38:15 +010086 */
Richard Uhlerc739c8c2018-12-12 11:03:34 +000087 @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
Richard Uhler4b092ef2019-01-24 13:08:38 +000088 public @NonNull List<RollbackInfo> getRecentlyCommittedRollbacks() {
Richard Uhlerb29f1452018-09-12 16:38:15 +010089 try {
90 return mBinder.getRecentlyExecutedRollbacks().getList();
91 } catch (RemoteException e) {
92 throw e.rethrowFromSystemServer();
93 }
94 }
95
96 /**
Richard Uhler2a48c292019-01-28 17:33:48 +000097 * Status of a rollback commit. Will be one of
98 * {@link #STATUS_SUCCESS}, {@link #STATUS_FAILURE},
99 * {@link #STATUS_FAILURE_ROLLBACK_UNAVAILABLE}, {@link #STATUS_FAILURE_INSTALL}
100 *
101 * @see Intent#getIntExtra(String, int)
102 */
103 public static final String EXTRA_STATUS = "android.content.rollback.extra.STATUS";
104
105 /**
106 * Detailed string representation of the status, including raw details that
107 * are useful for debugging.
108 *
109 * @see Intent#getStringExtra(String)
110 */
111 public static final String EXTRA_STATUS_MESSAGE =
112 "android.content.rollback.extra.STATUS_MESSAGE";
113
114 /**
115 * The rollback was successfully committed.
116 */
117 public static final int STATUS_SUCCESS = 0;
118
119 /**
120 * The rollback could not be committed due to some generic failure.
121 *
122 * @see #EXTRA_STATUS_MESSAGE
123 */
124 public static final int STATUS_FAILURE = 1;
125
126 /**
127 * The rollback could not be committed because it was no longer available.
128 *
129 * @see #EXTRA_STATUS_MESSAGE
130 */
131 public static final int STATUS_FAILURE_ROLLBACK_UNAVAILABLE = 2;
132
133 /**
134 * The rollback failed to install successfully.
135 *
136 * @see #EXTRA_STATUS_MESSAGE
137 */
138 public static final int STATUS_FAILURE_INSTALL = 3;
139
140 /**
Richard Uhler4b092ef2019-01-24 13:08:38 +0000141 * Commit the rollback with given id, rolling back all versions of the
142 * packages to the last good versions previously installed on the device
143 * as specified in the corresponding RollbackInfo object. The
144 * rollback will fail if any of the installed packages or available
145 * rollbacks are inconsistent with the versions specified in the given
146 * rollback object, which can happen if a package has been updated or a
147 * rollback expired since the rollback object was retrieved from
148 * {@link #getAvailableRollbacks()}.
Richard Uhlerb29f1452018-09-12 16:38:15 +0100149 *
Richard Uhlere87368e2019-01-24 16:34:14 +0000150 * @param rollbackId ID of the rollback to commit
Richard Uhlerbf5b5c42019-01-28 15:26:37 +0000151 * @param causePackages package versions to record as the motivation for this
152 * rollback.
Richard Uhler2a48c292019-01-28 17:33:48 +0000153 * @param statusReceiver where to deliver the results. Intents sent to
154 * this receiver contain {@link #EXTRA_STATUS}
155 * and {@link #EXTRA_STATUS_MESSAGE}.
Richard Uhlerc739c8c2018-12-12 11:03:34 +0000156 * @throws SecurityException if the caller does not have the
157 * MANAGE_ROLLBACKS permission.
Richard Uhlerb29f1452018-09-12 16:38:15 +0100158 */
Richard Uhlerc739c8c2018-12-12 11:03:34 +0000159 @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
Richard Uhlerbf5b5c42019-01-28 15:26:37 +0000160 public void commitRollback(int rollbackId, @NonNull List<VersionedPackage> causePackages,
161 @NonNull IntentSender statusReceiver) {
Richard Uhlerb29f1452018-09-12 16:38:15 +0100162 try {
Richard Uhlerbf5b5c42019-01-28 15:26:37 +0000163 mBinder.commitRollback(rollbackId, new ParceledListSlice(causePackages),
164 mCallerPackageName, statusReceiver);
Richard Uhlerb29f1452018-09-12 16:38:15 +0100165 } catch (RemoteException e) {
166 throw e.rethrowFromSystemServer();
167 }
168 }
169
170 /**
171 * Reload all persisted rollback data from device storage.
172 * This API is meant to test that rollback state is properly preserved
173 * across device reboot, by simulating what happens on reboot without
174 * actually rebooting the device.
175 *
Richard Uhlerc739c8c2018-12-12 11:03:34 +0000176 * @throws SecurityException if the caller does not have the
177 * MANAGE_ROLLBACKS permission.
Richard Uhlerb29f1452018-09-12 16:38:15 +0100178 */
Richard Uhlerc739c8c2018-12-12 11:03:34 +0000179 @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
Richard Uhlerb29f1452018-09-12 16:38:15 +0100180 public void reloadPersistedData() {
181 try {
182 mBinder.reloadPersistedData();
183 } catch (RemoteException e) {
184 throw e.rethrowFromSystemServer();
185 }
186 }
187
188 /**
189 * Expire the rollback data for a given package.
190 * This API is meant to facilitate testing of rollback logic for
Richard Uhler6f8a33b2019-02-26 10:40:36 +0000191 * expiring rollback data. Removes rollback data for available and
192 * recently committed rollbacks that contain the given package.
Richard Uhlerb29f1452018-09-12 16:38:15 +0100193 *
194 * @param packageName the name of the package to expire data for.
Richard Uhlerc739c8c2018-12-12 11:03:34 +0000195 * @throws SecurityException if the caller does not have the
196 * MANAGE_ROLLBACKS permission.
Richard Uhlerb29f1452018-09-12 16:38:15 +0100197 */
Richard Uhlerc739c8c2018-12-12 11:03:34 +0000198 @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
Richard Uhlerb29f1452018-09-12 16:38:15 +0100199 public void expireRollbackForPackage(@NonNull String packageName) {
200 try {
201 mBinder.expireRollbackForPackage(packageName);
202 } catch (RemoteException e) {
203 throw e.rethrowFromSystemServer();
204 }
205 }
206}