Add ArchiveState to the PackageUserState

Test: PackageManagerSettingsTests

Change-Id: I31fba0fb34600e0ec3f3030b0d180c5e0949781b
This commit is contained in:
Jakob Schneider
2023-06-16 14:15:35 +01:00
parent 0073d0927d
commit 272f482d1f
11 changed files with 565 additions and 16 deletions

View File

@@ -101,6 +101,30 @@ message PackageProto {
COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4;
}
// Information about the state of an archived app.
// All fields are gathered at the time of archival.
message ArchiveState {
option (android.msg_privacy).dest = DEST_AUTOMATIC;
message ArchiveActivityInfo {
// Corresponds to android:label in the app's locale at the time of archival.
optional string title = 1;
// Icon of the archived app.
optional string icon_bitmap_path = 2;
// Only set if the app defined a monochrome icon.
optional string monochrome_icon_bitmap_path = 3;
}
/** Information about main activities. */
repeated ArchiveActivityInfo activity_infos = 1;
// Corresponds to android:label of the installer responsible for the unarchival of the
// app. Stored in the installer's locale at the time of archival.
optional string installer_title = 2;
}
optional int32 id = 1;
optional InstallType install_type = 2;
// Is the app restricted by owner / admin
@@ -114,6 +138,7 @@ message PackageProto {
optional int32 distraction_flags = 10;
// UTC timestamp of first install for the user
optional int32 first_install_time_ms = 11;
optional ArchiveState archive_state = 12;
}
message InstallSourceProto {

View File

@@ -633,7 +633,8 @@ final class DeletePackageHelper {
null /*harmfulAppWarning*/,
null /*splashScreenTheme*/,
0 /*firstInstallTime*/,
PackageManager.USER_MIN_ASPECT_RATIO_UNSET);
PackageManager.USER_MIN_ASPECT_RATIO_UNSET,
null /*archiveState*/);
}
mPm.mSettings.writeKernelMappingLPr(ps);
}

File diff suppressed because one or more lines are too long

View File

