Merge "typo fix in AEP Cider G test session. Configuraton --> configuration." into main
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index cdeddfb..250a6ff 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -3860,6 +3860,7 @@
method public void setInstallAsInstantApp(boolean);
method public void setInstallAsVirtualPreload();
method public void setRequestDowngrade(boolean);
+ method @FlaggedApi("android.content.pm.recoverability_detection") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackImpactLevel(int);
method @FlaggedApi("android.content.pm.rollback_lifetime") @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS) public void setRollbackLifetimeMillis(long);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setStaged();
}
@@ -4023,6 +4024,9 @@
field public static final int ROLLBACK_DATA_POLICY_RESTORE = 0; // 0x0
field public static final int ROLLBACK_DATA_POLICY_RETAIN = 2; // 0x2
field public static final int ROLLBACK_DATA_POLICY_WIPE = 1; // 0x1
+ field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_HIGH = 1; // 0x1
+ field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_LOW = 0; // 0x0
+ field @FlaggedApi("android.content.pm.recoverability_detection") public static final int ROLLBACK_USER_IMPACT_ONLY_MANUAL = 2; // 0x2
field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_HIDDEN = 0; // 0x0
field public static final int SYSTEM_APP_STATE_HIDDEN_UNTIL_INSTALLED_VISIBLE = 1; // 0x1
field public static final int SYSTEM_APP_STATE_INSTALLED = 2; // 0x2
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index e3bb53a..32b031b 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1148,6 +1148,10 @@
package android.content.rollback {
+ public final class RollbackInfo implements android.os.Parcelable {
+ method @FlaggedApi("android.content.pm.recoverability_detection") public int getRollbackImpactLevel();
+ }
+
public final class RollbackManager {
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void blockRollbackManager(long);
method @RequiresPermission(android.Manifest.permission.TEST_MANAGE_ROLLBACKS) public void expireRollbackForPackage(@NonNull String);
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index f946754..01ea4e9 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -664,7 +664,7 @@
* has at least one HTTP or HTTPS data URI pattern defined, and optionally
* does not define any non-http/https data URI patterns.
*
- * This will check if if the Intent action is {@link android.content.Intent#ACTION_VIEW} and
+ * This will check if the Intent action is {@link android.content.Intent#ACTION_VIEW} and
* the Intent category is {@link android.content.Intent#CATEGORY_BROWSABLE} and the Intent
* data scheme is "http" or "https".
*
@@ -705,7 +705,7 @@
}
// We get here if:
- // 1) onlyWebSchemes and no non-web schemes were found, i.e success; or
+ // 1) onlyWebSchemes and no non-web schemes were found, i.e. success; or
// 2) !onlyWebSchemes and no http/https schemes were found, i.e. failure.
return onlyWebSchemes;
}
@@ -715,7 +715,7 @@
*
* @return True if the filter needs to be automatically verified. False otherwise.
*
- * This will check if if the Intent action is {@link android.content.Intent#ACTION_VIEW} and
+ * This will check if the Intent action is {@link android.content.Intent#ACTION_VIEW} and
* the Intent category is {@link android.content.Intent#CATEGORY_BROWSABLE} and the Intent
* data scheme is "http" or "https".
*
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 0897f85..6ca6194 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -2374,6 +2374,8 @@
/** @hide */
public long rollbackLifetimeMillis = 0;
/** {@hide} */
+ public int rollbackImpactLevel = PackageManager.ROLLBACK_USER_IMPACT_LOW;
+ /** {@hide} */
public boolean forceQueryableOverride;
/** {@hide} */
public int requireUserAction = USER_ACTION_UNSPECIFIED;
@@ -2428,6 +2430,7 @@
}
rollbackDataPolicy = source.readInt();
rollbackLifetimeMillis = source.readLong();
+ rollbackImpactLevel = source.readInt();
requireUserAction = source.readInt();
packageSource = source.readInt();
applicationEnabledSettingPersistent = source.readBoolean();
@@ -2461,6 +2464,7 @@
ret.dataLoaderParams = dataLoaderParams;
ret.rollbackDataPolicy = rollbackDataPolicy;
ret.rollbackLifetimeMillis = rollbackLifetimeMillis;
+ ret.rollbackImpactLevel = rollbackImpactLevel;
ret.requireUserAction = requireUserAction;
ret.packageSource = packageSource;
ret.applicationEnabledSettingPersistent = applicationEnabledSettingPersistent;
@@ -2799,6 +2803,28 @@
}
/**
+ * rollbackImpactLevel is a measure of impact a rollback has on the user. This can take one
+ * of 3 values:
+ * <ul>
+ * <li>{@link PackageManager#ROLLBACK_USER_IMPACT_LOW} (default)</li>
+ * <li>{@link PackageManager#ROLLBACK_USER_IMPACT_HIGH} (1)</li>
+ * <li>{@link PackageManager#ROLLBACK_USER_IMPACT_ONLY_MANUAL} (2)</li>
+ * </ul>
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_ROLLBACKS)
+ @FlaggedApi(Flags.FLAG_RECOVERABILITY_DETECTION)
+ public void setRollbackImpactLevel(@PackageManager.RollbackImpactLevel int impactLevel) {
+ if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
+ throw new IllegalArgumentException(
+ "Can't set rollbackImpactLevel when rollback is not enabled");
+ }
+ rollbackImpactLevel = impactLevel;
+ }
+
+ /**
* @deprecated use {@link #setRequestDowngrade(boolean)}.
* {@hide}
*/
@@ -3152,6 +3178,7 @@
pw.printPair("dataLoaderParams", dataLoaderParams);
pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
pw.printPair("rollbackLifetimeMillis", rollbackLifetimeMillis);
+ pw.printPair("rollbackImpactLevel", rollbackImpactLevel);
pw.printPair("applicationEnabledSettingPersistent",
applicationEnabledSettingPersistent);
pw.printHexPair("developmentInstallFlags", developmentInstallFlags);
@@ -3194,6 +3221,7 @@
}
dest.writeInt(rollbackDataPolicy);
dest.writeLong(rollbackLifetimeMillis);
+ dest.writeInt(rollbackImpactLevel);
dest.writeInt(requireUserAction);
dest.writeInt(packageSource);
dest.writeBoolean(applicationEnabledSettingPersistent);
@@ -3391,6 +3419,9 @@
public long rollbackLifetimeMillis;
/** {@hide} */
+ public int rollbackImpactLevel;
+
+ /** {@hide} */
public int requireUserAction;
/** {@hide} */
@@ -3458,6 +3489,7 @@
isPreapprovalRequested = source.readBoolean();
rollbackDataPolicy = source.readInt();
rollbackLifetimeMillis = source.readLong();
+ rollbackImpactLevel = source.readInt();
createdMillis = source.readLong();
requireUserAction = source.readInt();
installerUid = source.readInt();
@@ -4082,6 +4114,7 @@
dest.writeBoolean(isPreapprovalRequested);
dest.writeInt(rollbackDataPolicy);
dest.writeLong(rollbackLifetimeMillis);
+ dest.writeInt(rollbackImpactLevel);
dest.writeLong(createdMillis);
dest.writeInt(requireUserAction);
dest.writeInt(installerUid);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 1bc0418..6b156cf 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -1429,6 +1429,44 @@
public static final int ROLLBACK_DATA_POLICY_RETAIN = 2;
/** @hide */
+ @IntDef(prefix = {"ROLLBACK_USER_IMPACT_"}, value = {
+ ROLLBACK_USER_IMPACT_LOW,
+ ROLLBACK_USER_IMPACT_HIGH,
+ ROLLBACK_USER_IMPACT_ONLY_MANUAL,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RollbackImpactLevel {}
+
+ /**
+ * Rollback will be performed automatically in response to native crashes on startup or
+ * persistent service crashes. More suitable for apps that do not store any user data.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
+ public static final int ROLLBACK_USER_IMPACT_LOW = 0;
+
+ /**
+ * Rollback will be performed automatically only when the device is found to be unrecoverable.
+ * More suitable for apps that store user data and have higher impact on user.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
+ public static final int ROLLBACK_USER_IMPACT_HIGH = 1;
+
+ /**
+ * Rollback will not be performed automatically. It can be triggered externally.
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(android.content.pm.Flags.FLAG_RECOVERABILITY_DETECTION)
+ public static final int ROLLBACK_USER_IMPACT_ONLY_MANUAL = 2;
+
+ /** @hide */
@IntDef(flag = true, prefix = { "INSTALL_" }, value = {
INSTALL_REPLACE_EXISTING,
INSTALL_ALLOW_TEST,
diff --git a/core/java/android/content/rollback/RollbackInfo.java b/core/java/android/content/rollback/RollbackInfo.java
index a363718..d128055 100644
--- a/core/java/android/content/rollback/RollbackInfo.java
+++ b/core/java/android/content/rollback/RollbackInfo.java
@@ -16,8 +16,12 @@
package android.content.rollback;
+import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.pm.Flags;
+import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -25,17 +29,14 @@
import java.util.List;
/**
- * Information about a set of packages that can be, or already have been
- * rolled back together.
+ * Information about a set of packages that can be, or already have been rolled back together.
*
* @hide
*/
@SystemApi
public final class RollbackInfo implements Parcelable {
- /**
- * A unique identifier for the rollback.
- */
+ /** A unique identifier for the rollback. */
private final int mRollbackId;
private final List<PackageRollbackInfo> mPackages;
@@ -44,15 +45,39 @@
private final boolean mIsStaged;
private int mCommittedSessionId;
+ private int mRollbackImpactLevel;
/** @hide */
- public RollbackInfo(int rollbackId, List<PackageRollbackInfo> packages, boolean isStaged,
- List<VersionedPackage> causePackages, int committedSessionId) {
+ public RollbackInfo(
+ int rollbackId,
+ List<PackageRollbackInfo> packages,
+ boolean isStaged,
+ List<VersionedPackage> causePackages,
+ int committedSessionId,
+ @PackageManager.RollbackImpactLevel int rollbackImpactLevel) {
this.mRollbackId = rollbackId;
this.mPackages = packages;
this.mIsStaged = isStaged;
this.mCausePackages = causePackages;
this.mCommittedSessionId = committedSessionId;
+ this.mRollbackImpactLevel = rollbackImpactLevel;
+ }
+
+ /** @hide */
+ public RollbackInfo(
+ int rollbackId,
+ List<PackageRollbackInfo> packages,
+ boolean isStaged,
+ List<VersionedPackage> causePackages,
+ int committedSessionId) {
+ // If impact level is not set default to 0
+ this(
+ rollbackId,
+ packages,
+ isStaged,
+ causePackages,
+ committedSessionId,
+ PackageManager.ROLLBACK_USER_IMPACT_LOW);
}
private RollbackInfo(Parcel in) {
@@ -61,34 +86,28 @@
mIsStaged = in.readBoolean();
mCausePackages = in.createTypedArrayList(VersionedPackage.CREATOR);
mCommittedSessionId = in.readInt();
+ mRollbackImpactLevel = in.readInt();
}
- /**
- * Returns a unique identifier for this rollback.
- */
+ /** Returns a unique identifier for this rollback. */
public int getRollbackId() {
return mRollbackId;
}
- /**
- * Returns the list of package that are rolled back.
- */
+ /** Returns the list of package that are rolled back. */
@NonNull
public List<PackageRollbackInfo> getPackages() {
return mPackages;
}
- /**
- * Returns true if this rollback requires reboot to take effect after
- * being committed.
- */
+ /** Returns true if this rollback requires reboot to take effect after being committed. */
public boolean isStaged() {
return mIsStaged;
}
/**
- * Returns the session ID for the committed rollback for staged rollbacks.
- * Only applicable for rollbacks that have been committed.
+ * Returns the session ID for the committed rollback for staged rollbacks. Only applicable for
+ * rollbacks that have been committed.
*/
public int getCommittedSessionId() {
return mCommittedSessionId;
@@ -96,6 +115,7 @@
/**
* Sets the session ID for the committed rollback for staged rollbacks.
+ *
* @hide
*/
public void setCommittedSessionId(int sessionId) {
@@ -103,15 +123,40 @@
}
/**
- * Gets the list of package versions that motivated this rollback.
- * As provided to {@link #commitRollback} when the rollback was committed.
- * This is only applicable for rollbacks that have been committed.
+ * Gets the list of package versions that motivated this rollback. As provided to {@link
+ * #commitRollback} when the rollback was committed. This is only applicable for rollbacks that
+ * have been committed.
*/
@NonNull
public List<VersionedPackage> getCausePackages() {
return mCausePackages;
}
+ /**
+ * Get rollback impact level. Refer {@link
+ * android.content.pm.PackageInstaller.SessionParams#setRollbackImpactLevel(int)} for more info
+ * on impact level.
+ *
+ * @hide
+ */
+ @TestApi
+ @FlaggedApi(Flags.FLAG_RECOVERABILITY_DETECTION)
+ public @PackageManager.RollbackImpactLevel int getRollbackImpactLevel() {
+ return mRollbackImpactLevel;
+ }
+
+ /**
+ * Set rollback impact level. Refer {@link
+ * android.content.pm.PackageInstaller.SessionParams#setRollbackImpactLevel(int)} for more info
+ * on impact level.
+ *
+ * @hide
+ */
+ public void setRollbackImpactLevel(
+ @PackageManager.RollbackImpactLevel int rollbackImpactLevel) {
+ mRollbackImpactLevel = rollbackImpactLevel;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -124,16 +169,17 @@
out.writeBoolean(mIsStaged);
out.writeTypedList(mCausePackages);
out.writeInt(mCommittedSessionId);
+ out.writeInt(mRollbackImpactLevel);
}
public static final @android.annotation.NonNull Parcelable.Creator<RollbackInfo> CREATOR =
new Parcelable.Creator<RollbackInfo>() {
- public RollbackInfo createFromParcel(Parcel in) {
- return new RollbackInfo(in);
- }
+ public RollbackInfo createFromParcel(Parcel in) {
+ return new RollbackInfo(in);
+ }
- public RollbackInfo[] newArray(int size) {
- return new RollbackInfo[size];
- }
- };
+ public RollbackInfo[] newArray(int size) {
+ return new RollbackInfo[size];
+ }
+ };
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index f5635f4..720324c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5758,7 +5758,7 @@
<permission android:name="android.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS"
android:protectionLevel="signature|privileged" />
- <!-- Allows an application to collect usage infomation about brightness slider changes.
+ <!-- Allows an application to collect usage information about brightness slider changes.
<p>Not for use by third-party applications.</p>
@hide
@SystemApi
diff --git a/core/res/res/layout/app_perms_summary.xml b/core/res/res/layout/app_perms_summary.xml
index b8d93ac..509b988 100644
--- a/core/res/res/layout/app_perms_summary.xml
+++ b/core/res/res/layout/app_perms_summary.xml
@@ -14,7 +14,7 @@
limitations under the License.
-->
-<!-- Describes permission item consisting of a group name and the list of permisisons under the group -->
+<!-- Describes permission item consisting of a group name and the list of permissions under the group -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java
index 6a6a951..00afba8d 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java
@@ -264,7 +264,7 @@
int scanStatus = mRadioTuner.scan(RadioTuner.DIRECTION_DOWN, /* skipSubChannel= */ false);
verify(mTunerMock).seek(/* directionDown= */ true, /* skipSubChannel= */ false);
- assertWithMessage("Status for scaning")
+ assertWithMessage("Status for scanning")
.that(scanStatus).isEqualTo(RadioManager.STATUS_OK);
verify(mCallbackMock, timeout(CALLBACK_TIMEOUT_MS)).onProgramInfoChanged(FM_PROGRAM_INFO);
}
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
index 0806fa0..db95d7a 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerStressTestRunner.java
@@ -99,7 +99,7 @@
}
}
- public int getSoftApInterations() {
+ public int getSoftApIterations() {
return mSoftApIterations;
}
diff --git a/graphics/java/android/view/PixelCopy.java b/graphics/java/android/view/PixelCopy.java
index 0e198d5..1200ff9 100644
--- a/graphics/java/android/view/PixelCopy.java
+++ b/graphics/java/android/view/PixelCopy.java
@@ -96,7 +96,7 @@
*
* The contents of the source will be scaled to fit exactly inside the bitmap.
* The pixel format of the source buffer will be converted, as part of the copy,
- * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+ * to fit the bitmap's {@link Bitmap.Config}. The most recently queued buffer
* in the SurfaceView's Surface will be used as the source of the copy.
*
* @param source The source from which to copy
@@ -117,7 +117,7 @@
*
* The contents of the source will be scaled to fit exactly inside the bitmap.
* The pixel format of the source buffer will be converted, as part of the copy,
- * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+ * to fit the bitmap's {@link Bitmap.Config}. The most recently queued buffer
* in the SurfaceView's Surface will be used as the source of the copy.
*
* @param source The source from which to copy
@@ -143,7 +143,7 @@
*
* The contents of the source will be scaled to fit exactly inside the bitmap.
* The pixel format of the source buffer will be converted, as part of the copy,
- * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+ * to fit the bitmap's {@link Bitmap.Config}. The most recently queued buffer
* in the Surface will be used as the source of the copy.
*
* @param source The source from which to copy
@@ -164,7 +164,7 @@
*
* The contents of the source rect will be scaled to fit exactly inside the bitmap.
* The pixel format of the source buffer will be converted, as part of the copy,
- * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+ * to fit the bitmap's {@link Bitmap.Config}. The most recently queued buffer
* in the Surface will be used as the source of the copy.
*
* @param source The source from which to copy
@@ -201,7 +201,7 @@
*
* The contents of the source will be scaled to fit exactly inside the bitmap.
* The pixel format of the source buffer will be converted, as part of the copy,
- * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+ * to fit the bitmap's {@link Bitmap.Config}. The most recently queued buffer
* in the Window's Surface will be used as the source of the copy.
*
* Note: This is limited to being able to copy from Window's with a non-null
@@ -231,7 +231,7 @@
*
* The contents of the source rect will be scaled to fit exactly inside the bitmap.
* The pixel format of the source buffer will be converted, as part of the copy,
- * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
+ * to fit the bitmap's {@link Bitmap.Config}. The most recently queued buffer
* in the Window's Surface will be used as the source of the copy.
*
* Note: This is limited to being able to copy from Window's with a non-null
diff --git a/media/java/android/media/AudioHalVersionInfo.java b/media/java/android/media/AudioHalVersionInfo.java
index b0c68d6..472cb3f 100644
--- a/media/java/android/media/AudioHalVersionInfo.java
+++ b/media/java/android/media/AudioHalVersionInfo.java
@@ -76,6 +76,9 @@
/**
* List of all valid Audio HAL versions. This list need to be in sync with sAudioHALVersions
* defined in frameworks/av/media/libaudiohal/FactoryHal.cpp.
+ *
+ * Note: update {@link android.media.audio.cts.AudioHalVersionInfoTest} CTS accordingly if
+ * there is a change to supported versions.
*/
public static final @NonNull List<AudioHalVersionInfo> VERSIONS =
List.of(AIDL_1_0, HIDL_7_1, HIDL_7_0, HIDL_6_0, HIDL_5_0);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 7c307bd..57b89e3 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -762,6 +762,24 @@
}
}
+ if (Flags.recoverabilityDetection()) {
+ if (params.rollbackImpactLevel == PackageManager.ROLLBACK_USER_IMPACT_HIGH
+ || params.rollbackImpactLevel
+ == PackageManager.ROLLBACK_USER_IMPACT_ONLY_MANUAL) {
+ if ((params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) == 0) {
+ throw new IllegalArgumentException(
+ "Can't set rollbackImpactLevel when rollback is not enabled");
+ }
+ if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_ROLLBACKS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Setting rollbackImpactLevel requires the MANAGE_ROLLBACKS permission");
+ }
+ } else if (params.rollbackImpactLevel < 0) {
+ throw new IllegalArgumentException("rollbackImpactLevel can't be negative.");
+ }
+ }
+
boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0;
if (isApex) {
if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGE_UPDATES)
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 94c6b8b..fbd6526 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -1207,6 +1207,7 @@
info.autoRevokePermissionsMode = params.autoRevokePermissionsMode;
info.installFlags = params.installFlags;
info.rollbackLifetimeMillis = params.rollbackLifetimeMillis;
+ info.rollbackImpactLevel = params.rollbackImpactLevel;
info.isMultiPackage = params.isMultiPackage;
info.isStaged = params.isStaged;
info.rollbackDataPolicy = params.rollbackDataPolicy;
diff --git a/services/core/java/com/android/server/rollback/Rollback.java b/services/core/java/com/android/server/rollback/Rollback.java
index a5b90f1..a580bb7 100644
--- a/services/core/java/com/android/server/rollback/Rollback.java
+++ b/services/core/java/com/android/server/rollback/Rollback.java
@@ -215,7 +215,8 @@
/* packages */ new ArrayList<>(),
/* isStaged */ isStaged,
/* causePackages */ new ArrayList<>(),
- /* committedSessionId */ -1);
+ /* committedSessionId */ -1,
+ /* rollbackImpactLevel */ PackageManager.ROLLBACK_USER_IMPACT_LOW);
mUserId = userId;
mInstallerPackageName = installerPackageName;
mBackupDir = backupDir;
@@ -394,7 +395,8 @@
*/
@WorkerThread
boolean enableForPackage(String packageName, long newVersion, long installedVersion,
- boolean isApex, String sourceDir, String[] splitSourceDirs, int rollbackDataPolicy) {
+ boolean isApex, String sourceDir, String[] splitSourceDirs, int rollbackDataPolicy,
+ @PackageManager.RollbackImpactLevel int rollbackImpactLevel) {
assertInWorkerThread();
try {
RollbackStore.backupPackageCodePath(this, packageName, sourceDir);
@@ -415,6 +417,10 @@
isApex, false /* isApkInApex */, new ArrayList<>(), rollbackDataPolicy);
info.getPackages().add(packageRollbackInfo);
+
+ if (info.getRollbackImpactLevel() < rollbackImpactLevel) {
+ info.setRollbackImpactLevel(rollbackImpactLevel);
+ }
return true;
}
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index b38d6c7..d96fc33 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -954,7 +954,7 @@
ApplicationInfo appInfo = pkgInfo.applicationInfo;
return rollback.enableForPackage(packageName, newPackage.getVersionCode(),
pkgInfo.getLongVersionCode(), isApex, appInfo.sourceDir,
- appInfo.splitSourceDirs, rollbackDataPolicy);
+ appInfo.splitSourceDirs, rollbackDataPolicy, session.rollbackImpactLevel);
}
@ExtThread
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index 0af137f..14539d5 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -193,16 +193,27 @@
json.put("isStaged", rollback.isStaged());
json.put("causePackages", versionedPackagesToJson(rollback.getCausePackages()));
json.put("committedSessionId", rollback.getCommittedSessionId());
+ if (Flags.recoverabilityDetection()) {
+ json.put("rollbackImpactLevel", rollback.getRollbackImpactLevel());
+ }
return json;
}
private static RollbackInfo rollbackInfoFromJson(JSONObject json) throws JSONException {
- return new RollbackInfo(
+ RollbackInfo rollbackInfo = new RollbackInfo(
json.getInt("rollbackId"),
packageRollbackInfosFromJson(json.getJSONArray("packages")),
json.getBoolean("isStaged"),
versionedPackagesFromJson(json.getJSONArray("causePackages")),
json.getInt("committedSessionId"));
+
+ if (Flags.recoverabilityDetection()) {
+ // to make it backward compatible.
+ rollbackInfo.setRollbackImpactLevel(json.optInt("rollbackImpactLevel",
+ PackageManager.ROLLBACK_USER_IMPACT_LOW));
+ }
+
+ return rollbackInfo;
}
/**
diff --git a/services/tests/mockingservicestests/src/com/android/server/OWNERS b/services/tests/mockingservicestests/src/com/android/server/OWNERS
index c0f0ce0..b363f54 100644
--- a/services/tests/mockingservicestests/src/com/android/server/OWNERS
+++ b/services/tests/mockingservicestests/src/com/android/server/OWNERS
@@ -1,3 +1,4 @@
per-file *Alarm* = file:/apex/jobscheduler/OWNERS
per-file *AppStateTracker* = file:/apex/jobscheduler/OWNERS
per-file *DeviceIdleController* = file:/apex/jobscheduler/OWNERS
+per-file SensitiveContentProtectionManagerServiceTest.java = file:/core/java/android/permission/OWNERS
diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
index 9d56a36..5e11e17 100644
--- a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
+import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
import android.util.SparseIntArray;
@@ -81,7 +82,8 @@
+ "'installedUsers':[55,79],"
+ "'ceSnapshotInodes':[]}],'isStaged':false,'causePackages':[{'packageName':'hello',"
+ "'longVersionCode':23},{'packageName':'something','longVersionCode':999}],"
- + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z',"
+ + "'committedSessionId':45654465, 'rollbackImpactLevel':1},"
+ + "'timestamp':'2019-10-01T12:29:08.855Z',"
+ "'originalSessionId':567,'state':'enabling','apkSessionId':-1,"
+ "'restoreUserDataInProgress':true, 'userId':0,"
+ "'installerPackageName':'some.installer'}";
@@ -138,6 +140,8 @@
assertThat(rollback.getOriginalSessionId()).isEqualTo(567);
assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
assertThat(rollback.info.getPackages()).isEmpty();
+ assertThat(rollback.info.getRollbackImpactLevel()).isEqualTo(
+ PackageManager.ROLLBACK_USER_IMPACT_LOW);
assertThat(rollback.isEnabling()).isTrue();
assertThat(rollback.getExtensionVersions().toString())
.isEqualTo(extensionVersions.toString());
@@ -158,6 +162,8 @@
assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
assertThat(rollback.info.getPackages()).isEmpty();
+ assertThat(rollback.info.getRollbackImpactLevel()).isEqualTo(
+ PackageManager.ROLLBACK_USER_IMPACT_LOW);
assertThat(rollback.isEnabling()).isTrue();
assertThat(rollback.getExtensionVersions().toString())
.isEqualTo(extensionVersions.toString());
@@ -175,6 +181,7 @@
origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2));
origRb.info.getCausePackages().add(new VersionedPackage("com.pack.age", 99));
origRb.info.setCommittedSessionId(123456);
+ origRb.info.setRollbackImpactLevel(PackageManager.ROLLBACK_USER_IMPACT_HIGH);
PackageRollbackInfo pkgInfo1 =
new PackageRollbackInfo(new VersionedPackage("com.made.up", 18),
@@ -226,6 +233,7 @@
expectedRb.info.getCausePackages().add(new VersionedPackage("hello", 23));
expectedRb.info.getCausePackages().add(new VersionedPackage("something", 999));
expectedRb.info.setCommittedSessionId(45654465);
+ expectedRb.info.setRollbackImpactLevel(PackageManager.ROLLBACK_USER_IMPACT_HIGH);
PackageRollbackInfo pkgInfo1 = new PackageRollbackInfo(new VersionedPackage("blah", 55),
new VersionedPackage("blah1", 50), new ArrayList<>(), new ArrayList<>(),
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index cbdcb88..518183f 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -30,6 +30,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.PackageManager;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
import android.os.UserManager;
@@ -146,7 +147,8 @@
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
// Upgrade from v1 to v2, with rollbacks enabled.
- Install.single(TestApp.A2).setEnableRollback().commit();
+ Install.single(TestApp.A2).setEnableRollback().setRollbackImpactLevel(
+ PackageManager.ROLLBACK_USER_IMPACT_HIGH).commit();
assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
// The app should now be available for rollback.
@@ -154,6 +156,8 @@
assertThat(available).isNotStaged();
assertThat(available).packagesContainsExactly(
Rollback.from(TestApp.A2).to(TestApp.A1));
+ assertThat(available.getRollbackImpactLevel()).isEqualTo(
+ PackageManager.ROLLBACK_USER_IMPACT_HIGH);
// We should not have received any rollback requests yet.
// TODO: Possibly flaky if, by chance, some other app on device
@@ -264,6 +268,8 @@
RollbackInfo rollbackB = waitForAvailableRollback(TestApp.B);
assertThat(rollbackB).packagesContainsExactly(
Rollback.from(TestApp.B2).to(TestApp.B1));
+ assertThat(rollbackB.getRollbackImpactLevel()).isEqualTo(
+ PackageManager.ROLLBACK_USER_IMPACT_LOW);
// Register rollback committed receiver
RollbackBroadcastReceiver rollbackReceiver = new RollbackBroadcastReceiver();