@@ -107,6 +107,7 @@ import com.android.server.pm.permission.LegacyPermissionSettings;
import com.android.server.pm.permission.LegacyPermissionState;
import com.android.server.pm.permission.LegacyPermissionState.PermissionState;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.ArchiveState;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
@@ -153,6 +154,7 @@ import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -316,6 +318,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
private static final String TAG_SUSPEND_PARAMS = "suspend-params";
private static final String TAG_MIME_GROUP = "mime-group";
private static final String TAG_MIME_TYPE = "mime-type";
private static final String TAG_ARCHIVE_STATE = "archive-state";
private static final String TAG_ARCHIVE_ACTIVITY_INFO = "archive-activity-info";
public static final String ATTR_NAME = "name";
public static final String ATTR_PACKAGE = "package";
@@ -362,6 +366,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
private static final String ATTR_DATABASE_VERSION = "databaseVersion";
private static final String ATTR_VALUE = "value";
private static final String ATTR_FIRST_INSTALL_TIME = "first-install-time";
private static final String ATTR_ARCHIVE_ACTIVITY_TITLE = "activity-title";
private static final String ATTR_ARCHIVE_INSTALLER_TITLE = "installer-title";
private static final String ATTR_ARCHIVE_ICON_PATH = "icon-path";
private static final String ATTR_ARCHIVE_MONOCHROME_ICON_PATH = "monochrome-icon-path";
private final Handler mHandler;
@@ -1131,7 +1139,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
null /*harmfulAppWarning*/,
null /*splashscreenTheme*/,
0 /*firstInstallTime*/,
PackageManager.USER_MIN_ASPECT_RATIO_UNSET
PackageManager.USER_MIN_ASPECT_RATIO_UNSET,
null /*archiveState*/
);
}
}
@@ -1807,7 +1816,8 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
null /*harmfulAppWarning*/,
null /* splashScreenTheme*/,
0 /*firstInstallTime*/,
PackageManager.USER_MIN_ASPECT_RATIO_UNSET
PackageManager.USER_MIN_ASPECT_RATIO_UNSET,
null /*archiveState*/
);
}
return;
@@ -1911,6 +1921,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
PersistableBundle suspendedAppExtras = null;
PersistableBundle suspendedLauncherExtras = null;
SuspendDialogInfo oldSuspendDialogInfo = null;
ArchiveState archiveState = null;
int packageDepth = parser.getDepth();
ArrayMap<String, SuspendParams> suspendParamsMap = null;
@@ -1952,6 +1963,9 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
suspendParamsMap.put(suspendingPackage,
SuspendParams.restoreFromXml(parser));
break;
case TAG_ARCHIVE_STATE:
archiveState = parseArchiveState(parser);
break;
default:
Slog.wtf(TAG, "Unknown tag " + parser.getName() + " under tag "
+ TAG_PACKAGE);
@@ -1982,7 +1996,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
uninstallReason, harmfulAppWarning, splashScreenTheme,
firstInstallTime != 0 ? firstInstallTime :
origFirstInstallTimes.getOrDefault(name, 0L),
minAspectRatio);
minAspectRatio, archiveState);
mDomainVerificationManager.setLegacyUserState(name, userId, verifState);
} else if (tagName.equals("preferred-activities")) {
@@ -2011,6 +2025,64 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
}
private static ArchiveState parseArchiveState(TypedXmlPullParser parser)
throws XmlPullParserException, IOException {
String installerTitle = parser.getAttributeValue(null,
ATTR_ARCHIVE_INSTALLER_TITLE);
List<ArchiveState.ArchiveActivityInfo> activityInfos =
parseArchiveActivityInfos(parser);
if (installerTitle == null) {
Slog.wtf(TAG, "parseArchiveState: installerTitle is null");
return null;
}
if (activityInfos.size() < 1) {
Slog.wtf(TAG, "parseArchiveState: activityInfos is empty");
return null;
}
return new ArchiveState(activityInfos, installerTitle);
}
private static List<ArchiveState.ArchiveActivityInfo> parseArchiveActivityInfos(
TypedXmlPullParser parser) throws XmlPullParserException, IOException {
List<ArchiveState.ArchiveActivityInfo> activityInfos = new ArrayList<>();
int type;
int outerDepth = parser.getDepth();
String tagName;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG
|| parser.getDepth() > outerDepth)) {
if (type == XmlPullParser.END_TAG
|| type == XmlPullParser.TEXT) {
continue;
}
tagName = parser.getName();
if (tagName.equals(TAG_ARCHIVE_ACTIVITY_INFO)) {
String title = parser.getAttributeValue(null,
ATTR_ARCHIVE_ACTIVITY_TITLE);
Path iconPath = Path.of(parser.getAttributeValue(null,
ATTR_ARCHIVE_ICON_PATH));
Path monochromeIconPath = Path.of(parser.getAttributeValue(null,
ATTR_ARCHIVE_MONOCHROME_ICON_PATH));
if (title == null || iconPath == null) {
Slog.wtf(TAG,
TextUtils.formatSimple("Missing attributes in tag %s. %s: %s, %s: %s",
TAG_ARCHIVE_ACTIVITY_INFO, ATTR_ARCHIVE_ACTIVITY_TITLE, title,
ATTR_ARCHIVE_ICON_PATH,
iconPath));
continue;
}
activityInfos.add(
new ArchiveState.ArchiveActivityInfo(title, iconPath, monochromeIconPath));
}
}
return activityInfos;
}
void setBlockUninstallLPw(int userId, String packageName, boolean blockUninstall) {
ArraySet<String> packages = mBlockUninstallPackages.get(userId);
if (blockUninstall) {
@@ -2323,6 +2395,7 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
serializer.endTag(null, TAG_DISABLED_COMPONENTS);
}
writeArchiveStateLPr(serializer, ustate.getArchiveState());
serializer.endTag(null, TAG_PACKAGE);
}
@@ -2361,6 +2434,28 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
}
private void writeArchiveStateLPr(TypedXmlSerializer serializer, ArchiveState archiveState)
throws IOException {
if (archiveState == null) {
return;
}
serializer.startTag(null, TAG_ARCHIVE_STATE);
serializer.attribute(null, ATTR_ARCHIVE_INSTALLER_TITLE, archiveState.getInstallerTitle());
for (ArchiveState.ArchiveActivityInfo activityInfo : archiveState.getActivityInfos()) {
serializer.startTag(null, TAG_ARCHIVE_ACTIVITY_INFO);
serializer.attribute(null, ATTR_ARCHIVE_ACTIVITY_TITLE, activityInfo.getTitle());
serializer.attribute(null, ATTR_ARCHIVE_ICON_PATH,
activityInfo.getIconBitmap().toAbsolutePath().toString());
if (activityInfo.getMonochromeIconBitmap() != null) {
serializer.attribute(null, ATTR_ARCHIVE_MONOCHROME_ICON_PATH,
activityInfo.getMonochromeIconBitmap().toAbsolutePath().toString());
}
serializer.endTag(null, TAG_ARCHIVE_ACTIVITY_INFO);
}
serializer.endTag(null, TAG_ARCHIVE_STATE);
}
void readInstallPermissionsLPr(TypedXmlPullParser parser,
LegacyPermissionState permissionsState, List<UserInfo> users)
throws IOException, XmlPullParserException {
@@ -5203,6 +5298,10 @@ public final class Settings implements Watchable, Snappable, ResilientAtomicFile
}
}
}
ArchiveState archiveState = userState.getArchiveState();
if (archiveState != null) {
pw.print(archiveState.toString());
}
}
}

View File

@@ -0,0 +1,306 @@
/*
* Copyright (C) 2023 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.pm.pkg;
import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.internal.util.DataClass;
import java.nio.file.Path;
import java.util.List;
/**
* Information about the state of an archived app. All fields are gathered at the time of
* archival.
*
* @hide
*/
@DataClass(genEqualsHashCode = true, genToString = true)
public class ArchiveState {
/**
* Information about main activities.
*
* <p> This list has at least one entry. In the vast majority of cases, this list has only one
* entry.
*/
@NonNull
private final List<ArchiveActivityInfo> mActivityInfos;
/**
* Corresponds to android:label of the installer responsible for the unarchival of the app.
* Stored in the installer's locale .
*/
@NonNull
private final String mInstallerTitle;
/** Information about a main activity of an archived app. */
@DataClass(genEqualsHashCode = true, genToString = true)
public static class ArchiveActivityInfo {
/** Corresponds to the activity's android:label in the app's locale. */
@NonNull
private final String mTitle;
/** The path to the stored icon of the activity in the app's locale. */
@NonNull
private final Path mIconBitmap;
/** See {@link #mIconBitmap}. Only set if the app defined a monochrome icon. */
@Nullable
private final Path mMonochromeIconBitmap;
// Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/pkg/ArchiveState.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
//@formatter:off
/**
* Creates a new ArchiveActivityInfo.
*
* @param title
* Corresponds to the activity's android:label in the app's locale.
* @param iconBitmap
* The path to the stored icon of the activity in the app's locale.
* @param monochromeIconBitmap
* See {@link #mIconBitmap}. Only set if the app defined a monochrome icon.
*/
@DataClass.Generated.Member
public ArchiveActivityInfo(
@NonNull String title,
@NonNull Path iconBitmap,
@Nullable Path monochromeIconBitmap) {
this.mTitle = title;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mTitle);
this.mIconBitmap = iconBitmap;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mIconBitmap);
this.mMonochromeIconBitmap = monochromeIconBitmap;
// onConstructed(); // You can define this method to get a callback
}
/**
* Corresponds to the activity's android:label in the app's locale.
*/
@DataClass.Generated.Member
public @NonNull String getTitle() {
return mTitle;
}
/**
* The path to the stored icon of the activity in the app's locale.
*/
@DataClass.Generated.Member
public @NonNull Path getIconBitmap() {
return mIconBitmap;
}
/**
* See {@link #mIconBitmap}. Only set if the app defined a monochrome icon.
*/
@DataClass.Generated.Member
public @Nullable Path getMonochromeIconBitmap() {
return mMonochromeIconBitmap;
}
@Override
@DataClass.Generated.Member
public String toString() {
// You can override field toString logic by defining methods like:
// String fieldNameToString() { ... }
return "ArchiveActivityInfo { " +
"title = " + mTitle + ", " +
"iconBitmap = " + mIconBitmap + ", " +
"monochromeIconBitmap = " + mMonochromeIconBitmap +
" }";
}
@Override
@DataClass.Generated.Member
public boolean equals(@Nullable Object o) {
// You can override field equality logic by defining either of the methods like:
// boolean fieldNameEquals(ArchiveActivityInfo other) { ... }
// boolean fieldNameEquals(FieldType otherValue) { ... }
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@SuppressWarnings("unchecked")
ArchiveActivityInfo that = (ArchiveActivityInfo) o;
//noinspection PointlessBooleanExpression
return true
&& java.util.Objects.equals(mTitle, that.mTitle)
&& java.util.Objects.equals(mIconBitmap, that.mIconBitmap)
&& java.util.Objects.equals(mMonochromeIconBitmap, that.mMonochromeIconBitmap);
}
@Override
@DataClass.Generated.Member
public int hashCode() {
// You can override field hashCode logic by defining methods like:
// int fieldNameHashCode() { ... }
int _hash = 1;
_hash = 31 * _hash + java.util.Objects.hashCode(mTitle);
_hash = 31 * _hash + java.util.Objects.hashCode(mIconBitmap);
_hash = 31 * _hash + java.util.Objects.hashCode(mMonochromeIconBitmap);
return _hash;
}
@DataClass.Generated(
time = 1689169065133L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/ArchiveState.java",
inputSignatures = "private final @android.annotation.NonNull java.lang.String mTitle\nprivate final @android.annotation.NonNull java.nio.file.Path mIconBitmap\nprivate final @android.annotation.Nullable java.nio.file.Path mMonochromeIconBitmap\nclass ArchiveActivityInfo extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true)")
@Deprecated
private void __metadata() {}
//@formatter:on
// End of generated code
}
// Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
//
// To regenerate run:
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/pm/pkg/ArchiveState.java
//
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
// Settings > Editor > Code Style > Formatter Control
//@formatter:off
/**
* Creates a new ArchiveState.
*
* @param activityInfos
* Information about main activities.
*
* <p> This list has at least one entry. In the vast majority of cases, this list has only one
* entry.
* @param installerTitle
* Corresponds to android:label of the installer responsible for the unarchival of the app.
* Stored in the installer's locale .
*/
@DataClass.Generated.Member
public ArchiveState(
@NonNull List<ArchiveActivityInfo> activityInfos,
@NonNull String installerTitle) {
this.mActivityInfos = activityInfos;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mActivityInfos);
this.mInstallerTitle = installerTitle;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mInstallerTitle);
// onConstructed(); // You can define this method to get a callback
}
/**
* Information about main activities.
*
* <p> This list has at least one entry. In the vast majority of cases, this list has only one
* entry.
*/
@DataClass.Generated.Member
public @NonNull List<ArchiveActivityInfo> getActivityInfos() {
return mActivityInfos;
}
/**
* Corresponds to android:label of the installer responsible for the unarchival of the app.
* Stored in the installer's locale .
*/
@DataClass.Generated.Member
public @NonNull String getInstallerTitle() {
return mInstallerTitle;
}
@Override
@DataClass.Generated.Member
public String toString() {
// You can override field toString logic by defining methods like:
// String fieldNameToString() { ... }
return "ArchiveState { " +
"activityInfos = " + mActivityInfos + ", " +
"installerTitle = " + mInstallerTitle +
" }";
}
@Override
@DataClass.Generated.Member
public boolean equals(@Nullable Object o) {
// You can override field equality logic by defining either of the methods like:
// boolean fieldNameEquals(ArchiveState other) { ... }
// boolean fieldNameEquals(FieldType otherValue) { ... }
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
@SuppressWarnings("unchecked")
ArchiveState that = (ArchiveState) o;
//noinspection PointlessBooleanExpression
return true
&& java.util.Objects.equals(mActivityInfos, that.mActivityInfos)
&& java.util.Objects.equals(mInstallerTitle, that.mInstallerTitle);
}
@Override
@DataClass.Generated.Member
public int hashCode() {
// You can override field hashCode logic by defining methods like:
// int fieldNameHashCode() { ... }
int _hash = 1;
_hash = 31 * _hash + java.util.Objects.hashCode(mActivityInfos);
_hash = 31 * _hash + java.util.Objects.hashCode(mInstallerTitle);
return _hash;
}
@DataClass.Generated(
time = 1689169065144L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/ArchiveState.java",
inputSignatures = "private final @android.annotation.NonNull java.util.List<com.android.server.pm.pkg.ArchiveActivityInfo> mActivityInfos\nprivate final @android.annotation.NonNull java.lang.String mInstallerTitle\nclass ArchiveState extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true)")
@Deprecated
private void __metadata() {}
//@formatter:on
// End of generated code
}

View File

@@ -380,6 +380,8 @@ public class PackageStateImpl implements PackageState {
@PackageManager.UserMinAspectRatio
private final int mMinAspectRatio;
private final long mFirstInstallTimeMillis;
@Nullable
private final ArchiveState mArchiveState;
private UserStateImpl(@NonNull PackageUserState userState) {
mCeDataInode = userState.getCeDataInode();
@@ -403,6 +405,7 @@ public class PackageStateImpl implements PackageState {
setBoolean(Booleans.SUSPENDED, userState.isSuspended());
setBoolean(Booleans.VIRTUAL_PRELOAD, userState.isVirtualPreload());
mFirstInstallTimeMillis = userState.getFirstInstallTimeMillis();
mArchiveState = userState.getArchiveState();
}
@Override
@@ -555,6 +558,11 @@ public class PackageStateImpl implements PackageState {
return mFirstInstallTimeMillis;
}
@DataClass.Generated.Member
public @Nullable ArchiveState getArchiveState() {
return mArchiveState;
}
@DataClass.Generated.Member
public @NonNull UserStateImpl setBooleans( int value) {
mBooleans = value;
@@ -562,10 +570,10 @@ public class PackageStateImpl implements PackageState {
}
@DataClass.Generated(
time = 1687938966108L,
time = 1689171425723L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java",
inputSignatures = "private int mBooleans\nprivate final long mCeDataInode\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mDisabledComponents\nprivate final @android.content.pm.PackageManager.DistractionRestriction int mDistractionFlags\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mEnabledComponents\nprivate final int mEnabledState\nprivate final @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate final @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate final @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate final @android.annotation.NonNull android.content.pm.overlay.OverlayPaths mOverlayPaths\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate final @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate final @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate final @android.content.pm.PackageManager.UserMinAspectRatio int mMinAspectRatio\nprivate final long mFirstInstallTimeMillis\npublic static com.android.server.pm.pkg.PackageUserState copy(com.android.server.pm.pkg.PackageUserState)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isSuspended()\npublic @java.lang.Override boolean isVirtualPreload()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\nclass UserStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageUserState]\nprivate static final int HIDDEN\nprivate static final int INSTALLED\nprivate static final int INSTANT_APP\nprivate static final int NOT_LAUNCHED\nprivate static final int STOPPED\nprivate static final int SUSPENDED\nprivate static final int VIRTUAL_PRELOAD\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)")
inputSignatures = "private int mBooleans\nprivate final long mCeDataInode\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mDisabledComponents\nprivate final @android.content.pm.PackageManager.DistractionRestriction int mDistractionFlags\nprivate final @android.annotation.NonNull android.util.ArraySet<java.lang.String> mEnabledComponents\nprivate final int mEnabledState\nprivate final @android.annotation.Nullable java.lang.String mHarmfulAppWarning\nprivate final @android.content.pm.PackageManager.InstallReason int mInstallReason\nprivate final @android.annotation.Nullable java.lang.String mLastDisableAppCaller\nprivate final @android.annotation.NonNull android.content.pm.overlay.OverlayPaths mOverlayPaths\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,android.content.pm.overlay.OverlayPaths> mSharedLibraryOverlayPaths\nprivate final @android.content.pm.PackageManager.UninstallReason int mUninstallReason\nprivate final @android.annotation.Nullable java.lang.String mSplashScreenTheme\nprivate final @android.content.pm.PackageManager.UserMinAspectRatio int mMinAspectRatio\nprivate final long mFirstInstallTimeMillis\nprivate final @android.annotation.Nullable com.android.server.pm.pkg.ArchiveState mArchiveState\npublic static com.android.server.pm.pkg.PackageUserState copy(com.android.server.pm.pkg.PackageUserState)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @java.lang.Override boolean isHidden()\npublic @java.lang.Override boolean isInstalled()\npublic @java.lang.Override boolean isInstantApp()\npublic @java.lang.Override boolean isNotLaunched()\npublic @java.lang.Override boolean isStopped()\npublic @java.lang.Override boolean isSuspended()\npublic @java.lang.Override boolean isVirtualPreload()\npublic @java.lang.Override boolean isComponentEnabled(java.lang.String)\npublic @java.lang.Override boolean isComponentDisabled(java.lang.String)\npublic @java.lang.Override android.content.pm.overlay.OverlayPaths getAllOverlayPaths()\nclass UserStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageUserState]\nprivate static final int HIDDEN\nprivate static final int INSTALLED\nprivate static final int INSTANT_APP\nprivate static final int NOT_LAUNCHED\nprivate static final int STOPPED\nprivate static final int SUSPENDED\nprivate static final int VIRTUAL_PRELOAD\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)")
@Deprecated
private void __metadata() {}
@@ -737,7 +745,7 @@ public class PackageStateImpl implements PackageState {
}
@DataClass.Generated(
time = 1671671043929L,
time = 1689171425753L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java",
inputSignatures = "private int mBooleans\nprivate final @android.annotation.Nullable com.android.server.pm.pkg.AndroidPackage mAndroidPackage\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mVolumeUuid\nprivate final int mAppId\nprivate final int mCategoryOverride\nprivate final @android.annotation.Nullable java.lang.String mCpuAbiOverride\nprivate final @android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy int mHiddenApiEnforcementPolicy\nprivate final long mLastModifiedTime\nprivate final long mLastUpdateTime\nprivate final long mLongVersionCode\nprivate final @android.annotation.NonNull java.util.Map<java.lang.String,java.util.Set<java.lang.String>> mMimeGroups\nprivate final @android.annotation.NonNull java.io.File mPath\nprivate final @android.annotation.Nullable java.lang.String mPrimaryCpuAbi\nprivate final @android.annotation.Nullable java.lang.String mSecondaryCpuAbi\nprivate final @android.annotation.Nullable java.lang.String mSeInfo\nprivate final boolean mHasSharedUser\nprivate final int mSharedUserAppId\nprivate final @android.annotation.NonNull java.lang.String[] mUsesSdkLibraries\nprivate final @android.annotation.NonNull long[] mUsesSdkLibrariesVersionsMajor\nprivate final @android.annotation.NonNull java.lang.String[] mUsesStaticLibraries\nprivate final @android.annotation.NonNull long[] mUsesStaticLibrariesVersions\nprivate final @android.annotation.NonNull java.util.List<com.android.server.pm.pkg.SharedLibrary> mUsesLibraries\nprivate final @android.annotation.NonNull java.util.List<java.lang.String> mUsesLibraryFiles\nprivate final @android.annotation.NonNull long[] mLastPackageUsageTime\nprivate final @android.annotation.NonNull android.content.pm.SigningInfo mSigningInfo\nprivate final @android.annotation.NonNull android.util.SparseArray<com.android.server.pm.pkg.PackageUserState> mUserStates\nprivate final @android.annotation.Nullable java.lang.String mApexModuleName\npublic static com.android.server.pm.pkg.PackageState copy(com.android.server.pm.pkg.PackageStateInternal)\nprivate void setBoolean(int,boolean)\nprivate boolean getBoolean(int)\npublic @android.annotation.NonNull @java.lang.Override com.android.server.pm.pkg.PackageUserState getStateForUser(android.os.UserHandle)\npublic @java.lang.Override boolean isExternalStorage()\npublic @java.lang.Override boolean isForceQueryableOverride()\npublic @java.lang.Override boolean isHiddenUntilInstalled()\npublic @java.lang.Override boolean isInstallPermissionsFixed()\npublic @java.lang.Override boolean isOdm()\npublic @java.lang.Override boolean isOem()\npublic @java.lang.Override boolean isPrivileged()\npublic @java.lang.Override boolean isProduct()\npublic @java.lang.Override boolean isRequiredForSystemUser()\npublic @java.lang.Override boolean isSystem()\npublic @java.lang.Override boolean isSystemExt()\npublic @java.lang.Override boolean isUpdateAvailable()\npublic @java.lang.Override boolean isUpdatedSystemApp()\npublic @java.lang.Override boolean isApkInUpdatedApex()\npublic @java.lang.Override boolean isVendor()\npublic @java.lang.Override long getVersionCode()\npublic @java.lang.Override boolean hasSharedUser()\npublic @java.lang.Override boolean isApex()\nclass PackageStateImpl extends java.lang.Object implements [com.android.server.pm.pkg.PackageState]\nprivate static final int SYSTEM\nprivate static final int EXTERNAL_STORAGE\nprivate static final int PRIVILEGED\nprivate static final int OEM\nprivate static final int VENDOR\nprivate static final int PRODUCT\nprivate static final int SYSTEM_EXT\nprivate static final int REQUIRED_FOR_SYSTEM_USER\nprivate static final int ODM\nprivate static final int FORCE_QUERYABLE_OVERRIDE\nprivate static final int HIDDEN_UNTIL_INSTALLED\nprivate static final int INSTALL_PERMISSIONS_FIXED\nprivate static final int UPDATE_AVAILABLE\nprivate static final int UPDATED_SYSTEM_APP\nprivate static final int APK_IN_UPDATED_APEX\nclass Booleans extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false)")

View File

@@ -225,4 +225,12 @@ public interface PackageUserState {
*/
@PackageManager.UserMinAspectRatio
int getMinAspectRatio();
/**
* Information about the archived state of an app. Set only if an app is archived.
*
* @hide
*/
@Immutable.Ignore
@Nullable
ArchiveState getArchiveState();
}

View File

@@ -185,4 +185,10 @@ class PackageUserStateDefault implements PackageUserStateInternal {
@NonNull ComponentName componentName) {
return null;
}
@Nullable
@Override
public ArchiveState getArchiveState() {
return null;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -68,6 +68,7 @@ import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.permission.LegacyPermissionDataProvider;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.ArchiveState;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.SuspendParams;
@@ -863,6 +864,34 @@ public class PackageManagerSettingsTests {
.containsExactlyElementsIn(ps2VersionsAsList).inOrder();
}
@Test
public void testWriteReadArchiveState() {
Settings settings = makeSettings();
PackageSetting packageSetting = createPackageSetting(PACKAGE_NAME_1);
packageSetting.setAppId(Process.FIRST_APPLICATION_UID);
packageSetting.setPkg(PackageImpl.forTesting(PACKAGE_NAME_1).hideAsParsed()
.setUid(packageSetting.getAppId())
.hideAsFinal());
ArchiveState archiveState = new ArchiveState(
List.of(new ArchiveState.ArchiveActivityInfo("title1", Path.of("/path1"),
Path.of("/monochromePath1")),
new ArchiveState.ArchiveActivityInfo("title2", Path.of("/path2"),
Path.of("/monochromePath2"))),
"installerTitle");
packageSetting.modifyUserState(UserHandle.SYSTEM.getIdentifier()).setArchiveState(
archiveState);
settings.mPackages.put(PACKAGE_NAME_1, packageSetting);
settings.writeLPr(computer, /*sync=*/true);
settings.mPackages.clear();
assertThat(settings.readLPw(computer, createFakeUsers()), is(true));
Truth.assertThat(settings.getPackageLPr(PACKAGE_NAME_1).getStateForUser(
UserHandle.SYSTEM).getArchiveState()).isEqualTo(archiveState);
}
@Test
public void testPackageRestrictionsDistractionFlagsDefault() {
final PackageSetting defaultSetting = createPackageSetting(PACKAGE_NAME_1);
@@ -971,7 +1000,7 @@ public class PackageManagerSettingsTests {
origPkgSetting01.setUserState(0, 100, 1, true, false, false, false, 0, null, false,
false, "lastDisabledCaller", new ArraySet<>(new String[]{"enabledComponent1"}),
new ArraySet<>(new String[]{"disabledComponent1"}), 0, 0, "harmfulAppWarning",
"splashScreenTheme", 1000L, PackageManager.USER_MIN_ASPECT_RATIO_UNSET);
"splashScreenTheme", 1000L, PackageManager.USER_MIN_ASPECT_RATIO_UNSET, null);
final PersistableBundle appExtras1 = createPersistableBundle(
PACKAGE_NAME_1, 1L, 0.01, true, "appString1");
final PersistableBundle launcherExtras1 = createPersistableBundle(

View File

@@ -35,6 +35,7 @@ import android.util.ArraySet;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.server.pm.pkg.ArchiveState;
import com.android.server.pm.pkg.PackageStateUnserialized;
import com.android.server.pm.pkg.PackageUserStateImpl;
import com.android.server.pm.pkg.SuspendParams;
@@ -44,6 +45,9 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import java.nio.file.Path;
import java.util.List;
@Presubmit
@RunWith(AndroidJUnit4.class)
@SmallTest
@@ -394,4 +398,14 @@ public class PackageUserStateTest {
assertFalse(testState.setSharedLibraryOverlayPaths(LIB_ONE, null));
}
@Test
public void archiveState() {
PackageUserStateImpl packageUserState = new PackageUserStateImpl();
ArchiveState.ArchiveActivityInfo archiveActivityInfo = new ArchiveState.ArchiveActivityInfo(
"appTitle", Path.of("/path1"), Path.of("/path2"));
ArchiveState archiveState = new ArchiveState(List.of(archiveActivityInfo),
"installerTitle");
packageUserState.setArchiveState(archiveState);
assertEquals(archiveState, packageUserState.getArchiveState());
}
}